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:
- Playwright TypeScript
- Locators
- Assertions
- Auto waiting
- Browser contexts
- Fixtures
- Page Object Model
- API testing
- Screenshots and traces
- Reporting
- Parallel execution
- CI/CD
- Git and GitHub
What Is Playwright?
Playwright is a browser automation and end-to-end testing framework developed for modern web applications.
It supports:
- Chromium
- Firefox
- WebKit
- Desktop browser testing
- Mobile browser emulation
- API testing
- Parallel test execution
- CI/CD execution
The Playwright Test package provides the runner and testing features needed to organize and execute automated tests.
A simplified architecture is:
↓
↓
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
- Test case
- Test scenario
- Assertions
- Regression testing
- Smoke testing
- Functional testing
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:
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
↓
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
- Login
- Search product
- Open product
- Add product to cart
- Validate cart
- Checkout
- Verify order
- 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:
- Project objective
- Technologies
- Installation
- Test execution
- Framework architecture
- Test scenarios
- Browser coverage
- Reporting
- CI/CD
- Future improvements
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:
- Playwright interview questions
- Automation framework questions
- API testing questions
- CI/CD questions
- Debugging scenarios
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.
