Skip to content

feat(page): add wait_for_navigation and wait_for_navigation! for a navigation a block starts - #679

Merged
route merged 1 commit into
mainfrom
feat/wait-for-navigation
Oct 25, 2026
Merged

route merged 1 commit into
mainfrom
feat/wait-for-navigation

Conversation

@route

@route route commented Oct 25, 2026

Copy link
Copy Markdown
Member

Page#command(wait:) already waits for a navigation its command starts, which is how a click waits for the next page. But that only covers commands Ferrum sends itself. A navigation started from JavaScript, such as node.evaluate("this.click()") on a link, had no way to be waited for: wait_for_reload resets the navigation event after the block has run, so it can miss a navigation that has already started.

page.wait_for_navigation { page.at_css("a").evaluate("this.click()") } # => true
page.wait_for_navigation! { page.at_css("a").evaluate("this.click()") } # raises Ferrum::TimeoutError if the page doesn't load
  • wait_for_navigation(wait = 0.1) { } resets the event, runs the block, watches wait seconds for a navigation, and waits for it to finish within the page timeout. It returns false if it doesn't, true otherwise, including when nothing navigates. wait defaults to FERRUM_CLICK_WAIT, like click.
  • wait_for_navigation! { } raises Ferrum::TimeoutError instead, the same split as network.wait_for_idle and wait_for_idle!.
  • Page#command(wait:) now uses wait_for_navigation!, so it behaves as before.
  • Both are delegated from Browser, with YARD, RBS and a section in docs/3-navigation.md.

The specs check that the block's navigation finished by recording a load event that follows the navigation, and they fail against a version that only runs the block.

This also gives the deprecated evaluate_on(wait:) a replacement for #673, which removes it in 0.21.

…vigation a block starts

Page#command(wait:) already waited for a navigation its command started, but only for commands Ferrum sends itself,
like a click. A navigation started from JavaScript, e.g. `node.evaluate("this.click()")`, had no way to be waited for:
wait_for_reload resets the navigation event after the fact, so it can miss one that already started.

wait_for_navigation(wait) { } resets the event, runs the block, watches `wait` seconds for a navigation and waits for
it to finish within the page timeout, returning false if it doesn't. wait_for_navigation! raises TimeoutError instead.
Page#command(wait:) now uses it.
@route
route force-pushed the feat/wait-for-navigation branch from 3bb4c2c to da08189 Compare October 25, 2026 18:14
@route
route merged commit 2b89afb into main Oct 25, 2026
6 checks passed
@route
route deleted the feat/wait-for-navigation branch October 25, 2026 18:53
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