Files
pulse/frontend-modern/browser-tests
pulse-triage[bot] 2970e7b946 Compose batch-start published History provenance with reviewed maintenance
Change-source: pulse-maintainer
2026-10-14 13:27:26 +01:00
..
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00
2026-10-11 22:20:25 +01:00

Backup polling browser regression

From the repository root, after npm ci at the root and in frontend-modern:

pulse-heavy-run -- node scripts/check-backup-browser-polling.mjs
pulse-heavy-run -- env PULSE_BROWSER_WIDTH=390 node scripts/check-backup-browser-polling.mjs

Requires Playwright Chromium (npx playwright install chromium). The runner starts and closes a loopback-only Vite server on port 5198 and a headless browser; it neither needs nor contacts a live Pulse deployment. API responses are synthetic.

The fixture mounts the production backup table, router and CSS in a native scroll container, with 40 workloads replaced by HTTP polling once per second. It expands a mid-table workload and focuses its toggle, then verifies three changed snapshot names render while focus, restore evidence, scroll offset and the coverage route survive. Non-zero initial scroll prevents a vacuous pass.

This covers #1869's refresh stability at the coverage-table boundary. It does not qualify the full application resource provider/WebSocket path, PBS drawer, By date view, virtualised large tables, Settings editing, or Brave. A passing result is not grounds to close #1869 or claim the reported top-of-page jump fixed.

Application refresh boundary

pulse-heavy-run -- node scripts/check-backup-app-refresh.mjs
pulse-heavy-run -- env PULSE_BROWSER_WIDTH=390 node scripts/check-backup-app-refresh.mjs

This separate runner loads the actual application entry point, authentication bootstrap, router, scoped/paginated resource queries, WebSocket store and PBS resource drawer. Authentication and all API/socket data are synthetic; no live Pulse server or credentials are used. The browser blocks off-origin HTTP traffic. It supplies 240 workloads and a hybrid PBS resource with a metrics-history target. Three replacement rawData frames per view change rendered names, rather than merely waiting on a timer with unchanged content.

Assertions cover:

  • Coverage: fewer rendered rows than the inventory (windowing enabled), non-zero scroll, expanded restore evidence, focused expansion button and route retained.
  • By date: changed workload name, non-zero scroll, focused navigation link and route retained. This view has no per-artifact expansion toggle.
  • PBS: real History panel remains visible and selected, with its tab focused and route/scroll retained while the PBS name changes. Its baseline scroll is zero; this checks drawer state, not a non-zero drawer-scroll regression.
  • No uncaught page errors or error-level browser console messages.

Printed samples record scroll offsets and active controls. The fixed 500ms waits allow initial layout/scroll synchronisation; each refresh waits for changed text. The backup artifact HTTP payload itself is static after initial loading: this is resource-provider/socket replacement qualification, not backup API refetch proof. Narrow-width interaction is keyboard-driven, not touch or Brave qualification. The test does not cover Settings Manage editing, Authentication strategy selection, expansion padding, arbitrary inventory churn/reordering, or a deployed release. Passing is not grounds to close the mixed report #1869.

Final guest and Patrol presentation fixtures

Prepare the existing guest filesystem, memory, reading-help and Patrol-rule fixtures once, before browser execution, from frontend-modern:

node browser-tests/build-publication-fixtures.mjs
npm run test -- browser-tests/publication-fixture-server.test.mjs

The server regression uses Vitest's runner and is included in npm test. The command above also runs its binding, listener and cleanup checks on their own. The server checks exercise only a locally owned loopback listener and synthetic temporary files; no standalone Node bridge is needed.

The four corresponding browser runners use the resulting static bundles in tmp/publication-final-static at the repository root. They no longer compile or start Vite inside the browser process tree. Rebuild after source changes: the server refuses altered imported sources, Tailwind scan inputs, the dependency lock, runner code, compiled assets or the shipped safety document before listening. Only bound assets and the explicit reading-help Docs route are served; missing JS, CSS and Markdown stay errors rather than receiving an HTML fallback.

The builder's prepared-not-browser-verified result and the server tests are preparation evidence only. Desktop/phone interactions, inspected captures, own-parent and final-content receipts still require a real browser pass. No native guest-agent, thaw, filesystem-write, installed or publication acceptance is established by compiling these synthetic fixtures.

The isolated browser copy has no Git store. When preparing its preview there, pass --source-sha <full SHA> with the source owner's externally checked HEAD. The binding marks this as supplied-for-isolated-copy, not a Git observation. The default remains an actual Git HEAD read, with no silent fallback. Verify the binding's source and artifact hashes against the assigned tree before using the preview as evidence; a supplied SHA alone establishes no source identity.

CI and release evidence

These standalone runners are manual qualification commands: the current GitHub workflows do not invoke them. A green Frontend or Core E2E check therefore does not establish that either runner passed on the checked commit. Record the exact source revision, command, viewport and output when using their results for release review; retained JSON samples describe their recorded run, not later commits or distributed images.

The separate integration spec tests/integration/tests/64-workloads-proxmox-refresh-stability.spec.ts covers workload History, LXC refresh/deletion and off-screen PBS drawer scrolling. It is currently listed in PROBATION_SPECS in tests/integration/e2e-tiering.mjs: its failures are reported but do not fail the Core E2E gate. Inspect the probation report as well as the aggregate check. It is not a substitute for these runners' Coverage/By date assertions. Promotion remains subject to the existing ten-clean- executed-main-runs rule; a local pass is not grounds to bypass it.

Alert recovery acceptance

The separate alert recovery checklist covers installed ordinary-event receipts, recurrence/restart isolation, and separately identified main-build screen-reader feedback. It is a manual procedure, not an automated runner or evidence that a candidate passed.

Patrol provider protocol tests

The credential-free local provider uses Node's test runner, not Vitest. Run its protocol controls explicitly from frontend-modern:

node --test browser-tests/patrol-setup-provider.node-tests.cjs

The .node-tests.cjs name deliberately stays outside Vitest's .test/.spec discovery. The provider controls still execute with Node; naming them .test.cjs makes npm test import a second runner and fail with “No test suite found”, even when the protocol controls themselves pass. The browser journey continues to use patrol-setup-real-backend.cjs.