Repository navigation
fix(tty): wait for the app to finish drawing before a shot - #9
Merged
Merged
Conversation
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Issue #3: a tty shot could be taken mid-frame. The root cause is confirmed: a macOS pty hands the fixture's
detailsframe (one 1217-byte write) to the kit as a 1024-byte read that ends exactly atoran, plus a 193-byte read 0.05 to 0.8 ms later (logged over 10 runs).waitFor: 'name: postgres-main'matched on the first read and the shutter fired before the second arrived, which is the cut-off image in the issue.waitFor, after the change wait for keys withoutwaitFor, afternav, and for the first shot afterreadyor arestart), the kit now waits until the flushed screen has not changed for 100 ms, polled every 25 ms. It compares screens, not raw output, so an app that redraws the same frame on a timer settles at once.timeouts.shotMs. An app whose screen never stops changing (a spinner, a clock) is shot when the cap runs out, not failed, with one warning per shot that points to the terminal determinism guide.TtySessiontype is unchanged.waitForsteps get no settle wait: the recorder samples on its own frame clock by design, and a quiet wait would break that lockstep timing.CodeQL
js/polynomial-redosalerts 1 to 4. A small linear helper insrc/text.ts(trimTrailing,trailingRunStart: a loop from the end) replaces the four flagged regexes (src/capture.ts,src/config/resolve.tsx2,src/tty/pty.ts). It also replaces four trims of the same shape that CodeQL did not flag (/\n+$/insrc/record.tsandsrc/tty/capture.ts,/ +$/insrc/tty/render.tsandsrc/tty/session.ts). Behaviour is unchanged, byte for byte.Also:
macos-latestis added to thebuild-testmatrix (action SHAs unchanged), the guide lines about tty shot timing are updated, the CONTRIBUTING lines about the CI platforms and the fixture TUI's env vars are updated, and there is a patch changeset.Test plan
waits for a frame that arrives in two parts before any kind of shot): a new fixture mode,TUI_SPLIT_MS=70, writes the bottom three rows 70 ms after the rest of each frame. On the old code it failed 10 of 10 runs, with every kind of shot (first,waitFor, keys only, restart) missing its bottom rows.bunx vitest run test/capture-tty.test.ts20 times on this Mac: 6 of 20 failed before (always the determinism test), 0 of 20 failed after.TUI_REDRAW_MS) settles with no warning. An app that never stops changing (counter.mjs) is shot, with the warning, at the 1 s cap, and within a 300 msshotMswhen that is shorter.shotMs, a regex inside the helper, an off-by-one in the helper.'/'.repeat(n) + 'x'takes 1405 ms (n = 50k) and 5921 ms (n = 100k) with/\/+$/. WithtrimTrailingit takes 0.04 ms and 0.01 ms, and 0.11 ms at n = 1M.bun install --frozen-lockfile,bun run typecheck,bun run test(twice, 246 passed, 2 Windows-only skipped),bun run --cwd site test,bun run docs:build, all on macOS.Closes #3