# Dependency-free Chromium responsive production UAT

Use when a private production UI needs responsive read-only evidence, Chromium plus `chromedriver` are available, but Selenium/Playwright are not installed. This is a fallback technique, not a reason to avoid a preferred existing browser harness.

## Safe execution pattern

1. Start `chromedriver` on loopback only (for example `--port=9515 --allowed-ips=127.0.0.1`) as a tracked background process.
2. Use Python stdlib `urllib.request` against the W3C WebDriver HTTP API. Create one isolated session per viewport with headless Chromium and an exact window rectangle.
3. Exercise the changed/deep routes, not only the root page. Wait for an explicit application-ready condition and a bounded quiet period before collecting evidence.
4. Enable browser and performance logs. Fail on browser `SEVERE`, `Network.loadingFailed`, and responses with status `>=400`.
5. Record only aggregate evidence: route, readiness, exact CSS viewport, page overflow, navigation visibility, console/network failure counts, and privacy-safe element metadata. Never print visible financial text.
6. Capture owner-only screenshots only when needed for actual visual review. Ask the vision pass to evaluate layout without transcribing values, then delete screenshots and temporary browser artifacts after extracting the verdict.
7. Stop the tracked driver process explicitly.

## W3C endpoints

- Create session: `POST /session`
- Set viewport: `POST /session/{id}/window/rect`
- Navigate: `POST /session/{id}/url`
- Evaluate DOM: `POST /session/{id}/execute/sync`
- Browser/performance logs: `POST /session/{id}/se/log`
- Screenshot: `GET /session/{id}/screenshot`
- Close session: `DELETE /session/{id}`

Do not assume the create-session response has one fixed shape; handle either a direct session ID or a nested `sessionId` field.

## Responsive evidence pitfalls

- `documentElement.scrollWidth <= clientWidth` proves only absence of page-level overflow. A table may still be clipped, internally scrolled, or visually unreadable.
- A DOM list of elements extending beyond the viewport can be legitimate inside an `overflow-x:auto` container. Inspect the nearest scroll ancestor and the screenshot before calling it a defect.
- Conversely, an internal scroll container is not automatically acceptable. Reject unreadable column collisions, per-digit value wrapping, clipped controls, or a heading squeezed into broken word fragments.
- Compare the URL by parsed pathname; an otherwise correct route may add a harmless query string and make a naive `endswith(path)` assertion fail.
- Chromium window chrome can make `documentElement.clientWidth` smaller than the requested outer window. Record both requested and actual CSS viewport dimensions.
- Generic element-height heuristics produce false positives for text links. Treat them as leads for visual review, not automatic touch-target failures.

## Financial no-write bracketing

Before the first production page load, compute owner-only deterministic count and ordered-row digests for every live SQLite table using a `mode=ro` connection. Recompute after the complete direct-API plus browser matrix. Require:

- `PRAGMA integrity_check = ok`;
- zero unexpected foreign-key findings;
- identical table sets, counts, and ordered-row hashes;
- no service-log traceback, critical error, or HTTP 500.

A whole-database file hash is not the canonical no-write proof because WAL/checkpoint and page-layout changes can alter it without changing business rows. Keep only aggregate digest evidence in the report.

## Verdict discipline

Separate these outcomes explicitly:

- deployment and services healthy;
- API/data-integrity UAT passed;
- responsive UAT passed, passed with a non-blocking visual finding, or failed.

A responsive production finding after a merged exact-SHA deployment is a follow-up release candidate. Do not patch production directly; use a focused PR, CI, exact-SHA redeployment, and repeat the affected matrix.