From c9421df54db9426382e991215e856ecaa84531a6 Mon Sep 17 00:00:00 2001 From: dormouse-bot <287024035+dormouse-bot@users.noreply.github.com> Date: Wed, 23 Sep 2026 19:17:42 +0000 Subject: [PATCH 1/2] Preload the QR chunk before the SetupPhoneQr story waits for it On a loaded WebKit runner the lazily-imported QrCode chunk can take longer than findByRole's 1 s default to arrive after the click, failing the Argos run on main (run 35907472490). Importing it in the play function first lets the panel's own lazy import resolve from the module cache. --- lib/src/stories/RemoteControlSection.stories.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/stories/RemoteControlSection.stories.tsx b/lib/src/stories/RemoteControlSection.stories.tsx index e77bf686e..a8ccdd988 100644 --- a/lib/src/stories/RemoteControlSection.stories.tsx +++ b/lib/src/stories/RemoteControlSection.stories.tsx @@ -206,6 +206,10 @@ export const SetupPhoneQr: Story = { // The one setup-panel story that settles on the QR's accessible name rather // than on text, so it cannot use {@link setupPanel}. play: async (context) => { + // The QR is a lazily-imported chunk. Fetched cold after the click, it can + // outlast `findByRole`'s 1 s on a loaded WebKit runner; loaded here first, + // the panel's own import resolves from the module cache. + await import('../components/QrCode'); const canvas = within(context.canvasElement); await userEvent.click(await canvas.findByRole('button', { name: 'Set up a phone' })); await canvas.findByRole('img', { name: 'Setup code for this machine' }); From 6a5289e1746d930dbf66d69fd5a899ce9fe38ae7 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Wed, 23 Sep 2026 13:17:00 -0700 Subject: [PATCH 2/2] Hold terminal-context stories until the helper's autorun finishes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every story that opens the terminal context captured whichever helper step the runner had reached ("Waiting for shell…", "Running git status…", or "autoran"), so Argos, rendering 550 captures at once on CI, saw a different frame from its baseline. `settleTerminalContext` waits for the status spinner to clear and the helper to paint; the six context-dialog stories, Wall's alert modal, and Wall's TerminalContext (replacing its one-off gate) all use it. Co-Authored-By: Claude Opus 5.5 (1M context) --- lib/src/stories/TerminalPaneHeader.stories.tsx | 5 ++--- lib/src/stories/Wall.stories.tsx | 12 +++--------- lib/src/stories/settle-terminals.ts | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/src/stories/TerminalPaneHeader.stories.tsx b/lib/src/stories/TerminalPaneHeader.stories.tsx index 64cdf2d54..f748662f4 100644 --- a/lib/src/stories/TerminalPaneHeader.stories.tsx +++ b/lib/src/stories/TerminalPaneHeader.stories.tsx @@ -17,7 +17,7 @@ import { flattenScenario, SCENARIO_SHELL_PROMPT } from '../lib/platform'; import { removeMouseSelectionState, setMouseReporting, setOverride } from '../lib/mouse-selection'; import { addPlainNote, clearAllNotepads } from '../lib/notepad/notepad-store'; import { recordToolDirty, resetToolDirty } from '../lib/tool-dirty-store'; -import { requireElement, settleTerminals, waitForCondition, waitForPrimedState } from './settle-terminals'; +import { requireElement, settleTerminalContext, waitForCondition, waitForPrimedState } from './settle-terminals'; const SESSION_ID = 'tab-story'; @@ -230,8 +230,7 @@ async function openHeaderRightClickDialog() { clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, })); - await requireElement('[data-terminal-context]', 'terminal context'); - await settleTerminals(); + await settleTerminalContext(); } /** diff --git a/lib/src/stories/Wall.stories.tsx b/lib/src/stories/Wall.stories.tsx index 9b3fb5a5c..2aa952020 100644 --- a/lib/src/stories/Wall.stories.tsx +++ b/lib/src/stories/Wall.stories.tsx @@ -6,7 +6,7 @@ import { SCENARIO_LS_OUTPUT, } from '../lib/platform'; import type { ActivityState } from '../lib/terminal-registry'; -import { requireElement, settleTerminals, waitForCondition } from './settle-terminals'; +import { requireElement, settleTerminalContext, settleTerminals, waitForCondition } from './settle-terminals'; const meta: Meta = { title: 'App/Wall', @@ -101,8 +101,7 @@ async function minimizeFirstVisiblePane() { async function openAlertDialog() { const header = await requireElement('[data-pane-header-for]', 'pane header'); header.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true, cancelable: true, button: 2 })); - await requireElement('[data-terminal-context]', 'terminal context'); - await settleTerminals(); + await settleTerminalContext(); } export const Default: Story = { @@ -219,11 +218,6 @@ export const TerminalContext: Story = { await settleTerminals(); const header = await requireElement('[data-pane-header-for="context-live"]', 'terminal header'); header.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true, cancelable: true, button: 2 })); - await waitForCondition(() => !!document.querySelector('[data-helper-terminal]')); - // Hold until autorun has finished and the helper has painted, so the capture - // is never the "Waiting for shell…" or "Running …" frame on the way there. - await waitForCondition(() => - document.querySelector('[aria-label="Helper terminal status"]')?.textContent?.includes('autoran') ?? false); - await settleTerminals(); + await settleTerminalContext(); }, }; diff --git a/lib/src/stories/settle-terminals.ts b/lib/src/stories/settle-terminals.ts index 6bb1fdf08..731231a3d 100644 --- a/lib/src/stories/settle-terminals.ts +++ b/lib/src/stories/settle-terminals.ts @@ -42,6 +42,24 @@ export async function settleTerminals(opts?: { timeoutMs?: number }): Promise { + await requireElement('[data-terminal-context]', 'terminal context'); + const settled = () => { + const status = document.querySelector('[data-terminal-context] [aria-label$="terminal status"]'); + return !!status && !status.querySelector('.animate-spin'); + }; + await waitForCondition(settled, opts); + if (!settled()) throw new Error('terminal context autorun never finished'); + await settleTerminals(opts); +} + /** * Hold until the preview's primed-state decorator has applied. *