Getting Started August 15, 2026 14 min read

How to Use Playwright: Step-by-Step Getting Started Guide (2026)

Everything you need to go from zero to running your first Playwright test. This step-by-step guide covers installation, project structure, writing tests, running them, debugging failures, locator strategies, and configuration — with real code examples you can copy and use today.

How to use Playwright is the most common question new QA engineers and developers ask when they discover Microsoft's test automation framework. The good news: Playwright is one of the easiest frameworks to get started with. You can go from zero to a running test in under ten minutes — no complex configuration, no driver downloads, no XML files.

This guide walks you through every step: installing Playwright, understanding the project structure, writing your first real test, running it in different modes, debugging failures, choosing the right locators, and configuring your project for production use. By the end, you will have a working Playwright test suite and the knowledge to expand it confidently.

If you are completely new to test automation, start with our Playwright Automation for Beginners guide first, then come back here for the hands-on walkthrough.


1. Prerequisites

Before you install Playwright, make sure you have three things ready:

  • Node.js 18 or later: Playwright runs on Node.js. Download the LTS version from nodejs.org. To check your version, run node --version in your terminal.
  • VS Code (recommended): Any code editor works, but VS Code has an official Playwright extension that adds IntelliSense, test running, and debugging support. Download it from code.visualstudio.com.
  • Basic JavaScript or TypeScript knowledge: You should understand variables, functions, and async/await. If you have written any JavaScript before — even basic DOM manipulation — you have enough to get started.

Tip: You do not need to install browsers separately. Playwright downloads its own bundled versions of Chromium, Firefox, and WebKit during setup. This guarantees consistent behavior across machines.

Verify your Node.js installation is working:

Terminal
node --version    # Should show v18.x or later
npm --version     # Should show 9.x or later

2. Installing Playwright

Playwright's installation process is a single command that scaffolds your entire project. Open your terminal and run:

Terminal — Installation
# Create a new project directory
mkdir my-playwright-project
cd my-playwright-project

# Initialize Playwright (this does everything)
npm init playwright@latest

The npm init playwright@latest command launches an interactive setup wizard. Here is what each prompt means and what to choose:

  1. Do you want to use TypeScript or JavaScript? — Choose TypeScript. It provides autocomplete, type checking, and better error messages. Playwright's documentation is TypeScript-first.
  2. Where to put your end-to-end tests? — Accept the default tests folder. You can change this later in your config file.
  3. Add a GitHub Actions workflow? — Choose Yes if you plan to run tests in CI/CD. This creates a .github/workflows/playwright.yml file. You can always add it later too.
  4. Install Playwright browsers? — Choose Yes. This downloads Chromium, Firefox, and WebKit (about 400MB total). These are isolated browser binaries that will not interfere with your system browsers.

The full installation takes 1 to 3 minutes depending on your internet speed. When it finishes, you will see a confirmation message with next steps.

Tip: If you need to add Playwright to an existing project instead of creating a new one, use npm install -D @playwright/test followed by npx playwright install to download browsers.

3. Understanding the Project Structure

After installation, your project directory looks like this:

Project Structure
my-playwright-project/
  playwright.config.ts    # Main configuration file
  package.json             # Node.js project file
  tests/
    example.spec.ts        # Example test file
  tests-examples/
    demo-todo-app.spec.ts  # Full example test suite
  node_modules/            # Dependencies

Here is what each file and folder does:

  • playwright.config.ts — The central configuration file. It controls which browsers to test against, the base URL, timeouts, retries, number of parallel workers, and reporter settings. This is where you customize Playwright's behavior for your project.
  • tests/ — Where your test files live. Any file matching the pattern *.spec.ts is automatically discovered and executed by Playwright.
  • tests-examples/ — Contains a complete TodoMVC test suite as a reference. You can study it or delete it once you are comfortable writing your own tests.
  • package.json — Standard Node.js manifest. It lists @playwright/test as a dev dependency.

4. Writing Your First Playwright Test

Let us write a real test from scratch. Create a new file at tests/my-first-test.spec.ts and paste this code:

tests/my-first-test.spec.ts
import { test, expect } from '@playwright/test';

test('homepage has correct title and links', async ({ page }) => {
  // Step 1: Navigate to the website
  await page.goto('https://playwright.dev');

  // Step 2: Verify the page title contains "Playwright"
  await expect(page).toHaveTitle(/Playwright/);

  // Step 3: Click the "Get started" link
  await page.getByRole('link', { name: 'Get started' }).click();

  // Step 4: Verify navigation to the intro page
  await expect(page).toHaveURL(/.*intro/);
});

Let us break down what each part does:

  • import { test, expect } — Imports Playwright's test runner and assertion library. Every test file starts with this line.
  • test('description', async ({ page }) => { ... }) — Defines a test. The page parameter is a Playwright Page object — a real browser tab you can interact with.
  • page.goto(url) — Navigates the browser to a URL and waits for the page to load.
  • expect(page).toHaveTitle(/Playwright/) — Asserts that the page title matches a regular expression. Playwright automatically retries this assertion until it passes or times out.
  • page.getByRole('link', { name: 'Get started' }).click() — Finds a link by its accessible role and visible text, then clicks it. Playwright auto-waits for the element to be visible and clickable.
  • expect(page).toHaveURL(/.*intro/) — Asserts that the URL changed after clicking the link.

Now let us write a more practical test — one that fills out a form:

tests/login-form.spec.ts
import { test, expect } from '@playwright/test';

test('user can fill and submit a login form', async ({ page }) => {
  await page.goto('https://example.com/login');

  // Fill in the email field
  await page.getByLabel('Email').fill('user@example.com');

  // Fill in the password field
  await page.getByLabel('Password').fill('securePassword123');

  // Click the submit button
  await page.getByRole('button', { name: 'Sign in' }).click();

  // Verify successful login
  await expect(page.getByText('Welcome back')).toBeVisible();
  await expect(page).toHaveURL(/.*dashboard/);
});

This test demonstrates the core Playwright workflow: navigate, interact with elements, and assert the expected outcome. Every test you write follows this pattern.

5. Running Tests

Playwright offers several ways to run your tests. Here are the commands you will use daily:

Run all tests (headless, all browsers)

Terminal
# Run all tests across all configured browsers
npx playwright test

This runs every *.spec.ts file in your tests directory across all browsers defined in playwright.config.ts (Chromium, Firefox, WebKit by default). Tests run in parallel using multiple workers.

Run a specific test file

Terminal
# Run only the login form test
npx playwright test tests/login-form.spec.ts

# Run tests matching a keyword
npx playwright test -g "login"

Run in headed mode (watch the browser)

Terminal
# Open a visible browser window while tests run
npx playwright test --headed

Headed mode launches a real browser window so you can watch exactly what Playwright is doing. This is useful for understanding how your test interacts with the page, especially when you are writing new tests.

Run in UI mode (interactive test runner)

Terminal
# Launch the interactive UI runner
npx playwright test --ui

UI mode is the best way to develop tests. It opens an interactive window where you can pick which tests to run, watch them execute in real time, see a timeline of every action, inspect DOM snapshots, and re-run individual tests instantly. If you learn one Playwright feature today, make it UI mode.

Run on a single browser

Terminal
# Run only in Chromium
npx playwright test --project=chromium

# Run only in Firefox
npx playwright test --project=firefox

# Run only in WebKit (Safari engine)
npx playwright test --project=webkit

Tip: During development, run tests on a single browser (Chromium is fastest) for quick feedback. Run the full cross-browser suite before committing or in your CI/CD pipeline.

6. Debugging Tests

Every test fails eventually. Playwright provides three powerful debugging tools that make finding the problem straightforward:

Playwright Inspector (step-by-step debugging)

Terminal
# Launch the Inspector
npx playwright test --debug

The Playwright Inspector opens a browser window alongside a debugging panel. You can step through each action one at a time, see the locator Playwright is using, inspect the DOM state at each step, and modify locators live. It is the most hands-on way to debug a failing test.

You can also add a page.pause() call inside your test code to pause execution at a specific point:

Pause at a specific step
test('debug this test', async ({ page }) => {
  await page.goto('https://example.com');
  await page.getByRole('button', { name: 'Submit' }).click();

  // Execution pauses here — Inspector opens
  await page.pause();

  // Continue debugging from this point
  await expect(page.getByText('Success')).toBeVisible();
});

Trace Viewer (post-mortem analysis)

Traces record everything that happened during a test run — screenshots, DOM snapshots, network requests, and console logs. Enable tracing in your config or run with:

Terminal
# Record traces for failed tests
npx playwright test --trace on

# View a trace file
npx playwright show-trace test-results/my-test/trace.zip

The Trace Viewer opens in your browser and lets you scrub through every action like a video timeline. You can see exactly what the page looked like when an assertion failed, what network requests were made, and what console errors occurred. This is especially valuable for debugging flaky tests or failures that only happen in CI/CD.

VS Code Extension

Install the official Playwright Test for VS Code extension. It adds:

  • Run/debug buttons next to each test in the editor
  • Breakpoint debugging — set breakpoints in your test code and step through execution
  • Test explorer — a sidebar panel listing all your tests with pass/fail status
  • Pick locator — hover over elements in the browser to generate locator code

Tip: The VS Code extension's "Pick Locator" feature is the fastest way to find the right locator for any element. Click the button, hover over the element in the browser, and Playwright generates the best locator automatically. For a deeper dive, read our complete debugging guide.

7. Playwright Locator Strategies

Locators are how you tell Playwright which element to interact with. Playwright offers several locator methods, ranked from most recommended to least:

getByRole — the gold standard

getByRole finds elements by their ARIA role and accessible name. This is the most resilient locator because it mirrors how users and assistive technologies see the page:

getByRole examples
// Click a button with visible text "Submit"
await page.getByRole('button', { name: 'Submit' }).click();

// Click a navigation link
await page.getByRole('link', { name: 'About Us' }).click();

// Check a checkbox
await page.getByRole('checkbox', { name: 'Accept terms' }).check();

// Select a tab
await page.getByRole('tab', { name: 'Settings' }).click();

// Find a heading
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();

getByText — find by visible text

getByText examples
// Find element containing exact text
await page.getByText('Welcome back, John').click();

// Partial text match (default behavior)
await page.getByText('Welcome').click();

// Exact text match
await page.getByText('Submit', { exact: true }).click();

getByLabel — find form inputs by their label

getByLabel examples
// Fill an input field associated with a label
await page.getByLabel('Email address').fill('user@test.com');

// Fill a password field
await page.getByLabel('Password').fill('secret123');

// Select a dropdown by its label
await page.getByLabel('Country').selectOption('Canada');

getByTestId — find by data-testid attribute

getByTestId examples
// Find element with data-testid="submit-button"
await page.getByTestId('submit-button').click();

// Find a specific card component
await expect(page.getByTestId('user-profile-card')).toBeVisible();

Use getByTestId as a fallback when there is no accessible role or visible text to target. It requires developers to add data-testid attributes to the HTML, but it never breaks due to text changes or styling updates.

Tip: Avoid CSS selectors and XPath in Playwright tests. They are brittle — a single class name or DOM structure change breaks them. Stick to getByRole, getByText, getByLabel, and getByTestId for tests that survive refactors. For a complete deep dive, see our upcoming Playwright Locators Guide.

8. Configuration Essentials

The playwright.config.ts file controls how your test suite behaves. Here is a production-ready configuration with the most important options explained:

playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  // Directory where tests live
  testDir: './tests',

  // Run tests in parallel for speed
  fullyParallel: true,

  // Fail the build if test.only is left in code
  forbidOnly: !!process.env.CI,

  // Retry failed tests (2 retries in CI, 0 locally)
  retries: process.env.CI ? 2 : 0,

  // Number of parallel workers
  workers: process.env.CI ? 1 : undefined,

  // Reporter: HTML report for detailed results
  reporter: 'html',

  // Shared settings for all tests
  use: {
    // Base URL for relative navigations
    baseURL: 'https://your-app.com',

    // Collect trace on first retry of a failed test
    trace: 'on-first-retry',

    // Take screenshot on failure
    screenshot: 'only-on-failure',

    // Record video on failure
    video: 'on-first-retry',
  },

  // Browser configurations
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },

    // Mobile browsers
    {
      name: 'mobile-chrome',
      use: { ...devices['Pixel 7'] },
    },
    {
      name: 'mobile-safari',
      use: { ...devices['iPhone 14'] },
    },
  ],
});

Key configuration options explained:

  • baseURL — Set this to your application's URL. Then in your tests, you can write page.goto('/login') instead of the full URL. This makes switching between environments (staging, production) trivial.
  • retries — In CI/CD, network flakiness and timing issues can cause occasional failures. Setting retries to 2 means a test must fail three times consecutively before it is marked as failed.
  • workers — Controls parallelism. Locally, Playwright auto-detects the optimal number. In CI, you may want to limit this to 1 to reduce resource contention.
  • trace — Set to 'on-first-retry' to record traces only when a test is retried. This saves disk space while still giving you debugging data for flaky tests.
  • projects — Each project is a browser/device configuration. Playwright runs your tests once per project, giving you cross-browser coverage without duplicating test code.

Tip: Start with just Chromium during development. Add Firefox and WebKit when you set up your CI/CD pipeline with GitHub Actions. Mobile device testing is important too — Playwright emulates real device viewports, touch events, and user agents.

9. Next Steps: From Beginner to Advanced

You now know how to use Playwright — install it, write tests, run them, debug failures, choose locators, and configure your project. Here is the roadmap for taking your skills to the next level:

Organize tests with the Page Object Model

As your test suite grows beyond 10-15 tests, you will need a way to organize your code. The Page Object Model (POM) pattern separates page interactions from test logic, making your tests easier to read and maintain. It is the industry standard for production test suites.

Test APIs alongside your UI

Playwright is not just for browser testing. It has a built-in APIRequestContext that lets you make HTTP requests, set up test data via API calls, and test your backend endpoints — all within the same test framework. This is a significant advantage over tools that require separate API testing tools.

Set up CI/CD with GitHub Actions

Running tests locally is a start, but the real value comes from running them automatically on every pull request. Our Playwright + GitHub Actions CI/CD guide shows you how to set this up in under 15 minutes — including parallel execution, artifact storage, and Slack notifications on failure.

Use Claude AI to accelerate test writing

The fastest way to write Playwright tests in 2026 is to describe what you want to test in plain English and let Claude AI generate the code. With the MCP Server integration, Claude can connect directly to your Playwright project, read your page structure, and generate complete test files — including Page Object classes, assertions, and edge cases you might not think of.

10. Frequently Asked Questions

How do I install Playwright?

Run npm init playwright@latest in your terminal. This single command scaffolds a complete project with TypeScript configuration, example tests, and downloads browser binaries for Chromium, Firefox, and WebKit. You need Node.js 18 or later installed first.

How long does it take to learn how to use Playwright?

You can write and run your first test within 30 minutes of installation. Learning the full API — locators, assertions, fixtures, and configuration — typically takes 1 to 2 weeks of daily practice. Reaching production proficiency with Page Object Model and CI/CD takes 4 to 8 weeks with structured learning.

Can I use Playwright without knowing TypeScript?

Yes. Playwright supports JavaScript, TypeScript, Python, Java, and C#. You can write tests in plain JavaScript. However, TypeScript is recommended because it provides autocomplete, type checking, and better error messages — and Playwright's official documentation uses TypeScript throughout.

What is the difference between Playwright and Selenium?

Playwright is a modern framework with built-in auto-waiting, native multi-browser support, parallel execution, and a TypeScript-first API. Selenium is a legacy tool requiring manual waits, separate browser drivers, and more boilerplate. Playwright runs 3 to 5 times faster than Selenium for most test suites. See our detailed Playwright vs Selenium comparison.

How do I debug a failing Playwright test?

Playwright provides three built-in debugging tools: the Playwright Inspector (--debug flag) for step-by-step execution, the Trace Viewer for post-mortem analysis with screenshots and network logs, and the VS Code extension for breakpoint debugging. You can also run tests in headed mode with --headed to watch the browser.


Asim Noaman - Playwright and Claude AI course instructor

Asim Noaman

Senior QA Automation Engineer & AI Testing Specialist

With years of hands-on experience building test automation frameworks for production applications, Asim specializes in combining traditional QA methodologies with cutting-edge AI tools. He has helped teams adopt Playwright and AI-driven testing workflows to ship faster with fewer bugs.

Udemy Instructor Published course author
Playwright + AI Expert Specialized in AI-powered QA
Production Experience Enterprise-grade frameworks
Connect on LinkedIn