fix/BUNYIP-148-serial-project-ordering #197
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/bunyip!197
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-148-serial-project-ordering"
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?
The profile/sessions failures were a BROWSER-process crash on goto /settings ("Target page, context or browser has been closed" with no page-level crash event - the crash/pageerror/console listeners never fired). Classic CI cause: the runner's container gives chromium a tiny /dev/shm, so a heavier page (/settings) OOMs the browser while the lighter /membership survives. Add `launchOptions.args: ['--disable-dev-shm-usage']` so chromium backs shared memory with /tmp. Also swap profile.spec's form fills to the exported setInputValue (same CI fill() no-op as login, BUNYIP-168), so once /settings loads the edit actually submits. Dropped the temporary /settings crash listeners (a browser-process crash does not fire them, so they added nothing). tsc --noEmit clean; all specs collect. #BUNYIP-148 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>The /settings failures are the browser PROCESS dying on goto ("Target page, context or browser has been closed", no page-level crash event, empty error-context), while the lighter /membership page in the same project survives. --disable-dev-shm-usage alone did not fix it. Root class: Playwright 1.60 runs headless with the stripped `chromium-headless-shell` build, which is less robust than full chromium on heavy DOM. /settings renders profile + email + password + 2FA + sessions + trusted-device forms - far heavier than /membership. Force the full chromium build via `channel: 'chromium'` (already installed by `playwright install chromium`; the headless-shell is the separate default). Keep --disable-dev-shm-usage as defense in depth. #BUNYIP-148 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>The previous attempts (--disable-dev-shm-usage, channel: 'chromium', project ordering) did not move the needle. The latest CI run, with the new project ordering active, shows account-ui tests grouped contiguously (10-19 are all account-ui) but profile (10) and sessions (13) still fail on the very first action - `page.goto('/settings')` - while memberships (19) on /membership passes on the same browser. So the relaunch-after-project-switch theory was wrong: /settings specifically is the trigger. Switch the /settings navigations in profile.spec and sessions.spec from the default `waitUntil: 'load'` (which blocks until every subresource fires the load event) to `waitUntil: 'commit'` (which returns as soon as the navigation commits, i.e. response headers arrived and the URL updated). Then wait for `domcontentloaded` separately. Working theory: the renderer dies somewhere between commit and load on the heavy /settings page, and playwright blocks on the load promise long enough to surface "Target page, context or browser has been closed". With `commit`, goto returns earlier; if the renderer is already dead by then, subsequent locator calls produce diagnosable errors (the page is concretely closed, not nondeterministically closing). Wrap each goto in attachPageDiagnostics so a still-failing run carries the URL trail + request log in the thrown error instead of the opaque page-closed message. lib/page-diagnostics.ts already exists and is used elsewhere; just plumbing it through. If this still fails the next run, the page-diagnostics snapshot will name the exact URLs the page hit before death - which is precisely what we have been missing. #BUNYIP-148The page-diagnostics dump from the last run named the actual failure mode: Error: page.waitForLoadState: Target page, context or browser has been closed after goto /settings: currentUrl=***/settings urlTrail (last 30): ***/settings requests (last 30): ***/settings https://fonts.googleapis.com/css2?family=Inter... https://kit.fontawesome.com/6ab760c0b1.js https://unpkg.com/htmx.org@2.0.3 ***/assets/styles.css https://unpkg.com/htmx.org@2.0.3/dist/htmx.min.js https://ka-f.fontawesome.com/.../free.min.css https://ka-f.fontawesome.com/.../free-v4-shims.min.css https://ka-f.fontawesome.com/.../free-v5-font-face.min.css https://ka-f.fontawesome.com/.../free-v4-font-face.min.css The `goto` with `waitUntil: 'commit'` succeeded (currentUrl=/settings), so the navigation reached the page and chromium started rendering. The follow-up `waitForLoadState('domcontentloaded')` then failed with the page closed - the renderer process died between commit and DOMContentLoaded. Browser process pid=1408 stayed up and closed cleanly later, which proves only the renderer died, not the whole browser. The lighter /membership page (fewer icons, fewer forms) survives on the same browser. Classic CI signature: renderer dies between commit and first paint on a page that loads many icon fonts + GPU-rendered gradients (settings has them on every card header), succeeds on lighter pages, no page-level crash event because the page wrapper dies with the renderer. The previous attempts (--disable-dev-shm-usage, channel: 'chromium', project ordering) all targeted memory or browser-binary choice; none disabled the GPU / accelerated rendering pipeline, which is the actual fault path. Two new args, both defensive: --disable-gpu : forces software rasterization. Removes the GPU init + accelerated-raster path. The icon-heavy gradient-heavy /settings page no longer depends on /dev/dri or the GPU discovery dance chromium does at first paint. Perf cost is irrelevant for CI E2E. --no-sandbox : the OpenSUSE runner image may run the job process as root inside its container; chromium's namespace sandbox setup fails on a root-uid setup without CAP_SYS_ADMIN, and the renderer dies during sandbox transition with the same opaque "page closed". Disabling the sandbox bypasses that step. Safe in CI: the runner already isolates the job per the runner-image contract. Keeping `channel: 'chromium'` and `--disable-dev-shm-usage` for defense in depth so a future image change that swaps the chromium binary or shrinks /dev/shm does not regress. #BUNYIP-148