You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(e2e): extensions tab tests, CI parallelization, and 3 production bug fixes (#584)
* feat(e2e): extensions tab tests, CI parallelization, and 3 bug fixes
## E2E test coverage
- Add tests/e2e/scenarios/test_extensions.py with 57 tests covering all
extensions tab flows: installed WASM tool/MCP/channel cards, configure
modal (open, fields, cancel, save, OAuth, error), auth card (token,
OAuth, submit, cancel, error, multi-extension coexistence), activate
flow, install/remove flows, WASM channel stepper states, and tab reload
behaviour. All network calls intercepted via page.route() — no real
binaries or external registries needed.
- Expand tests/e2e/helpers.py with 50+ new CSS selectors for the
extensions tab UI.
- Add tests/e2e/README.md documentation on the page.route() mocking
pattern, LIFO handler ordering, and page.evaluate() injection.
## CI parallelization
- Split .github/workflows/e2e.yml into a build job (compile once,
upload artifact) and a 3-way parallel test matrix (core / features /
extensions), matching the pattern in test.yml. Reduces wall-clock time
from ~15–20 min serial to ~10–12 min. Adds an e2e roll-up job for
branch protection.
## Bug fixes in app.js (found via test-driven code review)
- Fix null crash: renderExtensionCard() called ext.tools.length without
a null guard; add ext.tools && check (regression: test_ext_tools_null).
- Fix modal UX: submitConfigureModal() closed the overlay before checking
success, making failures unrecoverable without reopening; close only on
success, re-enable buttons and keep modal open on failure
(regression: test_configure_modal_stays_open_on_save_failure).
- Fix URL injection: all window.open() calls for server-supplied auth_url
now go through openOAuthUrl() which rejects non-HTTPS schemes
(regression: test_oauth_url_injection_blocked).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(e2e): prune extensions tests 57→46 by merging redundant setups
Merge 11 tests that shared identical fixture+navigation overhead:
- Group A: 3 empty-state tests → test_extensions_empty_tab_layout
- Group B: card_renders absorbs ext_tools_list_shown (same _WASM_TOOL fixture)
- Group B: auth_dot_unauthed + unauthed_shows_configure_btn → test_installed_wasm_tool_unauthed_state
- Group D: installed + configured states → test_wasm_channel_setup_states (identical UI)
- Group D: failed_state + stepper_failed_circle → test_wasm_channel_failed_renders
- Group G: 5 field badge tests → test_configure_modal_field_variants (4 fields, one pass)
- Group H: submit_success + enter_key_submits → test_auth_card_submit_success
Coverage preserved: all assertions kept, no unique behaviors removed.
Extensions CI job estimated to drop from ~7 min to ~5 min.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(e2e): fix configure_input selector scoping in merged field variants test
modal.locator(".configure-modal input[type='password']") scoped the absolute
selector inside .configure-modal, effectively searching for a nested
.configure-modal which never exists → count() == 0. Use page.locator()
instead, consistent with all other tests in the file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(e2e): address PR review comments — replace fixed sleeps with deterministic waits
- Remove unnecessary wait_for_timeout(1000) from test_remove_cancelled_keeps_card
(window.confirm = () => false is synchronous; DOM is unchanged when click() returns)
- Replace wait_for_timeout(800) with wait_for_function() for window._lastOpenedUrl
checks in configure_modal_save_oauth and activate_with_auth_url_opens_popup
- Replace wait_for_timeout(300) with nth(1).wait_for(visible) in
test_auth_card_multiple_extensions_coexist
- Remove wait_for_timeout(800/300) in test_auth_card_submit_empty_noop and
test_auth_completed_sse_dismisses_card (both check synchronous JS side-effects)
- Add comment in test_oauth_url_injection_blocked explaining why timeout is kept
(negative assertion — cannot use wait_for_function for absence of event)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(e2e): address remaining PR review comments
- Remove unused `import pytest` from test_extensions.py
- Fix unawaited coroutine bug: convert lambda route handlers to async def
in test_extensions_tab_reloads_on_revisit and
test_auth_completed_sse_triggers_extensions_reload (lambda r: r.fulfill(...)
returns an unawaited coroutine; requests silently fell through to real server)
- Fix README.md example to use async def handler (same bug in docs)
- Harden openOAuthUrl() in app.js: use URL constructor instead of
.startsWith() so non-string server-supplied values (objects, null, etc.)
are safely rejected rather than throwing TypeError
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(e2e): address second round of PR review comments
- Add timeout-minutes to CI build job to prevent hung workflows
- Use parsed.href instead of raw url in openOAuthUrl for safety
- Remove unused MessageEvent variable in auth_completed test
- Replace wait_for_timeout(800) with expect_response in activate test
- Replace wait_for_timeout(300) with tab panel wait_for in reload test
[skip-regression-check]
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
0 commit comments