Playwright Complete Course Tutorial: Learn Playwright Automation with TypeScript

Introduction: Why Learn Playwright in 2026?

Modern web applications are increasingly dynamic, distributed, and dependent on APIs. Traditional UI automation approaches can become difficult to maintain when applications contain asynchronous content, multiple browser engines, responsive layouts, and complex authentication flows.

This is why Playwright Automation Testing has become an important skill for QA Automation Engineers, SDETs, developers, and test engineers.

This playwright complete course tutorial is designed as a practical learning path from beginner concepts to advanced framework development.

You will learn how to install Playwright, write your first TypeScript test, work with locators and assertions, design Page Object Models, use fixtures, perform data-driven testing, authenticate users, test APIs, emulate mobile devices, run tests in parallel, debug failures, generate reports, use Docker, and integrate the framework with CI/CD.

The official Playwright project describes Playwright Test as an end-to-end framework that includes a test runner, assertions, isolation, parallelization, and tooling. It supports Chromium, Firefox, and WebKit, as well as native mobile emulation for selected configurations.


What Is Playwright?

Microsoft Playwright is an open-source browser automation framework for testing modern web applications.

It supports:

  • Chromium
  • Firefox
  • WebKit
  • Windows
  • Linux
  • macOS
  • Mobile browser emulation
  • API testing
  • Screenshots
  • Videos
  • Trace Viewer
  • Parallel execution
  • CI/CD

A simplified architecture is:

                Playwright

                    |

       +————+————+

       |            |            |

   Chromium      Firefox      WebKit

       |            |            |

       +————+————+

                    |

              Web Application

Playwright can also interact with APIs directly through APIRequestContext, which is useful for API testing and for preparing or validating server-side state around UI tests.


Why Learn Playwright for Automation Testing?

A Playwright complete course is valuable because modern QA roles increasingly require more than basic browser scripting.

You should understand:

SkillWhy it matters
PlaywrightBrowser automation
TypeScriptFramework development
POMMaintainability
FixturesReusable setup
API testingEnd-to-end coverage
AuthenticationReal application workflows
CI/CDContinuous testing
DockerConsistent execution
ReportingFailure analysis
Parallel executionFaster regression

Playwright vs Selenium vs Cypress

FeaturePlaywrightSeleniumCypress
ChromiumYesYesYes
FirefoxYesYesYes
WebKitYesLimited/varies by setupNo equivalent native engine
Mobile emulationYesVia browser/device toolingYes, viewport-focused
API testingYesExternal libraries commonly usedYes
Multi-page workflowsStrongStrongDifferent architecture
Auto-waitingBuilt inMore explicit synchronization often neededBuilt in
TypeScriptExcellentAvailableExcellent
Parallel executionBuilt inGrid/setup commonly usedAvailable

The best tool depends on the application and team. Playwright is particularly attractive when teams want cross-browser coverage, API capabilities, isolated browser contexts, modern locators, tracing, and an integrated test runner.


Playwright Installation and Project Setup

The easiest way to start this playwright complete course tutorial is with the official project generator.

npm init playwright@latest

Choose:

TypeScript

tests

Install Playwright browsers

Playwright’s installer creates files such as playwright.config.ts, package.json, and a starter test.

You can verify the installation:

npx playwright –version

Run your tests:

npx playwright test

Open the HTML report:

npx playwright show-report

Playwright also provides UI Mode:

npx playwright test –ui

which is useful for interactive debugging and test development.


First Playwright Test with TypeScript

Create:

tests/homepage.spec.ts

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

test(‘homepage should load successfully’, async ({ page }) => {

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

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

 await expect(

   page.getByRole(‘heading’, {

     name: /Playwright/

   })

 ).toBeVisible();

});

Run:

npx playwright test tests/homepage.spec.ts

The { page } parameter is a built-in Playwright fixture that provides an isolated page for the test.


Playwright Locators, Assertions, and Auto-Waiting

Locators are central to Playwright.

Common locator methods include:

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

page.getByLabel(‘Email’);

page.getByPlaceholder(‘Search’);

page.getByText(‘Products’);

page.getByTestId(‘product-card’);

Example:

await page.getByLabel(‘Email’).fill(‘user@example.com’);

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

await page.getByRole(‘button’, {

 name: ‘Login’

}).click();

Assertions:

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

await expect(

 page.getByText(‘Welcome’)

).toBeVisible();

Why auto-waiting matters

Modern applications frequently render elements asynchronously.

Instead of manually adding:

await page.waitForTimeout(3000);

prefer web-first assertions and locator actions.

For example:

await expect(

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

).toBeVisible();

await page.getByRole(‘button’, {

 name: ‘Checkout’

}).click();

Avoid fixed sleeps whenever possible because they can make tests slower and less reliable.


Playwright Test Runner, Fixtures, Hooks, and Configuration

Playwright Test provides built-in fixtures such as:

  • page
  • context
  • browser
  • request

Fixtures establish the environment required by a test and are isolated between tests.

Example:

test(‘fixture example’, async ({

 page,

 context

}) => {

 await page.goto(‘/’);

 console.log(

   await context.cookies()

 );

});

Hooks

Use hooks for reusable setup:

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

 await page.goto(‘/login’);

});

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

 console.log(‘Test completed’);

});

Configuration

A basic configuration:

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

export default defineConfig({

 testDir: ‘./tests’,

 use: {

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

   screenshot: ‘only-on-failure’,

   trace: ‘retain-on-failure’

 },

 projects: [

   {

     name: ‘chromium’,

     use: {

       …devices[‘Desktop Chrome’]

     }

   }

 ]

});

Keep common configuration in playwright.config.ts instead of duplicating it across tests.


Real-World Playwright Automation Examples

A beginner should practice different types of workflows rather than only writing simple navigation tests.

Login example

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

 await page.goto(‘/login’);

 await page.getByLabel(‘Email’)

   .fill(process.env.TEST_USERNAME!);

 await page.getByLabel(‘Password’)

   .fill(process.env.TEST_PASSWORD!);

 await page.getByRole(‘button’, {

   name: ‘Login’

 }).click();

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

});

Use environment variables instead of hard-coded production credentials.

Registration example

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

 await page.goto(‘/register’);

 await page.getByLabel(‘First name’)

   .fill(‘Test’);

 await page.getByLabel(‘Last name’)

   .fill(‘User’);

 await page.getByLabel(‘Email’)

   .fill(`test-${Date.now()}@example.com`);

 await page.getByLabel(‘Password’)

   .fill(‘TestPassword123!’);

 await page.getByRole(‘button’, {

   name: ‘Register’

 }).click();

 await expect(

   page.getByText(/registration successful/i)

 ).toBeVisible();

});


Forms, Dropdowns, and Dynamic Elements

For a native select:

await page.getByLabel(‘Country’)

 .selectOption(‘IN’);

For a custom dropdown:

await page.getByRole(‘combobox’, {

 name: ‘Country’

}).click();

await page.getByRole(‘option’, {

 name: ‘India’

}).click();

For dynamic content:

await expect(

 page.getByText(‘Order confirmed’)

).toBeVisible();

The goal is to wait for meaningful application state instead of arbitrary time periods.


File Upload and Download

File upload

await page.getByLabel(‘Upload document’)

 .setInputFiles(‘test-data/document.pdf’);

File download

const downloadPromise =

 page.waitForEvent(‘download’);

await page.getByRole(‘button’, {

 name: ‘Download’

}).click();

const download = await downloadPromise;

await download.saveAs(

 ‘downloads/report.pdf’

);

These capabilities are useful for document-management, banking, HR, and e-commerce applications.


Playwright Page Object Model

Page Object Model separates page interaction logic from test scenarios.

Create:

pages/LoginPage.ts

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

export class LoginPage {

 constructor(private page: Page) {}

 private email = this.page.getByLabel(‘Email’);

 private password = this.page.getByLabel(‘Password’);

 private loginButton = this.page.getByRole(

   ‘button’,

   { name: ‘Login’ }

 );

 async open() {

   await this.page.goto(‘/login’);

 }

 async login(

   username: string,

   password: string

 ) {

   await this.email.fill(username);

   await this.password.fill(password);

   await this.loginButton.click();

 }

}

Test:

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

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

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

 const loginPage = new LoginPage(page);

 await loginPage.open();

 await loginPage.login(

   process.env.TEST_USERNAME!,

   process.env.TEST_PASSWORD!

 );

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

});

A good POM framework centralizes locators and reusable actions while keeping test cases readable.


Playwright Data Driven Testing

Data-driven testing allows one test structure to run against multiple datasets.

const users = [

 {

   username: ‘user1@example.com’,

   password: ‘Password123’

 },

 {

   username: ‘user2@example.com’,

   password: ‘Password456’

 }

];

for (const user of users) {

 test(`login – ${user.username}`, async ({ page }) => {

   await page.goto(‘/login’);

   await page.getByLabel(‘Email’)

     .fill(user.username);

   await page.getByLabel(‘Password’)

     .fill(user.password);

   await page.getByRole(‘button’, {

     name: ‘Login’

   }).click();

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

 });

}

For larger frameworks, test data can be stored in:

data/users.json

data/products.json

data/checkout.json

You can also use CSV files or generate data through APIs.


Playwright Authentication and Storage State

Authentication is one of the most important advanced Playwright topics.

Instead of logging in before every test, you can authenticate once and reuse the browser state.

Playwright supports storageState, which can preserve authenticated cookies and other storage information for later tests.

Example setup:

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

setup(‘authenticate’, async ({ page }) => {

 await page.goto(‘/login’);

 await page.getByLabel(‘Email’)

   .fill(process.env.TEST_USERNAME!);

 await page.getByLabel(‘Password’)

   .fill(process.env.TEST_PASSWORD!);

 await page.getByRole(‘button’, {

   name: ‘Login’

 }).click();

 await page.context().storageState({

   path: ‘playwright/.auth/user.json’

 });

});

Then:

use: {

 storageState: ‘playwright/.auth/user.json’

}

Security warning: authentication state files may contain sensitive cookies or headers. Playwright recommends keeping playwright/.auth out of source control.

Add:

playwright/.auth/

.env

to .gitignore.


Playwright API Testing

Playwright is not limited to browser UI automation.

The request fixture can send HTTP requests.

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

test(‘get products API’, async ({ request }) => {

 const response = await request.get(‘/api/products’);

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

 const products = await response.json();

 expect(products.length).toBeGreaterThan(0);

});

You can also create server-side data:

const response = await request.post(‘/api/products’, {

 data: {

   name: ‘Test Laptop’,

   price: 50000

 }

});

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

This enables powerful hybrid testing:

API

Create test data

UI

Perform workflow

API

Validate backend state

Playwright officially supports API requests for testing APIs, preparing server state, and validating postconditions after browser actions.


Playwright End-to-End Testing

End-to-end testing validates a complete business workflow.

For e-commerce:

Login

Search product

Open product

Add to cart

Checkout

Place order

Verify confirmation

Example:

test(‘complete shopping workflow’, async ({ page }) => {

 await page.goto(‘/login’);

 await page.getByLabel(‘Email’)

   .fill(process.env.TEST_USERNAME!);

 await page.getByLabel(‘Password’)

   .fill(process.env.TEST_PASSWORD!);

 await page.getByRole(‘button’, {

   name: ‘Login’

 }).click();

 await page.getByPlaceholder(‘Search’)

   .fill(‘laptop’);

 await page.getByRole(‘button’, {

   name: ‘Search’

 }).click();

 await page.getByText(‘Laptop’)

   .first()

   .click();

 await page.getByRole(‘button’, {

   name: /add to cart/i

 }).click();

 await page.getByRole(‘link’, {

   name: /cart/i

 }).click();

 await expect(

   page.getByText(/laptop/i)

 ).toBeVisible();

});


Playwright Mobile Emulation and Cross-Browser Testing

Playwright supports mobile emulation through device descriptors.

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

export default defineConfig({

 projects: [

   {

     name: ‘Desktop Chrome’,

     use: {

       …devices[‘Desktop Chrome’]

     }

   },

   {

     name: ‘iPhone’,

     use: {

       …devices[‘iPhone 12’]

     }

   },

   {

     name: ‘Android’,

     use: {

       …devices[‘Pixel 5’]

     }

   }

 ]

});

Run a specific project:

npx playwright test –project=iPhone

This lets you validate responsive behavior without maintaining separate test suites.


Playwright Parallel Execution

Parallel execution is important when regression suites become large.

Run with workers:

npx playwright test –workers=4

Playwright isolates tests using browser contexts, helping tests execute independently.

However, parallel execution requires proper test-data isolation.

Avoid:

Test A → modifies same account

Test B → modifies same account

Prefer:

Worker 1 → Account A

Worker 2 → Account B

Worker 3 → Account C

Playwright recommends considering reduced worker counts in CI when stability and reproducibility are more important than maximum throughput.


Screenshots, Videos, Trace Viewer, and Reporting

Configure:

use: {

 screenshot: ‘only-on-failure’,

 video: ‘retain-on-failure’,

 trace: ‘retain-on-failure’

}

Use the HTML reporter:

reporter: [

 [‘html’],

 [‘list’]

]

Run:

npx playwright test

Then:

npx playwright show-report

Trace Viewer is especially useful when a test passes locally but fails in CI.

You can inspect:

  • Actions
  • Screenshots
  • DOM snapshots
  • Network activity
  • Timing
  • Errors

For debugging browser-launch problems, Playwright also supports the DEBUG environment variable, such as DEBUG=pw:browser.


Playwright CI/CD with GitHub Actions

A basic workflow:

name: Playwright Tests

on:

 push:

   branches: [main]

 pull_request:

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: Type check

       run: npx tsc –noEmit

     – name: Install Playwright

       run: npx playwright install –with-deps

     – name: Run tests

       run: npx playwright test

     – name: Upload report

       if: ${{ !cancelled() }}

       uses: actions/upload-artifact@v5

       with:

         name: playwright-report

         path: playwright-report/

Playwright’s current CI guidance uses npm ci, browser installation with –with-deps, test execution, and report artifacts in GitHub Actions.

Type checking should be performed separately because Playwright transforms TypeScript for execution but does not perform complete type checking itself.


Docker and Playwright Automation

Docker provides a consistent environment for browser testing.

A simplified Dockerfile:

FROM mcr.microsoft.com/playwright:v1.62.0-noble

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

CMD [“npx”, “playwright”, “test”]

Build:

docker build -t playwright-tests .

Run:

docker run –rm playwright-tests

Playwright publishes Docker images intended for browser testing in CI environments.

For production frameworks, pin the Playwright version and keep the container version aligned with the package version.


Real-World E-Commerce Playwright Automation Framework Project

A professional portfolio project should contain more than a collection of unrelated scripts.

Use this structure:

ecommerce-playwright/

├── tests/

│   ├── login.spec.ts

│   ├── search.spec.ts

│   ├── product.spec.ts

│   ├── cart.spec.ts

│   ├── checkout.spec.ts

│   └── api.spec.ts

├── pages/

│   ├── LoginPage.ts

│   ├── HomePage.ts

│   ├── ProductPage.ts

│   ├── CartPage.ts

│   └── CheckoutPage.ts

├── fixtures/

│   └── test.fixture.ts

├── data/

│   ├── users.json

│   └── products.json

├── playwright/

│   └── .auth/

├── .github/

│   └── workflows/

│       └── playwright.yml

├── Dockerfile

├── playwright.config.ts

├── package.json

└── README.md

Project functionality

Authentication

Implement:

Product search

Test:

  • Search keyword
  • Search results
  • Filters
  • Sorting

Product details

Test:

  • Product name
  • Price
  • Description
  • Images
  • Add to cart

Shopping cart

Test:

  • Add product
  • Remove product
  • Quantity
  • Total

Checkout

Test:

  • Customer information
  • Shipping
  • Payment
  • Order confirmation

API testing

Use APIs to:

  • Create products
  • Prepare test data
  • Validate orders

Framework features

Add:

  • POM
  • Fixtures
  • Data-driven tests
  • Authentication
  • Cross-browser projects
  • Mobile projects
  • Parallel execution
  • Screenshots
  • Videos
  • Traces
  • HTML reports
  • Docker
  • GitHub Actions

This is a strong Playwright automation framework tutorial project because it demonstrates framework design rather than only individual test scripting.


Common Playwright Errors and Solutions

ErrorLikely causeSolution
Locator not foundWrong locator or page stateInspect locator and use web-first assertions
TimeoutElement never became actionableCheck application state and locator
Browser launch failureMissing dependenciesRun npx playwright install –with-deps
Test passes locally but fails CIEnvironment differenceUse CI artifacts and traces
Authentication failsExpired stateRegenerate storage state
Flaky testsShared state/timingIsolate data and remove sleeps
Download failsEvent not handledWait for download event
Mobile test failsWrong projectCheck device configuration
API test failsWrong endpoint/authVerify request and environment
TypeScript errorsNo type-check stageRun npx tsc –noEmit

Playwright Best Practices

A professional framework should follow these principles.

1. Prefer user-facing locators

Use:

getByRole()

getByLabel()

getByText()

when appropriate.

2. Avoid hard waits

Don’t depend on:

await page.waitForTimeout(5000);

unless there is a specific reason.

3. Use Page Object Model carefully

POM should simplify tests, not become an enormous abstraction layer.

4. Keep test data separate

Use:

JSON

CSV

API-generated data

database fixtures

when appropriate.

5. Protect authentication state

Never commit:

playwright/.auth/

because it can contain sensitive browser state.

6. Make tests independent

A test should ideally be runnable by itself.

7. Use API setup where practical

Creating test data through APIs can be faster than navigating through the UI.

8. Use traces for CI failures

They dramatically reduce debugging time.

9. Run type checking separately

npx tsc –noEmit

10. Keep CI environments reproducible

Pin versions, standardize browsers, and use Docker where appropriate.


Playwright Interview Questions with Answers

1. What is Playwright?

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

2. Why use Playwright instead of Selenium?

Playwright provides built-in auto-waiting, browser contexts, tracing, modern locators, mobile emulation, API capabilities, and an integrated test runner.

Selenium remains widely used and has a mature ecosystem, so the right choice depends on the project’s requirements.

3. What is a browser context?

A BrowserContext is an isolated browser environment. It helps keep tests independent.

4. What are Playwright fixtures?

Fixtures establish the environment needed by tests, such as page, context, or custom resources.

5. What is storageState?

It stores browser authentication state so later tests can reuse authenticated sessions.

6. Can Playwright perform API testing?

Yes. APIRequestContext and the request fixture support HTTP API testing.

7. What is Page Object Model?

POM is a design pattern that encapsulates page locators and actions into reusable classes.

8. How does Playwright handle synchronization?

Playwright automatically waits for many actionability conditions and works well with web-first assertions.

9. Can Playwright run tests in parallel?

Yes. Playwright Test supports parallel execution and multiple workers.

10. How do you debug Playwright failures?

Use:

HTML Report

Trace Viewer

Screenshots

Videos

UI Mode

DEBUG logs

11. How do you run Playwright in CI?

Install dependencies and browsers, execute npx playwright test, and upload reports/artifacts.

12. What should an enterprise Playwright framework contain?

A strong framework may include:

TypeScript + POM + Fixtures + API Testing + Authentication + Data-Driven Testing + Reporting + CI/CD + Docker + Cross-Browser Testing.


Complete Playwright Learning Roadmap for Beginners

If you’re following this playwright complete course tutorial for beginners, don’t try to learn every advanced feature on day one.

Use this sequence.

Level 1: Fundamentals

Learn:

  1. What is Playwright?
  2. Installation
  3. Test structure
  4. Locators
  5. Assertions
  6. Auto-waiting

Level 2: Browser Automation

Practice:

  1. Login
  2. Registration
  3. Forms
  4. Dropdowns
  5. Checkboxes
  6. Radio buttons
  7. File upload
  8. Downloads
  9. Popups
  10. Frames
  11. Multiple tabs

Level 3: Test Framework

Learn:

  1. Fixtures
  2. Hooks
  3. Configuration
  4. Projects
  5. Test tags
  6. Retries
  7. Timeouts
  8. Parallel execution

Level 4: Framework Design

Learn:

  1. TypeScript
  2. Page Object Model
  3. Custom fixtures
  4. Test data
  5. Utilities
  6. Authentication
  7. API setup

Level 5: Advanced Testing

Learn:

  1. API testing
  2. Mobile emulation
  3. Visual testing
  4. Cross-browser testing
  5. Network mocking
  6. Storage state
  7. Parallel execution

Level 6: DevOps

Learn:

  1. Git
  2. GitHub Actions
  3. Docker
  4. CI/CD
  5. Reports
  6. Test artifacts
  7. Debugging failed pipelines

Level 7: Career Preparation

Build a portfolio framework and prepare for:


FAQs: Playwright Complete Course Tutorial

What is Playwright?

Playwright is an automation framework for testing modern web applications across Chromium, Firefox, and WebKit.

How do I get started with Playwright?

Install it with:

npm init playwright@latest

Choose TypeScript and install the browsers.

Is Playwright good for beginners?

Yes. Beginners can start with locators and assertions, then gradually learn fixtures, POM, API testing, authentication, and CI/CD.

Does Playwright support TypeScript?

Yes. Playwright supports TypeScript out of the box. For reliable projects, run a separate TypeScript compiler check in addition to Playwright tests.

Can Playwright test APIs?

Yes. Playwright provides API request capabilities through APIRequestContext.

Can Playwright replace Selenium?

For many modern web automation projects, yes. However, Selenium remains a strong choice for organizations with established Selenium infrastructure, language requirements, or WebDriver-based ecosystems.

Does Playwright support mobile testing?

Yes. Playwright supports mobile browser emulation using device configurations.

Can Playwright run tests in parallel?

Yes. Playwright Test supports parallel workers and project-based execution.

Can Playwright run in Docker?

Yes. Playwright provides official Docker images for browser testing and CI environments.

Is Playwright useful for SDET jobs?

Yes. Combining Playwright with TypeScript, API testing, POM, fixtures, CI/CD, Docker, and reporting provides a strong automation engineering skill set.

Leave a Comment

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