test(storybook): wait for plus-menu popups to settle - #4897
Conversation
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed current head 3956ab444e879caeb68d7c4617c0d6eb58ad233f (OPEN, MERGEABLE/BLOCKED awaiting human review). Technical GO — no P0–P3. But the integration gate is not closed: current test fails on the unmodified Electron E2E budget check (session-workbar.spec.ts budget 5, actual 6), before Storybook smoke — not attributed to this PR, but not green either.
What it does
Two Storybook files only (app-shell.stories.tsx:1494-1563, composer-slash-menu.stories.tsx:423-457): popup visibility waits and controlled projection release. Real Composer loading behavior, Plan boundaries, menu hold/close, and settled-listbox paths checked (composer.tsx:1979-1989,2015-2030, desktop wiring app-shell.tsx:3019-3028). Historical CI reproduces both target stories' toBeVisible() timing failures, and the fix matches the failure points.
Scope and limits
Merge-tree/diff check clean. Desktop build/typecheck/Storybook smoke/real Electron run not performed locally (no usable deps/dist in this worktree).
Automated review notice: This comment was posted by an automated review agent operated by Astro-Han. It is not an independent human review and does not replace one.
简体中文
评审结论来自自动化审查流程;发布者没有读这份 diff,核的是当前 head 有没有漂移、以及 exact-head 的门禁状态。当前 head 是 3956ab4,未关闭。技术上无阻断问题;但门禁没闭合(E2E 预算红,与本改动无关)。合并由人类定。
jest-dom's toBeVisible reads the Astryx layer's computed opacity, which stays 0 until the first frame ticks its backwards-filled entry animation. On a loaded CI runner that frame lands after the assertion and a popup that never closed reads as hidden. Retry the visibility reads the way the slash-menu story already does, and let the refresh harness settle on an explicit release instead of a 150ms timer that a slow runner outlives before the click. Generated-by: Claude Code
3956ab4 to
c65ef8b
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Re-reviewed at c65ef8b against main (e226ac532), +14/−8 over 2 story files, CI green.
The gate that held this yesterday is closed: #4895 fixed the budget entry on main, and this head is green. main itself now fails on exactly the story this PR fixes (plus-menu-during-skill-refresh, run 34017497207), so this is the fix main needs.
The three waitFor wraps are the same idiom #4889 used for the same layer-opacity read, and the explicit release replaces the only clock in the harness. Nothing else changes. #4829 carries a narrower version of the harness change; it will rebase onto this.
AI-assisted review: drafted with Maka; I verified the three reads and the release path myself.
Summary
The Storybook smoke intermittently reads the composer's + menu as hidden right after it opens, although it never closed. jest-dom's
toBeVisiblewalks up to the Astryx layer and reads its computedopacity; the layer's entry keyframes useanimation-fill-mode: backwards, so until the first frame ticks the animation that value is0, and on a loaded CI runner the assertion lands inside that window. #4889 already retries the one read in the slash-menu story; this covers the same read in the app-shell sibling and the twofindByRole('listbox')reads that follow, using the samewaitForidiom.The app-shell harness also held its Skill refresh on
setTimeout(…, 150). A slow runner outlives that before the story clicks the row, so the click activates the row for real and the menu closes. The harness now settles on an explicit release the story calls once the busy-row assertions are done, the way the slash-menu story already latches its projection.Fixes #4896
Verification
format:checkandnode --test scripts/storybook-visual-smoke.test.mjspass.typecheck:storiesreports only the fourrightCollapsederrors main already carries from #4694, which #4895 fixes; nothing in this diff. The stories were looped inmcr.microsoft.com/playwright:v1.62.1-nobleat--cpus=2with four concurrent pages, which is the only environment where this reproduces (never on macOS in 44 runs).Before (
origin/maind2d7efe), slash-menu story, 40 rounds, withgetComputedStyle/showPopover/animation events hooked:Before, app-shell story, 40 rounds (18 of the
toBeVisiblefailures end with"editor": "/"and the Skill listbox open, the timer having expired before the click):After, same container, same loops:
Root cause
See #4896. Emulating
prefers-reduced-motionin the smoke script would remove the animation but also switchesscroll-motion-policy.tsto instant scrolling, and two app-shell scroll stories fail by design under it, so the fix stays in the stories.AI use
Select exactly one:
Tool(s) and scope: Claude Code (Fable 5.1) ran the CI-log triage, built the Linux repro and instrumentation, identified the mechanism, and authored the story changes; commit carries
Generated-by: Claude Code.Checklist
Does this PR entail a change in behavior?