Surfaced while shipping #587 (phase 2 of #593) — out of scope there, filed per the "surface out-of-scope findings" rule.
Symptom
Under a full-parallel local npx playwright test --project=chromium --project=webkit, two specs fail intermittently — each failed once across five runs, on different tests each time, and both pass reliably in isolation:
tests/e2e/inspector-dock-layout.spec.js:147 — "viewport resize while OPEN live re-clamps the displayed width, all the way down to the shared 320 floor"
tests/e2e/tile-open-workbench.spec.js:365
Neither references side-panel / saved-history / sidebar-upper code, and a clean 414-passed/0-failed run is reproducible, so this is pre-existing rather than a #587 regression.
Likely root cause (verified for the first one)
tests/e2e/inspector-dock-layout.spec.js:154-155:
await page.setViewportSize({ width: 900, height: 800 });
const after = await inspectorHost.boundingBox();
setViewportSize resolves as soon as the viewport is applied, but the value under assertion is recomputed by the dock-aware re-clamp in a window resize handler (app-shell.ts's reclampInspectorWidth, added by #586). There is no expect.poll, no waitForFunction, and no explicit wait between the resize and the geometry read, so the assertion races the handler. Under parallel load the handler is likelier to lose.
This is the same class of defect as the Chromium-only async-reflow race already seen on this repo: happy-dom cannot catch it because it evaluates no CSS layout, so only e2e sees it — and only sometimes.
Suggested fix
Replace the bare boundingBox() reads that follow a viewport change with a polled assertion, e.g. await expect.poll(async () => Math.round((await inspectorHost.boundingBox()).width)).toBe(320), or await page.waitForFunction on the expected width. Then audit the rest of both specs for the same resize-then-measure shape.
Why deferred
#587 is a side-panel registry refactor; these specs cover the #586 docked inspector and the dashboard tile→workbench path. Fixing them inside that PR would mix an unrelated test-infrastructure change into a shell-refactor diff. Phase 1's own e2e was green at merge, so this is not a regression gate for #593.
Surfaced while shipping #587 (phase 2 of #593) — out of scope there, filed per the "surface out-of-scope findings" rule.
Symptom
Under a full-parallel local
npx playwright test --project=chromium --project=webkit, two specs fail intermittently — each failed once across five runs, on different tests each time, and both pass reliably in isolation:tests/e2e/inspector-dock-layout.spec.js:147— "viewport resize while OPEN live re-clamps the displayed width, all the way down to the shared 320 floor"tests/e2e/tile-open-workbench.spec.js:365Neither references side-panel / saved-history / sidebar-upper code, and a clean 414-passed/0-failed run is reproducible, so this is pre-existing rather than a #587 regression.
Likely root cause (verified for the first one)
tests/e2e/inspector-dock-layout.spec.js:154-155:setViewportSizeresolves as soon as the viewport is applied, but the value under assertion is recomputed by the dock-aware re-clamp in a windowresizehandler (app-shell.ts'sreclampInspectorWidth, added by #586). There is noexpect.poll, nowaitForFunction, and no explicit wait between the resize and the geometry read, so the assertion races the handler. Under parallel load the handler is likelier to lose.This is the same class of defect as the Chromium-only async-reflow race already seen on this repo: happy-dom cannot catch it because it evaluates no CSS layout, so only e2e sees it — and only sometimes.
Suggested fix
Replace the bare
boundingBox()reads that follow a viewport change with a polled assertion, e.g.await expect.poll(async () => Math.round((await inspectorHost.boundingBox()).width)).toBe(320), orawait page.waitForFunctionon the expected width. Then audit the rest of both specs for the same resize-then-measure shape.Why deferred
#587 is a side-panel registry refactor; these specs cover the #586 docked inspector and the dashboard tile→workbench path. Fixing them inside that PR would mix an unrelated test-infrastructure change into a shell-refactor diff. Phase 1's own e2e was green at merge, so this is not a regression gate for #593.