Skip to content

TUI coverage gate flakes: App.test.tsx OAuth step-up tests fail under v8 instrumentation only #1942

Closed

Description

@olaservo

Version: v2 (main, reproduced at 07a2b4b)
Affected client: clients/tui (test infrastructure; Windows only)

Symptom

On Windows 11, npm run test:coverage in clients/tui fails with exactly one test failing per run — but a different one each time, always in App.test.tsx > App (OAuth result branches):

  • run 1: shows insufficient-scope message when step-up OAuth stays insufficient
  • run 2: completes a standard step-up authorize when OAuth succeeds
  • run 3 (clean upstream tree): same as run 2

npx vitest run __tests__/App.test.tsx without coverage passes 80/80 every time. The failures only appear under v8 instrumentation, which slows the Ink render loop enough for these waitFor-style OAuth-branch assertions to race.

What's known

  • Pre-exists unrelated work: reproduced identically on the upstream tip with no local changes.
  • Linux CI is green, so it's Windows-manifested (slower instrumented renders under the runner here).
  • 3/3 instrumented runs failed; 0 failures uninstrumented.

Impact

coverage:tui → root coverage → npm run ci fails on Windows even on a clean tree. Together with #1939 (verify scripts can't spawn npx) and #1941 (CLI worker teardown crash), the mandatory pre-push gate currently cannot pass on a Windows machine.

Context

Found while validating the fix for #1852 on a Windows machine.

Activity

  1. self-assigned this
    on Aug 6, 2026
  2. modified the milestones: v2.2.0, v2.3.0 on Aug 10, 2026
  3. olaservo commented on Aug 12, 2026

    @olaservo
    MemberAuthor

    Investigated on Windows against current v2/main (57d6e0d). The flake did not reproduce as filed (0 failures across 4 full test:coverage runs, 5 single-file coverage runs, 2 runs under CPU load, and 3 runs at the original repro commit 07a2b4b — the relevant files and installed deps are byte-identical to HEAD, so the failures were machine-condition-dependent). The underlying race is real, though, and can be made deterministic:

    Root cause — test synchronization, not a product bug. In ink 6 a visible frame does not imply armed input handlers: the frame is written during React's commit, but useInput handlers re-subscribe in the passive-effect flush (a setImmediate). The test helper's waitUntil polls on setTimeout, and Node runs timers before the check phase — so a test can see the step-up prompt and press a before the new handlers exist. The key dispatches into the previous commit's stale closures and is silently swallowed; there's no retry, so the success frame never renders. v8 instrumentation widens the window, hence "coverage only".

    Deterministic proof: a probe pressing at the earliest frame observation fails 10/10 (10/10 pass with one setImmediate yield), and shrinking waitUntil's poll to 1ms makes exactly the three step-up tests fail 3/3 runs — green with the fix.

    Planned fix (test-only, ~15 lines): await one setImmediate turn after a waitUntil predicate passes — check-queue FIFO guarantees React's already-scheduled effect flush runs first. Verified with 3 consecutive full green coverage runs.

  4. changed the title [-]TUI coverage gate flakes on Windows: App.test.tsx OAuth step-up tests fail under v8 instrumentation only[/-] [+]TUI coverage gate flakes: App.test.tsx OAuth step-up tests fail under v8 instrumentation only[/+] on Aug 12, 2026
  5. cliffhall commented on Aug 12, 2026

    @cliffhall
    Member

    Updated this one to remove Windows from the title, the same flake has been observed in CI.

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

Metadata

Metadata

Labels

bugSomething isn't workingv2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions