diff --git a/src/Cli/dotnet/Commands/Test/MTP/MicrosoftTestingPlatformTestCommand.cs b/src/Cli/dotnet/Commands/Test/MTP/MicrosoftTestingPlatformTestCommand.cs
index 72544580293c..2883069e62e3 100644
--- a/src/Cli/dotnet/Commands/Test/MTP/MicrosoftTestingPlatformTestCommand.cs
+++ b/src/Cli/dotnet/Commands/Test/MTP/MicrosoftTestingPlatformTestCommand.cs
@@ -111,12 +111,23 @@ private void InitializeOutput(int degreeOfParallelism, ParseResult parseResult,
// TODO: Replace this with proper CI detection that we already have in telemetry. https://github.com/microsoft/testfx/issues/5533#issuecomment-2838893327
bool inCI = string.Equals(Environment.GetEnvironmentVariable("TF_BUILD"), "true", StringComparison.OrdinalIgnoreCase) || string.Equals(Environment.GetEnvironmentVariable("GITHUB_ACTIONS"), "true", StringComparison.OrdinalIgnoreCase);
+ AnsiMode ansiMode = AnsiMode.AnsiIfPossible;
+ if (noAnsi)
+ {
+ // User explicitly specified --no-ansi.
+ // We should respect that.
+ ansiMode = AnsiMode.NoAnsi;
+ }
+ else if (inCI)
+ {
+ ansiMode = AnsiMode.SimpleAnsi;
+ }
+
_output = new TerminalTestReporter(console, new TerminalTestReporterOptions()
{
ShowPassedTests = showPassedTests,
ShowProgress = !noProgress,
- UseAnsi = !noAnsi,
- UseCIAnsi = inCI,
+ AnsiMode = ansiMode,
ShowAssembly = true,
ShowAssemblyStartAndComplete = true,
MinimumExpectedTests = parseResult.GetValue(definition.MinimumExpectedTestsOption),
diff --git a/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs b/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs
index b41c516cb27b..6dff401f6793 100644
--- a/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs
+++ b/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs
@@ -1,6 +1,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Collections.Concurrent;
+using System.Diagnostics;
using System.Globalization;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
@@ -70,27 +71,32 @@ public TerminalTestReporter(IConsole console, TerminalTestReporterOptions option
int nonAnsiUpdateCadenceInMs = 3_000;
// When writing to ANSI we update the progress in place and it should look responsive so we update every half second, because we only show seconds on the screen, so it is good enough.
int ansiUpdateCadenceInMs = 500;
- if (!_options.UseAnsi)
+
+ if (_options.AnsiMode == AnsiMode.SimpleAnsi)
{
- terminalWithProgress = new TestProgressStateAwareTerminal(new NonAnsiTerminal(console), _options.ShowProgress, writeProgressImmediatelyAfterOutput: false, updateEvery: nonAnsiUpdateCadenceInMs);
+ // We are told externally that we are in CI, use simplified ANSI mode.
+ terminalWithProgress = new TestProgressStateAwareTerminal(new SimpleAnsiTerminal(console), _options.ShowProgress, writeProgressImmediatelyAfterOutput: true, updateEvery: nonAnsiUpdateCadenceInMs);
}
else
{
- if (_options.UseCIAnsi)
- {
- // We are told externally that we are in CI, use simplified ANSI mode.
- terminalWithProgress = new TestProgressStateAwareTerminal(new SimpleAnsiTerminal(console), _options.ShowProgress, writeProgressImmediatelyAfterOutput: true, updateEvery: nonAnsiUpdateCadenceInMs);
- }
- else
+ // We are not in CI, or in CI non-compatible with simple ANSI, autodetect terminal capabilities
+ // Autodetect.
+ (bool consoleAcceptsAnsiCodes, bool _, uint? originalConsoleMode) = NativeMethods.QueryIsScreenAndTryEnableAnsiColorCodes();
+ _originalConsoleMode = originalConsoleMode;
+
+ bool useAnsi = _options.AnsiMode switch
{
- // We are not in CI, or in CI non-compatible with simple ANSI, autodetect terminal capabilities
- // Autodetect.
- (bool consoleAcceptsAnsiCodes, bool _, uint? originalConsoleMode) = NativeMethods.QueryIsScreenAndTryEnableAnsiColorCodes();
- _originalConsoleMode = originalConsoleMode;
- terminalWithProgress = consoleAcceptsAnsiCodes
- ? new TestProgressStateAwareTerminal(new AnsiTerminal(console, _options.BaseDirectory), _options.ShowProgress, writeProgressImmediatelyAfterOutput: true, updateEvery: ansiUpdateCadenceInMs)
- : new TestProgressStateAwareTerminal(new NonAnsiTerminal(console), _options.ShowProgress, writeProgressImmediatelyAfterOutput: false, updateEvery: nonAnsiUpdateCadenceInMs);
- }
+ AnsiMode.ForceAnsi => true,
+ AnsiMode.NoAnsi => false,
+ AnsiMode.AnsiIfPossible => consoleAcceptsAnsiCodes,
+ _ => throw new UnreachableException(),
+ };
+
+ terminalWithProgress = new TestProgressStateAwareTerminal(
+ useAnsi ? new AnsiTerminal(console, _options.BaseDirectory) : new NonAnsiTerminal(console),
+ _options.ShowProgress,
+ writeProgressImmediatelyAfterOutput: useAnsi,
+ updateEvery: useAnsi ? ansiUpdateCadenceInMs : nonAnsiUpdateCadenceInMs);
}
_terminalWithProgress = terminalWithProgress;
diff --git a/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporterOptions.cs b/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporterOptions.cs
index ebce31bfc35d..3a92d4873882 100644
--- a/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporterOptions.cs
+++ b/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporterOptions.cs
@@ -41,13 +41,32 @@ internal sealed class TerminalTestReporterOptions
public bool ShowActiveTests { get; init; }
///
- /// Gets a value indicating whether we should use ANSI escape codes or disable them. When true the capabilities of the console are autodetected.
+ /// Gets a value indicating the ANSI mode.
///
- public bool UseAnsi { get; init; }
+ public AnsiMode AnsiMode { get; init; }
+}
+
+internal enum AnsiMode
+{
+ ///
+ /// Disable ANSI escape codes.
+ ///
+ NoAnsi,
+
+ ///
+ /// Use simplified ANSI renderer, which colors output, but does not move cursor.
+ /// This is used in compatible CI environments.
+ ///
+ SimpleAnsi,
+
+ ///
+ /// Enable ANSI escape codes, including cursor movement, when the capabilities of the console allow it.
+ ///
+ AnsiIfPossible,
///
- /// Gets a value indicating whether we are running in compatible CI, and should use simplified ANSI renderer, which colors output, but does not move cursor.
- /// Setting to false will disable this option.
+ /// Force ANSI escape codes, regardless of the capabilities of the console.
+ /// This is needed only for testing.
///
- public bool UseCIAnsi { get; init; }
+ ForceAnsi,
}