#!/usr/bin/env python3 """Deterministic static-analysis regression for Phase 07-04: Resilient Run. The extension JS can't run headless here, so we assert the wiring CONTRACT by inspecting the source — mirroring how the Phase 06 plans static-checked JS with Python. No browser, no network. Runs from the repo root in well under 3 seconds. What it proves: * background.js OWNS generation: writes a status:'running' marker (with startedAt) to chrome.storage.local BEFORE the API call, then overwrites with a terminal status:'done'/'error' result — keyed by the normalized job URL. * popup.js restores running/done/error on open (spinner for in-flight) and live-refreshes an open popup via chrome.storage.onChanged. * The popup<->background contract matches: both sides use the SAME storage key (ats_results) and the SAME URL normalization (normalizeUrl). Exit code: 0 when every assertion passes, 1 otherwise. """ import os import sys REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BG_PATH = os.path.join(REPO_ROOT, "extension", "background.js") POPUP_PATH = os.path.join(REPO_ROOT, "extension", "popup", "popup.js") _failures = [] def _read(path): with open(path, encoding="utf-8") as fh: return fh.read() def check(condition, message): """Accumulate a failure for each unmet assertion (never raises).""" if condition: print(f" [PASS] {message}") else: print(f" [FAIL] {message}") _failures.append(message) def check_any(substrings, source, message): check(any(s in source for s in substrings), message) def main(): if not os.path.exists(BG_PATH): print(f" [FAIL] missing file: {BG_PATH}") _failures.append("background.js not found") if not os.path.exists(POPUP_PATH): print(f" [FAIL] missing file: {POPUP_PATH}") _failures.append("popup.js not found") if _failures: _banner() return 1 bg = _read(BG_PATH) popup = _read(POPUP_PATH) # ── background.js: owns the lifecycle + persists to storage ──────────────── print("background.js (generation owner / source of truth):") check("status: 'running'" in bg, "writes a running marker (status: 'running')") check("startedAt" in bg, "stamps startedAt on the running marker") check("chrome.storage.local.set" in bg, "persists via chrome.storage.local.set") check("ats_results" in bg, "uses the shared 'ats_results' storage map") check("writeEntry" in bg, "has a writeEntry storage helper") check("normalizeUrl" in bg, "keys persistence by normalizeUrl(job URL)") check_any(["msg.url", "url }", "url ="], bg, "reads the job URL from the message") check("chrome.tabs.query" in bg, "falls back to the active tab when url is absent") check("status: 'done'" in bg, "writes a terminal done state") check("status: 'error'" in bg, "writes a terminal error state") # ── popup.js: reflects background-owned state ────────────────────────────── print("popup.js (reflects background state, never resets to idle Run):") check("restoreResultForTab" in popup, "has restoreResultForTab") check("currentUrlKey" in popup, "restoreResultForTab keys off currentUrlKey") check("'running'" in popup, "handles the running state") check("spinner" in popup, "renders a spinner path for in-flight runs") check("'error'" in popup, "handles the persisted error state") check("url:" in popup, "sends url: in the GENERATE/REPAIR payload") check("chrome.storage.onChanged" in popup, "live-refreshes via chrome.storage.onChanged") # ── contract: both sides agree on key + normalization ────────────────────── print("contract (popup <-> background consistency):") check("ats_results" in bg and "ats_results" in popup, "both files use the 'ats_results' key") check("normalizeUrl" in bg and "normalizeUrl" in popup, "both files normalize the URL with normalizeUrl") _banner() return 1 if _failures else 0 def _banner(): print() if _failures: print("=" * 60) print(f"FAIL: resilient-run wiring incomplete ({len(_failures)} issue(s))") for f in _failures: print(f" - {f}") print("=" * 60) else: print("=" * 60) print("PASS: resilient-run wiring verified (background-owned + restore + live-refresh)") print("=" * 60) if __name__ == "__main__": sys.exit(main())