diff --git a/scripts/hyde/elmhurst_lib.py b/scripts/hyde/elmhurst_lib.py index 4f137988..9b27443d 100644 --- a/scripts/hyde/elmhurst_lib.py +++ b/scripts/hyde/elmhurst_lib.py @@ -64,8 +64,12 @@ HERE = Path(__file__).parent SESSION_DIR = HERE / ".elmhurst-session" CREDS_FILE = HERE / ".elmhurst-creds.json" # gitignored; {"access":..,"pwd":..} -# The single reusable campaign assessment ("Khalim-test"). Overwrite it per UPRN. -ASSESSMENT_GUID = "B44A0DB4-4C08-4241-B818-86F060172105" +# The reusable campaign assessment ("Khalim-test"), overwritten per UPRN. Can be +# overridden per run via the `ELM_GUID` env var (e.g. a per-UPRN assessment under +# a different account) — see Limitations "parameterize the GUID". +ASSESSMENT_GUID = os.environ.get( + "ELM_GUID", "B44A0DB4-4C08-4241-B818-86F060172105" +) ENTRY_URL = ( "https://rdsap10online.elmhurstenergy.co.uk/Processing/WebFormAddress.aspx" f"?Guid={ASSESSMENT_GUID}" @@ -98,17 +102,31 @@ def session() -> Generator[tuple[BrowserContext, Page], None, None]: headless=False, accept_downloads=True, viewport={"width": 1400, "height": 1000}, + # Container /dev/shm is tiny (64M) → chromium renderer "Target + # crashed" mid-build without this. --no-sandbox for rootless Xvfb. + args=["--disable-dev-shm-usage", "--no-sandbox"], ) page = ctx.pages[0] if ctx.pages else ctx.new_page() page.on("dialog", lambda d: d.accept()) - page.goto(ENTRY_URL, wait_until="networkidle", timeout=60_000) - if "WebFormLogin" in page.url: - access, pwd = _creds() - page.fill("#ctl00_ctl00_ContentBody_ContentBody_TextBoxAccessCode", access) - page.fill("#ctl00_ctl00_ContentBody_ContentBody_TextBoxPassword", pwd) - with page.expect_navigation(wait_until="networkidle", timeout=60_000): - page.click("#ctl00_ctl00_ContentBody_ContentBody_ImageButtonEnter") - page.wait_for_timeout(1000) + # Login can be slow/flaky; retry the whole goto+fill a few times. + for attempt in range(4): + try: + page.goto(ENTRY_URL, wait_until="domcontentloaded", timeout=60_000) + if "WebFormLogin" not in page.url: + break # already authed (server session still valid) + access, pwd = _creds() + ac = "#ctl00_ctl00_ContentBody_ContentBody_TextBoxAccessCode" + page.wait_for_selector(ac, state="visible", timeout=30_000) + page.fill(ac, access) + page.fill("#ctl00_ctl00_ContentBody_ContentBody_TextBoxPassword", pwd) + with page.expect_navigation(wait_until="networkidle", timeout=60_000): + page.click("#ctl00_ctl00_ContentBody_ContentBody_ImageButtonEnter") + page.wait_for_timeout(1000) + if "WebFormLogin" not in page.url: + break + except PlaywrightTimeoutError: + print(f" login attempt {attempt+1} timed out, retrying...", flush=True) + page.wait_for_timeout(2000) try: yield ctx, page finally: