HOMELAB-1885: fix(cockpit-e2e): wait for the SPA to mount before measuring the honest row #601
No reviewers
Labels
No labels
operator-review
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Homelab/infra-core!601
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "plane/HOMELAB-1885-cockpit-e2e"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Root cause
e2e/telemetry.spec.ts:275("the honest row reads as a sentence at 390px, outside any scroller") is the only measurement in the suite taken straight offpage.goto('/')— every other DOM-touching assertion awaits a locator first (telemetry.spec.ts:58,136,263), andresponsive.spec.tsinsertswaitForTimeout(300).page.gotoresolves onload, but the cockpit mounts after it. The build isadapter-staticwithssr = false:build/index.htmlis an empty body plus the SvelteKit bootstrap script, whose entry (entry/start.*.js) is a dynamic import. So atloadthe body holds nothing but the inline__sveltekit_*script —document.querySelector('[data-testid="wave-row-note"]')(and[data-pane="fleet"]) returnnull,getBoundingClientRect()never runs, and line 295 receivesnull.Not a product regression: the component renders the note (line 248 of
wave-view.svelte), and it renders at 390px inside the pane. The spec was green when LD3 merged — PR #589 cockpit-e2esuccess 3m0s— and red on a slower runner: run #1839 (PR #593, a longhorn retention change that touches no cockpit code) cockpit-e2efailure 5m4s, failing on attempt #1 and retry #1. The window is the runner's mount latency, so any unrelated PR inherits it.What changed and why
lab-director/cockpit/web/e2e/telemetry.spec.ts— two awaited locators added betweengotoand the measurement:The assertions below are unchanged and not weakened: the note must still exist and its own measured box must sit inside the pane's box at 390px, outside any scroller. The waits only make the measurement mean "the rendered row" instead of "whatever the DOM held at
load" — the same discipline the sibling test in that describe already uses.Evidence (local, live @
b3108c2+ this patch)Reproduced the CI window headless by throttling the CPU 20x via CDP, then running both legs of the sequence:
The un-waited read is exactly the CI symptom (both boxes null); the fixed read measures the note inside the pane at 390px. Then, with the probe removed:
npx playwright test e2e/telemetry.spec.ts→ 12 passednpx playwright test(full suite,CI=true) → 76 passed (1.1m) — includingtelemetry.spec.ts:275Blocker note
This blocks the infra-core merge queue: cockpit-e2e runs only on PRs (not on
livepushes), so the failure is charged to whichever unrelated PR is next. Branch is off currentorigin/liveonly, one file, no rebase of other branches.Review verdict — HOMELAB-1885 (PR #601)
Head sha reviewed:
a72435a87453bfe851ea3eb007c543cd32ec0a18(baselive)Changed:
lab-director/cockpit/web/e2e/telemetry.spec.tsonly, +12/-0.Verdict: APPROVED — no blocker findings. Harmless class (test-only, no runtime/manifest change).
Reviewed in a fresh context against the ticket's acceptance criteria, from primary sources only (PR diff, ticket,
livecontents ofe2e/telemetry.spec.ts,svelte.config.js,src/routes/+layout.ts,src/lib/components/dashboard/wave-view.svelte,playwright.config.ts, Forgejo status API).Correctness vs acceptance criteria
adapter-static+fallback: index.htmlandexport const ssr = falsemeanbuild/index.htmlis an empty body plus the inline SvelteKit bootstrap, whose app entry is a dynamic import.page.gotoresolves onload, sodocument.querySelector('[data-testid="wave-row-note"]')/[data-pane="fleet"]returnnull,getBoundingClientRect()never runs, and line 295 getsnull— exactly the CI symptom. The component itself renders the row (wave-view.svelte:248), so this is not a product regression.plane/HOMELAB-1885-cockpit-e2e→live.a72435a8: runs #1859/#1860/#1861, 12/12 jobs success, incl.cockpit-e2e success 5m50s(slower than the 5m4s run that failed — the fix does not depend on runner speed),cockpit-test 2m46s,dispatcher-test 2m48s,build-and-push 3m49s,terraform-validate 4m49s.live") is inherently post-merge and is what landing this PR unblocks; it cannot be evidenced by the diff itself.Fix correctness
Two awaited locators are inserted between
gotoand the measurement:This matches the discipline the sibling test in the same
describealready uses (telemetry.spec.ts:263onlive), and the diff is additions only — no assertion line is touched, removed, or relaxed.expectrather than later, so a real regression surfaces earlier, not later. A clipped/off-screen note still passestoBeVisible(Playwright ignores scroll clipping) and must then satisfy the unchanged out-of-scroller box assertion, so clipping is not masked either.expecttimeout inside a 45s test timeout against a locally served static asset — ample margin.Findings
No blocker findings were raised: the review produced one concern and two suggestions, none of which block.
getByTestId('wave-row-note')is strict-mode; if the DOM ever renders more than one such node the wait would throw rather than pick the first. CI green implies a single node today.document.fonts.ready) rather than adding another visibility wait.getByTestIdhere vs[data-testid=...]in thepage.evaluatebelow; cosmetic only.Concern/suggestion findings do not block. Proceeding to merge (repo convention: merge commit).