Skip to content

refactor(test): extract shared TUI test helpers - #838

Closed
kelsonpw wants to merge 1 commit into
mainfrom
refactor/tui-test-helpers
Closed

refactor(test): extract shared TUI test helpers#838
kelsonpw wants to merge 1 commit into
mainfrom
refactor/tui-test-helpers

Conversation

@kelsonpw

@kelsonpw kelsonpw commented May 17, 2026

Copy link
Copy Markdown
Member

Summary

  • Add src/ui/tui/__tests__/helpers/ with strip-ansi.ts (stripAnsi + ANSI_CSI_REGEX / ANSI_OSC_REGEX) and render-frame.tsx (frameOf(node) render-strip-unmount shorthand).
  • Migrate 21 TUI test files to use the shared helpers, removing ~19 copy-paste ANSI = /.../ + per-file stripAnsi definitions and 6 hand-rolled frameOf wrappers.
  • snapshot-utils.tsx now reuses the shared stripAnsi.

No behavior changes: every callsite still strips CSI sequences; callers that previously stripped only CSI now also strip OSC (no-op on CSI-only frames, defensive on TTY-capable terminals — same rationale as snapshot-utils.tsx already used).

Follows up #814/#819 (mkdtempSync helper extraction) — same playbook applied to the next-largest cluster of duplication in TUI tests.

Patterns deferred (with reasons)

  • FinalizingPanel.test.tsx — narrower SGR-only regex /[0-9;]*m/. Folding it in would broaden strip semantics for that file; left alone.
  • new WizardStore(...) / per-file makeStore variants — 5 distinct signatures (4 take different Partial shapes; ActivityLine.makeStoreWithActivity is unique). A shared createTestStore would need careful design to not regress per-test setup; deferred.
  • useStdoutDimensions mock — only 3 callsites and 2 already share via ink-stdin.tsx. Below the duplication threshold.
  • await new Promise((r) => setTimeout(r, ...)) Ink-tick yielding — 41 instances across 10 files, but the delay values and surrounding wait conditions vary per case; a shared helper would force a one-size-fits-all timeout.

Test plan

  • pnpm tsc --noEmit clean
  • pnpm lint clean (prettier + eslint)
  • pnpm test — all 298 files / 4473 tests pass
  • All 21 migrated files pass individually under --pool=forks --maxWorkers=1
  • Snapshot tests (AuthScreen.snap, OutroScreen.snap, RegionSelectScreen.snap) match unchanged

🤖 Generated with Claude Code


Note

Low Risk
Test-only refactor that centralizes ANSI stripping and frame rendering; low risk aside from potential snapshot churn if OSC/CSI stripping semantics differ across environments.

Overview
Refactors TUI tests to use shared rendering/sanitization helpers. Adds __tests__/helpers/strip-ansi.ts (shared stripAnsi + CSI/OSC regexes) and __tests__/helpers/render-frame.tsx (frameOf() render→strip→unmount shortcut).

Updates TUI component/screen/primitive tests and snapshot-utils.tsx to remove per-file ANSI regexes and ad-hoc frameOf wrappers, standardizing on always stripping both CSI and OSC sequences for more deterministic snapshots across TTY vs CI runs.

Reviewed by Cursor Bugbot for commit a1e4cc1. Bugbot is set up for automated code reviews on this repo. Configure here.

Add `src/ui/tui/__tests__/helpers/`:

- `strip-ansi.ts` — `stripAnsi(s)` + `ANSI_CSI_REGEX` / `ANSI_OSC_REGEX`.
  Replaces 19 per-file `ANSI = /.../` + `stripAnsi = (s) => s.replace(...)`
  definitions scattered across TUI tests. Every callsite that previously
  stripped only CSI also gets the OSC strip — a no-op on plain CSI frames
  but defensive on TTY-capable terminals where Ink emits OSC 8 hyperlinks
  (same rationale as `snapshot-utils.tsx`).

- `render-frame.tsx` — `frameOf(node)` shorthand for the
  render-strip-unmount idiom used by 6 component tests. The pattern was
  literally identical at each call site (`render` → `lastFrame()` → strip
  → `unmount` → return).

`snapshot-utils.tsx` now reuses the shared `stripAnsi` instead of
defining its own.

Migrated 21 test files (no behavior changes — only the source of the
helper changes). `FinalizingPanel.test.tsx` is intentionally left alone:
it uses a narrower SGR-only `/[0-9;]*m/` regex and the test cases assert
on cursor/clear sequences elsewhere; folding it in would broaden the
strip semantics for that file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kelsonpw
kelsonpw requested a review from a team as a code owner May 17, 2026 15:57
@kelsonpw
kelsonpw removed the request for review from a team May 18, 2026 18:04
@kelsonpw

Copy link
Copy Markdown
Member Author

Closing as part of pat-leave handoff to reduce open-PR load on the team. Branch preserved on origin — reopen if specific changes are wanted. The highest-impact wins from this refactor round already merged.

@kelsonpw kelsonpw closed this May 22, 2026
Sign up for free to 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.

1 participant