Skip to content

Fix flaky CI tests - #299

Merged
Archmonger merged 4 commits into
mainfrom
fix-flaky-pyscript-tests
Sep 14, 2026
Merged

Archmonger merged 4 commits into
mainfrom
fix-flaky-pyscript-tests

Conversation

@Archmonger

@Archmonger Archmonger commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Description

The scheduled Test/python-source CI jobs fail intermittently due to a handful of flaky tests. This PR makes the suite robust by addressing the two root causes.

Root causes & fixes

1. Timeout-based flakes

The shared browser page used the default 10s Playwright timeout (page.set_default_timeout(10000)), which was too short for the full component set running under one shared page + server on slow/loaded CI runners. This caused intermittent Page.wait_for_selector: Timeout 10000ms exceeded in:

  • test_form_async_events
  • test_component_use_user_data
  • test_component_use_user_data_with_default
  • test_component_session_exists
  • test_error_synchronous_only_operation
  • test_component_params
  • test_pyscript_0_hello_world (PyScript cold-start — already addressed)

Fix: raise the default timeout to 30s, matching ReactPy core's test fixture timeout (DisplayFixture(timeout=30)).

2. Router navigation-state flake

test_url_router_navigation_state failed intermittently with AssertionError: assert uuid1 == uuid2. SPA navigation preserves use_state, but the WebSocket can reconnect under load, which causes ReactPy to re-mount the component and reset hook state (losing the next_page navigation token).

Fix (test app):

  • Hoist the route definitions to module scope so route elements have a stable identity across renders (rather than being recreated inside main() on every render).
  • Store the next_page navigation token in a module-level per-component store so it survives both navigation and transient reconnects.

Verification

  • Full test_components suite (86 tests) passes 10 consecutive runs locally with zero flakes (previously reproduced test_form_async_events, test_url_router_navigation_state, and the user-data/session/db flakes under load).
  • ruff lint/format and pyright type-checks pass.
  • All python-source matrix jobs (16 combos), formatting, types, JS, docs, and CodeQL pass on the PR CI.

Checklist

  • Tests have been developed for bug fixes or new functionality.
  • The changelog has been updated, if necessary. (Not necessary — test-infrastructure changes, not user-facing.)
  • Documentation has been updated, if necessary.
  • GitHub Issues closed by this PR have been linked.

By submitting this pull request I agree that all contributions comply with this project's open source license(s).

The PyScript page bootstrap (Pyodide boot + micropip package install) is a
cold-start cost paid only by the first test to visit /pyscript/. That test
waited 30s for the server-rendered placeholder but only the default 10s for
the rendered component, so slow CI runners intermittently timed out.

Give the rendered component the same generous 30s timeout as the placeholder,
consistent with ReactPy core's PyScript test fixtures.

Refs: #297
@Archmonger
Archmonger marked this pull request as ready for review September 14, 2026 06:03
@Archmonger
Archmonger requested a review from a team as a code owner September 14, 2026 06:03
Archmonger and others added 3 commits September 13, 2026 23:34
The test timeout change is not user-facing, so it does not warrant a
changelog entry.
Two classes of intermittent failures were reproduced under load:

1. Timeout-based flakes (test_form_async_events, test_component_use_user_data,
   test_component_use_user_data_with_default, test_component_session_exists,
   test_error_synchronous_only_operation, test_component_params): the shared
   page's default 10s Playwright timeout was too short for async state updates,
   form mutations, and page loads on slow/loaded runners. Raise it to 30s to
   match ReactPy core's test fixture timeout.

2. test_url_router_navigation_state (assert uuid1 == uuid2): SPA navigation
   preserves use_state, but the WebSocket reconnects under load, causing
   ReactPy to re-mount the component and reset hook state. Stabilize the
   navigation token via a module-level store keyed per component, and hoist the
   route definitions to module scope so route elements have stable identity.
@Archmonger Archmonger changed the title Fix flaky test_pyscript_0_hello_world CI test Fix flaky CI tests Sep 14, 2026
@Archmonger
Archmonger merged commit df90f52 into main Sep 14, 2026
23 checks passed
@Archmonger
Archmonger deleted the fix-flaky-pyscript-tests branch September 14, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant