Yes, you can navigate through the browser history using Playwright. The framework provides two main methods for history navigation: page.goBack()
and page.goForward()
, which work exactly like the browser's back and forward buttons.
Basic History Navigation
JavaScript/TypeScript
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
// Navigate to first page
await page.goto('https://example.com');
// Navigate to second page
await page.goto('https://playwright.dev');
// Go back to previous page (example.com)
await page.goBack();
// Go forward to next page (playwright.dev)
await page.goForward();
await browser.close();
})();
Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
# Navigate to first page
page.goto('https://example.com')
# Navigate to second page
page.goto('https://playwright.dev')
# Go back to previous page
page.go_back()
# Go forward to next page
page.go_forward()
browser.close()
Handling Navigation Responses
Both methods return the response from the navigation or null
if navigation is unsuccessful:
// Check if navigation was successful
const backResponse = await page.goBack();
if (backResponse) {
console.log(`Navigated back to: ${backResponse.url()}`);
console.log(`Response status: ${backResponse.status()}`);
} else {
console.log('Cannot navigate back (no previous page or cross-origin)');
}
Safe Navigation with Validation
async function safeNavigateBack(page) {
// Check if we can navigate back
const historyLength = await page.evaluate(() => window.history.length);
if (historyLength > 1) {
const response = await page.goBack();
return response !== null;
}
return false;
}
// Usage
const canGoBack = await safeNavigateBack(page);
if (canGoBack) {
console.log('Successfully navigated back');
} else {
console.log('Cannot navigate back');
}
Waiting for Navigation
Sometimes you need to wait for the navigation to complete:
// Wait for navigation and network to be idle
await Promise.all([
page.waitForLoadState('networkidle'),
page.goBack()
]);
// Or wait for a specific element after navigation
await page.goBack();
await page.waitForSelector('#main-content');
Complete Example: Multi-Page Navigation
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
const urls = [
'https://example.com',
'https://httpbin.org/html',
'https://playwright.dev'
];
// Visit multiple pages
for (const url of urls) {
await page.goto(url);
await page.waitForTimeout(1000); // Brief pause for demonstration
}
// Navigate backwards through history
console.log('Going back through history...');
while (true) {
const response = await page.goBack();
if (!response) break;
console.log(`Current URL: ${page.url()}`);
await page.waitForTimeout(1000);
}
// Navigate forwards through history
console.log('Going forward through history...');
while (true) {
const response = await page.goForward();
if (!response) break;
console.log(`Current URL: ${page.url()}`);
await page.waitForTimeout(1000);
}
await browser.close();
})();
Important Notes
- Cross-origin navigation: Methods return
null
when navigating to a different origin due to security restrictions - No history: If there's no previous/next page, the methods won't perform any action
- Network conditions: Navigation may fail due to network issues or page errors
- Wait states: Consider using
waitForLoadState()
after navigation for reliable automation
Alternative: Direct URL Navigation
For more control, you can also navigate directly to specific URLs from the browser history:
// Get current history state
const historyLength = await page.evaluate(() => window.history.length);
// Navigate to specific history position (if supported by the page)
await page.evaluate((steps) => window.history.go(steps), -2); // Go back 2 steps