public override ColorTextBuilder Write(object parameters = null)
        {
            var allReports    = (IEnumerable <DataEvent>)parameters;
            var builder       = new ColorTextBuilder();
            var lineSeparator = new string(UTF8Constants.HorizontalLine, !_console.IsOutputRedirected ? (Console.WindowWidth - 1) : DefaultBorderWidth);

            var showErrors      = _configuration.GenerateReportType.HasFlag(GenerateReportType.Errors);
            var showStackTraces = _configuration.GenerateReportType.HasFlag(GenerateReportType.StackTraces);
            var showTestOutput  = _configuration.GenerateReportType.HasFlag(GenerateReportType.TestOutput);

            if (showErrors || showStackTraces || showTestOutput)
            {
                var isPassed = allReports
                               .SelectMany(x => x.Report.TestReports)
                               .Count(x => x.TestStatus == TestStatus.Fail) == 0;

                if (!isPassed)
                {
                    WriteRoundBox(builder, "FAILED TESTS", 0, _colorScheme.Error);
                }

                var testIndex    = 0;
                var groupedByRun = allReports
                                   .GroupBy(x => x.RunNumber);
                var failedTestCases = groupedByRun
                                      .ToDictionary(x => x.Key, value => value.SelectMany(y => y.Report.TestReports.Where(z => z.TestStatus == TestStatus.Fail)));
                var lineSeparatorColor = _colorScheme.RaisedBackground;
                foreach (var testGroup in failedTestCases)
                {
                    var runNumber = testGroup.Key;
                    foreach (var test in testGroup.Value)
                    {
                        testIndex++;

                        // write the failed test header
                        if (!_console.IsOutputRedirected)
                        {
                            builder.AppendLine($"{DisplayUtil.Pad(Console.WindowWidth - 1)}", _colorScheme.Error, _colorScheme.DarkError);
                        }
                        var testIndexStr = $"#{testIndex}) ";
                        if (failedTestCases.Count() > 1)
                        {
                            testIndexStr = $"#{runNumber}-{testIndex}) ";
                        }
                        builder.Append(testIndexStr, _colorScheme.DarkError);

                        // write the test name only
                        builder.Append(test.TestName, _colorScheme.Error);
                        if (!_console.IsOutputRedirected)
                        {
                            builder.AppendLine($"{DisplayUtil.Pad(Console.WindowWidth - testIndexStr.Length - test.TestName.Length - 1)}", _colorScheme.Error);
                        }
                        else
                        {
                            builder.AppendLine();
                        }

                        // write the test path + name (for Stack Trace Explorer)
                        var fullName = $"{DisplayUtil.Pad(testIndexStr.Length)}{test.FullName}";
                        builder.Append(fullName, _colorScheme.DarkDuration);
                        if (!_console.IsOutputRedirected)
                        {
                            builder.AppendLine($"{DisplayUtil.Pad(Console.WindowWidth - fullName.Length - 1)}", _colorScheme.Error);
                        }
                        else
                        {
                            builder.AppendLine();
                        }

                        var runtimeVersion = $"{DisplayUtil.Pad(testIndexStr.Length)}{test.RuntimeVersion}";
                        builder.Append($"{runtimeVersion}", _colorScheme.DarkDefault);
                        if (!_console.IsOutputRedirected)
                        {
                            builder.AppendLine($"{DisplayUtil.Pad(Console.WindowWidth - runtimeVersion.Length)}", _colorScheme.Error);
                        }
                        else
                        {
                            builder.AppendLine();
                        }

                        builder.Append($"  Duration ", _colorScheme.DarkDefault);
                        builder.AppendLine($"{test.Duration.ToElapsedTime()}", _colorScheme.Duration);

                        if (showErrors && !string.IsNullOrEmpty(test.ErrorMessage))
                        {
                            builder.AppendLine($"  Error Output ", _colorScheme.Bright);
                            builder.AppendLine(lineSeparator, lineSeparatorColor);
                            if (!_configuration.DontPrettify)
                            {
                                var errorMessage = ErrorEncoding.Format(test.ErrorMessage, _colorScheme);
                                builder.Append(errorMessage);
                            }
                            else
                            {
                                builder.Append(test.ErrorMessage);
                            }
                            builder.AppendLine();
                            builder.AppendLine(lineSeparator, lineSeparatorColor);
                        }
                        if (showStackTraces && !string.IsNullOrEmpty(test.StackTrace))
                        {
                            builder.AppendLine($"  Stack Trace:", _colorScheme.Bright);
                            builder.AppendLine(lineSeparator, lineSeparatorColor);
                            if (!_configuration.DontPrettify)
                            {
                                builder.Append(StackTracePrettify.Format(test.StackTrace, _colorScheme));
                            }
                            else
                            {
                                builder.Append(test.StackTrace);
                            }
                            builder.AppendLine();
                            builder.AppendLine(lineSeparator, lineSeparatorColor);
                        }
                        if (showTestOutput && !string.IsNullOrEmpty(test.TestOutput))
                        {
                            builder.AppendLine($"  Test Output: ", _colorScheme.Bright);
                            builder.AppendLine(lineSeparator, lineSeparatorColor);
                            if (!_configuration.DontPrettify)
                            {
                                builder.Append(ErrorEncoding.Format(test.TestOutput, _colorScheme));
                            }
                            else
                            {
                                builder.Append(test.TestOutput);
                            }
                            builder.AppendLine();
                            builder.AppendLine(lineSeparator, lineSeparatorColor);
                        }
                        builder.AppendLine(Environment.NewLine);
                    }
                }
            }
            return(builder);
        }
예제 #2
0
        public void Draw(ViewContext context, long ticks)
        {
            if (_startTicks == 0)
            {
                _startTicks = ticks;
                context.Console.Clear();
            }

            if (!context.Console.IsOutputRedirected)
            {
                // if the user has scrolled the page don't perform any drawing
                if (Console.WindowTop > 0)
                {
                    return;
                }

                Console.CursorVisible = false;
                _performFullDraw      = (_startTicks - ticks) % DefaultTickWait == 0;
                var windowWidth  = Console.WindowWidth;
                var windowHeight = Console.WindowHeight;
                if (windowHeight != _previousWindowHeight)
                {
                    _performFullDraw = true;
                }
                _previousWindowHeight = windowHeight;

                if (_performFullDraw)
                {
                    ClearScreen(context);
                }

                var lineSeparator = DisplayUtil.Pad(Console.WindowWidth - 1, UTF8Constants.HorizontalLine);
                var yPos          = 0;
                WriteHeader(context);
                // figure out how many tests we can fit on screen
                var maxActiveTestsToDisplay = Console.WindowHeight - yPos - 2;

                var totalActive         = context.ActiveTests.Count(x => !x.IsQueuedForRemoval);
                var totalPasses         = context.EventLog.Count(x => x.Event.Event == EventNames.EndTest && x.Event.TestStatus == TestStatus.Pass);
                var totalFails          = context.EventLog.Count(x => x.Event.Event == EventNames.EndTest && x.Event.TestStatus == TestStatus.Fail);
                var totalIgnored        = context.EventLog.Count(x => x.Event.Event == EventNames.EndTest && x.Event.TestStatus == TestStatus.Skipped);
                var totalTestsProcessed = context.EventLog.Count(x => x.Event.Event == EventNames.EndTest);

                // write the summary of all test state
                context.Console.WriteAt(ColorTextBuilder.Create
                                        .Append("Tests state: ", context.ColorScheme.Bright)
                                        .Append($"Active=", context.ColorScheme.Default)
                                        .Append($"{totalActive} ", context.ColorScheme.Highlight)
                                        .Append($"Pass="******"{totalPasses} ", context.ColorScheme.Success)
                                        .AppendIf(totalPasses == 0, $"{totalPasses} ", context.ColorScheme.Default)
                                        .Append($"Fail=", context.ColorScheme.Default)
                                        .AppendIf(totalFails > 0, $"{totalFails} ", context.ColorScheme.DarkError)
                                        .AppendIf(totalFails == 0, $"{totalFails} ", context.ColorScheme.Default)
                                        .AppendIf(!context.Console.IsOutputRedirected, $"Ignored=", context.ColorScheme.Default)
                                        .AppendIf(!context.Console.IsOutputRedirected, $"{totalIgnored} ", context.ColorScheme.DarkDefault)
                                        .Append($"Total=", context.ColorScheme.Default)
                                        .Append($"{totalTestsProcessed} ", context.ColorScheme.DarkDefault)
                                        .AppendIf(context.TotalTestsQueued > 0, $"of ", context.ColorScheme.Default)
                                        .AppendIf(context.TotalTestsQueued > 0, $"{context.TotalTestsQueued} ", context.ColorScheme.DarkDefault)
                                        .AppendIf(context.TotalTestsQueued > 0, $"{UTF8Constants.LeftBracket}", context.ColorScheme.Bright)
                                        .AppendIf(context.TotalTestsQueued > 0, $"{((totalTestsProcessed / (double)context.TotalTestsQueued) * 100.0):F0}%", context.ColorScheme.DarkDuration)
                                        .AppendIf(context.TotalTestsQueued > 0, $"{UTF8Constants.RightBracket}", context.ColorScheme.Bright)
                                        //.Append(context.Client.IsWaitingForConnection ? $"{UTF8Constants.LeftBracket}waiting{UTF8Constants.RightBracket}" : "", context.ColorScheme.DarkDuration)
                                        .AppendIf(!context.Console.IsOutputRedirected, (length) => DisplayUtil.Pad(windowWidth - length)),
                                        0,
                                        yPos + 1,
                                        DirectOutputMode.Static);

                var failedTests = context.EventLog
                                  .Where(x => x.Event.Event == EventNames.EndTest && x.Event.TestStatus == TestStatus.Fail)
                                  .GroupBy(x => x.Event.TestName)
                                  .Select(x => x.FirstOrDefault())
                                  .OrderByDescending(x => x.DateAdded)
                                  .Take(context.Configuration.MaxFailedTestsToDisplay);
                context.Console.WriteAt(ColorTextBuilder.Create.AppendLine($"Failed Tests Report", context.ColorScheme.Error), 0, yPos + 2, DirectOutputMode.Static);
                if (!failedTests.Any())
                {
                    context.Console.WriteAt(ColorTextBuilder.Create.AppendLine($"There are no failed tests.", context.ColorScheme.Default), 0, yPos + 4, DirectOutputMode.Static);
                }
                else
                {
                    // don't display this as often as its expensive to write
                    if (_performFullDraw)
                    {
                        context.Console.SetCursorPosition(0, yPos + 5);
                        foreach (var test in failedTests)
                        {
                            var testOutput = new ColorTextBuilder();
                            var errorTime  = test.DateAdded;
                            var duration   = DateTime.Now.Subtract(test.Event.StartTime);
                            if (test.Event.EndTime != DateTime.MinValue)
                            {
                                duration = test.Event.Duration;
                            }
                            var prettyTestName = DisplayUtil.GetPrettyTestName(test.Event.FullName, context.ColorScheme.DarkDefault, context.ColorScheme.Default, context.ColorScheme.DarkDefault, context.MaxTestCaseArgumentLength);
                            // print out this test name and duration
                            testOutput.Append(ColorTextBuilder.Create
                                              .Append($" {UTF8Constants.Bullet} ")
                                              .Append(prettyTestName)
                                              .Append($" {duration.ToTotalElapsedTime()}", context.ColorScheme.Duration)
                                              .Append($" {UTF8Constants.LeftBracket}", context.ColorScheme.Bright)
                                              .Append("FAILED", context.ColorScheme.Error)
                                              .Append($"{UTF8Constants.RightBracket}", context.ColorScheme.Bright)
                                              // clear out the rest of the line
                                              .AppendIf((length) => !context.Console.IsOutputRedirected && length < windowWidth, (length) => DisplayUtil.Pad(windowWidth - length))
                                              .Truncate(windowWidth));
                            testOutput.Append(ColorTextBuilder.Create.Append("  Failed at: ", context.ColorScheme.Default).AppendLine($"{errorTime.ToString(Constants.TimeFormat)}", context.ColorScheme.DarkDuration));

                            // print out errors
                            if (!string.IsNullOrEmpty(test.Event.ErrorMessage))
                            {
                                testOutput.AppendLine($"  Error Output: ", context.ColorScheme.Bright);
                                testOutput.AppendLine(lineSeparator, context.ColorScheme.DarkDefault);
                                if (!context.Configuration.DontPrettify)
                                {
                                    testOutput.Append(ErrorEncoding.Format(test.Event.ErrorMessage, context.ColorScheme));
                                }
                                else
                                {
                                    testOutput.Append(test.Event.ErrorMessage);
                                }
                                testOutput.AppendLine();
                                testOutput.AppendLine(lineSeparator, context.ColorScheme.DarkDefault);
                            }
                            if (!string.IsNullOrEmpty(test.Event.StackTrace))
                            {
                                testOutput.AppendLine($"  Stack Trace:", context.ColorScheme.Bright);
                                testOutput.AppendLine(lineSeparator, context.ColorScheme.DarkDefault);
                                if (!context.Configuration.DontPrettify)
                                {
                                    testOutput.Append(StackTracePrettify.Format(test.Event.StackTrace, context.ColorScheme));
                                }
                                else
                                {
                                    testOutput.Append(test.Event.StackTrace);
                                }
                                testOutput.AppendLine();
                                testOutput.AppendLine(lineSeparator, context.ColorScheme.DarkDefault);
                            }
                            if (!string.IsNullOrEmpty(test.Event.TestOutput))
                            {
                                testOutput.AppendLine($"  Test Output: ", context.ColorScheme.Bright);
                                testOutput.AppendLine(lineSeparator, context.ColorScheme.DarkDefault);
                                if (!context.Configuration.DontPrettify)
                                {
                                    testOutput.Append(ErrorEncoding.Format(test.Event.TestOutput, context.ColorScheme));
                                }
                                else
                                {
                                    testOutput.Append(test.Event.TestOutput);
                                }
                                testOutput.AppendLine();
                                testOutput.AppendLine(lineSeparator, context.ColorScheme.DarkDefault);
                            }
                            testOutput.AppendLine();
                            testOutput.AppendLine();

                            context.Console.WriteLine(testOutput);
                        }

                        context.Console.SetCursorPosition(0, 0);
                    }
                }
            }
        }