Playwright is a cross-browser end-to-end testing framework for Chromium, Firefox, and WebKit. Create a project with npm init playwright@latest, run it with npx playwright test, and use locator-based actions with web-first assertions. The syntax table below is verified against Playwright 1.62.
🤖 Summarize this article with AI:
💬 ChatGPT 🔍 Perplexity 💥 Claude 🐦 Grok 🔮 Google AI Mode
Playwright is an open-source automation library for web testing and automation. It allows developers to write scripts that can control a web browser and perform actions just like a human would, such as clicking on elements, typing text, navigating through pages, and capturing screenshots.
Playwright supports multiple browsers, including Chrome, Firefox, and WebKit, which allows for cross-browser testing. It provides a powerful API to automate web interactions and is capable of running tests in headless mode (without a browser UI) for faster execution.

.
🎯 TL;DR
- Playwright Cheat Sheet is a comprehensive guide covering everything from installation to advanced interactions.
- It includes detailed sections on selectors, basic and advanced commands, assertions, debugging, and CI/CD integration.
- It provides practical examples and best practices to help you efficiently automate your web testing workflows.
Check also
Why Use Playwright?
It enables interaction with elements of a web page, handling tasks from inputting text to asserting the visibility of a key element. Its robust API supports automation scenarios such as navigating browsers, managing cookies, and capturing dialog boxes.
Playwright tests can emulate complex user interactions with a web's structure, including selecting items from a list, clicking on labels, or handling CSS selectors.
Automate your tests for free
Test easier than ever with BugBug test recorder. Faster than coding. Free forever.
Sign up for free
Compared to tools like Cypress, Playwright offers cross-browser testing capabilities and the flexibility to write tests in multiple programming languages. Developers can write Playwright code to automate and interact with web elements, ensuring their applications work as intended in different environments. Tool also offers local parallel mode when tests are run (feature not available in Cypress).
Playwright integrates with Chrome DevTools Protocol to automate and control browser operations, providing a powerful interface for web automation and testing. This allows developers to programmatically interact with web pages, manipulate DOM elements, and monitor network requests, leveraging Chrome's extensive debugging capabilities.
💡 Check out also our other Cheat Sheets
Browsers
In Playwright, a Browser represents an instance of a web browser. It's not just limited to a single tab or window; rather, it's the actual program itself, like an instance of Chrome or Firefox. When you start a browser through Playwright, you're effectively opening the application which can then contain multiple web pages and contexts.
Contexts
A BrowserContext is an independent incarnation of a browser environment within Playwright. It can be thought of as an incognito session where no state is shared with other browser contexts.
This isolation is particularly useful for simulating multiple sessions or users in testing scenarios. Each context can have its own cookies, local storage, and session information, and you can have multiple contexts within the same browser instance.
Pages
A Page in Playwright is akin to a single tab or window in a web browser. It provides methods to interact with and control a single web page. Actions such as navigating to URLs, interacting with page content, and evaluating JavaScript within the context of the web page are done at this level. Pages live within a browser context, and you can have multiple pages within a single context.
Understanding Selectors and Elements
Selectors are the means by which Playwright identifies elements on a web page to interact with. They can be CSS selectors, XPath selectors, text selectors, or even custom selectors defined by the user. Once a selector is defined, Playwright can perform actions on the element it points to, such as clicking, typing, or reading text.
Elements, or more specifically ElementHandles, are objects that reference an element on a page. Once you have an ElementHandle, you can perform actions on that element, and it will ensure that the element is available and not stale.
💡 TIP
This is useful for interacting with elements that may not be immediately available due to dynamic content loading and other asynchronous behavior common in modern web applications.
The Playwright API Structure
The Playwright API is designed to be intuitive and straightforward. It mirrors the structure of a web browsing experience at a high level while providing detailed control at the lower levels. The API is organized around the following hierarchy:
- Browser: Methods to control browser-level actions, such as launching or closing a browser.
- BrowserContext: Methods to manage contexts, like creating new contexts or closing them, along with setting context-wide options (e.g., viewport size, geolocation, permissions).
- Page: Methods to interact with and control a web page, like navigating to a URL, selecting elements, and executing page-level scripts.
- ElementHandle: Methods to perform actions on individual elements, such as clicking, typing into inputs, or retrieving properties and text content.
Automate your tests for free
Test easier than ever with BugBug test recorder. Faster than coding. Free forever.
Sign up for free
Playwright Test Automation Cheat Sheet
Playwright syntax quick reference
| Task | Syntax |
|---|---|
| Create or add Playwright to a project | npm init playwright@latest |
| Update Playwright Test | npm install -D @playwright/test@latest |
| Install browsers and system dependencies | npx playwright install --with-deps |
| Check the installed version | npx playwright --version |
| Run all tests | npx playwright test |
| Run one test file | npx playwright test tests/example.spec.ts |
| Run a test at a specific line | npx playwright test tests/example.spec.ts:42 |
| Run tests matching a title | npx playwright test -g "checkout" |
| Run one browser project | npx playwright test --project=chromium |
| Run in headed mode | npx playwright test --headed |
| Open UI Mode | npx playwright test --ui |
| Open Playwright Inspector | npx playwright test --debug |
| Run with one worker | npx playwright test --workers=1 |
| Re-run failed tests | npx playwright test --last-failed |
| Generate a test | npx playwright codegen https://example.com |
| Open the HTML report | npx playwright show-report |
| Open a trace | npx playwright show-trace trace.zip |
| Locate a button | page.getByRole('button', { name: 'Submit' }) |
| Fill an input | await page.getByLabel('Email').fill('qa@example.com') |
| Click an element | await page.getByRole('button', { name: 'Submit' }).click() |
| Check a checkbox | await page.getByLabel('Accept terms').check() |
| Select an option | await page.getByLabel('Country').selectOption('PL') |
| Assert visibility | await expect(page.getByText('Success')).toBeVisible() |
| Assert the page URL | await expect(page).toHaveURL(/dashboard/) |
| Capture a screenshot | await page.screenshot({ path: 'page.png', fullPage: true }) |
Installation Guide
Playwright 1.62 supports the latest Node.js 22.x, 24.x, and 26.x releases.
For a new project, run:
npm init playwright@latest
The installer lets you choose TypeScript or JavaScript, select the test directory, add a GitHub Actions workflow, and install the required browser binaries.
For an existing project, install or update Playwright Test and its browsers:
npm install -D @playwright/test@latest
npx playwright install --with-deps
Verify the installed version:
npx playwright --version
To install only one browser, add its name:
npx playwright install chromium
npx playwright install firefox
npx playwright install webkit
Creating your first test
Create a file named tests/example.spec.ts:
import { test, expect } from '@playwright/test';
test('opens the example page', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example Domain/);
await expect(page.getByRole('heading')).toBeVisible();
await page.screenshot({ path: 'example.png' });
});
Run the test:
npx playwright test tests/example.spec.ts
Playwright Test provides an isolated browser context for every test and closes it automatically after execution.
Basic Commands
Launching browsers:
const browser = await chromium.launch({ headless: false }); // for visible browser
Navigating pages
const page = await browser.newPage();
await page.goto('https://example.com');
Interacting with elements
Playwright can interact with HTML Input elements such as text inputs, checkboxes, radio buttons, select options, mouse clicks, type characters, keys and shortcuts as well as upload files and focus elements
Text Inputs: Using the locator.fill() method is a highly efficient technique for populating form fields. This approach automatically focuses on the targeted element and initiates an input event that inputs the specified text. It is compatible with <input>, <textarea>, and [contenteditable] elements, making it a versatile tool for form automation.
await page.getByRole('textbox').fill('Example Text');
Checkboxes and Radio Buttons: Using locator.setChecked() is the easiest way to check and uncheck a checkbox or a radio button
await page.getByLabel('Agree to Terms').check();
await expect(page.getByLabel('Agree to Terms')).toBeChecked();
Select Options: The locator.selectOption() method is used to choose one or several options within a <select> element. It allows selection based on the option's value or label. This function supports the selection of multiple options simultaneously.
await page.getByLabel('Select Color').selectOption('blue');
Mouse Interactions: Perform clicks, double-clicks, right-clicks, and hovers using page.click() and page.hover().
-
Generic click
await page.getByRole('button').click(); -
Double click
await page.getByText('Item').dblclick(); -
Right click
await page.getByText('Item').click({ button: 'right' }); -
Shift + click
await page.getByText('Item').click({ modifiers: ['Shift'] }); -
Hover over element
await page.getByText('Item').hover(); -
Click the top left corner
await page.getByText('Item').click({ position: { x: 0, y: 0 } }); -
Type Characters: Using
await page.locator('#area').pressSequentially('Hello World!');, you can simulate the pressing of keys one after another. This function generates all required keyboard events, including 'keydown', 'keyup', and 'keypress' events.Additionally, you have the option to set a delay between each key press, effectively mimicking real user typing behavior.
-
Press keys one by one
await page.locator('#area').pressSequentially('Hello World!'); -
Shortcuts: For special keyboard handling, use
locator.pressSequentially()andlocator.press().await page.getByText('Submit').press('Enter'); -
Upload Files: Select files for upload with
locator.setInputFiles().await page.getByLabel('Upload File').setInputFiles('path/to/file.txt'); -
Focus and Drag-and-Drop: Focus elements with locator.focus() and perform drag-and-drop with locator.dragTo().
const source = page.getByText('Draggable Item'); const target = page.getByText('Drop Area'); await source.dragTo(target);
Automate your tests for free
Test easier than ever with BugBug test recorder. Faster than coding. Free forever.
Sign up for free
Advanced Interactions
Working with frames
Use a frame locator and then locate the element inside the iframe:
await page
.frameLocator('iframe[name="frame-name"]')
.getByRole('button', { name: 'Submit' })
.click();
Uploading files
await page
.getByLabel('Upload File')
.setInputFiles('path/to/file.txt');
Downloading files
Start waiting for the download before clicking the link:
const downloadPromise = page.waitForEvent('download');
await page.getByRole('link', { name: 'Download' }).click();
const download = await downloadPromise;
await download.saveAs(`downloads/${download.suggestedFilename()}`);
Simulating offline mode
Offline mode belongs to BrowserContext, not Page:
await page.context().setOffline(true);
await page.context().setOffline(false);
Common selectors and their syntax
| Locator type | Syntax |
|---|---|
| Role and accessible name | page.getByRole('button', { name: 'Submit' }) |
| Form label | page.getByLabel('Email') |
| Placeholder | page.getByPlaceholder('Search') |
| Visible text | page.getByText('Welcome') |
| Test ID | page.getByTestId('submit-button') |
| CSS | page.locator('button.primary') |
| XPath | page.locator('//button[@id="submit"]') |
Best practices for selecting elements
Prefer user-facing locators such as getByRole(), getByLabel(), and getByText(). Use getByTestId() when the application provides an explicit testing contract. Avoid long CSS or XPath paths tied to the current DOM structure, and avoid positional selectors unless order is the behavior being tested.
Custom test IDs
await page.getByTestId('submit-button').click();
💡 Check also our Selectors Cheat Sheet.
Best practices for selecting elements
- Use ID or class selectors when possible.
- Avoid using indexes in selectors; prefer text content or specific attributes.
Custom selectors and functions
await page.$('data-testid=submit-button'); // Custom attribute selector
Working with Assertions
Overview of assertions in Playwright
Playwright Test includes its own expect assertion library. Web-first assertions automatically retry until the expected condition is met or the assertion timeout expires, so you normally do not need to wait for an element manually.
Common assertion examples
await expect(page).toHaveTitle('Expected Title');
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByRole('heading')).toBeVisible();
await expect(page.getByTestId('status')).toHaveText('Complete');
await expect(page.getByLabel('Email')).toHaveValue('qa@example.com');
await expect(page.getByRole('listitem')).toHaveCount(3);
Tips for effective assertions
- Always
awaitasynchronous Playwright assertions. - Prefer auto-retrying assertions such as
toBeVisible()andtoHaveText(). - Assert user-visible outcomes rather than implementation details.
- Avoid fixed waits such as
page.waitForTimeout(). - Use
expect.poll()orexpect().toPass()when a more complex condition must be retried.
Playwright APIs added since August 2025
The following table covers the most useful test-authoring, execution, and debugging additions introduced between Playwright 1.55 and 1.62.
| Version | Addition | Example syntax |
|---|---|---|
| 1.55 | Full test-step title path | testStepInfo.titlePath() |
| 1.56 | Recent console messages, page errors, and requests | await page.consoleMessages() · await page.pageErrors() · await page.requests() |
| 1.57 | Global run tags | defineConfig({ tag: '@e2e' }) |
| 1.57 | Read a locator description | locator.description() |
| 1.57 | Wait for output from a development server | webServer: { command: 'npm start', wait: { stdout: /Ready/ } } |
| 1.58 | Local CDP connection optimization | chromium.connectOverCDP(endpoint, { isLocal: true }) |
| 1.59 | Record a controlled screencast | await page.screencast.start({ path: 'video.webm' }) |
| 1.59 | Capture a page ARIA snapshot | await page.ariaSnapshot() |
| 1.59 | Replace storage state in an existing context | await context.setStorageState(state) |
| 1.59 | Retrieve stored console messages or page errors with filters | await page.consoleMessages({ filter: 'error' }) |
| 1.59 | Create live traces | await context.tracing.start({ live: true }) |
| 1.60 | Record HAR through the tracing API | await using har = await context.tracing.startHar('trace.har') |
| 1.60 | Drop files or data onto an element | await page.locator('#dropzone').drop({ files }) |
| 1.60 | Abort the current test | test.abort('Unrecoverable test state') |
| 1.60 | Match a complete page ARIA snapshot | await expect(page).toMatchAriaSnapshot() |
| 1.60 | Match an accessible description in getByRole() |
page.getByRole('button', { description: 'Saves changes' }) |
| 1.61 | Test WebAuthn passkeys | await context.credentials.install() |
| 1.61 | Read or update web storage directly | await page.localStorage.setItem('token', 'abc') |
| 1.61 | Read API security and server information | await apiResponse.securityDetails() |
| 1.62 | Cancel actions and assertions with AbortSignal |
await locator.click({ signal: controller.signal }) |
| 1.62 | Save WebP screenshots | await page.screenshot({ path: 'page.webp' }) |
| 1.62 | Isolate retries at the end of a run | defineConfig({ retries: 2, retryStrategy: 'isolated' }) |
| 1.62 | Wait on a function scoped to an element | await locator.waitForFunction(element => element.dataset.ready) |
| 1.62 | Read API response timing | await apiResponse.timing() |
| 1.62 | Start the bundled Playwright CLI or MCP server | npx playwright cli · npx playwright mcp |
Automation Recipes
Login automation example:
await page.getByLabel('Username').fill('user');
await page.getByLabel('Password').fill('pass');
await page.getByRole('button', { name: 'Log in' }).click();
await expect(page).toHaveURL(/dashboard/);
Data scraping example
const data = await page.evaluate(() => {
// Return scraped data from page
return document.querySelector('.elementClass').textContent
});
End-to-end test scenario
E-Commerce Checkout Process Automation
1. Environment Setup
Initialize Playwright: Set up the Playwright environment with the required browser (e.g., Chromium).
Test Data Preparation: Prepare test data, like product details and user credentials.
2. Launch Browser and Navigate to E-Commerce Site
Start Browser: Launch the browser in headless or non-headless mode based on the requirement.
Open Website: Navigate to the e-commerce website's homepage.
3. User Login
Access Login Page: Click on the login link/button.
Enter Credentials: Fill in the username and password fields.
Submit Form: Click on the submit button.
Verify Login: Check if the user's account page is loaded.
4. Product Selection
Browse Products: Navigate to the product category.
Select a Product: Click on a product.
Add to Cart: Click the 'Add to Cart' button.
Verify Cart: Ensure that the product is added to the cart.
5. Cart Review
View Cart: Navigate to the shopping cart.
Check Product Details: Verify the selected product's details (name, quantity, price).
Proceed to Checkout: Click on the 'Proceed to Checkout' button.
6. Checkout Process
Delivery Information: Fill in the delivery address and contact information.
Choose Delivery Option: Select a delivery method.
Payment Information: Enter payment details (credit card, PayPal, etc.).
Review Order: Confirm all details are correct.
7. Place Order
Submit Order: Click the 'Place Order' button.
Verify Order Confirmation: Check for a successful order confirmation message or page.
Order Details: Optionally, capture order details like order number for further verification.
8. Logout and Close Browser
Logout: Click the logout button.
Close Browser: Close the browser session.
💡 Additional Considerations
Assertions: Throughout the test, include assertions to verify if each step is completed as expected (e.g., page titles, confirmation messages).
Error Handling: Implement error handling for scenarios like out-of-stock products or payment failures
Responsive Design Testing: Optionally, test the checkout process on different screen sizes.
Cross-Browser Testing: Run the test across different browsers supported by Playwright.
Clean Up: Ensure that the test cleans up any data it creates, like removing test orders from the system.
Debugging Playwright Scripts
Tools and techniques for debugging
- Use
page.on('console', message => console.log(message.text()));to listen to page console events. - Use
DEBUG=pw:apibefore running the script to get Playwright's API call logs.
Common errors and their solutions
- Element not found: Use a resilient locator such as
getByRole(),getByLabel(), orgetByTestId()and confirm that it uniquely identifies the element. - Timeout: Check whether the expected state actually occurs. Prefer a web-first assertion such as
await expect(locator).toBeVisible()instead of adding a fixed delay. - Strict mode violation: Narrow the locator until it resolves to exactly one element.
- Browser executable missing: Run
npx playwright install --with-deps.
Logging and reporting
Use traces, screenshots, videos, and the HTML report to investigate failures. Video must first be enabled in playwright.config.ts; page.video() only returns a video object when recording is active.
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
});
Automate your tests for free
Test easier than ever with BugBug test recorder. Faster than coding. Free forever.
Sign up for free
Integration with Test Runners
Playwright Test is the recommended test runner for Playwright projects. It provides fixtures, isolation, parallel execution, retries, reporters, tracing, projects, and the built-in expect assertion library without requiring Jest or Mocha.
Tests are defined with test(), grouped with test.describe(), and prepared with hooks such as test.beforeEach() and test.afterEach():
import { test, expect } from '@playwright/test';
test.describe('account settings', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/settings');
});
test('updates the profile', async ({ page }) => {
await page.getByLabel('Display name').fill('QA User');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Changes saved')).toBeVisible();
});
});
- Compatibility with Popular Test Runners: Playwright is designed to work with a range of test runners like Jest, Mocha, and others. This flexibility allows developers to choose their preferred testing environment.
- Seamless Integration: Playwright integrates smoothly with these test runners, enabling features like parallel test execution, test retries, and reporting.
- Automated Browser Testing: Playwright can automate tests in multiple browsers (like Chrome, Firefox, and Safari), ensuring cross-browser compatibility.
- CI/CD Integration: Playwright's compatibility with test runners makes it easy to integrate automated browser tests into Continuous Integration/Continuous Deployment (CI/CD) pipelines.
Organizing Tests and Suites
- Using describe Blocks: Tests in Playwright can be grouped using describe blocks. This is a common practice in test runners like Jest and Mocha. describe blocks help in organizing tests into logical groups or suites, making it easier to understand the structure of tests.
- Individual Tests with test or it: For writing individual tests, Playwright uses the test or it functions. These functions define individual test cases. test is generally used in Jest, while it is common in Mocha. Both serve the same purpose of delineating a single test.
- Hierarchical Test Organization: By combining describe blocks with test or it, tests can be organized hierarchically. This hierarchy aids in creating structured, readable, and maintainable test suites.
- Scoped Setup and Teardown: Within these blocks, Playwright allows for scoped setup and teardown (using hooks like
beforeEach,afterEach), which is essential for setting up the conditions for each test and cleaning up afterward. - Tagging and Filtering: Tests can be tagged, and these tags can be used to filter tests during execution. This is particularly useful in large test suites where you might want to run only a subset of tests based on certain criteria.
Parallel execution and headless mode
Parallel Execution:
Parallel execution in Playwright refers to the ability to run multiple browser instances or tests simultaneously. This is crucial for speeding up the testing process, especially when dealing with a large suite of tests.
Playwright supports parallel execution. It can also integrate with Jest or Mocha testing frameworks.
💡 TIP
In Playwright, each test or browser instance runs in its own context, which ensures that tests do not interfere with each other, providing isolation and more reliable results.
Headless Mode:
Headless mode in Playwright allows you to run browsers without a graphical user interface. This is especially useful for automated testing, particularly in continuous integration (CI) environments where you may not need a display for running tests.
Running in headless mode often results in faster execution of tests because it doesn't need to render the UI elements on the screen.
💡 TIP
You can enable headless mode in Playwright by setting the headless option to true when launching a browser. For example, in Playwright for JavaScript, you would use browserType.launch({ headless: true });.
Continuous Integration and Deployment
Setting up Playwright in CI/CD pipelines:
- Run
npm init playwright@latestto generate a current GitHub Actions workflow, or create a workflow that installs dependencies, runsnpx playwright install --with-deps, executesnpx playwright test, and uploads the HTML report. - Configure environment variables for sensitive data like login credentials.
Docker integration:
- Use Playwright's official Docker image to run tests in containers.
Best practices for CI/CD with Playwright:
- Do not cache browser binaries by default. Playwright's documentation notes that restoring the cache often takes about as long as downloading the browsers, while Linux system dependencies still need to be installed.
- Use artifacts for storing screenshots and videos from test runs.
💡 Resources
Official documentation: Playwright Documentation
Community forums and support: Playwright GitHub Discussions
Happy (automated) testing!
FAQ
What is Playwright Cheat Sheet?
A: The Playwright Cheat Sheet is a resource that provides a quick reference guide for leveraging Playwright for browser automation and testing.
How can I explore the capabilities of Playwright?
A: To explore the features and capabilities of Playwright, you can refer to the official documentation and tutorials provided by the Playwright team.
What are the key features of Playwright?
A: Playwright offers features such as cross-browser testing, parallel and headless execution, and the ability to automate tasks across different web platforms.
What is the recommended way to set up Playwright for automation?
A: It is recommended to set up Playwright for automation by following the installation and setup instructions provided in the official Playwright documentation.
How can I locate a specific element on a web page using Playwright?
A: Use built-in locators such as getByRole(), getByLabel(), getByText(), getByPlaceholder(), and getByTestId(). CSS and XPath locators are also available through page.locator(), but user-facing locators are usually more resilient.
Can Playwright be used for mobile automation?
A: Playwright supports mobile web testing through device, viewport, touch, locale, and browser emulation. It does not automate native Android or iOS applications.
What are the benefits of migrating to Playwright from other automation frameworks like Cypress?
A: Migrating to Playwright from frameworks like Cypress can offer benefits like local parallel testing. Playwright is also much easier when it comes to complexity of the code - and it also supports multiple languages.
How can I ensure accessibility in automated tests using Playwright?
A: You can ensure accessibility in automated tests using Playwright by leveraging features such as 'text alternative', 'accessible value await', 'label await', and 'placeholder'.
Can Playwright be integrated with Git for version control?
A: Yes, Playwright can be integrated with Git for version control to manage and track changes in automation scripts and test files.
How can I master Playwright for advanced automation tasks?
A: To master Playwright for advanced automation tasks, it is recommended to explore advanced features, APIs, and best practices provided by the Playwright team and community.
What is async in Playwright?
A: In the Playwright framework, async ({page}) signifies a function that operates asynchronously, accepting an argument named page that denotes a web page. The use of async indicates that the function is designed to execute without hindering the concurrent running of other scripts.
What Is Playwright Logging?
Logging in Playwright refers to capturing and displaying information about the browser's activities during a test run. This can include network requests, API calls, console messages, errors, and other events that occur while Playwright scripts are executing. Logging is crucial for debugging and understanding the behavior of web applications during automated testing.


