Playwright Tutorial for Beginners

Updated June 2026
This tutorial walks you through Playwright from zero to running your first automated browser test. You will install the framework, understand its project structure, write tests using locators and assertions, debug failures with built-in tools, and set up continuous integration so your tests run automatically on every commit.

Playwright is a browser automation framework by Microsoft that controls Chromium, Firefox, and WebKit from a single API. If you are new to browser automation or coming from another tool like Selenium, this guide gives you everything you need to start writing reliable, fast tests with Playwright.

Step 1: Install Node.js and Playwright

Playwright's JavaScript bindings require Node.js version 18 or later. If you do not already have Node.js installed, download it from the official Node.js website and run the installer for your operating system. Verify the installation by opening a terminal and running node --version, which should print a version number of 18 or higher.

With Node.js ready, create a new directory for your project and initialize Playwright inside it. Open your terminal and run these commands:

mkdir my-playwright-project

cd my-playwright-project

npm init playwright@latest

The initialization wizard asks a few questions: which language to use (TypeScript or JavaScript), where to put your tests, whether to add a GitHub Actions workflow, and whether to install the browsers. Accept the defaults for all of these. Playwright will download Chromium, Firefox, and WebKit browser binaries, which may take a few minutes depending on your connection speed.

Once the installation completes, you will have a working Playwright project with example tests ready to run. The browsers are stored in a cache directory managed by Playwright, so you do not need to install Chrome, Firefox, or Safari separately.

Step 2: Understand the Project Structure

The initialization creates several files and directories in your project. Understanding each one helps you navigate the framework confidently.

playwright.config.ts is the central configuration file. It defines which browsers to test (called "projects"), timeout values for tests and assertions, the base URL for your application, and settings for screenshots, videos, and traces. The default configuration runs tests in Chromium, Firefox, and WebKit, which gives you cross-browser coverage immediately.

The tests/ directory contains your test files. Playwright looks for files matching the pattern *.spec.ts or *.spec.js by default. The generated example test demonstrates basic navigation and assertion patterns.

The tests-examples/ directory contains a more comprehensive demo test that interacts with the Playwright documentation site. Study this file to see locators, assertions, and page object patterns in action. You can delete this directory once you understand the patterns.

The package.json file lists @playwright/test as a dev dependency. This single package includes the Playwright library, the test runner, assertion library, and all CLI tools. No additional test frameworks or assertion libraries are needed.

Step 3: Write Your First Test

Create a new file called tests/my-first-test.spec.ts in your project. A Playwright test consists of a test function that receives a page object, which represents a browser tab. You use this object to navigate, interact with elements, and verify behavior.

A typical test follows three phases: arrange (navigate to the page and set up state), act (interact with elements like clicking buttons or filling forms), and assert (verify that the page shows the expected result). Playwright's auto-waiting handles the timing, so you never need to add manual delays between steps.

Start with something simple: navigate to a public website, verify the page title, click a link, and verify the resulting page. Each action is awaited because Playwright operations are asynchronous. The expect function from @playwright/test provides web-first assertions that automatically retry until the condition is met or the timeout expires.

For example, await expect(page).toHaveTitle(/substring/) checks that the page title contains a specific string. If the page is still loading or the title changes dynamically, the assertion retries until it passes. This retry mechanism is one of the reasons Playwright tests are more reliable than tests written with tools that check conditions only once.

Run your test with npx playwright test tests/my-first-test.spec.ts. By default, tests run in headless mode (no visible browser window) across all configured browsers. The terminal output shows which tests passed and which failed, along with timing information.

Step 4: Use Locators to Find Elements

Locators are the mechanism Playwright uses to find elements on a page. Choosing the right locator strategy is crucial for writing tests that do not break when the application's markup changes. Playwright offers several locator types, each suited to different situations.

Role-based locators are the recommended default. page.getByRole('button', { name: 'Submit' }) finds a button element whose accessible name is "Submit." This approach mirrors how real users interact with a page, finding elements by their semantic role rather than their CSS class or DOM position. Role locators are resilient to markup refactoring because the accessible role and name typically remain stable even when the underlying HTML changes.

Text locators find elements by their visible text content. page.getByText('Welcome back') finds any element displaying that text. Use the exact option for precise matching or pass a regular expression for pattern matching. Text locators are intuitive and readable but can break if the displayed text changes due to internationalization or copy updates.

Test ID locators use a dedicated data-testid attribute (configurable in playwright.config.ts). page.getByTestId('login-form') finds the element with data-testid="login-form". This approach requires adding test IDs to your application's markup but provides the most stable selectors since test IDs do not change with visual redesigns.

CSS and XPath locators are available through page.locator('css-selector') for cases where semantic locators do not work. These are more fragile and harder to maintain, so use them as a fallback when role, text, and test ID locators are not practical.

Locators can be chained with .filter() to narrow down results. For example, page.getByRole('listitem').filter({ hasText: 'Product A' }) finds a list item containing specific text. This is powerful for complex pages where multiple elements share the same role.

Step 5: Run and Debug Tests

Running all tests is as simple as npx playwright test. The test runner finds all spec files, distributes them across worker processes, and reports results. For focused work, specify a single file or use the --grep flag to filter tests by name.

Headed mode (npx playwright test --headed) opens a visible browser window so you can watch the test execute. This is helpful during development when you want to see exactly what the test is doing. Slow motion mode (--headed --slow-mo 500) adds a delay between each action, making it easier to follow fast-moving test sequences.

The Playwright Inspector (npx playwright test --debug) opens a debugging panel alongside the browser. You can step through actions one at a time, inspect the DOM at each point, and try different locators interactively. The inspector also highlights the element each locator matches, which helps you verify that your selectors target the right elements.

UI Mode (npx playwright test --ui) is the most powerful debugging tool. It provides a visual test runner with a tree of all tests, a time-travel timeline showing each action's effect on the page, live DOM snapshots, and network request logs. You can click on any point in the timeline to see exactly what the page looked like at that moment. UI Mode also supports watch mode, re-running tests automatically when you save changes to your test files.

Trace Viewer is essential for debugging CI failures where you cannot observe the browser directly. Configure traces in your playwright.config.ts (the default is to capture traces on first retry) and open them with npx playwright show-trace trace.zip. The trace contains a complete record of the test execution: screenshots, DOM snapshots, network requests, console logs, and the action timeline. You can share trace files with teammates to collaborate on debugging.

Step 6: Add Tests to CI/CD

Running tests locally is valuable during development, but the real benefit comes from running them automatically in your CI/CD pipeline. The Playwright initialization wizard can generate a GitHub Actions workflow file that handles this setup for you.

The workflow installs Node.js, installs project dependencies, installs Playwright browsers with system dependencies, runs the test suite, and uploads the HTML report as an artifact. The playwright install --with-deps command handles all operating system level dependencies that browsers need on Ubuntu runners.

For other CI platforms like GitLab CI, Jenkins, or Azure DevOps, the setup follows the same pattern: install Node.js, install dependencies, install browsers, run tests. Playwright's official Docker images (mcr.microsoft.com/playwright) come with all dependencies pre-installed, which simplifies Docker-based CI configurations.

CI performance can be optimized by running only the browsers you need (for example, just Chromium for fast feedback, with full cross-browser runs on merge), sharding tests across multiple CI machines with the --shard flag, and caching browser binaries between runs. Most teams find that Playwright tests run fast enough in CI without extensive optimization, thanks to the framework's efficient parallelism.

When a test fails in CI, the HTML report and trace artifacts give you everything needed to diagnose the failure without reproducing it locally. Review the trace timeline to see what the test did, what the page looked like at each step, and where the assertion failed. This workflow makes CI test failures far less frustrating than they are with tools that only provide text-based error messages.

Key Takeaway

Playwright's combination of auto-waiting, powerful locators, and built-in debugging tools makes it the most beginner-friendly browser automation framework available. Start with role-based locators, use UI Mode for interactive debugging, and set up CI early so your tests run automatically on every change.