Code Reference

Navigation

Playwright · Reference cheat sheet

Navigation

Playwright · Reference cheat sheet


📋 Overview

page.goto, history APIs, and wait helpers synchronize tests with loads, SPA route changes, and downloads. Pair navigation with URL assertions.

🔧 Core concepts

APIRole
page.goto(url)Full navigation
page.reload()Refresh
page.goBack / goForwardHistory
waitForURLSPA / redirect
waitForLoadStateload / domcontentloaded / networkidle
baseURLRelative paths in config

goto waits for load by default (waitUntil option). Prefer domcontentloaded for SPAs that keep connections open.

💡 Examples

Basic:

await page.goto('/');
await page.goto('/settings', { waitUntil: 'domcontentloaded' });
await expect(page).toHaveURL(/\/settings/);

Click that navigates:

await Promise.all([
  page.waitForURL('**/dashboard'),
  page.getByRole('link', { name: 'Dashboard' }).click(),
]);
// or simply:
await page.getByRole('link', { name: 'Dashboard' }).click();
await expect(page).toHaveURL(/dashboard/);

Load states:

await page.goto('/heavy');
await page.waitForLoadState('networkidle'); // avoid if websockets/polling

Popups / new tabs:

const [popup] = await Promise.all([
  page.waitForEvent('popup'),
  page.getByRole('link', { name: 'Open report' }).click(),
]);
await popup.waitForLoadState();
await expect(popup).toHaveTitle(/Report/);

Downloads:

const [download] = await Promise.all([
  page.waitForEvent('download'),
  page.getByRole('button', { name: 'Export' }).click(),
]);
await download.saveAs('out/report.csv');

⚠️ Pitfalls

  • networkidle flakes on apps with long-polling or analytics.
  • Missing await on goto — race with next assertion.
  • Absolute URLs ignoring baseURL in multi-env setups.
  • Not handling client-side redirects with waitForURL / toHaveURL.
  • Assuming same-tab navigation when target opens a popup.

On this page