public async Task <TestResult> ExecuteTest(TestInfo testInfo) { var stopWatch = new Stopwatch(); stopWatch.Start(); var testResult = new TestResult { Success = true }; var summary = _execContext.Storage.Summary; // don't log sub flows as the TestName changes _log.Info($"------- {testInfo.Name} started... -------"); summary.LogData[SummaryFields.TestName] = testInfo.Name; LoadTasks(testInfo); summary.LogData[SummaryFields.TaskCount] = testInfo.Tasks.Count.ToString(); try { foreach (var taskInfo in testInfo.Tasks) { var taskResult = await new TaskHelper(_execContext).ExecuteTask(testInfo, taskInfo); if (!taskResult.Success) { _log.Info($"{taskInfo.TaskName} ({taskInfo.Action}) failed!"); summary.LogData[SummaryFields.FailedTask] = $"{taskInfo.TaskName} ({taskInfo.Action})"; // Saving failed test log for debugging purpose PersistLog(testInfo); testResult.Success = false; // Retry when there is a recoverable error testResult.Retry = taskResult.IsError; break; } _log.Info($"{taskInfo.TaskName} ({taskInfo.Action}) succeeded."); } } finally { testResult.Status = $"{testInfo.Name} {(testResult.Success ? "passed" : "failed")}!"; summary.LogData[SummaryFields.FullName] = testInfo.FullName; summary.LogData[SummaryFields.Environment] = testInfo.Environment.ToString(); summary.LogData[SummaryFields.Plugin] = testInfo.GetPlugin(); summary.LogData[SummaryFields.TestResult] = testResult.Success ? "Pass" : "Fail"; summary.LogData[SummaryFields.ExecutionTime] = stopWatch.ElapsedMilliseconds.ToString(); SeleniumHelper.Cleanup(testInfo.Browser, testInfo.Language); stopWatch.Stop(); _log.Info($"------- {testResult.Status} -------"); } return(testResult); }