Playwright Tutorial Step by Step: Complete Beginner-to-Advanced Guide

Introduction: Why Learn Playwright Step by Step in 2026?

If you are starting browser automation, moving from manual testing, or transitioning from Selenium, learning Playwright systematically is more effective than trying to memorize hundreds of APIs.

This Playwright tutorial step by step guide takes you from installation to a practical automation framework.

Playwright Test is an end-to-end testing framework that bundles a test runner, assertions, test isolation, parallelization, and debugging/reporting tools. It supports Chromium, Firefox, and WebKit across Windows, Linux, and macOS.

The goal is not just to write one browser test. By the end of this Playwright tutorial step by step, you should understand how to build a maintainable automation project using:


What Is Playwright?

Playwright is a browser automation and end-to-end testing framework developed for modern web applications.

It supports:

The Playwright Test package provides the runner and testing features needed to organize and execute automated tests.

A simplified architecture is:

Test Code

   ↓

Playwright Test Runner

   ↓

Browser Context

   ↓

Page

   ↓

Browser Engine

   ↓

Chromium / Firefox / WebKit

For beginners, remember:

Browser → browser instance
BrowserContext → isolated browser session
Page → browser tab
Locator → element finder
Assertion → expected result
Test → automation scenario


Playwright Architecture Explained for Beginners

One reason Playwright is useful for modern automation is that several testing capabilities are integrated into the framework.

For example:

                   Playwright

                       |

       +—————+—————+

       |               |               |

     UI Tests       API Tests       Debugging

       |               |               |

    Locators       Requests        Traces

    Assertions     Responses       Reports

       |

   Browser Contexts

       |

Chromium / Firefox / WebKit

Playwright also provides isolated test fixtures. The built-in page fixture, for example, gives a test an isolated Page instance.


Prerequisites for Learning Playwright

Before following this Playwright tutorial step by step, you should understand basic:

Programming

  • Variables
  • Functions
  • Arrays
  • Objects
  • Classes
  • Conditions
  • Loops
  • async and await

Web concepts

  • HTML
  • CSS
  • DOM
  • Forms
  • Buttons
  • Links
  • HTTP basics

Testing concepts

If you are new to programming, TypeScript basics should be learned alongside Playwright.


Step 1: Install Node.js

Playwright’s Node.js installation requires a supported Node.js environment. Current Playwright documentation lists supported Node.js releases and supported operating systems on its installation page.

After installing Node.js, verify:

node –version

Then check npm:

npm –version

If both commands return versions, your Node.js environment is ready.


Step 2: Install Playwright

The easiest way to start a new project is:

npm init playwright@latest

The Playwright setup wizard asks you to select options such as:

  • TypeScript or JavaScript
  • Test directory
  • GitHub Actions workflow
  • Browser installation

TypeScript is the default option in the current setup flow.

You can also install Playwright into an existing project.

After installation, verify the version:

npx playwright –version

If the browser binaries were not installed during setup, use:

npx playwright install


Step 3: Create a Playwright Project

Run:

npm init playwright@latest

For a beginner project, select:

TypeScript

tests

Install Playwright browsers: Yes

Playwright creates the basic configuration, package files, and starter test.

You can then run:

npx playwright test


Step 4: Understand the Playwright Project Structure

A practical project can eventually look like this:

playwright-project/

├── tests/

│   ├── login.spec.ts

│   ├── product.spec.ts

│   └── checkout.spec.ts

├── pages/

│   ├── LoginPage.ts

│   ├── ProductPage.ts

│   └── CheckoutPage.ts

├── fixtures/

├── test-data/

├── utils/

├── playwright.config.ts

├── package.json

└── README.md

tests/

Contains test scenarios.

pages/

Contains Page Object classes.

fixtures/

Contains reusable test setup and custom fixtures.

test-data/

Contains test input data.

utils/

Contains reusable helper functions.

playwright.config.ts

Contains framework configuration.

README.md

Documents project setup and execution.

Do not create all these folders on day one. Start small and add structure as the project grows.


Step 5: Configure playwright.config.ts

A basic configuration is:

import { defineConfig, devices } from ‘@playwright/test’;

export default defineConfig({

 testDir: ‘./tests’,

 use: {

   baseURL: ‘https://example.com’,

   screenshot: ‘only-on-failure’,

   trace: ‘on-first-retry’

 },

 projects: [

   {

     name: ‘chromium’,

     use: { …devices[‘Desktop Chrome’] }

   },

   {

     name: ‘firefox’,

     use: { …devices[‘Desktop Firefox’] }

   },

   {

     name: ‘webkit’,

     use: { …devices[‘Desktop Safari’] }

   }

 ]

});

The configuration file can control the test directory, projects, retries, workers, reporters, browser settings, base URL, traces, and more.


Step 6: Write Your First Playwright Test

Here is the most important example in this Playwright tutorial step by step:

import { test, expect } from ‘@playwright/test’;

test(‘homepage title validation’, async ({ page }) => {

 await page.goto(‘https://playwright.dev’);

 await expect(page).toHaveTitle(/Playwright/);

});

Understanding the code

1. Import Playwright

import { test, expect } from ‘@playwright/test’;

test creates the test. expect performs assertions.

2. Create the test

test(‘homepage title validation’, async ({ page }) => {

The test receives the built-in page fixture.

3. Navigate

await page.goto(‘https://playwright.dev’);

This opens the website.

4. Validate

await expect(page).toHaveTitle(/Playwright/);

The assertion verifies the page title.


Step 7: Run Playwright Tests

Run all tests:

npx playwright test

Run one file:

npx playwright test tests/example.spec.ts

Run in headed mode:

npx playwright test –headed

Run a specific browser project:

npx playwright test –project=chromium

Playwright also provides UI Mode:

npx playwright test –ui

The official installation guide documents headed execution, project selection, individual test files, UI Mode, and HTML reports.


Step 8: Understand Playwright Locators

Locators identify elements.

Common Playwright locators include:

page.getByRole()

page.getByText()

page.getByLabel()

page.getByPlaceholder()

page.getByAltText()

page.getByTestId()

For example:

await page.getByLabel(‘Username’).fill(‘admin’);

await page.getByLabel(‘Password’).fill(‘password123’);

await page.getByRole(‘button’, {

 name: ‘Login’

}).click();

Prefer meaningful locators over fragile CSS or XPath expressions whenever possible.


Step 9: Add Assertions

Assertions validate application behavior.

Examples:

await expect(page).toHaveTitle(/Dashboard/);

await expect(page).toHaveURL(/dashboard/);

await expect(

 page.getByText(‘Login successful’)

).toBeVisible();

await expect(

 page.getByRole(‘button’, { name: ‘Submit’ })

).toBeEnabled();

Playwright’s web-first assertions are designed to wait for conditions to become true, which helps avoid unnecessary synchronization code.


Step 10: Handle Forms and User Interactions

A login scenario could look like:

import { test, expect } from ‘@playwright/test’;

test(‘login test’, async ({ page }) => {

 await page.goto(‘https://example.com/login’);

 await page.getByLabel(‘Username’).fill(‘testuser’);

 await page.getByLabel(‘Password’).fill(‘password123’);

 await page.getByRole(‘button’, {

   name: ‘Login’

 }).click();

 await expect(page).toHaveURL(/dashboard/);

});

The basic pattern is:

Navigate

  ↓

Locate

  ↓

Interact

  ↓

Assert

This pattern will appear repeatedly in real automation projects.


Step 11: Handle Dropdowns, Checkboxes, Alerts, and Tables

Dropdown

For a native <select>:

await page.getByLabel(‘Country’)

 .selectOption(‘india’);

Checkbox

await page.getByLabel(‘Accept terms’).check();

await expect(

 page.getByLabel(‘Accept terms’)

).toBeChecked();

Alert

page.on(‘dialog’, async dialog => {

 console.log(dialog.message());

 await dialog.accept();

});

await page.getByRole(‘button’, {

 name: ‘Delete’

}).click();

Table

const rows = page.locator(‘table tbody tr’);

console.log(await rows.count());

const product = rows.filter({

 hasText: ‘Laptop’

});

await expect(product).toContainText(‘Laptop’);

The exact approach depends on how the application’s dropdowns, dialogs, and tables are implemented.


Step 12: Handle Dynamic Web Elements

Dynamic elements are common in modern applications.

Avoid:

await page.waitForTimeout(5000);

Instead, wait for the actual condition:

await expect(

 page.getByText(‘Order created successfully’)

).toBeVisible();

Or:

await page.getByRole(‘button’, {

 name: ‘Submit’

}).click();

await expect(

 page.getByRole(‘heading’, {

   name: ‘Success’

 })

).toBeVisible();

Playwright’s actionability checks and assertions provide built-in waiting behavior. This is one reason beginners should learn Playwright’s locator and assertion model before relying on manual waits.


Step 13: Take Screenshots and Record Videos

You can capture screenshots:

await page.screenshot({

 path: ‘screenshots/homepage.png’,

 fullPage: true

});

For framework-level configuration:

use: {

 screenshot: ‘only-on-failure’,

 video: ‘on-first-retry’

}

Playwright supports screenshot and video recording options such as off, on, only-on-failure, retain-on-failure, and on-first-retry.

For CI, capturing artifacts only when useful can reduce storage requirements.


Step 14: Debug Tests with Playwright Trace Viewer

When a test fails in CI, reproducing the exact failure locally can be difficult.

This is where tracing becomes useful.

Configure:

use: {

 trace: ‘on-first-retry’

}

You can also use:

npx playwright test –debug

Trace Viewer helps investigate browser operations and test execution. Playwright recommends configuring tracing through Playwright Test because the test-runner trace includes more useful information for test debugging than manually tracing browser operations alone.

A typical debugging workflow is:

Test fails

  ↓

Open report

  ↓

Open trace

  ↓

Inspect actions

  ↓

Inspect page state

  ↓

Inspect network/timing

  ↓

Identify failure

  ↓

Fix test/application issue


Step 15: Understand Browser Contexts

A BrowserContext is an isolated browser session.

Think of it as:

Browser

├── Context A

│   └── Page

└── Context B

   └── Page

Contexts can isolate:

  • Cookies
  • Local storage
  • Session state
  • Pages

This is important when multiple tests use different users.

Playwright Test’s built-in fixtures provide isolated page and context objects for tests.


Step 16: Use Playwright Test Fixtures and Hooks

Fixtures provide the environment a test needs.

Example:

import { test } from ‘@playwright/test’;

test.beforeEach(async ({ page }) => {

 await page.goto(‘/login’);

});

test(‘login page validation’, async ({ page }) => {

 await page.getByLabel(‘Username’).fill(‘admin’);

});

Playwright fixtures are designed to establish and tear down test environments and can also be customized with test.extend().

Common hooks include:

test.beforeEach()

test.afterEach()

test.beforeAll()

test.afterAll()

Use hooks for genuine shared setup, not to hide important test behavior.


Step 17: Implement Page Object Model

For a larger framework, create a page class:

import { expect, type Page } from ‘@playwright/test’;

export class LoginPage {

 constructor(private page: Page) {}

 async login(username: string, password: string) {

   await this.page.getByLabel(‘Username’).fill(username);

   await this.page.getByLabel(‘Password’).fill(password);

   await this.page.getByRole(‘button’, {

     name: ‘Login’

   }).click();

 }

 async verifyDashboard() {

   await expect(this.page).toHaveURL(/dashboard/);

 }

}

Then use it in the test:

import { test } from ‘@playwright/test’;

import { LoginPage } from ‘../pages/LoginPage’;

test(‘user login’, async ({ page }) => {

 const loginPage = new LoginPage(page);

 await page.goto(‘/login’);

 await loginPage.login(

   ‘testuser’,

   ‘password123’

 );

 await loginPage.verifyDashboard();

});

POM makes locators and reusable page operations easier to maintain as the test suite grows.


Step 18: Perform API Testing

Playwright can also send API requests.

Example:

import { test, expect } from ‘@playwright/test’;

test(‘GET API validation’, async ({ request }) => {

 const response = await request.get(

   ‘https://api.example.com/users/1’

 );

 expect(response.ok()).toBeTruthy();

 expect(response.status()).toBe(200);

 const body = await response.json();

 expect(body.id).toBe(1);

});

This can support workflows such as:

API → Create user

UI → Login

UI → Perform action

API → Validate backend state

This is especially useful in end-to-end automation.


Step 19: Run Tests in Parallel

Playwright Test supports workers for parallel execution.

For example:

npx playwright test –workers=4

You can also configure workers:

export default defineConfig({

 workers: process.env.CI ? 1 : undefined

});

Playwright’s configuration supports workers, fullyParallel, projects, retries, and other execution controls.

For large CI environments, sharding can distribute tests across multiple CI jobs. Playwright’s CI guidance recommends prioritizing stability and reproducibility and notes that stronger infrastructure can support more parallelism.


Step 20: Generate Test Reports

Playwright includes an HTML reporter.

Run:

npx playwright show-report

The HTML report provides filtering and details for passed, failed, skipped, and flaky tests, along with errors, attachments, and steps.

You can configure multiple reporters:

import { defineConfig } from ‘@playwright/test’;

export default defineConfig({

 reporter: [

   [‘html’, { open: ‘never’ }],

   [‘junit’, {

     outputFile: ‘results/results.xml’

   }]

 ]

});

Playwright also supports built-in reporters including JSON and JUnit.


Step 21: Integrate Playwright with CI/CD

A basic GitHub Actions workflow is:

name: Playwright Tests

on:

 push:

   branches: [main]

 pull_request:

   branches: [main]

jobs:

 test:

   runs-on: ubuntu-latest

   steps:

     – uses: actions/checkout@v6

     – uses: actions/setup-node@v6

       with:

         node-version: lts/*

     – name: Install dependencies

       run: npm ci

     – name: Install Playwright browsers

       run: npx playwright install –with-deps

     – name: Run tests

       run: npx playwright test

     – uses: actions/upload-artifact@v5

       if: ${{ !cancelled() }}

       with:

         name: playwright-report

         path: playwright-report/

The current Playwright CI guidance follows the same basic sequence: install npm dependencies, install browsers and dependencies, run tests, and preserve reports as CI artifacts.

Jenkins

Typical pipeline:

Checkout code

   ↓

npm ci

   ↓

Playwright browser installation

   ↓

npx playwright test

   ↓

Publish reports

Azure DevOps

The same pattern can be implemented using Node setup, npm ci, browser installation, and npx playwright test. Playwright provides an Azure Pipelines example in its CI documentation.

Docker

Playwright provides an official Docker image and documents container-based CI execution.


Real-World Playwright Automation Project

E-Commerce Automation Testing Project

A strong Playwright project example for beginners is an e-commerce application.

Test scenarios

  1. Login
  2. Search product
  3. Open product
  4. Add product to cart
  5. Validate cart
  6. Checkout
  7. Verify order
  8. Run regression tests across browsers

Suggested framework

ecommerce-playwright/

├── tests/

│   ├── login.spec.ts

│   ├── product.spec.ts

│   └── checkout.spec.ts

├── pages/

│   ├── LoginPage.ts

│   ├── ProductPage.ts

│   └── CheckoutPage.ts

├── fixtures/

├── test-data/

├── utils/

├── playwright.config.ts

├── package.json

└── README.md

Add to GitHub

Your README should explain:

This transforms a tutorial exercise into a portfolio project.


Common Errors and Solutions

Error: Browser executable not found

Try:

npx playwright install

For Linux CI environments:

npx playwright install –with-deps

Error: Tests cannot find an element

Check:

  • Locator accuracy
  • Page state
  • Element visibility
  • Frame usage
  • Application timing

Prefer resilient locators instead of immediately adding a fixed wait.

Error: TypeScript errors

Playwright can transform and run TypeScript, but it does not perform full type checking before every test execution. Playwright recommends running TypeScript separately.

Use:

npx tsc -p tsconfig.json –noEmit

Then:

npx playwright test

Error: CI works differently from local

Check:

  • Node.js version
  • Browser installation
  • OS dependencies
  • Environment variables
  • Test data
  • Workers
  • Timeouts

Playwright Best Practices

Follow these principles:

1. Use stable locators

Prefer:

page.getByRole()

page.getByLabel()

page.getByTestId()

2. Avoid unnecessary hard waits

Don’t use waitForTimeout() as your default synchronization method.

3. Keep tests independent

One test should not depend unnecessarily on another test’s execution order.

4. Use POM for larger suites

Centralize page-specific behavior.

5. Use fixtures for reusable setup

Fixtures are better suited to shared test environments than copying setup into every test.

6. Use API testing strategically

API calls can help prepare data and validate backend state.

7. Keep reports useful

Capture traces, screenshots, and videos according to your debugging needs rather than collecting every artifact for every test.

8. Run type checks

Use tsc –noEmit as part of local development and CI.

9. Configure browsers intentionally

Use Playwright projects when your application requires multiple browser engines.


Playwright Interview Questions and Answers

1. What is Playwright?

Playwright is a web automation and end-to-end testing framework supporting Chromium, Firefox, and WebKit.

2. What is a BrowserContext?

It is an isolated browser session that separates browser state such as cookies and storage.

3. What is a Page?

A Page represents a browser tab.

4. What are Playwright fixtures?

Fixtures establish the environment and resources required by tests. Built-in fixtures include page, context, and browser.

5. How does Playwright handle waiting?

It performs actionability checks and provides web-first assertions that wait for conditions rather than requiring arbitrary delays.

6. How do you execute tests in parallel?

Use Playwright workers and, for larger CI environments, consider sharding across jobs.

7. How do you debug a failed Playwright test?

Use the HTML report, Inspector, UI Mode, screenshots, videos, and Trace Viewer.

8. Can Playwright test APIs?

Yes. The Playwright Test framework provides the request fixture and API request capabilities.

9. What is Page Object Model?

It is a design approach that encapsulates page-specific locators and operations into reusable objects.

10. How do you integrate Playwright into CI/CD?

Install dependencies and browsers, run npx playwright test, and publish reports and artifacts.


Playwright Learning Roadmap

If you’re following this Playwright tutorial step by step, use this progression.

Level 1: Beginner

Learn:

  • TypeScript basics
  • Installation
  • Test structure
  • Locators
  • Assertions
  • Navigation
  • Forms
  • Checkboxes
  • Dropdowns

Level 2: Intermediate

Learn:

  • Browser contexts
  • Authentication
  • Fixtures
  • Hooks
  • Page Object Model
  • Test data
  • API testing
  • Reporting

Level 3: Advanced

Learn:

  • Parallel execution
  • CI/CD
  • Docker
  • Network interception
  • Trace analysis
  • Multi-browser projects
  • Framework architecture

Level 4: Career

Build:

  • E-commerce framework
  • API automation suite
  • CI/CD pipeline
  • GitHub portfolio

Then prepare for:


FAQs About Playwright Tutorial Step by Step

What is a Playwright tutorial step by step?

It is a structured learning approach that takes you through Playwright installation, project creation, tests, locators, assertions, framework development, API testing, debugging, reporting, and CI/CD.

How do I get started with Playwright?

Install Node.js and run:

npm init playwright@latest

Then select TypeScript, your test directory, and browser installation options.

Is Playwright difficult for beginners?

The fundamentals are approachable if you already understand basic programming and testing. Start with simple tests before learning framework architecture.

Should beginners learn TypeScript for Playwright?

Yes. TypeScript is a strong choice for maintainable Playwright automation, particularly for larger projects.

Can Playwright run tests across browsers?

Yes. Playwright supports Chromium, Firefox, and WebKit, and projects can be configured for different browser configurations.

Can Playwright be used for API testing?

Yes. Playwright provides API request capabilities that can be combined with browser-based workflows.

Can Playwright run in CI/CD?

Yes. Playwright provides official CI guidance for GitHub Actions, Azure Pipelines, Docker-based execution, and other CI environments.

Is Playwright useful for SDET jobs?

Yes, but professional SDET roles generally require more than a browser automation tool. Combine Playwright with programming, API testing, Git, CI/CD, SQL, Docker, test architecture, and debugging.

Leave a Comment

Your email address will not be published. Required fields are marked *