Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Wait for a page load in Browser.open() #19583

Merged
merged 2 commits into from
Nov 8, 2023

Conversation

martinpitt
Copy link
Member

@martinpitt martinpitt commented Nov 8, 2023

Commit 8284618 dropped all explicit "wait for page load" calls (fka. expect_load()) in favor of allowing page loads during wait commands. This is better in almost all cases, but it created a race condition on the login page in tests which logged out and back in. In particular, this can happen:

  1. Test calls Browser.logout().

  2. That destroys a lot of execution contexts from the session, and creates a new one for the login page. It waits until the #login field becomes visible.

  3. Test starts a new session by calling Browser.open() usually via Browser.login_and_go(). This results in a Page.navigate() CDP call. Sometimes this takes a while.

  4. Browser.try_login() fills in the login form. In most cases, the wait: ph_is_present("#login") command runs into the page load from 3., sees the destroyed/new execution context, and resumes on the new frame.

    However, if cockpit/ws or the browser take a while to load the login page, it could happen that it gets all the way to e.g. filling in the user or even password form before the page load from 3. happens. That page load resets the form.

  5. try_login() clicks on "Login" button, which fails because no user or password is given.

Fix this by always waiting for a page load in Browser.open() after a Page.navigate(). But we don't need the unnecessary complex and brittle polling machinery of the old expectLoad() before commit 8284618. We can use the loadEventFired CDP signal, which happens after the page and all of its frames finished loading, and execution contexts are set up. Introduce a new little waitPageLoad() helper which re-uses the existing pageLoadHandler promise.


This fixes this common flake pair, which both fail in > 30% of runs.

See #19578 for the debugging note details and a stress test with amplification.

@martinpitt martinpitt added blocked Don't land until something else happens first (see task list) flake unstable test labels Nov 8, 2023
@martinpitt martinpitt removed the blocked Don't land until something else happens first (see task list) label Nov 8, 2023
@martinpitt martinpitt requested review from mvollmer and jelly and removed request for jelly and mvollmer November 8, 2023 07:25
@martinpitt martinpitt marked this pull request as draft November 8, 2023 07:58
@martinpitt
Copy link
Member Author

martinpitt commented Nov 8, 2023

Meh, too soon -- several test failures which now hang forever. So at the very least, we need to teach this thing about a timeout. TestKeys.testAuthorizedKeys reproduces fine locally.

https://bugzilla.mozilla.org/show_bug.cgi?id=1702860 got fixed 8 months
ago, and works fine with current Firefox.
Commit 8284618 dropped all explicit "wait for page load" calls (fka.
`expect_load()`) in favor of allowing page loads during wait commands.
This is better in almost all cases, but it created a race condition on
the login page in tests which logged out and back in. In particular,
this can happen:

 1. Test calls `Browser.logout()`.

 2. That destroys a lot of execution contexts from the session, and
    creates a new one for the login page. It waits until the `#login`
    field becomes visible.

 3. Test starts a new session by calling `Browser.open()`  usually via
    `Browser.login_and_go()`. This results in a `Page.navigate()` CDP
    call. Sometimes this takes a while.

 4. `Browser.try_login()` fills in the login form. In *most cases*, the
    `wait: ph_is_present("#login")` command runs into the page load from
    3., sees the destroyed/new execution context, and resumes on the new
    frame.

    However, if cockpit/ws or the browser take a while to load the login
    page, it could happen that it gets all the way to e.g. filling in
    the user or even password form before the page load from 3. happens.
    That page load resets the form.

 5. `try_login()` clicks on "Login" button, which fails because no user
    or password is given.

Fix this by always waiting for a page load in `Browser.open()` after a
`Page.navigate()`. But we don't need the unnecessary complex and brittle
polling machinery of the old `expectLoad()` before commit 8284618. We
can use the `loadEventFired` CDP signal, which happens *after* the page
and all of its frames finished loading, and execution contexts are set
up. Introduce a new `waitPageLoad()` helper which re-uses the existing
`pageLoadHandler` promise.
@martinpitt martinpitt marked this pull request as ready for review November 8, 2023 10:05
@martinpitt martinpitt requested review from mvollmer and jelly November 8, 2023 10:05
@mvollmer mvollmer merged commit 49ee017 into cockpit-project:main Nov 8, 2023
32 checks passed
@martinpitt martinpitt deleted the wait-page-load branch November 8, 2023 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flake unstable test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants