From 73e5c3f3f8e992f63b25c04d45c8f7c550dce995 Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:40:12 -0500 Subject: [PATCH] fix: codechef submit fixes and atcoder cleanup (#355) ## Problem After the initial CodeChef implementation, submit silently swallowed "contest not available for submission" errors, and the submit flow used blind `wait_for_timeout` delays. AtCoder had an unnecessary 500ms settle delay after file upload. ## Solution Replace the initial page-load sleep in CodeChef submit with `wait_for_selector`, replace the 3s post-click sleep with a proper `wait_for_selector` on the result dialog, and extend the practice fallback check to catch both dialog variants. Remove AtCoder's `BROWSER_SETTLE_DELAY` and the constant from `timeouts.py`. --- README.md | 3 ++- scrapers/atcoder.py | 2 -- scrapers/codechef.py | 18 +++++++++++------- scrapers/timeouts.py | 1 - 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 427496d..be37094 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ https://github.com/user-attachments/assets/e81d8dfb-578f-4a79-9989-210164fc0148 ## Features -- **Multi-platform support**: AtCoder, CodeChef, Codeforces, and CSES +- **Multi-platform support**: AtCoder, CodeChef, Codeforces, USACO, CSES, + Kattis - **Automatic problem setup**: Scrape test cases and metadata in seconds - **Dual view modes**: Lightweight I/O view for quick feedback, full panel for detailed analysis diff --git a/scrapers/atcoder.py b/scrapers/atcoder.py index 8645beb..a9876cf 100644 --- a/scrapers/atcoder.py +++ b/scrapers/atcoder.py @@ -30,7 +30,6 @@ from .timeouts import ( BROWSER_ELEMENT_WAIT, BROWSER_NAV_TIMEOUT, BROWSER_SESSION_TIMEOUT, - BROWSER_SETTLE_DELAY, BROWSER_SUBMIT_NAV_TIMEOUT, BROWSER_TURNSTILE_POLL, HTTP_TIMEOUT, @@ -500,7 +499,6 @@ def _submit_headless( "buffer": Path(file_path).read_bytes(), }, ) - page.wait_for_timeout(BROWSER_SETTLE_DELAY) page.locator('button[type="submit"]').click(no_wait_after=True) page.wait_for_url( lambda url: "/submissions/me" in url, diff --git a/scrapers/codechef.py b/scrapers/codechef.py index 7767b72..0427d5d 100644 --- a/scrapers/codechef.py +++ b/scrapers/codechef.py @@ -178,16 +178,15 @@ def _submit_headless_codechef( needs_relogin = True return try: - page.wait_for_timeout(2000) + page.wait_for_selector('[aria-haspopup="listbox"]', timeout=10000) page.locator('[aria-haspopup="listbox"]').click() page.wait_for_selector('[role="option"]', timeout=5000) page.locator(f'[role="option"][data-value="{language_id}"]').click() - page.wait_for_timeout(2000) + page.wait_for_timeout(250) page.locator(".ace_editor").click() page.keyboard.press("Control+a") - page.wait_for_timeout(200) page.evaluate( """(code) => { const textarea = document.querySelector('.ace_text-input'); @@ -199,20 +198,25 @@ def _submit_headless_codechef( }""", source_code, ) - page.wait_for_timeout(1000) + page.wait_for_timeout(125) page.evaluate( "() => document.getElementById('submit_btn').scrollIntoView({block:'center'})" ) - page.wait_for_timeout(200) page.locator("#submit_btn").dispatch_event("click") - page.wait_for_timeout(3000) + try: + page.wait_for_selector('[role="dialog"], .swal2-popup', timeout=5000) + except Exception: + pass dialog_text = page.evaluate("""() => { const d = document.querySelector('[role="dialog"], .swal2-popup'); return d ? d.textContent.trim() : null; }""") - if dialog_text and "not available for accepting solutions" in dialog_text: + if dialog_text and ( + "not available for accepting solutions" in dialog_text + or "not available for submission" in dialog_text + ): submit_error = "PRACTICE_FALLBACK" elif dialog_text: submit_error = dialog_text diff --git a/scrapers/timeouts.py b/scrapers/timeouts.py index e4ff583..4148d4a 100644 --- a/scrapers/timeouts.py +++ b/scrapers/timeouts.py @@ -11,4 +11,3 @@ BROWSER_SUBMIT_NAV_TIMEOUT["atcoder"] = BROWSER_NAV_TIMEOUT * 2 BROWSER_SUBMIT_NAV_TIMEOUT["codeforces"] = BROWSER_NAV_TIMEOUT * 2 BROWSER_TURNSTILE_POLL = 5000 BROWSER_ELEMENT_WAIT = 10000 -BROWSER_SETTLE_DELAY = 500