Playwright is exceptional for end-to-end testing. It can do so much, from interacting with forms to mocking server requests and a heap of other things. In this article, we’ll go over 12 tips and tricks (some you might already be aware of).
1. Parallel Testing
Playwright makes it easy to run multiple tests in parallel. This is done by creating multiple context
objects, which are isolated and can run in parallel without interfering with each other. Here’s an example:
const context1 = await browser.newContext(); const context2 = await browser.newContext(); // Use Promise.all to run these operations in parallel await Promise.all([ context1.newPage().then(page => page.goto('https://example1.com')), context2.newPage().then(page => page.goto('https://example2.com')) ]);
2. Auto-Waiting
Playwright automatically waits for elements to be ready before performing actions on them. This removes the need for arbitrary sleeps or waits in your tests and makes your tests more reliable. Playwright can wait for elements to become visible, to become hidden, to contain certain text, and more:
// Click the button once it becomes visible await page.click('text="Submit"', { state: 'visible' }); // Wait for the button to hide before proceeding with the test await page.waitForSelector('text="Submit"', { state: 'hidden' }); // Wait for the button to contain certain text before clicking it await page.waitForSelector('text="Submit"', { state: 'attached' }); await page.click('text="Ready to Submit"');
3. Context Options for Configurations
With Playwright, you can create multiple browser contexts with different configurations. This is useful for simulating different testing scenarios. For example, you could simulate a scenario where a user is accessing your site from a mobile device in incognito mode:
const iPhone = playwright.devices['iPhone 12']; const context = await browser.newContext({ ...iPhone, isMobile: true, hasTouch: true, colorScheme: 'dark', acceptDownloads: true }); const page = await context.newPage();
4. Cross-Browser Testing
Playwright supports multiple browsers, including Chromium, Firefox, and WebKit. You can easily run your tests across all these browsers to ensure your website works correctly on each of them:
const browsers = ['chromium', 'firefox', 'webkit']; for (let browserType of browsers) { const browser = await playwright[browserType].launch(); const context = await browser.newContext(); const page = await context.newPage(); await page.goto('https://example.com'); // Insert your test here await browser.close(); }
5. Network Interception
Playwright’s network interception feature lets you control the network traffic in your tests. You can block certain requests, stub responses, or monitor network activity. Here’s an example where we stub a response:
await page.route('**/api/user', (route, request) => { route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ name: 'John Doe' }) }); }); // Now when the page makes a request to '/api/user', Playwright will return the stubbed response await page.goto('https://example.com');
6. Handling Authentication
Playwright can handle different types of authentication, including JWT tokens, cookies, or even basic HTTP authentication. Here’s an example of how to set a JWT token:
const context = await browser.newContext(); // Imagine we logged in and received a JWT token const jwtToken = 'your-jwt-token'; // Set the JWT token in localStorage or cookies await context.addInitScript((token) => { localStorage.setItem('jwt-token', token); }, jwtToken); // Now all pages created in this context will have the JWT token const page = await context.newPage();
7. Tracing for Advanced Debugging
Playwright’s tracing feature gives you a detailed trace of all actions taken during a test, including network requests, JavaScript execution, and more. The trace can be viewed in Playwright’s Trace Viewer for a visual debugging experience:
await context.tracing.start({ screenshots: true, snapshots: true }); // Execute actions await context.tracing.stop({ path: 'trace.zip' });
8. Accessibility Testing
Playwright offers built-in support for accessibility testing. You can retrieve the accessibility tree and ARIA attributes of any element on the page:
const snapshot = await page.accessibility.snapshot(); console.log(snapshot); // You can also target a specific element const buttonSnapshot = await page.accessibility.snapshot({ interestingOnly: false, root: await page.$('button') }); console.log(buttonSnapshot);
9. Keyboard and Mouse Actions
Playwright allows you to simulate complex user interactions, such as keyboard input, mouse movements, clicks, and scroll events:
// Type into an input field await page.fill('.search', 'Playwright'); // Press the Enter key await page.keyboard.press('Enter'); // Drag an element const element = await page.$('.draggable'); const box = await element.boundingBox(); await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); await page.mouse.down(); await page.mouse.move(100, 0); await page.mouse.up();
10. Evaluate Scripts in the Page Context
Playwright can execute scripts in the context of the page, which is useful for manipulating the DOM, extracting data, or testing the behaviour of your JavaScript code:
// Extract the text content of an element const textContent = await page.$eval('.my-element', el => el.textContent); console.log(textContent); // Run a script in the context of the page await page.evaluate(() => { // This will run in the browser context const element = document.querySelector('.my-element'); element.style.backgroundColor = 'red'; });
11. Geolocation and Timezone Testing
Playwright allows you to emulate different geolocations and timezones. This can be useful for testing location- and time-specific features:
// Set geolocation await context.setGeolocation({ latitude: 52.5200, longitude: 13.4050 }); // Set timezone await context.setTimezoneId('Europe/Berlin');
12. Emulating Different Network Conditions
Playwright lets you emulate different network conditions, which can be useful for testing your application’s behaviour under different network conditions:
// Offline mode await context.setOffline(true); await page.reload(); // Check if the correct offline message is displayed // Slow network await page.route('**', (route, request) => { // Add a delay before fulfilling the request setTimeout(() => route.continue(), 5000); }); await page.reload(); // Check if loading indicators are displayed correctly
I hope these expanded tips and tricks provide a more comprehensive guide to the capabilities of Playwright. With these techniques, you should be able to write more robust and comprehensive tests for your web applications.