When you're working with Playwright, you'll often come across timeouts that can interrupt your testing or web scraping. In this post, we’ll explore the causes of these timeouts and provide a few tips and solutions to help you overcome them.
What is a timeout in Playwright?
A timeout occurs when an action or a test takes longer than the specified time limit to complete. By default, Playwright sets a test timeout of 30 seconds and an assertion timeout of 5 seconds. If an action exceeds these limits, Playwright throws a timeout error.
Common causes of timeouts
Several factors can cause timeouts in Playwright:
- Slow test execution: Tests that perform many actions or interact with complex web elements may take longer to complete.
- Incorrect locators: Using incorrect or inefficient locators can slow down the test as Playwright struggles to find the element.
- Slow backend responses: If your application relies on backend services, slow responses from these services can delay test execution.
How to change timeout settings
Global timeout
To change the global timeout for all tests, just update your playwright.config.js
file:
module.exports = {
globalTimeout: 60000 // Sets global timeout to 60 seconds
};
Specific test timeout
For individual tests, use the test.setTimeout
method:
test('example test', async ({ page }) => {
test.setTimeout(45000); // Sets timeout to 45 seconds for this test
// Test code here
});
Assertion timeout
To adjust the timeout for assertions, use the expect
function’s timeout
option:
await expect(page.locator('button')).toHaveText('Submit', { timeout: 10000 }); // 10 seconds
Methods to deal with Playwright timeouts
Optimize locators
Efficient locators reduce the time Playwright spends searching for elements. Prefer using data-test-id attributes or unique CSS selectors:
await page.locator('[data-test-id="submit-button"]').click();
Set specific timeouts
Adjust timeouts for different actions to better suit their expected completion times. This helps you avoid unnecessary delays and timeout errors:
await page.click('button', { timeout: 15000 }); // 15 seconds for button click
Mock slow endpoints
Mocking slow backend responses can significantly speed up your tests by eliminating dependencies on external services:
page.route('**/api/**', route => route.fulfill({ body: 'mocked response' }));
Use retries for flaky tests
For tests that occasionally fail due to timeouts, use retries to give them another chance to pass:
test.describe('Retry mechanism', () => {
test.describe.configure({ retries: 2 }); // Retry the tests in this describe block up to 2 times
test('flaky test', async ({ page }) => {
await page.goto('https://example.com');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});
});
Split long tests
Divide long tests into smaller, more manageable tests. This helps isolate issues and reduces the chance of hitting timeouts:
// Split the long test into smaller tests
test.describe('Website Navigation Tests', () => {
// Part 1: Navigate to the homepage
test('Navigate to homepage', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example Domain/);
});
// Part 2: Navigate to the about page
test('Navigate to about page', async ({ page }) => {
await page.goto('https://example.com/about');
await expect(page.locator('h1')).toHaveText('About Us');
});
// Part 3: Navigate to the contact page and submit the form
test('Navigate to contact page and submit form', async ({ page }) => {
await page.goto('https://example.com/contact');
await page.fill('#name', 'John Doe');
await page.fill('#email', 'john.doe@example.com');
await page.click('button[type="submit"]');
await expect(page.locator('.success')).toHaveText('Thank you for contacting us!');
});
});
Effectively managing Playwright timeouts
Dealing with Playwright timeouts involves understanding their causes and implementing the right solutions. Optimizing locators, setting appropriate timeouts for different actions, mocking slow endpoints, using retries for flaky tests, and splitting long tests will help you with your tests and make sure that Playwright plays nicely.
If you're using Playwright, you might like to find out about web scraping with Playwright.