Files
cc-ci/runner/harness/browser.py
autonomic-bot 9a7772563a style: repo-wide lint pass — make the lint gate green again
Push builds have been RED on the lint step since ~build 209 from accumulated
formatting drift. This is the mechanical cleanup: ruff format + ruff --fix
(UP038 isinstance unions, SIM105 contextlib.suppress, UP031 f-strings, SIM115
tempfile context manager), shfmt -i 2 -ci, nixpkgs-fmt/statix/deadnix (merged
attrsets, dropped unused lib args), yamllint, and shell quoting fixes in
tests/lasuite-docs/setup_custom_tests.sh. No behaviour changes intended;
lint: PASS, unit tests: 138 passed.
2026-06-09 21:56:15 +00:00

64 lines
2.4 KiB
Python

"""Playwright helpers for Phase-2 recipe tests (plan §4.2).
Centralizes the `page.goto(...)` retry loop that absorbs transient network errors (F2-3 / F2-5):
Playwright's `page.goto` raises `PlaywrightError` on transport-level failures (`net::ERR_*`,
connection resets, CDP target gone) — those escape a naive loop that only retries on status
mismatches. Wrap every install-overlay `page.goto` in this helper so transient errors retry
without weakening the underlying assertion (same pattern as F1e-1's `exec_in_app` poll+raise
hardening).
"""
from __future__ import annotations
import time
def goto_with_retry(
page,
url,
*,
deadline_seconds: int = 120,
accept_statuses=(200, 304),
goto_timeout_ms: int = 30_000,
wait_until: str = "domcontentloaded",
):
"""Poll `page.goto(url)` until status is in `accept_statuses` OR the deadline expires.
Returns the final Playwright response. Raises AssertionError if the deadline expires without
a successful status. Each iteration catches `PlaywrightError` (and any other exception) so
transient network failures retry rather than fail the test.
Use case: recipe install overlays where the app's HTTP layer may be up (status 200 to
/healthz or generic readiness) but the requested route is still registering (404), or
Playwright's CDP connection transiently flakes (`net::ERR_NETWORK_CHANGED`).
"""
# Imported lazily so this module can be imported without playwright at unit-test time.
try:
from playwright.sync_api import Error as PlaywrightError
except ImportError: # pragma: no cover — playwright is always installed in cc-ci-run
PlaywrightError = Exception # noqa: N806
deadline = time.time() + deadline_seconds
resp = None
last_status = 0
last_err = ""
attempts = 0
while time.time() < deadline:
attempts += 1
try:
resp = page.goto(url, wait_until=wait_until, timeout=goto_timeout_ms)
except PlaywrightError as e:
last_err = str(e)
resp = None
last_status = 0
else:
last_status = resp.status if resp is not None else 0
if last_status in accept_statuses:
return resp
time.sleep(3)
raise AssertionError(
f"page.goto({url}) never returned a status in {accept_statuses} after "
f"{attempts} attempts ({deadline_seconds}s); last status={last_status}, "
f"last error={last_err or 'none'}"
)