Principle:MarketSquare Robotframework browser Navigation Aware Waiting
Synchronizing test execution with page navigation events in Robot Framework Browser.
Overview
Modern web applications, especially single-page applications (SPAs), frequently change the URL and page content without performing a full page reload. Traditional page-load-based synchronization strategies fail in these scenarios because the browser never fires a standard load event. The Robot Framework Browser library provides the Wait For Navigation keyword to handle navigation-aware waiting, where the test pauses until the page has navigated to a specific URL and reached a specified load state.
Core Concept
Navigation-aware waiting addresses the fundamental challenge of test timing: an action (such as a click on a link or form submission) triggers navigation, but the navigation may take an unpredictable amount of time. The test must wait until the navigation completes before proceeding to assertions or further actions.
The Wait For Navigation keyword works by:
- Registering a listener for Playwright's
page.waitForNavigation()event. - The listener waits until the page URL matches a specified pattern.
- Optionally waiting until the page reaches a specified load state (e.g., all network requests complete).
Page Load States
The wait_until parameter controls when the navigation is considered complete. The available states are:
| State | Description | Best For |
|---|---|---|
load |
The navigation is considered finished when the load event fires. This is the default and corresponds to the traditional full page load, including all resources (images, stylesheets, scripts). |
Traditional multi-page applications with full page reloads. |
domcontentloaded |
The navigation is considered finished when the DOMContentLoaded event fires. This occurs after the HTML is fully parsed but before stylesheets, images, and subframes finish loading. |
Tests that only need the DOM structure, not visual resources. |
networkidle |
The navigation is considered finished when there are no more than 0 network connections for at least 500 milliseconds. | Pages that load data asynchronously after the initial render (API-driven SPAs). |
commit |
The navigation is considered finished when a network response is received and the document has started loading. This is the earliest possible state. | Fast checks where only the initial server response matters. |
The choice of load state creates a trade-off between speed and completeness. Using commit is fastest but may proceed before the page is usable. Using networkidle is slowest but ensures all asynchronous data loading has completed.
URL Matching
The url parameter specifies the expected navigation target. It supports two forms:
- Exact string match: The URL must match the provided string exactly.
- JavaScript-like regex: The URL is matched against a regular expression wrapped in
/symbols (e.g.,/.*\/dashboard.*/).
On the Node side, the URL string is parsed by parseRegExpOrKeepString(), which converts regex-formatted strings into JavaScript RegExp objects and leaves plain strings as-is for exact matching.
Single-Page Application Considerations
In SPAs, URL changes often happen via the History API (pushState or replaceState) without triggering a traditional page load. The Wait For Navigation keyword handles these cases because Playwright's underlying page.waitForNavigation() listens for both traditional navigation and History API-based URL changes.
However, there is an important limitation: the keyword does not detect URL fragment changes (hash changes). For example, if the URL changes from https://example.com/page to https://example.com/page#section, the keyword will not detect this as a navigation event. Fragment-only changes are handled entirely by the browser's client-side code and do not trigger Playwright's navigation listeners.
Timing and the Promise Pattern
Like other wait keywords in the Browser library, Wait For Navigation can be used with the Promise To pattern to avoid race conditions:
*** Test Cases ***
Navigate After Click
${promise}= Promise To Wait For Navigation https://example.com/dashboard wait_until=networkidle
Click \#navigate-button
Wait For ${promise}
This ensures the navigation listener is active before the click that triggers the navigation, preventing missed events.
Deprecated Alternative
The Wait Until Network Is Idle keyword (at Browser/keywords/network.py:L254-276) is deprecated in favor of using Wait For Load State with the networkidle state. Tests using Wait Until Network Is Idle should be migrated:
# Old (deprecated):
Wait Until Network Is Idle timeout=3s
# New (recommended):
Wait For Load State networkidle timeout=3s