Get started

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.
  • 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)

FeatureSupported?Notes
goto(url)YesWaits for load event.
waitForURL(pattern, options?)YesString (substring), glob (**), or RegExp; optional timeout.
url()YesReturns current URL (Promise).
waitForLoad()YesWaits for load event on current document (no URL change).
waitForSelector(selector)YesUse to wait for elements after navigation or lazy content.
goto with timeoutNoNo per-call timeout; goto waits until load (or failure).
goto waitUntil: 'domcontentloaded' / 'commit'NoOnly load event is waited on.
Navigation events (e.g. domcontentloaded, load)NoNot exposed as API; goto uses load internally.
page.on('load')NoNo event listener API.
Response object from gotoNogoto does not return status or headers.
Abort navigation / raceNoNo way to cancel or race goto.