AppTestHelper.AssertAnsiSnapshot + make ToAnsi platform-independent#5343
Conversation
AppTestHelper already had AnsiScreenShot (dump ToAnsi() to a writer) but no way to *assert* the look. AssertAnsiSnapshot records the screen as pure ANSI (IDriver.ToAnsi() — truecolor/bold/reverse/blink/layout, excluding the non-deterministic terminal cursor) into a __snapshots__/<name>.ans golden on first run, then compares byte-for-byte. The .ans file IS the look: `cat <name>.ans` reproduces the screen in any truecolor terminal. On mismatch it writes a sibling .ans.actual and throws with the plain-text render inline plus the `cat` commands, so a CI log or an agent can verify the look without an interactive run. UPDATE_SNAPSHOTS=1 accepts an intended change; SNAPSHOT_DIR overrides the golden root. The exception type is framework-agnostic (no xunit dependency in AppTestHelpers). *.ans is marked binary in .gitattributes — they are CRLF escape blobs and core.autocrlf would corrupt the compare and `cat`. Prototyped in gui-cs/Editor's integration suite (used there to verify multi-caret/column-selection rendering); upstreaming the reusable core. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@copilot fix ci/cd failures. |
Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/d81858b1-5067-4b78-8173-6aeebfab7243 Co-authored-by: tig <585482+tig@users.noreply.github.com>
Fixed in 1483425 by making ANSI snapshots normalize row separators to LF before writing/comparing, which resolves the Linux/macOS integration-test mismatch. Local validation: build passed, IntegrationTests passed (256/256), UnitTestsParallelizable passed, UnitTests.NonParallelizable passed. |
OutputBase.ToAnsi / BuildAnsiForRegion separated rows with StringBuilder.AppendLine () == Environment.NewLine, so the "recreate the screen" ANSI stream was CRLF on Windows and LF on Linux/macOS. That makes ToAnsi output non-portable: golden snapshots or cross-platform diffs recorded on one OS never match another (the failure that surfaced this). ToAnsi is a portable representation, not the live render path (real output goes through Write/WriteToConsole, untouched here). Emit a fixed '\n' for row breaks in both the ANSI and legacy-console paths. Terminals map LF->CRLF via the ONLCR tty discipline, so `cat`/recreate fidelity is unchanged. Two OutputBaseTests assertions hard-coded "<g>" + Environment.NewLine — they encoded the bug; updated to "<g>\n". Audited every other ToAnsi consumer (ToAnsiTests splits on ['\r','\n']; OutputBase/Transparent/ Subview/Link/MenuBar tests use Contains on text/escapes) — none depended on the platform newline; all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d09dc286e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@copilot fix this CR feedback: #5343 (comment) |
Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/83b38eb7-83e4-4424-bc70-0d1413287f9c Co-authored-by: tig <585482+tig@users.noreply.github.com>
Fixed in fc8e271 by stopping the helper before throwing the ANSI snapshot mismatch exception, with an integration test covering the mismatch path. Local validation: build passed, |
Summary
Two related changes:
1.
AppTestHelper.AssertAnsiSnapshot (name)— golden-file ANSI snapshotsAppTestHelpercould dump the screen (ScreenShot,AnsiScreenShot) but not assert it doesn't regress.AssertAnsiSnapshotcaptures the screen viaIDriver.ToAnsi(), records__snapshots__/<name>.anson first run (orUPDATE_SNAPSHOTS=1), and compares byte-for-byte after. On mismatch it writes a.ans.actualsibling and throws (framework-agnostic) with the plain-text render inline +catcommands — verify the look from a CI log or agent loop, no interactive run. The golden is the look:cat <name>.ansreproduces it.2. Fix:
ToAnsiwas platform-dependent (root cause)OutputBase.ToAnsi/BuildAnsiForRegionseparated rows withStringBuilder.AppendLine()==Environment.NewLine→ CRLF on Windows, LF on Linux/macOS.ToAnsiis documented as a portable "recreate the screen" representation, so its bytes must not depend on the OS that produced them (this broke cross-platform golden snapshots — a real CI failure in gui-cs/Editor#142). Now emits a fixed'\n'for row breaks (both the ANSI and legacy-console paths).ToAnsiis not the live render path (real output goes throughWrite/WriteToConsole, untouched); terminals map LF→CRLF via ONLCR socat/recreate fidelity is unchanged.om/claude-code)