Blogs  

Writing and Running Your First Test with Playwright

Writing and Running Your First Test with Playwright

1. Introduction: The Start of Your Playwright Journey

Testing web applications is essential for modern software development. Whether you’re launching a startup site or managing enterprise-scale systems, automated testing ensures speed and quality.

Playwright, developed by Microsoft, empowers developers to create end-to-end tests that mimic real user interactions like clicking buttons, filling forms, or navigating between pages across all major browsers.

This guide shows you how to write and run your first Playwright test in JavaScript. You’ll learn not just the technical steps but also how Playwright works behind the scenes and why it’s now a preferred framework among QA engineers and developers alike.

2. What Is Playwright?

Playwright is an open-source automation framework that enables web testing across browsers, devices, and operating systems using a single API.

Supported Browsers

  • Chromium (Chrome, Edge)

  • Firefox

  • WebKit (Safari)

Core Capabilities

  • UI and API testing

  • Visual comparison and performance tracking

  • Network interception and mocking

Why Developers Prefer Playwright

  • One API for all browsers

  • Built-in auto-wait to prevent flaky tests

  • Deep network control

  • Parallel and cross-browser execution

  • Integrated test runner and reporting tools

3. Setting Up the Environment

Before writing your first test, prepare your environment.

Prerequisites:

  • Node.js v16 or higher

  • NPM (bundled with Node.js)

  • Code editor (VS Code recommended)

Check installation:

node -v npm -v

If both commands return versions, you’re ready.

4. Installing Playwright

Step 1: Create a project folder

mkdir playwright-demo cd playwright-demo

Step 2: Initialize Node.js

npm init -y

Step 3: Install Playwright

npm install @playwright/test --save-dev

Step 4: Install browsers

npx playwright install

This downloads Chromium, Firefox, and WebKit.

5. Recommended Project Structure

playwright-demo/ ├── tests/ │ └── firstTest.spec.js ├── playwright.config.js ├── package.json └── node_modules/

Purpose of key files:

  • tests/ → Store your test scripts

  • playwright.config.js → Define global settings

  • package.json → Manage dependencies

6. Writing Your First Test

Create tests/firstTest.spec.js:

const { test, expect } = require('@playwright/test');

test('Verify page title and content', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example Domain/);
  const heading = await page.locator('h1');
  await expect(heading).toHaveText('Example Domain');
  const moreInfo = await page.locator('a');
  await moreInfo.click();
  await expect(page).toHaveURL(/iana.org/);
});

This test opens a page, checks the title, validates content, and follows a link replicating real user behavior.

7. Understanding the Code

Code Line Explanation
const { test, expect } = require('@playwright/test') Imports Playwright’s test runner and assertions
page.goto(url) Navigates to the specified URL
expect(page).toHaveTitle() Validates the page title
locator(selector) Locates an element on the page
click() Performs a simulated click
await Ensures sequential, reliable execution

Playwright’s async/await model guarantees stability and accuracy.

8. Running Your First Test

Run in terminal:

npx playwright test

You’ll see output such as:

Running 1 test using 1 worker ✓ tests/firstTest.spec.js (5s)

Playwright launches the browser, runs the steps, and displays results.

9. Headed vs Headless Mode

By default, Playwright runs headless (without a visible browser).

To watch your test:

npx playwright test --headed

This is useful for debugging and demonstrations.

10. Running Tests on Multiple Browsers

Target specific browsers:

npx playwright test --project=chromium npx playwright test --project=firefox npx playwright test --project=webkit

Or run all simultaneously:

npx playwright test --parallel

11. Configuring Playwright

Create a playwright.config.js file:

module.exports = {
  testDir: './tests',
  timeout: 30000,
  retries: 1,
  use: {
    headless: true,
    viewport: { width: 1280, height: 720 },
    screenshot: 'on',
    video: 'on-first-retry'
  },
  projects: [
    { name: 'Chromium', use: { browserName: 'chromium' } },
    { name: 'Firefox', use: { browserName: 'firefox' } },
    { name: 'WebKit', use: { browserName: 'webkit' } }
  ]
};

Now tests automatically run on multiple browsers with consistent settings.

12. How Playwright Executes Tests

Behind the scenes:

  1. Launches a browser engine

  2. Opens a fresh browser context

  3. Creates a new page (tab)

  4. Executes your test commands via the Playwright API

  5. Waits automatically for elements to appear

  6. Closes the browser and reports results

This flow ensures reliability and isolation for each test.

13. Assertions: Validating Outcomes

Common Playwright assertions:

Assertion Purpose
toHaveTitle() Verify page title
toHaveURL() Confirm current URL
toHaveText() Match element text
toBeVisible() Ensure element visibility
toBeEnabled() Validate enabled state

Assertions transform automated steps into meaningful validations.

14. Debugging Playwright Tests

Option 1: Debug Mode

npx playwright test --debug

Option 2: Pause Execution

await page.pause();

Option 3: Generate HTML Report

npx playwright show-report

You can inspect screenshots, logs, and step details visually.

15. Capturing Screenshots and Videos

Add screenshots in your test:

await page.screenshot({ path: 'homepage.png' });

Enable video capture globally:

use: { video: 'on' }

These artifacts are invaluable for troubleshooting.

16. Parallel vs Sequential Execution

  • Parallel: Faster test runs using multiple workers

  • Sequential: One test at a time for controlled execution

Example:

npx playwright test --parallel

Each test runs in its own isolated browser context.

17. Test Hooks for Setup and Teardown

Hooks streamline repetitive actions:

test.beforeEach(async ({ page }) => {
  await page.goto('https://example.com');
});

test.afterEach(async ({ page }) => {
  await page.close();
});

They improve code organization and consistency.

18. Grouping Tests with describe()

test.describe('Login Suite', () => {
  test('Valid login', async ({ page }) => { /* code */ });
  test('Invalid login', async ({ page }) => { /* code */ });
});

Grouping simplifies management of related test cases.

19. Common Beginner Mistakes

Mistake Correction
Using waitForTimeout() Rely on auto-wait instead
Skipping await Always use await
Hardcoding credentials Use environment variables
Forgetting browser cleanup Use hooks
No assertions Always validate results

Following best practices ensures stable, repeatable automation.

20. Real-World Example: Login Automation

test('Valid user login', async ({ page }) => {
  await page.goto('https://example-login.com');
  await page.fill('#username', 'demoUser');
  await page.fill('#password', 'password123');
  await page.click('button[type="submit"]');
  await expect(page).toHaveURL(/dashboard/);
  await expect(page.locator('h1')).toHaveText('Welcome, demoUser');
});

This scenario verifies a successful login and dashboard redirect.

21. Continuous Integration Setup

Example GitHub Actions workflow:

name: Playwright Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npx playwright install
      - run: npx playwright test

Automated CI testing ensures quality with every commit.

22. Advanced Tips for Beginners

  • Use data-test attributes for selectors

  • Organize tests by modules or features

  • Store credentials securely in .env files

  • Run tests headless in CI environments

  • Integrate API testing using Playwright’s network control

23. Summary: Your First Step Toward Reliable Automation

You’ve now written and executed your first Playwright test.
You’ve learned to:

  • Install and configure Playwright

  • Write tests using async/await

  • Debug, capture reports, and integrate CI/CD

These foundations prepare you for advanced concepts like API testing, visual regression, and parallel execution across environments.

Frequently Asked Questions (FAQs)

Q1. What languages does Playwright support?
Ans: JavaScript, TypeScript, Python, Java, and .NET.

Q2. How does it differ from Selenium?
Ans: Playwright uses WebSocket communication, built-in waits, and supports multiple sessions making it faster and more stable.

Q3. Can Playwright emulate mobile browsers?
Ans: Yes, it supports device emulation for iPhone and Android.

Q4. Is it beginner-friendly?
Ans: Absolutely  clean syntax, robust docs, and a built-in test runner make learning straightforward.

Q5. Does Playwright support parallel testing?
Ans: Yes, with isolated browser contexts per test file.

Final Thoughts

Automation isn’t about memorizing commands it’s about mastering interaction. Playwright simplifies automation by bridging human-like browser actions with code precision.

By successfully writing and running your first test, you’ve taken a major step toward mastering modern web automation.

To deepen your understanding, explore [How to Set Up Playwright Software Testing in a JavaScript Project] for configuration essentials and [Playwright Architecture Explained: Browsers, Channels, and Contexts] for insights into how Playwright works under the hood.

Playwright Architecture Explained: Browsers, Channels, and Contexts

Playwright Architecture Explained: Browsers, Channels, and Contexts

1. Introduction: Why Architecture Matters in Automation Testing

Automation testing isn’t just about writing scripts it’s about how efficiently those scripts communicate with browsers. The true power of a framework lies in its architecture, and Playwright sets a new standard with its speed, stability, and scalability.

Developed by Microsoft, Playwright was designed to overcome the limitations of older tools like Selenium such as flaky tests, synchronization problems, and slow browser communication. Its layered design of Browsers, Channels, and Contexts gives it the edge.

This guide explains how Playwright’s architecture works, including:

  • How it communicates with browsers

  • The roles of browser contexts and channels

  • Why it’s faster and more reliable than traditional frameworks

  • How it supports multi-session and cross-browser testing

By the end, you’ll have a solid understanding of how Playwright works internally and how to use that knowledge to build better, more efficient tests.

2. What Makes Playwright Different?

Playwright is not just another browser automation tool it’s a next-generation framework designed for modern web applications.

Key Differentiators:

  • Single API for Chrome, Firefox, and Safari

  • Deep browser control, including cookies and network traffic

  • Isolated test environments with browser contexts

  • Auto-waiting and smart synchronization

  • Built for async JavaScript and parallel execution

These capabilities come from its intelligent client–core–browser architecture.

3. High-Level Architecture Overview

At a high level, Playwright’s architecture consists of three primary layers:

  1. Client Layer (Your Test Code) - Where you write tests using JavaScript, TypeScript, or Python.

  2. Playwright Core Layer - Translates your commands into browser actions and manages communication.

  3. Browser Layer - Executes the commands through active browser channels.

Data Flow:

[Test Script][Playwright Core][Browser Channel][Browser Process]

This layered design ensures both speed and reliability.

4. Layer 1: The Client (Playwright Test Runner)

When writing Playwright tests, you interact with the Client Layer, typically via @playwright/test.

Example:

const { test, expect } = require('@playwright/test');

test('verify title of example.com', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example Domain/);
});

Your code never talks directly to the browser. Instead, it communicates with Playwright Core, which handles browser commands and synchronization.

5. Layer 2: The Playwright Core

The Core Layer acts as the brain of Playwright. It:

  • Translates JavaScript commands into browser protocol messages

  • Manages WebSocket communication between your test and the browser

  • Handles multiple browser sessions simultaneously

  • Applies built-in waiting and synchronization logic

In essence, Playwright Core acts as a translator between your code and the browser engine.

6. Layer 3: The Browser Layer

The Browser Layer interacts directly with browser engines:

  • Chromium → Chrome, Edge

  • WebKit → Safari

  • Gecko → Firefox

Playwright maintains persistent WebSocket connections (channels) with these browsers, enabling real-time, bidirectional communication.

7. Understanding Playwright Channels

A Channel is a communication bridge between Playwright Core and the browser.

How It Works:

  1. When a test starts, Playwright launches the browser.

  2. It establishes a WebSocket channel.

  3. Commands (like click, goto) travel through the channel.

  4. The browser executes and returns responses instantly.

This approach is faster than Selenium’s HTTP-based communication, ensuring stability and speed.

8. Browser Processes and Workers

Each browser launch creates:

  • A main process (the browser)

  • Worker processes (for pages, tabs, and extensions)

Playwright manages these efficiently, ensuring isolation, faster execution, and lower resource consumption.

9. Browser Contexts Explained

A Browser Context is one of Playwright’s most powerful concepts.
It acts like a separate user session with unique cookies, cache, and storage all within the same browser instance.

Example:

const browser = await playwright.chromium.launch();
const context1 = await browser.newContext();
const context2 = await browser.newContext();

Each context is fully isolated, allowing parallel multi-user tests in a single browser.

10. Key Benefits of Browser Contexts

Benefit Description
Isolation Each test runs in a separate session
Performance Shared browser reduces memory usage
Parallelism Multiple contexts execute simultaneously
Efficiency Fewer resources and faster runs

Browser contexts make Playwright ideal for multi-user testing scenarios.

11. The Page Object: Where the Action Happens

Within each context, the Page object represents a tab or window.

Example:

const page = await context.newPage(); await page.goto('https://example.com');

You can click, type, scroll, take screenshots, and more — all within this page object.

12. Frames and Nested Pages

Many modern web apps use iframes. Playwright lets you interact with them effortlessly:

const frame = page.frame({ name: 'login-frame' }); await frame.fill('#username', 'user123');

Each frame behaves like an independent mini-page inside your main page.

13. Event-Driven Design and Auto-Waiting

Playwright listens for browser events such as page loads, navigation, and element visibility.
This allows it to auto-wait executing actions only when elements are ready removing the need for manual delays.

This design drastically reduces flaky test behavior.

14. The Multiprocess Model

Playwright’s architecture separates browser execution, test logic, and communication into multiple processes.

This ensures:

  • Crash isolation between tests

  • Faster parallel execution

  • Enhanced security via sandboxed contexts

It mirrors how modern browsers handle tabs for stability and speed.

15. Playwright vs Selenium Architecture

Feature Selenium Playwright
Protocol HTTP/WebDriver WebSocket
Context Isolation Limited Full
Parallel Execution Moderate Excellent
Auto-Waiting Manual Built-in
Startup Time Slow Fast
Architecture Client-Server Client-Driver

Playwright’s WebSocket-driven model eliminates latency and synchronization problems.

16. Network Control and Interception

Playwright’s architecture allows fine-grained network control.

Example:

await page.route('**/api/*', route => route.fulfill({ status: 200, body: '{"message":"Mocked Response"}' }) );

This enables API mocking, offline testing, and performance measurement without extra tools.

17. Trace Viewer: The Debugging Backbone

Playwright’s Trace Viewer lets you replay tests step-by-step with screenshots, console logs, and network data.

Command:

npx playwright show-trace trace.zip

It’s built into the architecture, making debugging intuitive and visual.

18. Multi-Browser Projects

Playwright supports seamless testing across all major browsers:

const { chromium, firefox, webkit } = require('playwright');

for (const browserType of [chromium, firefox, webkit]) {
  const browser = await browserType.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
}

This is possible due to Playwright’s unified browser channels.

19. Concurrency and Parallel Execution

Playwright uses worker threads to run tests concurrently.
Each file executes in its own process, ensuring thread safety and efficient resource use.

20. Real-World Analogy: The Playwright City

Think of Playwright as a city:

  • The Browser is the city.

  • Each Context is a neighborhood.

  • Each Page is a house.

  • The Channel is the road network connecting them.

This metaphor captures how Playwright maintains order, scale, and communication simultaneously.

21. Advantages of Playwright’s Architecture

Advantage Description
Speed WebSocket-based fast communication
Scalability Multiple contexts in one browser
Stability Isolated processes prevent crashes
Resource Efficiency Shared browser instances
Automation Depth Full access to browser internals

This architecture is designed for modern CI/CD and enterprise-grade automation.

22. The Future of Playwright Architecture

Upcoming advancements include:

  • Component testing for React and Angular

  • Cloud execution for distributed testing

  • AI-driven selector healing

  • Faster startup times and lightweight binaries

The open-source community ensures continuous innovation and scalability.

23. Summary: Why Understanding Architecture Matters

Knowing how Playwright works internally helps you:

  • Write efficient, stable tests

  • Debug faster

  • Optimize test pipelines

  • Scale automation for CI/CD

The architecture’s use of browsers, channels, and contexts is the secret behind Playwright’s unmatched reliability and speed.

Frequently Asked Questions (FAQs)

Q1. What are Playwright channels?
Ans: Channels are WebSocket-based communication bridges between Playwright Core and the browser.

Q2. What is a browser context?
Ans: A browser context is an isolated environment with its own cookies, cache, and session data.

Q3. Can I run multiple contexts in one browser?
Ans: Yes, Playwright supports multiple isolated sessions per browser instance.

Q4. How is Playwright faster than Selenium?
Ans: It uses WebSocket connections instead of HTTP, reducing delays and improving synchronization.

Q5. What browsers does Playwright support?
Ans: Chromium, Firefox, and WebKit covering Chrome, Edge, and Safari.

Q6. Can Playwright mock APIs?
Ans: Yes, through built-in network interception.

Final Thoughts

Playwright’s architecture combines performance, reliability, and simplicity making it one of the most advanced automation frameworks today.

Understanding how Browsers, Channels, and Contexts interact gives you the power to build scalable, maintainable test suites.

To learn how to get started with setup and configuration, explore [How to Set Up Playwright in a JavaScript Project]. For a foundational understanding of browser automation concepts, check out [Introduction to Playwright Automation with JavaScript].

How to Set Up Playwright in a JavaScript Project

How to Set Up Playwright in a JavaScript Project

1. Introduction: Why Playwright Setup Matters

In today’s agile development world, teams need speed and reliability. Automation testing ensures consistent quality while accelerating releases and Playwright stands out as one of the most advanced, developer-friendly frameworks for browser automation.

Created by Microsoft, Playwright automates real user actions like navigation, form filling, clicks, and screenshots. It supports all major browsers Chromium (Chrome/Edge), Firefox, and WebKit (Safari) with a single API.

This guide will help you set up Playwright from scratch in a JavaScript project, covering installation, test writing, configuration, CI/CD integration, and debugging everything you need to start automating confidently.

2. What Is Playwright?

Playwright is an open-source testing library that enables developers to automate browsers using JavaScript or TypeScript. It simplifies cross-browser testing and makes automation faster, more stable, and easier to maintain.

Key Features:

  • Cross-browser support: Chrome, Firefox, Safari, and Edge

  • Auto-waiting for elements to load

  • Parallel test execution

  • Network request interception and mocking

  • Headless and headed modes

  • Mobile device emulation

It integrates seamlessly with Node.js, making it perfect for modern JavaScript projects.

3. Prerequisites for Setting Up Playwright

Before installing Playwright, make sure your environment meets these requirements.

System Requirements

  • Operating System: Windows, macOS, or Linux

  • Node.js Version: 16 or higher

  • NPM: Installed automatically with Node.js

  • IDE: Visual Studio Code or any preferred editor

Verify Installation

Run the following commands in your terminal:

node -v npm -v

If both return valid versions, you’re good to proceed.

4. Creating a New JavaScript Project

Step 1: Create a Folder

mkdir playwright-setup-demo cd playwright-setup-demo

Step 2: Initialize the Project

npm init -y

This creates a package.json file that tracks dependencies and scripts.

5. Installing Playwright

Step 1: Install Playwright

npm install @playwright/test --save-dev

Step 2: Install Browser Binaries

npx playwright install

Step 3: Verify Installation

npx playwright browsers

You’ll see a list of installed browsers like Chromium, Firefox, and WebKit.

6. Setting Up Project Structure

A good structure keeps your tests clean and maintainable.

playwright-setup-demo/ │ ├── tests/ │ ├── example.spec.js │ ├── playwright.config.js ├── package.json └── README.md

Folder Breakdown:

  • tests/ - Test files

  • playwright.config.js - Global test configuration

  • package.json - Project settings and dependencies

  • README.md - Optional documentation

7. Writing Your First Playwright Test

Inside the tests folder, create example.spec.js:

const { test, expect } = require('@playwright/test');

test('Homepage has title and header text', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example Domain/);
  const header = await page.locator('h1');
  await expect(header).toHaveText('Example Domain');
});

Run the test:

npx playwright test

Playwright will launch a browser, navigate to the page, and verify the title.

8. Understanding the Test Script

Command Description
test() Defines an individual test
page Represents a browser tab
goto() Navigates to a page
expect() Asserts a condition
locator() Finds elements on the page

Playwright uses async/await syntax to handle asynchronous browser operations, eliminating timing-related errors.

9. Configuring Playwright

Generate a configuration file automatically:

npx playwright init 

Example:

// playwright.config.js
module.exports = {
  testDir: './tests',
  timeout: 30000,
  retries: 1,
  use: {
    headless: true,
    viewport: { width: 1280, height: 720 },
    screenshot: 'on',
    video: 'on-first-retry'
  },
  projects: [
    { name: 'Chromium', use: { browserName: 'chromium' } },
    { name: 'Firefox', use: { browserName: 'firefox' } },
    { name: 'WebKit', use: { browserName: 'webkit' } }
  ]
};

This configuration allows parallel testing across browsers with screenshots and videos on failure.

10. Running Tests Across Browsers

To run on specific browsers:

npx playwright test --project=chromium
npx playwright test --project=firefox
npx playwright test --project=webkit

npx playwright test --parallel

11. Running in Headed or Headless Mode

Headless (default): Faster, ideal for CI environments.
Headed: Opens the browser for visual testing.

npx playwright test --headed

12. Debugging Playwright Tests

Playwright offers several debugging options.

  • Debug Mode:

    npx playwright test --debug
  • Pause Command:

    await page.pause();
  • Trace Viewer:

    npx playwright show-trace trace.zip

13. Generating Test Reports

Playwright generates an HTML report automatically:

npx playwright show-report

You’ll get visual summaries of test results, including screenshots and logs.

14. Integrating Playwright with CI/CD

Here’s how to run Playwright tests in GitHub Actions:

name: Playwright Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npx playwright install
      - run: npx playwright test

This ensures your tests run automatically after every push.

15. Folder Management and Naming Conventions

Organize your project for scalability:

tests/
├── smoke/
│   └── homepage.spec.js
├── regression/
│   └── login.spec.js
├── integration/
│   └── cart.spec.js
└── utils/
    └── helpers.js

Naming Tips:

  • .spec.js for test files

  • describe() for grouping

  • test() for individual cases

16. Advanced Configurations

  • Environment Variables:
    Store credentials in a .env file:

    LOGIN_URL=https://example.com/login

    Access it:

    require('dotenv').config(); await page.goto(process.env.LOGIN_URL);
  • Command-Line Options:

    npx playwright test --grep "login" npx playwright test --reporter=list
  • Reusable Fixtures:test.beforeEach(async ({ page }) => {
      await page.goto('https://example.com/login');
    });

17. Common Playwright Setup Issues

Problem Cause Solution
playwright command not found Not installed locally Use npx playwright
Browser not launching Missing binaries Run npx playwright install
Random test failure Timing issue Use auto-wait features
Config not found Wrong filename Use playwright.config.js

18. Extending Playwright

You can expand Playwright’s capabilities by integrating it with:

  • Jest or Mocha for flexible reporting

  • Allure for advanced dashboards

  • Docker for containerized runs

  • BrowserStack or LambdaTest for cloud testing

  • API testing through network interception

For additional resources, explore [Introduction to Playwright Automation with JavaScript] and [Understanding the Data Analytics Lifecycle] for related guides.

19. Best Practices for Playwright Setup

  1. Store Playwright configs in version control

  2. Use descriptive test names

  3. Keep reusable selectors in utilities

  4. Avoid hardcoded waits

  5. Categorize tests using tags

  6. Automate report generation after runs

  7. Validate CI/CD compatibility regularly

20. Real-World Example: Login Test

const { test, expect } = require('@playwright/test');

test('Valid login redirects to dashboard', async ({ page }) => {
  await page.goto('https://example.com/login');
  await page.fill('#username', 'demo');
  await page.fill('#password', 'demo123');
  await page.click('button[type="submit"]');
  await expect(page).toHaveURL(/dashboard/);
});

This verifies that valid login credentials redirect users correctly.

21. Summary

A proper Playwright setup ensures smooth automation with fewer errors and faster test runs. Once configured, it scales effortlessly from local Software testing to enterprise-grade CI/CD pipelines.

Benefits of proper setup:

  • Reliable, consistent test runs

  • Minimal flakiness

  • Easier debugging

  • Seamless integration with DevOps pipelines

Mastering Playwright setup is the first step toward building robust, modern, and scalable browser automation frameworks.