From d052b0d38d3867fcde666e34f1a6ea7d68017b07 Mon Sep 17 00:00:00 2001 From: Steve Spicklemire Date: Sun, 23 Aug 2026 18:29:31 -0400 Subject: [PATCH] test(e2e): skip the anonymous-state tests when the server runs locally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ide/auth.py short-circuits identity for local servers: def get_user_info(): if routes.is_running_locally(): return {'email': 'localuser@local.host'} so a local server has NO anonymous state — every request is that user. Three tests assert anonymous behaviour and therefore cannot pass locally: test_home_page_sign_in_link a.signin is hidden (you are signed in) test_api_login_unauthenticated /api/login returns new_user, not not_logged_in test_docs_help_link_from_ide a jQuery-UI overlay (the new-user dialog) intercepts the click They now skip in that situation and still run against a deployed URL, where the assertions mean something. /api/login is the tell: locally it reports new_user for localuser@local.host, which has no User record. This makes the local run honest rather than green-by-deletion; the underlying hack is worth removing separately (see follow-up branch) so these paths can be tested locally against an auth emulator instead of being skipped. NOT VERIFIED BY ME — I have no local glowscript server. Expect 21 passed, 3 skipped against http://localhost:8080. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01G7y9rTA1r8r8EhEnPSQenR --- tests/test_e2e.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/test_e2e.py b/tests/test_e2e.py index d30d385f..75c57542 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -37,6 +37,31 @@ from playwright.sync_api import Page, expect +# --------------------------------------------------------------------------- +# Local-mode detection +# +# ide/auth.py short-circuits identity when running locally: +# +# def get_user_info(): +# if routes.is_running_locally(): +# return {'email': 'localuser@local.host'} +# +# so a local server has no anonymous state at all — every request is that user. +# Three tests below assert anonymous behaviour and therefore cannot pass +# locally; they skip rather than fail, and still run against a deployed URL. +# /api/login is the reliable tell: locally it reports `new_user` for +# localuser@local.host, which has no User record. +# --------------------------------------------------------------------------- + + +def _running_locally(page, base_url): + try: + data = page.request.get(f"{base_url}/api/login").json() + except Exception: + return False + return data.get("state") != "not_logged_in" + + # --------------------------------------------------------------------------- # Home page / IDE # --------------------------------------------------------------------------- @@ -66,6 +91,8 @@ def test_home_page_help_link(page: Page, base_url): def test_home_page_sign_in_link(page: Page, base_url): """IDE should show a Sign in link for unauthenticated users.""" + if _running_locally(page, base_url): + pytest.skip("local server auto-authenticates (ide/auth.py get_user_info)") page.goto(base_url) sign_in = page.locator("a.signin") expect(sign_in).to_be_visible() @@ -100,6 +127,8 @@ def test_docs_static_css_loads(page: Page, base_url): def test_api_login_unauthenticated(page: Page, base_url): """API login endpoint should return not_logged_in state for anonymous requests.""" + if _running_locally(page, base_url): + pytest.skip("local server auto-authenticates (ide/auth.py get_user_info)") response = page.request.get(f"{base_url}/api/login") assert response.status == 200 data = response.json() @@ -143,6 +172,8 @@ def test_docs_index_lists_group(page: Page, base_url): def test_docs_help_link_from_ide(page: Page, base_url): """Clicking the Help link in the IDE should open the docs index.""" + if _running_locally(page, base_url): + pytest.skip("local server auto-authenticates (ide/auth.py get_user_info)") page.goto(base_url) # Use the target=_blank Help link in the header with page.expect_popup() as popup_info: