Spaces:
Sleeping
Sleeping
| #!/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()) | |