Playwright TypeScript Tutorial: Complete 2026 Guide
Complete Playwright TypeScript tutorial for 2026. Setup, first test, locators, fixtures, POM, API testing, parallel execution, and CI/CD integration.

Playwright with TypeScript is the 2026 default for greenfield web testing. This tutorial takes you from zero to a production-ready framework in roughly 60 minutes. For broader context, see our Playwright Complete Guide and the canonical Playwright POM in TypeScript walkthrough.
Why Playwright + TypeScript in 2026?
- Auto-wait — no
Thread.sleepneeded. - Type safety — TypeScript catches errors at compile time.
- Trace Viewer — best-in-class debugging.
- Multi-browser — Chrome, Firefox, WebKit.
- API + UI — same runner, same fixtures.
- Mature ecosystem — 8M+ weekly downloads, 70k+ GitHub stars.
Compare options in Playwright vs Selenium.
Step 1 — Prerequisites
- Node.js 18 LTS or 20 LTS
- VS Code with the Playwright extension
- TypeScript basics — interfaces, types, generics
Step 2 — Project Setup
Create the project
mkdir playwright-demo
cd playwright-demo
npm init -y
npm install --save-dev @playwright/test
npx playwright install --with-deps chromium firefox webkitInstall TypeScript
npm install --save-dev typescript @types/nodeCreate tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022", "DOM"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"outDir": "./dist",
"rootDir": "./tests"
},
"include": ["tests/**/*", "playwright.config.ts"]
}Create playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 4 : undefined,
reporter: [['html'], ['list']],
use: {
baseURL: 'https://staging.example.com',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
});If you're brand new to Playwright, our Playwright installation guide walks through every flag.
Step 3 — Your First Test
Create tests/login.spec.ts:
import { test, expect } from '@playwright/test';
test.describe('Login flow', () => {
test('successful login redirects to dashboard', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('admin@example.com');
await page.getByLabel('Password').fill('Sup3rSecret!');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/\/dashboard$/);
await expect(page.getByRole('heading', { name: /welcome/i })).toBeVisible();
});
test('invalid credentials shows error', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('admin@example.com');
await page.getByLabel('Password').fill('wrong-password');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByRole('alert')).toContainText('Invalid credentials');
});
});Run the test
npx playwright test --project=chromium --headedYou'll see the browser open, navigate to the app, fill in the form, and verify the result.
Step 4 — Page Object Model
Create tests/pages/login-page.ts:
import { Page, Locator, expect } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailField: Locator;
readonly passwordField: Locator;
readonly submitButton: Locator;
readonly errorMessage: Locator;
constructor(page: Page) {
this.page = page;
this.emailField = page.getByLabel('Email');
this.passwordField = page.getByLabel('Password');
this.submitButton = page.getByRole('button', { name: 'Sign in' });
this.errorMessage = page.getByRole('alert');
}
async goto() { await this.page.goto('/login'); }
async loginAs(email: string, password: string) {
await this.emailField.fill(email);
await this.passwordField.fill(password);
await this.submitButton.click();
}
async expectError(text: string) {
await expect(this.errorMessage).toContainText(text);
}
}Use the page object in your test:
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/login-page';
test('login with valid credentials', async ({ page }) => {
const login = new LoginPage(page);
await login.goto();
await login.loginAs('admin@example.com', 'Sup3rSecret!');
await expect(page).toHaveURL(/\/dashboard$/);
});For the full pattern (base page, component POM, return-typed actions), see our Playwright Page Object Model TypeScript guide.
Step 5 — Fixtures for Cleaner Tests
Create tests/fixtures.ts:
import { test as base } from '@playwright/test';
import { LoginPage } from './pages/login-page';
type Fixtures = { loginPage: LoginPage };
export const test = base.extend<Fixtures>({
loginPage: async ({ page }, use) => {
await use(new LoginPage(page));
},
});
export { expect } from '@playwright/test';Now tests are even cleaner:
import { test, expect } from './fixtures';
test('login flow', async ({ loginPage, page }) => {
await loginPage.goto();
await loginPage.loginAs('admin@example.com', 'Sup3rSecret!');
await expect(page).toHaveURL(/\/dashboard$/);
});Step 6 — API Testing with Playwright
test('login API returns token', async ({ request }) => {
const response = await request.post('https://api.example.com/auth/login', {
data: {
email: 'admin@example.com',
password: 'Sup3rSecret!',
},
});
expect(response.status()).toBe(200);
const body = await response.json();
expect(body.token).toMatch(/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+$/);
});For deeper API coverage, see our Postman API Testing Tutorial.
Step 7 — CI/CD Integration
GitHub Actions
Create .github/workflows/playwright.yml:
name: Playwright Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/For a deeper CI pipeline reference, read GitHub Actions for Selenium CI — the same workflow patterns apply to Playwright.
Step 8 — Debugging with Trace Viewer
When a test fails, Playwright captures a trace. View it:
npx playwright show-trace trace.zipThe Trace Viewer shows DOM snapshots at every step, network requests with bodies, console logs, and an action timeline. This is the fastest way to debug flaky tests. See the official Trace Viewer docs.
Best Practices
Do
- Use role-based locators (
getByRole,getByLabel) - Use TypeScript for type safety
- Build POM from day one
- Use fixtures for clean test code
- Combine API + UI tests in one runner
- Enable traces for debugging
Don't
- Don't use arbitrary
waitForTimeout— rely on auto-wait - Don't share state across tests
- Don't ignore traces — debug every flake
- Don't use XPath unless necessary
Common Playwright TypeScript Patterns
Pattern 1 — expect with retries
await expect(page.getByText('Welcome')).toBeVisible({ timeout: 10000 });Pattern 2 — Group related tests
test.describe('User authentication', () => {
test.beforeEach(async ({ page }) => { await page.goto('/login'); });
test('valid login', async ({ page }) => { /* ... */ });
test('invalid login', async ({ page }) => { /* ... */ });
});Pattern 3 — Soft assertions
test('check multiple things', async ({ page }) => {
await expect.soft(page.getByTestId('header')).toBeVisible();
await expect.soft(page.getByTestId('footer')).toBeVisible();
});Pattern 4 — Skip tests conditionally
test('mobile-only test', async ({ page, isMobile }) => {
test.skip(!isMobile, 'Mobile only');
});Pattern 5 — Test annotations
test('critical path @smoke', { tag: '@smoke' }, async ({ page }) => {
// ...
});
// npx playwright test --grep "@smoke"Keep Learning
Once your TypeScript foundation is solid, scale up with our Playwright framework setup with TypeScript, then prep with Playwright interview questions and our AI mock interview.
Frequently asked questions
1.Is Playwright with TypeScript better than JavaScript?
2.How long does it take to learn Playwright TypeScript?
3.Can I use Playwright with other languages?
4.How do I debug a failing Playwright test?
5.What's the best IDE for Playwright TypeScript?
6.How do I run Playwright tests in parallel?
Practice these questions
Drill 200+ Playwright questions with senior-SDET sample answers — locators, auto-wait, fixtures, parallelism and trace viewer.
Was this article helpful?
More from Playwright TypeScript
Playwright with TypeScript — POM, fixtures, locators.
- Automation TestingPlaywright Locator Best Practices (2026) — The Only Guide You Need
- Automation TestingPlaywright Framework Setup with TypeScript: Complete 2026 Guide for QA Engineers
- Automation TestingPlaywright Locators: Complete 2026 Guide
Keep building your QA edge
Pillar guides- Selenium Pillarthe full Selenium reference300 Selenium WebDriver Q&A — locators, waits, frameworks.
- Playwright Installation Guidehow to install Playwright step by stepInstall Playwright the right way — Node, browsers, VS Code, first test.
- XPath & CSS Selector GeneratorSoftwareTestPilot's selector generatorInteractive locator generator for Playwright, Selenium and Cypress — with Page Object export.
- Automation QA Engineer RoleAutomation QA Engineer roleAutomation QA Engineer job scope, tools, salary, and hiring pipeline.
- QA Skills Hubstructured learning tracks for testersStructured skill tracks — Selenium, Playwright, Cypress, API, JMeter, SQL, Java, Python for testers.
- QA & Testing GlossarySoftwareTestPilot's QA glossary500+ software testing terms defined — from ISTQB vocabulary to CI/CD, AI testing, and framework jargon.
Practice these questions live
Rehearse with an AI QA interviewer that scores your answers in real time.
Continue reading

Playwright Locator Best Practices (2026) — The Only Guide You Need
11 min read
How to Migrate a Postman Collection to Playwright API Tests (2026 Guide)
12 min read
Why Every QA Engineer Must Master CI/CD Pipelines in 2026 (Or Risk Obsolescence)
12 min readRelated concepts, tools & standards around Automation Testing
A quick reference of the people, companies, frameworks and technologies most often mentioned alongside Automation Testing in real QA teams — useful when you're mapping a learning path, preparing for interviews, or scoping a new project.
Join the QA Community
Connect with fellow testers, share job leads, and get career advice.
Discussion
Ask a question, share your experience, or correct us. Be kind — real people are reading.