Navigations
Introduction
CSTesting can navigate to URLs and work with navigations caused by page interactions. You open a page with browser.goto(url), which loads the URL and waits for the browser's load event. You can wait for the URL to change after a click (e.g. redirect to login) with browser.waitForURL(), and read the current URL with browser.url().
You will learn
- Basic navigation with goto
- When the page is "loaded" and interacting safely
- Hydration and slow networks
- Waiting for URL changes with waitForURL
- Getting the current URL
- What is not supported (navigation events, timeouts, etc.)
Basic navigation
Open a URL with browser.goto(url). CSTesting navigates the page and waits for the load event (the browser's load event, fired when the document and its dependent resources have loaded).
await browser.goto('https://example.com');
If the server or page triggers a client-side redirect before load, goto waits for the load event on the final document.
When is the page loaded?
Many pages keep working after the load event: they fetch data, run scripts, and render UI later. There is no single rule for "page is ready"; it depends on the app.
In CSTesting you can interact as soon as you have a way to target elements. Use waitForSelector when an element appears only after some delay (e.g. after an API call):
await browser.goto('https://example.com');
await browser.waitForSelector('#main');
await browser.locator('#main').click();
So: goto waits for the load event; for app-specific readiness, combine goto with waitForSelector (or other waits) as needed.
Hydration
If you see actions that seem to do nothing (e.g. a click that doesn't run handlers, or typed text that disappears), the cause is often hydration: the server sends static HTML, then JavaScript runs and "hydrates" the page. If you act before hydration attaches listeners, the UI may not respond or may overwrite your input.
A simple check is to use Chrome DevTools → Network → "Slow 3G", reload, and try interacting as soon as the element appears. If clicks are ignored or text is reset, the fix is on the app side: keep interactive controls disabled until hydration is done.
Waiting for navigation
A click (e.g. "Sign in") may navigate to another URL. Use browser.waitForURL() to wait until the URL matches before continuing.
await browser.locator('//button[text()="Click me"]').click(); // or use a selector that matches the link/button
await browser.waitForURL('**/login');
waitForURL(urlOrPattern, options?)
- urlOrPattern: string, glob string, or RegExp.
- String without
**: current URL must include this substring. - String with
**: treated as glob (e.g.**/login→ pattern.*/login). - RegExp: current URL must match the regex.
- String without
- options.timeout (optional): milliseconds to wait; default 30000.
await browser.waitForURL('/dashboard'); // substring
await browser.waitForURL('**/login'); // glob
await browser.waitForURL(/\/users\/\d+/); // regex
await browser.waitForURL('/welcome', { timeout: 10000 });
If the URL does not match within the timeout, waitForURL throws.
Getting the current URL
Use browser.url() to get the current page URL (same as window.location.href). It returns a Promise.
await browser.goto('https://example.com');
const current = await browser.url();
expect(current).toContain('example.com');
When using tabs (multiple pages), each tab has getUrl():
const tab = browser.tabs()[0];
const tabUrl = await tab.getUrl();
Summary
- browser.goto(url) — Navigate to a URL and wait for the load event (and any client-side redirect before it).
- browser.waitForURL(urlOrPattern, { timeout? }) — Wait until the current URL matches a substring, glob (
**), or RegExp; default timeout 30s. - browser.url() — Current page URL (Promise).
- Use waitForSelector (or similar) when you need to wait for app-specific content; there is no built-in "network idle" or "domcontentloaded" API.
- For hydration issues, ensure the app disables controls until hydration is complete.
What is not supported (current version)
| Feature | Supported? | Notes |
|---|---|---|
| goto(url) | Yes | Waits for load event. |
| waitForURL(pattern, options?) | Yes | String (substring), glob (**), or RegExp; optional timeout. |
| url() | Yes | Returns current URL (Promise). |
| waitForLoad() | Yes | Waits for load event on current document (no URL change). |
| waitForSelector(selector) | Yes | Use to wait for elements after navigation or lazy content. |
| goto with timeout | No | No per-call timeout; goto waits until load (or failure). |
| goto waitUntil: 'domcontentloaded' / 'commit' | No | Only load event is waited on. |
| Navigation events (e.g. domcontentloaded, load) | No | Not exposed as API; goto uses load internally. |
| page.on('load') | No | No event listener API. |
| Response object from goto | No | goto does not return status or headers. |
| Abort navigation / race | No | No way to cancel or race goto. |