PRICING
PRODUCT
SOLUTIONS
by use cases
AI Lead ManagementInvoicingSocial MediaProject ManagementData Managementby Industry
learn more
BlogTemplatesVideosYoutubeRESOURCES
COMMUNITIES AND SOCIAL MEDIA
PARTNERS
Playwright is a test automation framework that simplifies browser testing with a single API for Chromium, Firefox, and WebKit. It’s fast, reliable, and widely adopted, with over 1.2 million weekly downloads.
npm init playwright@latest
Feature | Traditional Testing | Headless Testing |
---|---|---|
Speed | Slower | Up to 15x faster |
Resource Usage | High | Lower |
Browser Support | Limited | Chromium, Firefox, WebKit |
With Playwright, you can efficiently test dynamic content, handle multiple browsers, and even simulate devices and network conditions. Ready to start? Let’s dive into how you can set it up and create your first test.
Follow these steps to set up Playwright in headless mode and get started with testing.
Before diving in, make sure your system meets these requirements:
To quickly set up Playwright, run:
npm init playwright@latest
This command initializes Playwright and generates:
Prefer manual installation? Use the following commands:
npm i -D @playwright/test
npx playwright install
Playwright runs tests in headless mode by default, showing results directly in the terminal. To keep everything up to date, use:
npm install -D @playwright/test@latest
npx playwright install --with-deps
Testing across multiple browsers is simple with Playwright. Update your playwright.config.ts
file like this:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
});
Here’s how to run tests:
npx playwright test
npx playwright test --project webkit
npx playwright test --project webkit --project firefox
Browser compatibility for Playwright:
Browser | Windows | macOS | Linux |
---|---|---|---|
Chromium | ✓ | ✓ | ✓ |
Firefox | ✓ | ✓ | ✓ |
WebKit | ✓ | ✓ | ✓ |
When you install Playwright, it automatically downloads the necessary browser versions and stores them locally. This ensures consistent testing environments across different platforms and machines.
Now that Playwright is set up, you’re ready to create your first test.
Once you've set up Playwright, here's how to create and run your first test.
Start by creating a file called first-test.spec.ts
and add the following code. Then, run the test using the command npx playwright test first-test.spec.ts
:
import { test, expect } from '@playwright/test';
test('basic navigation test', async ({ page }) => {
await page.goto('https://playwright.dev');
const title = await page.title();
await expect(title).toBe('Playwright');
});
Here’s how you can interact with elements in Playwright:
test('element interactions', async ({ page }) => {
// Fill out a text field
await page.getByRole('textbox').fill('[email protected]');
// Click a button
await page.getByRole('button', { name: 'Submit' }).click();
// Check a checkbox
await page.getByLabel('Remember me').check();
// Select an option from a dropdown
await page.getByLabel('Country').selectOption('United States');
});
Here are some common locator methods you can use:
Locator Type | Example | Use Case |
---|---|---|
Role | getByRole('button') | For accessible elements |
Label | getByLabel('Password') | For form fields |
Text | getByText('Sign up') | For visible text |
TestId | getByTestId('submit-button') | For custom attributes |
To ensure your tests are reliable, use assertions to check outcomes:
test('verification examples', async ({ page }) => {
// Check if an element is visible
await expect(page.getByRole('heading')).toBeVisible();
// Verify the text content of an element
await expect(page.getByTestId('status')).toHaveText('Success');
// Confirm the URL after navigation
await expect(page).toHaveURL(/.*dashboard/);
// Ensure a button is enabled
await expect(page.getByRole('button')).toBeEnabled();
});
For debugging, you can run Playwright in UI mode with this command:
npx playwright test --ui
Playwright runs each test in a separate browser context, ensuring a clean slate every time. This isolation avoids interference between tests and, with headless mode, keeps execution fast and efficient.
Playwright builds on basic testing capabilities by offering tools that improve reliability and expand test scenarios.
Playwright simplifies testing dynamic web content with its built-in waiting mechanisms and web-first assertions. It ensures elements are ready for interaction, removing the need for manual timeouts, which often lead to unreliable tests .
Here’s how you can test dynamic content effectively:
// Wait for API response before proceeding
await page.waitForResponse(response =>
response.url().includes('/api/data') &&
response.status() === 200
);
// Wait for dynamic content updates
await page.waitForFunction(() => {
const element = document.querySelector('.dynamic-content');
return element && element.textContent.includes('Updated');
});
For situations with intermittent network issues, you can add retry mechanisms:
// Retry mechanism for flaky elements
const retryOptions = {
timeout: 30000,
intervals: [1000, 2000, 5000]
};
await page.waitForSelector('.loading-content', retryOptions);
Next, let’s look at how Playwright supports device emulation and network condition simulation.
Playwright includes a built-in device registry for emulating various devices. This feature helps test different screen sizes and user-agent configurations .
Here’s an example of device emulation:
const iPhone = playwright.devices['iPhone 13'];
const context = await browser.newContext({
...iPhone,
locale: 'en-US',
geolocation: { longitude: -122.084, latitude: 37.422 },
permissions: ['geolocation']
});
To test network conditions, you can use route handlers:
// Simulate slow network conditions
await page.route('**/*.{jpg,png,jpeg}', route => {
return new Promise(resolve => {
setTimeout(() => {
route.continue();
}, 5000); // 5-second delay
});
});
// Mock API responses
await page.route('/api/data', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ status: 'success' })
});
});
Playwright supports recording artifacts like screenshots, videos, and traces to help with debugging. These options can be configured in your playwright.config.js
file:
Recording Type | Configuration | Best Use Case |
---|---|---|
Screenshots | screenshot: 'only-on-failure' |
Capture the visual state during test failures |
Video | video: 'retain-on-failure' |
Record test execution for failed scenarios |
Trace | trace: 'on-first-retry' |
Generate detailed logs for debugging |
Here’s how to enable these features:
// playwright.config.js
module.exports = {
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'on-first-retry'
}
};
"Playwright waits for elements to be actionable prior to performing actions...eliminates the need for artificial timeouts - the primary cause of flaky tests." - Playwright Documentation
All recorded artifacts are stored in the test-results
directory, offering valuable insights for troubleshooting. Videos are saved automatically when the browser context closes .
Improving test performance in Playwright involves smart use of parallel execution, effective browser context management, and well-thought-out retry strategies. These methods help ensure tests run efficiently without compromising reliability.
Playwright allows you to run tests across multiple worker processes, which can significantly reduce the time it takes to complete a test suite. You can configure parallel execution in playwright.config.ts
:
export default {
fullyParallel: true,
workers: 4,
maxFailures: 5
};
Within a test file, you can enable parallel execution like this:
test.describe.configure({ mode: 'parallel' });
test.describe('User Authentication', () => {
test('login flow', async ({ page }) => {
// Test implementation
});
test('registration flow', async ({ page }) => {
// Test implementation
});
});
To avoid data conflicts between workers, use unique identifiers:
const testId = `user_${process.env.TEST_WORKER_INDEX}_${Date.now()}`;
const userEmail = `test_${testId}@example.com`;
Once parallelization is set up, managing browser contexts efficiently is the next step.
Using separate browser contexts ensures isolated test environments, similar to using incognito profiles. This keeps tests independent and prevents state conflicts.
Here’s an example of creating and using a browser context:
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
userAgent: 'Playwright/1.32.0',
storageState: './auth.json'
});
await test.step('Verify dashboard', async () => {
const page = await context.newPage();
await page.goto('https://app.example.com/dashboard');
// Test implementation
});
await context.close();
Some common browser context strategies include:
After ensuring clean and isolated environments, the next focus is handling transient failures with retry strategies.
Retries can help deal with flaky tests caused by timing issues or environmental instability. You can configure retries in the Playwright configuration file:
export default {
retries: process.env.CI ? 2 : 0,
expect: {
timeout: 10000,
toPass: { intervals: [1000, 2000, 5000] }
}
};
For assertions that might need multiple attempts, use polling:
await expect
.poll(async () => {
const element = page.locator('.dynamic-content');
return await element.textContent();
}, {
intervals: [1000, 2000, 10000],
timeout: 60000
})
.toBe('Expected Value');
"While retries enhance test reliability, excessive use can hide issues like timeouts and race conditions. It's critical to resolve root causes for stable tests, applying retries wisely with restrictions and logging data for unstable patterns." – Cerosh Jacob
To make sure the page is fully loaded before running your tests:
await page.waitForLoadState('networkidle', { timeout: 5000 });
await page.waitForSelector('.content-ready');
Integrating Playwright with Latenode's low-code platform simplifies web testing and workflow automation. This pairing allows teams to create advanced tests without needing deep coding skills.
Latenode complements Playwright's functionality by extending automation to broader workflow requirements.
Latenode is a low-code platform designed for integration and workflow automation, leveraging headless browser technology. Its visual workflow builder makes it easier to create and manage automated testing setups without writing complex code.
Here’s an example of how Latenode's browser automation can be configured:
// Example of a Latenode workflow configuration
const workflowConfig = {
browserAutomation: {
viewport: { width: 1920, height: 1080 },
headless: true,
scenarios: ['login', 'data-extraction', 'form-submission']
}
};
Combining Playwright with Latenode brings several technical perks:
Feature | Benefit |
---|---|
Visual Workflow Builder | Simplifies setup compared to traditional coding methods |
AI-Assisted Code Generation | Automatically generates Playwright test scripts |
Built-in Database Integration | Efficiently manages test data and results |
Multi-Browser Support | Runs tests across Chromium, Firefox, and WebKit |
This integration enhances test workflows and improves automation processes.
This combination supports a variety of practical automation scenarios. For instance:
// Example of a multi-browser test workflow
async function crossPlatformTest() {
const workflow = await latenode.createWorkflow({
name: 'E2E Testing Suite',
browser: playwright.chromium,
integrations: ['slack', 'jira']
});
await workflow.addStep({
type: 'ui-test',
script: async ({ page }) => {
await page.goto('https://app.example.com');
await page.fill('#username', process.env.TEST_USER);
await page.click('#submit');
}
});
}
For large-scale testing, Latenode's Prime plan ($297/month) supports up to 1.5 million scenario runs. This plan is ideal for teams needing advanced collaboration tools and detailed reporting.
Additionally, Latenode's built-in database features help teams manage test data and results without extra infrastructure. Automated reporting and analysis make it easier to identify trends and refine testing strategies effectively.
Playwright offers a range of advanced features and performance improvements that make it a standout choice for automated testing. Here's a quick recap of its main advantages.
Playwright's headless browser testing significantly boosts performance by skipping unnecessary rendering tasks. Tests show that headless mode can run 2x to 15x faster than traditional browser testing .
Some of the key performance benefits include:
Testing Aspect | Performance Comparison |
---|---|
Web Scraping Speed | 56.21 seconds (headless) vs. 73.77 seconds (headed) |
Resource Usage | Lower CPU and memory usage |
Browser Support | Chrome (64.16%), Safari (19.62%), Edge (4.87%) |
These benefits, combined with the setup and testing strategies discussed earlier, make Playwright a powerful tool for scalable and efficient automation.
The performance and scalability of Playwright make it an excellent choice for modern testing workflows. As Microsoft's Senior Product Manager, Arjun Attam, explains:
"Automated end-to-end tests have become more important than ever before. Teams are shipping faster and building apps that run on a growing set of devices. This increase in velocity and web targets puts immense pressure on the testing process, and automation is critical."
To start using Playwright for headless testing:
npm init playwright@latest
.example.spec.js
).npx playwright test
.For seamless integration, connect Playwright to your CI/CD pipeline using tools like Jenkins or GitHub Actions . Its unified API allows consistent testing across Chrome, Firefox, and WebKit without needing browser-specific code changes .
Playwright's headless mode shines in performance-intensive environments and CI/CD pipelines, where fast feedback is crucial . Its ability to handle multiple browser instances efficiently makes it a top choice for large-scale testing operations.