Point dev:verify at the Proxmox backups layout spec

The managed proof pack behind `npm run dev:verify` still named
tests/17-recovery-layout.spec.ts, which 1c38d79937 replaced with
tests/17-proxmox-backups-layout.spec.ts in July. The registered proof for
scripts/hot-dev-bg.sh pinned the stale path, so nothing flagged it.

The stale path did not fail the pack. Playwright treats each spec path as
a filter, so `test --list` with main's arguments reports 10 tests in 2
files and exits 0: the Proxmox backups layout guard had silently dropped
out of dev:verify.

The replacement spec reads the mock-mode estate, while dev:verify attaches
to the managed runtime in whatever mode it was left in. Under the managed
runtime it now skips with a `npm run mock:on` hint when mock mode is off,
instead of flipping modes in place: Monitor.SetMockMode clears the
runtime's active alerts and in-memory history on every switch. The Core
E2E harness runs mock mode and is unaffected.

test-hot-dev-bg.sh now pins the new spec and checks that every spec the
default verify command names exists under tests/integration; against
main's hot-dev-bg.sh that check fails on the retired path. The integration
README and its pin, the deployment-installability contract clause, and two
unused RECOVERY_PRODUCT_SURFACE_EXACT_FILES lists naming deleted files are
brought in line.
This commit is contained in:
rcourtman
2026-10-08 09:56:53 +01:00
parent b0ba51db16
commit 1289728ded
7 changed files with 72 additions and 26 deletions
@@ -5192,10 +5192,20 @@ browser runtime, cover both stream-only reconnect degradation and full backend
loss, bounce the real backend through the launcher contract when needed, and
prove that the shell degrades and recovers through the proxy instead of
relying on backend-only API checks that miss browser/runtime drift.
That same managed browser proof pack must also keep the desktop Recovery page
layout guard on the canonical entrypoint, so `dev:verify` catches right-edge
history-table overflow regressions introduced by more human-readable subject
labels instead of leaving that check as a hidden one-off Playwright command.
That same managed browser proof pack must also keep the desktop Proxmox Backups
layout guard, `tests/integration/tests/17-proxmox-backups-layout.spec.ts`, on
the canonical entrypoint instead of leaving that check as a hidden one-off
Playwright command. It checks that selecting an activity day keeps the
operator on `/proxmox/backups` with an `N of M backups` count, and that a
one-year activity range keeps the page inside the horizontal viewport with the
PBS servers table's trailing column inside its wrapper. The guard reads the
mock-mode estate, so against a real-mode managed runtime it skips with a
`npm run mock:on` hint rather than switching modes in place, which would clear
the runtime's active alerts. Every spec the default proof command names must
exist under `tests/integration/`: Playwright treats each path as a filter and
runs whatever still matches, so a retired spec would drop out of `dev:verify`
without failing it. `scripts/tests/test-hot-dev-bg.sh` pins the spec name
and that existence check.
That same proof pack must also keep the Patrol blocked-runtime page contract on
the canonical entrypoint, so `dev:verify` catches stale healthy-summary
regressions where the real `/ai` route would otherwise look healthy even after
+1 -1
View File
@@ -986,7 +986,7 @@ run_verify_proof_command() {
HOT_DEV_VERIFY_LOCK_FILE="${HOT_DEV_VERIFY_LOCK}" \
node ./scripts/run-playwright.mjs \
tests/16-dev-runtime-recovery.spec.ts \
tests/17-recovery-layout.spec.ts \
tests/17-proxmox-backups-layout.spec.ts \
tests/18-patrol-runtime-state.spec.ts \
--project=chromium
)
@@ -157,13 +157,6 @@ def first_matching_policy_id(rule: dict, rel: str) -> str:
return "DEFAULT"
RECOVERY_PRODUCT_SURFACE_EXACT_FILES = [
"frontend-modern/src/components/Recovery/__tests__/Recovery.test.tsx",
"frontend-modern/src/utils/__tests__/frontendResourceTypeBoundaries.test.ts",
"tests/integration/tests/17-recovery-layout.spec.ts",
]
class CanonicalCompletionGuardTest(unittest.TestCase):
def test_registry_exists_and_contains_required_subsystems(self):
self.assertTrue(SUBSYSTEM_REGISTRY.exists())
@@ -10,12 +10,6 @@ from repo_file_io import canonical_workspace_repos_root, strip_local_git_env
from subsystem_lookup import lookup_paths, normalize_input_path, parse_args, render_pretty
RECOVERY_PRODUCT_SURFACE_EXACT_FILES = [
"frontend-modern/src/components/Recovery/__tests__/Recovery.test.tsx",
"frontend-modern/src/utils/__tests__/frontendResourceTypeBoundaries.test.ts",
"tests/integration/tests/17-recovery-layout.spec.ts",
]
PATROL_PAGE_AND_STATE_EXACT_FILES = [
"frontend-modern/src/api/__tests__/patrolAttention.test.ts",
"frontend-modern/src/components/Brand/__tests__/PulsePatrolLogo.test.tsx",
+21 -2
View File
@@ -205,9 +205,27 @@ EOF
assert_contains "default verify proof runs from integration harness" "${output}" "cwd=${ROOT_DIR}/tests/integration"
assert_contains "default verify proof runs through the dedicated Playwright harness" "${output}" "args=./scripts/run-playwright.mjs"
assert_contains "default verify proof includes dev runtime recovery spec" "${output}" "tests/16-dev-runtime-recovery.spec.ts"
assert_contains "default verify proof includes recovery layout spec" "${output}" "tests/17-recovery-layout.spec.ts"
assert_contains "default verify proof includes Proxmox backups layout spec" "${output}" "tests/17-proxmox-backups-layout.spec.ts"
assert_contains "default verify proof includes patrol runtime-state spec" "${output}" "tests/18-patrol-runtime-state.spec.ts"
assert_contains "default verify proof keeps chromium project pin" "${output}" "--project=chromium"
# Playwright treats each spec path as a filter and runs whatever still
# matches, so a retired spec drops out of dev:verify without failing it.
local verify_cwd verify_args arg checked_specs=0 missing_specs=""
verify_cwd="$(printf '%s\n' "${output}" | sed -n 's/^cwd=//p')"
verify_args="$(printf '%s\n' "${output}" | sed -n 's/^args=//p')"
for arg in ${verify_args}; do
[[ "${arg}" == *.spec.ts ]] || continue
checked_specs=$((checked_specs + 1))
[[ -f "${verify_cwd}/${arg}" ]] || missing_specs+=" ${arg}"
done
if (( checked_specs > 0 )) && [[ -z "${missing_specs}" ]]; then
echo "[PASS] default verify proof names only specs that exist"
else
echo "[FAIL] default verify proof names only specs that exist" >&2
echo "Missing under ${verify_cwd}:${missing_specs:- no spec arguments found}" >&2
((failures++))
fi
}
test_managed_wrapper_defaults_to_local_only_runtime() {
@@ -1156,7 +1174,8 @@ test_integration_readme_uses_managed_backend_restart_wrapper() {
assert_contains "integration readme documents managed backend restart wrapper" "${output}" "npm run dev:backend-restart"
assert_contains "integration readme documents owner-process recovery proof" "${output}" "kills the supervised"
assert_contains "integration readme names the owner process" "${output}" "owner process"
assert_contains "integration readme documents recovery layout proof" "${output}" "tests/17-recovery-layout.spec.ts"
assert_contains "integration readme documents Proxmox backups layout proof" "${output}" "tests/17-proxmox-backups-layout.spec.ts"
assert_not_contains "integration readme drops the retired recovery layout spec" "${output}" "tests/17-recovery-layout.spec.ts"
assert_contains "integration readme documents patrol runtime-state proof" "${output}" "tests/18-patrol-runtime-state.spec.ts"
assert_contains "integration readme documents explicit browser override precedence" "${output}" "PLAYWRIGHT_BASE_URL"
assert_contains "integration readme documents backend base split" "${output}" "backend-oriented base"
+5 -5
View File
@@ -44,10 +44,10 @@ End-to-end Playwright tests that validate critical user flows against a running
- `tests/16-dev-runtime-recovery.spec.ts` — managed browser runtime proof:
- Attaches Playwright to the canonical `5173` browser entrypoint
- Restarts the managed backend and proves the browser shell recovers through the proxy
- `tests/17-recovery-layout.spec.ts` — desktop Recovery layout regression guard:
- Mocks a realistic Recovery dataset with human-readable subject labels
- Proves the focused history table fits the desktop wrapper without horizontal overflow
- Proves the `Outcome` column stays visible at the right edge
- `tests/17-proxmox-backups-layout.spec.ts` — desktop Proxmox Backups layout guard:
- Needs the mock-mode dataset and skips against a real-mode runtime (`npm run mock:on` first)
- Proves picking an activity day keeps `/proxmox/backups` and shows an `N of M backups` count
- Proves a one-year range keeps the page inside the horizontal viewport and the PBS servers table's trailing column inside its wrapper
- `tests/18-patrol-runtime-state.spec.ts` — Patrol runtime-state browser guard:
- Mocks a blocked Patrol runtime with stale healthy summary payloads
- Proves the real `/ai` route shows Patrol as paused and suppresses stale healthy summary copy
@@ -181,7 +181,7 @@ Equivalent direct proof command from the integration harness:
cd tests/integration
PULSE_E2E_USE_HOT_DEV=1 \
PULSE_E2E_SKIP_PLAYWRIGHT_INSTALL=1 \
npm test -- tests/16-dev-runtime-recovery.spec.ts tests/17-recovery-layout.spec.ts tests/18-patrol-runtime-state.spec.ts --project=chromium
npm test -- tests/16-dev-runtime-recovery.spec.ts tests/17-proxmox-backups-layout.spec.ts tests/18-patrol-runtime-state.spec.ts --project=chromium
```
This mode attaches Playwright to the canonical dev browser entrypoint on `http://127.0.0.1:5173`, uses the repo-root managed runtime wrappers as the control surface, and writes browser runtime connection state for Playwright instead of targeting the backend port directly. Those wrappers are backed by `scripts/hot-dev-bg.sh`, but the wrapper surface is the canonical operator contract.
@@ -1,8 +1,36 @@
import { expect, test, type Page } from "@playwright/test";
import { ensureAuthenticated, primaryNavigationLink } from "./helpers";
import {
ensureAuthenticated,
getMockMode,
primaryNavigationLink,
} from "./helpers";
const DESKTOP_VIEWPORT = { width: 1440, height: 900 };
const truthy = (value: string | undefined) =>
["1", "true", "yes", "on"].includes(
String(value || "")
.trim()
.toLowerCase(),
);
// The guards read the mock-mode estate: PBS servers and a populated backup
// calendar. The Core E2E harness runs mock mode, but `npm run dev:verify`
// attaches to the managed hot-dev runtime in whatever mode it was left in.
// There a real-mode runtime skips the guards instead of switching modes in
// place, because Monitor.SetMockMode clears the runtime's active alerts and
// in-memory history on every switch.
async function skipUnlessManagedRuntimeIsMock(page: Page) {
if (!truthy(process.env.PULSE_E2E_USE_HOT_DEV)) {
return;
}
const { enabled } = await getMockMode(page);
test.skip(
!enabled,
"Needs the mock-mode dataset; run `npm run mock:on` before `npm run dev:verify`",
);
}
async function openProxmoxBackups(page: Page) {
const proxmoxTab = primaryNavigationLink(page, "Proxmox");
await expect(proxmoxTab).toBeVisible({ timeout: 30_000 });
@@ -41,6 +69,7 @@ test.describe("Proxmox backups layout guards", () => {
await page.setViewportSize(DESKTOP_VIEWPORT);
await ensureAuthenticated(page);
await skipUnlessManagedRuntimeIsMock(page);
await openProxmoxBackups(page);
// The Backups section now opens the date view directly.
@@ -69,6 +98,7 @@ test.describe("Proxmox backups layout guards", () => {
await page.setViewportSize(DESKTOP_VIEWPORT);
await ensureAuthenticated(page);
await skipUnlessManagedRuntimeIsMock(page);
await openProxmoxBackups(page);
await page