Skip to content

test(webviews): U2 waits for conditions, not fixed times (157 waits) - #23415

Merged
teamleaderleo merged 13 commits into
feat-cmux-nextfrom
fixed-waits/u2
Oct 21, 2026
Merged

teamleaderleo merged 13 commits into
feat-cmux-nextfrom
fixed-waits/u2

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Part of the fixed-wait sweep that followed the ratchet in #23365. This PR removes 157 fixed-time waits from 19 webview unit-test files, and none are left in them. Their rows leave webviews/scripts/fixed-waits-baseline.tsv.

  • Timing under test now runs on bun's fake timers:
    • the New Tab's picked-name fade
    • the summary card's running-time tick
    • the kept-attachments rest timer
    • the transcript's anchor settle
    • the tooltip's scroll quiet time, which is now also checked inside the quiet window
    • the link bubble's no-hover-card check
  • Polls that already wait on a condition (render card, dropped chips, KaTeX, prompt accepted) yield one macrotask per try instead of sleeping.
  • The image viewer's actions wait for the host request, or for the refusal label. The changelog pages wait for their release to draw.
  • Menu and composer settle() helpers and PreviewCard's teardown yield one macrotask instead of sleeping 20 ms. act() already flushes the rest.
  • Negative asserts (no bubble, one request) let promises and a later task run before they check for absence.

It also carries #23414 (the base-red marker fix), which drops out once that merges.

Verification: an independent subagent review said SHIP. Each changed file passed 3 runs of bun test, and bun run check passes, including check:fixed-waits (835 on the baseline).

Agent session: huge-blue

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Removes all 157 fixed-time waits from 19 webview unit-test files so tests no longer sleep a fixed number of milliseconds. Timing under test now runs on bun's fake clock, and polls yield one macrotask per try until their condition is met.

  • The picked-name fade, running-time tick, kept-attachments rest timer, anchor settle, tooltip scroll quiet time, and no-hover-card check now run on fake timers the test advances.
  • Render-card, dropped-chip, KaTeX, and prompt-accepted polls yield one macrotask per try instead of sleeping.
  • Viewer actions wait for the host request or the refusal label; changelog pages wait for their release to draw.
  • Menu and composer settle() helpers and PreviewCard teardown yield one macrotask, with act() flushing the rest.
  • Negative asserts (no bubble, one request) yield a task before checking for absence.
  • The two 3-second frame-watch windows keep their waits with a // fixed-wait marker since the observation window is the test.

Written for commit ae9fa29. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 13 commits October 21, 2026 11:52
…soned marker

Fails until scripts/check-fixed-waits.ts exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
check:fixed-waits (in `bun run check`) names each test wait for a fixed number
of ms: page.waitForTimeout, Bun.sleep, a setTimeout that resolves a promise
after a non-zero delay, and calls to a local helper built on one. A fixed wait
passes on an idle machine and fails on a loaded runner that wakes it late, or
hides the bug it waits out (#23323). A test waits for a condition instead, uses
fake timers when the timing is the behavior, or keeps the wait with a
`// fixed-wait: <reason>` comment.

The 398 waits from before the rule have per-file counts in
scripts/fixed-waits-baseline.tsv. A file fails with more unmarked waits than
its row, and with fewer until the row is lowered (--update-baseline), so the
count only moves down; the sweep PRs lower it. pageSwitch's 16 ms
no-requestAnimationFrame fallback keeps its wait with a reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
…imers and exported helpers

Fails on the first detector: a helper with no delay parameter counted only at
its definition, a helper passed as a value (act(settle)) not at all, a timer
callback with a block body was missed, and so was an exported helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
From review. A wait inside a named function makes it a helper, and each use
counts instead of the definition: a call, or the helper passed or returned as a
value (act(settle), return { open }), applied outward through helpers built on
helpers. So another `await settle()` in a file raises its count. A helper whose
delay parameter defaults to 0 waits only when a use passes a delay. An exported
helper also counts at its definition, since its callers are in other files.

Also caught: timer callbacks with a block body that resolve the promise,
window/globalThis.setTimeout and Bun.sleepSync. A marker counts anywhere in the
wait's statement, or on a comment-only line above it, so a trailing marker no
longer covers the next line. The scan covers every source under test/
(harnesses, latency helpers), not just *.test files, and skips fixtures. A
malformed baseline row now fails instead of passing as NaN.

The baseline is regenerated: 819 waits in 132 files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
…ixed-wait count

Review of #23365 found that a second wait or helper call added inside a
function that already waits was not counted. These cases fail on the
current detector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
…lpers too

A wait counted only through the outer uses of its enclosing helper, so a new
wait or helper call inside a helper that already waited changed nothing. Now
each unmarked wait site counts, and each use of a helper outside its own
body, so any new wait raises the count. Waits in exported helpers count at
the site, which replaces the export rule. Export lists, typeof and member
declaration names are no longer uses. The baseline is regenerated: 989 waits
in 132 files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
The 19 U2 unit-test files had 142 fixed waits under the stricter
detector; none are left and their baseline rows are gone.

- Timing under test runs on bun's fake timers: the new tab's picked-name
  fade, the summary card's running-time tick, the kept-attachments rest
  timer, the transcript's anchor settle, the tooltip's scroll quiet time
  (now also checked inside the quiet window) and the link bubble's
  no-hover-card check.
- Polls that already waited on a condition (render card, dropped chips,
  KaTeX, prompt accepted) yield a macrotask per try instead of sleeping.
- The image viewer's actions wait for the host request (or the refusal
  label); the changelog pages wait for their release to draw.
- Menu and composer settle() helpers and PreviewCard's teardown yield
  one macrotask: act() flushes the rest, and the 20 ms were slack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
…its/u2

# Conflicts:
#	webviews/scripts/fixed-waits-baseline.tsv
…erts

The hover test now lets promises and a later task run before it asserts
no bubble, and the image viewer waits one more task so a duplicate
request would show.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
#23374 merged after the fixed-wait ratchet (#23365) ran CI, and it added a
3 s waitForTimeout in two tests, which puts feat-cmux-next over its baseline.
Both waits are observation windows: the test records every painted frame for
3 s after the chat opens and asserts none jumped, so the time is the test.
They carry a fixed-wait marker instead of a raised baseline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c78-27ca-7140-a6c7-95f0db83b18c&host=huge-blue
…its/u2

# Conflicts:
#	webviews/scripts/fixed-waits-baseline.tsv
@teamleaderleo teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 21, 2026
@cursor

cursor Bot commented Oct 21, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review ae9fa29: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr23415 -f ref=fixed-waits/u2 -f platform=macos -f backend_mode=local

Gallery before/after for ae9fa29: 16 states rendered, 5 images differ, 687 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 39603712395 -R manaflow-ai/cmux -n gallery-advisory-23415-ae9fa29b19ee41f3853ccc330d62c1d2115530df (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.add-project-panel/environment Apple System Colors Light unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/environment Apple System Colors unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/sources Apple System Colors Light unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/sources Apple System Colors unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/directory Apple System Colors Light unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/directory Apple System Colors unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/keyboard Apple System Colors Light unchanged 0% same-folder promptAccepted.test.ts
agent-pane.add-project-panel/keyboard Apple System Colors unchanged 0% same-folder promptAccepted.test.ts
agent-pane.agent-pair-note/paused Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/paused Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/held-list Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/held-list Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/repeating Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/repeating Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/cap Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/cap Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/release-failed Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/release-failed Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/resumed Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.agent-pair-note/resumed Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/closed Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/closed Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/markdown Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/markdown Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/html Apple System Colors Light changed 1.4% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/html Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/versions Apple System Colors Light unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.artifact-panel/versions Apple System Colors unchanged 0% same-folder PreviewCard.test.tsx
agent-pane.background-hint/claude Apple System Colors Light changed 0.226% same-folder PreviewCard.test.tsx
agent-pane.background-hint/claude Apple System Colors changed 0.0084% same-folder PreviewCard.test.tsx
agent-pane.background-hint/router Apple System Colors changed 0.229% same-folder PreviewCard.test.tsx
agent-pane.background-hint/router Apple System Colors Light changed 0.062% same-folder PreviewCard.test.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

Unclear: web / react-apps-check failed: no known signature; failed step: Check webview test shards.

CI failed on ae9fa29b19 (run 39603717111 attempt 1): 2 code, 1 unknown.

Job Verdict Why
web / react-apps-check (1) code a web test failed
web / react-apps-check (3) code a web test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs claimPaint.test.tsx a Settings page loaded fresh reports its first paint once its first screen is in: failed (job)
  • seen on other PRs agent-pane-bottom-stack.test.ts the question, the dock, the queue and the card stack without overlapping or a gap where the strip wa...: failed (job)
Matched log lines
web / react-apps-check (1): (fail) a Settings page loaded fresh reports its first paint once its first screen is in [893.88ms]
web / react-apps-check (3): (fail) the question, the dock, the queue and the card stack without overlapping or a gap where the strip was [1079.67ms]

Not re-run automatically: web / react-apps-check (1), web / react-apps-check (3), web / react-apps-check are not machine failures.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: web / Web status; NEW: green on the base 0b1a93e; do not merge until green; see lane-rules
red: web / react-apps-check; no finished base run on 0b1a93e to compare; do not merge until green; see lane-rules
red: web / react-apps-check (1); no finished base run on 0b1a93e to compare; do not merge until green; see lane-rules
red: web / react-apps-check (3); no finished base run on 0b1a93e to compare; do not merge until green; see lane-rules

CI fast guards failed on ae9fa29b19 (https://github.com/manaflow-ai/cmux/actions/runs/39603717111). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

Tour of ae9fa29b19 (run): no media. The tour did not run: only webview code changed (20 path(s)), which the gallery advisory run checks in Linux Chromium on the pull request (its artifact holds any captures); add the media-tour-mac label to tour it on a Mac.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-83xlg created for this PR by the cmux coordinator.

@blacksmith-sh

blacksmith-sh Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Found 4 test failures on Blacksmith runners:

Failures

Test View Logs
src/pages/settings/claimPaint.test.tsx/claimPaint.test.tsx View Logs
src/pages/settings/claimPaint.test.tsx/claimPaint.test.tsx View Logs
test/agent-pane-bottom-stack.test.ts/agent-pane-bottom-stack.test View Logs
test/agent-pane-bottom-stack.test.ts/agent-pane-bottom-stack.test View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent): SHIP at ae9fa29. Reds aren't this PR's own: composer-draft-wrap timeout (base flake), agent-pane-bottom-stack and settings claimPaint (files this PR doesn't touch; it changes test files only), defaults-snapshot (base, FileExplorerSectionView.swift).

@teamleaderleo
teamleaderleo merged commit d002d20 into feat-cmux-next Oct 21, 2026
@teamleaderleo
teamleaderleo deleted the fixed-waits/u2 branch October 21, 2026 14:27
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
summary-background-work.test.tsx keeps this PR's header comment and base's
fake timers (#23415). The webview catalog is base plus this PR's four
subagents.ended.* keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15d1f-ca00-7e31-b882-4d3c03033ee2&host=cosmic-gray
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

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

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant