Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add --ansi option for explicit ANSI control - #7107

Closed
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output
Closed

Add --ansi option for explicit ANSI control#7107
Amaury Levé (Evangelink) with Copilot wants to merge 5 commits into
mainfrom
copilot/add-ansi-option-to-force-output

Conversation

CopilotAI commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds a new --ansi <auto|on|off> CLI option to give users explicit control over ANSI escape sequence output. Fixes#5081.

Behavior

  • --ansi auto (default): Auto-detect terminal capabilities (existing behavior when no option is passed).
  • --ansi on|true|enable|1: Force ANSI output (including cursor movement) even when stdout is redirected, e.g. mytest.exe | Out-Host.
  • --ansi off|false|disable|0: Disable ANSI output.
  • --no-ansi: continues to work unchanged.
  • When both --ansi and --no-ansi are specified, --ansi wins (documented in the help text).

Implementation notes

  • New internal CommandLineOptionArgumentValidator helper exposes IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue / IsOffValue / IsAutoValue so future boolean and boolean+auto options (e.g. --no-progress) can reuse it.
  • The --ansi value parsing in TerminalOutputDevice uses a private AnsiOverride enum scoped to that file. We considered promoting a generic ActivationMode (Auto/On/Off) enum into the CommandLine namespace but kept it local for now to avoid widening the public/internal surface for a single consumer; a follow-up can introduce a shared type once a second option (e.g. --no-progress) actually needs it.
  • --no-ansi is intentionally left without deprecation/obsolescence metadata. The earlier prototype added obsolescence plumbing to CommandLineOption but it was reverted because the matching infrastructure was removed from main by Delete dead code #7734 as dead code, and reintroducing it for a single option felt out of scope. The help text for --ansi instead notes that --ansi wins over --no-ansi so users have a clear migration path.

Tests

  • Unit tests for CommandLineOptionArgumentValidator and the updated TerminalTestReporterCommandLineOptionsProvider.
  • New AnsiOptionTests acceptance tests covering on/off/auto behavior, the alias values, precedence vs --no-ansi, and invalid argument rejection.
  • Updated MTP and MSTest --help / --info acceptance expectations to include the new option.

CopilotAI changed the title [WIP] Add --ansi option to force Ansi outputAdd --ansi option for explicit ANSI controlDec 11, 2025
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to go through the logic around use ansi and force ansi on the internal options. I am not clear on why we needed / need both options. so please wait for me.

Comment threadsrc/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/OptionMode.cs Outdated
Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/TriStateMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just comments that you don't have to address.

Comment threadsrc/Platform/Microsoft.Testing.Platform/CommandLine/ActivationMode.cs Outdated

@nohwndJakub Jareš (nohwnd) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

auto-merge was automatically disabled December 19, 2025 12:38

Pull request was closed

Implements the user-facing --ansi option with auto/on/off values (plus
true|enable|1 / false|disable|0 aliases). The new option fulfils issue
#5081 by mapping --ansi on to the existing internal AnsiMode.ForceAnsi,
which emits ANSI escape codes (including cursor movement) even when
stdout is redirected (for example, in 'mytest.exe | Out-Host' pipelines).
- New internal CommandLineOptionArgumentValidator helper exposes
IsValidBooleanArgument / IsValidBooleanAutoArgument / IsOnValue /
IsOffValue / IsAutoValue for reuse by future on|off|auto options.
- --no-ansi continues to work unchanged. When both --ansi and --no-ansi
are specified, --ansi wins (documented in the help text).
- Updated MTP and MSTest acceptance test --help and --info expectations
to include the new option.
- Added unit tests for the validator and the provider plus integration
tests verifying the on/off/auto behavior, alias handling, and invalid
argument rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduce AnsiOverride.Auto so the switch can distinguish 'user typed
--ansi auto' from 'no --ansi at all'. With this, any explicit --ansi
value (auto, on, off) now overrides the legacy --no-ansi flag, which
makes the help text accurate.
- Drop the dead-defensive null check on TryGetOptionArgumentList output:
ArgumentArity.ExactlyOne guarantees a single-element array when the
call returns true.
- Clarify the AnsiOption_Auto integration test comment to explain it now
exercises the real AnsiIfPossible-plus-redirection path, and add a
companion test asserting --no-ansi --ansi auto runs successfully (i.e.
precedence is honored).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…istic
- AnsiOption_Auto_DoesNotProduceAnsiOutputWhenRedirected was passing
trivially under GITHUB_ACTIONS=true because the CI branch picked
SimpleAnsi (which emits color codes). Now explicitly clears
GITHUB_ACTIONS / TF_BUILD so the assertion is deterministic.
- AnsiOption_AutoExplicit_OverridesNoAnsiFlag used to only assert
ExitCode.Success which gave the same value for both fixed and
regressed code paths. It now sets GITHUB_ACTIONS=true so the
precedence story discriminates: when --ansi auto correctly wins over
--no-ansi the CI branch selects SimpleAnsi -> ANSI escape codes
appear; when --no-ansi wins (regression) no codes appear. The new
assertion catches that regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… vars
Replace AnsiOption_AutoExplicit_OverridesNoAnsiFlag with
AnsiOption_OnExplicit_AfterNoAnsi_StillForcesAnsiOutput. The new test
uses '--no-ansi --ansi on' instead of '--no-ansi --ansi auto'. Because
AnsiOverride.ForceOn short-circuits both the inCI and the
LLMEnvironmentDetector checks in TerminalOutputDevice, the assertion no
longer flakes on contributors running the suite from inside an LLM
agent (Claude Code, Cursor, Copilot CLI, Codex CLI, etc.) whose
environment variables would leak into the test child process via
TestHost.ExecuteAsync.
This still proves the same precedence invariant ('any explicit --ansi
value overrides --no-ansi', order-independent), and the assertion is a
direct function of the precedence fix alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 20, 2026 16:28
@Evangelink
Amaury Levé (Evangelink)force-pushed the copilot/add-ansi-option-to-force-output branch from 6a4bcd6 to 337033aCompareMay 20, 2026 16:28
@Evangelink

Copy link
Copy Markdown
Member

Rebased onto current main from scratch (the prior branch was stale and had non-trivial conflicts). I dropped the AutoOnOff enum and the obsolescence-marker plumbing for --no-ansi so the change stays small (the obsolescence infrastructure was removed from main by #7734 as dead code, and reintroducing it for one consumer felt out of scope). Instead, --ansi maps straight to the existing internal AnsiMode enum:

  • --ansi on|true|enable|1AnsiMode.ForceAnsi (fulfils Add --ansi option to force Ansi output #5081 — emits ANSI even when stdout is redirected)
  • --ansi off|false|disable|0AnsiMode.NoAnsi
  • --ansi auto (default) → current detection logic (LLM → NoAnsi, CI → SimpleAnsi, else → AnsiIfPossible)
  • --no-ansi stays working as-is; any explicit --ansi <value> wins over it

Help text calls out that --ansi on includes cursor movement and recommends pairing with --no-progress for clean redirected output.

The branch went through 3 rounds with the expert reviewer; iterations addressed: (1) --ansi auto + --no-ansi precedence, (2) CI-deterministic auto test, (3) a precedence test that's also immune to LLM env-var leakage. Final regression guard uses --no-ansi --ansi on because ForceOn short-circuits both inCI and LLMEnvironmentDetector checks.

Acceptance tests need build.cmd -pack to run locally; I built Microsoft.Testing.Platform, the unit-tests project (864/864 pass) and the integration tests project (compiles cleanly).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit --ansi <auto|on|off> command-line option to control whether ANSI escape sequences are emitted by the terminal reporter, while keeping --no-ansi for backward compatibility. It also updates localization resources and acceptance tests so --help/--info output reflects the new option.

Changes:

  • Add --ansi option (with auto|on/off aliases) and wire it into TerminalOutputDevice ANSI mode selection/precedence over --no-ansi.
  • Introduce a reusable CommandLineOptionArgumentValidator helper and add unit tests for the validator and the terminal option provider.
  • Update help/info acceptance-test expectations and add an integration test validating redirected-output behavior for --ansi.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProviderTests.csAdds unit tests for --ansi option validation and presence.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionArgumentValidatorTests.csAdds unit tests for the new boolean/auto argument validator helpers.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MSTest runner --help expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.csUpdates MTP --help and --info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates “all extensions” help/info expectations to include --ansi.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AnsiOptionTests.csAdds integration tests validating --ansi behavior (esp. when stdout is redirected).
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlfAdds localized entries for --ansi description + invalid-argument message.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resxAdds TerminalAnsiOptionDescription and TerminalAnsiOptionInvalidArgument resources.
src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.csParses --ansi and applies precedence over --no-ansi to select AnsiMode.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.csDeclares --ansi and validates its argument via the new validator.
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionArgumentValidator.csAdds reusable helpers for auto/on/off argument validation.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

…options
- Guard against empty argument list when validating --ansi (e.g. `--ansi on --ansi` would have invoked the validator twice, once with an empty arguments array).
- Move --ansi from the platform 'Options:' section to the 'Extension options:' section in HelpInfoAllExtensionsTests because TerminalTestReporterCommandLineOptionsProvider registers the option as a non built-in extension option.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Closing in favor of #8493, which is a refreshed version of this PR (cleaner validator code using LINQ, refactored TerminalOutputDevice branch using CIEnvironmentDetector, and an additional acceptance test for the missing-argument case).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --ansi option to force Ansi output

4 participants

@Evangelink@nohwnd