private static TestCaseExecutor GetTestCaseExecutor(TestExecutionData testExecutionData, RunOptions options, TestCategory inputTestCategory, RSACryptoServiceProvider rsaProvider, RSACryptoServiceProvider rsaProviderOld)
        {
            bool officeNative = inputTestCategory == TestCategory.OfficeNativeClient ||
                                testExecutionData.TestCase.TestCategory == TestCategory.OfficeNativeClient;
            string userAgent = officeNative ? Constants.HeaderValues.OfficeNativeClientUserAgent : null;

            return(new TestCaseExecutor(testExecutionData, options.WopiEndpoint, options.AccessToken, options.AccessTokenTtl, userAgent, rsaProvider, rsaProviderOld));
        }
        private static TestCaseExecutor GetTestCaseExecutor(TestExecutionData testExecutionData, Options options, TestCategory inputTestCategory)
        {
            TestCategory testCategory;

            if (!Enum.TryParse(testExecutionData.TestCase.Category, true /* ignoreCase */, out testCategory))
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "Invalid TestCategory for TestCase : {0}", testExecutionData.TestCase.Name));
            }

            string userAgent = (inputTestCategory == TestCategory.OfficeNativeClient || testCategory == TestCategory.OfficeNativeClient) ? Constants.HeaderValues.OfficeNativeClientUserAgent : null;

            return(new TestCaseExecutor(testExecutionData, options.WopiEndpoint, options.AccessToken, options.AccessTokenTtl, userAgent));
        }
        private static ExitCode Execute(Options options)
        {
            // get run configuration from XML
            IEnumerable <TestExecutionData> testData = ConfigParser.ParseExecutionData(options.RunConfigurationFilePath, options.TestCategory);

            if (!String.IsNullOrEmpty(options.TestGroup))
            {
                testData = testData.Where(d => d.TestGroupName == options.TestGroup);
            }

            IEnumerable <TestExecutionData> executionData;

            if (!String.IsNullOrWhiteSpace(options.TestName))
            {
                executionData = new TestExecutionData[] { TestExecutionData.GetDataForSpecificTest(testData, options.TestName) };
            }
            else
            {
                executionData = testData;
            }

            // Create executor groups
            var executorGroups = executionData.GroupBy(d => d.TestGroupName)
                                 .Select(g => new
            {
                Name      = g.Key,
                Executors = g.Select(x => GetTestCaseExecutor(x, options, options.TestCategory))
            });

            ConsoleColor           baseColor      = ConsoleColor.White;
            HashSet <ResultStatus> resultStatuses = new HashSet <ResultStatus>();

            foreach (var group in executorGroups)
            {
                WriteToConsole($"\nTest group: {group.Name}\n", ConsoleColor.White);

                // define execution query - evaluation is lazy; test cases are executed one at a time
                // as you iterate over returned collection
                var results = group.Executors.Select(x => x.Execute());

                // iterate over results and print success/failure indicators into console
                foreach (TestCaseResult testCaseResult in results)
                {
                    resultStatuses.Add(testCaseResult.Status);
                    switch (testCaseResult.Status)
                    {
                    case ResultStatus.Pass:
                        baseColor = ConsoleColor.Green;
                        WriteToConsole($"Pass: {testCaseResult.Name}\n", baseColor, 1);
                        break;

                    case ResultStatus.Skipped:
                        baseColor = ConsoleColor.Yellow;
                        if (!options.IgnoreSkipped)
                        {
                            WriteToConsole($"Skipped: {testCaseResult.Name}\n", baseColor, 1);
                        }
                        break;

                    case ResultStatus.Fail:
                    default:
                        baseColor = ConsoleColor.Red;
                        WriteToConsole($"Fail: {testCaseResult.Name}\n", baseColor, 1);
                        break;
                    }

                    if (testCaseResult.Status == ResultStatus.Fail ||
                        (testCaseResult.Status == ResultStatus.Skipped && !options.IgnoreSkipped))
                    {
                        foreach (var request in testCaseResult.RequestDetails)
                        {
                            var responseStatus = (HttpStatusCode)request.ResponseStatusCode;
                            var color          = request.ValidationFailures.Count == 0 ? ConsoleColor.DarkGreen : baseColor;
                            WriteToConsole($"{request.Name}, response code: {request.ResponseStatusCode} {responseStatus}\n", color, 2);
                            foreach (var failure in request.ValidationFailures)
                            {
                                foreach (var error in failure.Errors)
                                {
                                    WriteToConsole($"{error}\n", baseColor, 3);
                                }
                            }
                        }

                        WriteToConsole($"Re-run command: .\\wopivalidator.exe -n {testCaseResult.Name} -w {options.WopiEndpoint} -t {options.AccessToken} -l {options.AccessTokenTtl}\n", baseColor, 2);
                        Console.WriteLine();
                    }
                }

                if (options.IgnoreSkipped && !resultStatuses.ContainsAny(ResultStatus.Pass, ResultStatus.Fail))
                {
                    WriteToConsole($"All tests skipped.\n", baseColor, 1);
                }
            }

            // If skipped tests are ignored, don't consider them when determining whether the test run passed or failed
            if (options.IgnoreSkipped)
            {
                if (resultStatuses.Contains(ResultStatus.Fail))
                {
                    return(ExitCode.Failure);
                }
            }
            // Otherwise consider skipped tests as failures
            else if (resultStatuses.ContainsAny(ResultStatus.Skipped, ResultStatus.Fail))
            {
                return(ExitCode.Failure);
            }
            return(ExitCode.Success);
        }