Test Automation

50 Playwright Commands Every QA Engineer Should Know

Master the 50 most important Playwright commands with syntax, TypeScript examples, parameters, and enterprise use cases for modern QA engineers.

77 min read
50 Playwright Commands Every QA Engineer Should Know
Advertisement
What You Will Learn
Introduction
Why Automation Testing Has Evolved
Challenges of Modern Web Applications
Why Playwright Was Created
⚡ Quick Answer
This guide covers 50 essential Playwright commands that empower QA Engineers and SDETs to build modern browser automation solutions. It explains the engineering principles and provides practical examples for creating reliable and scalable tests.

Introduction

Software testing has undergone a remarkable transformation over the past two decades. The era of manually validating web pages and writing simple automation scripts has evolved into a sophisticated discipline known as Quality Engineering (QE). Today’s QA Engineers are expected to deliver reliable software at an unprecedented speed while supporting Agile development, DevOps practices, Continuous Integration/Continuous Deployment (CI/CD), cloud-native applications, and AI-assisted software development.

Modern organizations release software multiple times a day instead of a few times a year. Every deployment introduces new features, bug fixes, security enhancements, and infrastructure changes. This rapid pace makes manual testing alone insufficient for maintaining software quality. Automated testing has become a critical pillar of modern software delivery, enabling teams to validate functionality, detect regressions early, and release updates with confidence.

However, simply writing automated tests is no longer enough. Enterprise automation frameworks must be scalable, maintainable, readable, and resilient against constant application changes. This is where Playwright has emerged as one of the most influential browser automation frameworks available today.

Playwright is more than another testing tool—it represents a modern philosophy for browser automation. Instead of forcing engineers to solve synchronization problems manually, Playwright intelligently handles browser interactions, automatically waits for elements to become actionable, supports multiple browsers from a unified API, and provides powerful debugging capabilities. These innovations enable QA Engineers to focus on validating business functionality rather than fighting unstable automation scripts.

This comprehensive guide has been designed to help you master the 50 most essential Playwright commands that every QA Engineer, SDET, Automation Architect, and software testing professional should know. Rather than merely introducing APIs, it explains the engineering principles behind each command, demonstrates practical enterprise use cases, and provides production-ready TypeScript examples that can be applied immediately in real-world automation projects.

Whether you are beginning your Playwright journey, migrating from Selenium, or refining an existing automation framework, this guide will help you develop the technical confidence required to build reliable, maintainable, and scalable browser automation solutions.

Why Automation Testing Has Evolved

Automation testing has always existed to solve one fundamental challenge: delivering high-quality software efficiently. Yet the nature of software itself has changed dramatically, requiring automation frameworks to evolve alongside it.

Early web applications consisted primarily of static HTML pages generated by servers. Browser interactions were relatively predictable, and automation scripts could easily locate elements using IDs, names, or simple XPath expressions. Selenium became the industry standard because it provided a consistent way to control browsers through the WebDriver protocol.

Today’s applications are fundamentally different.

Modern front-end frameworks such as React, Angular, Vue, Svelte, and Next.js continuously modify the user interface without refreshing the page. Components are rendered dynamically, content loads asynchronously through APIs, and user interactions trigger complex JavaScript execution behind the scenes. Features such as lazy loading, infinite scrolling, virtual DOM updates, client-side routing, WebSockets, and real-time notifications have become standard.

As a result, browser automation has become significantly more challenging.

QA Engineers are no longer testing static pages—they are validating highly dynamic digital experiences where timing, synchronization, and browser behavior play a critical role. Traditional automation approaches often require explicit waits, complex synchronization logic, fragile locators, and extensive maintenance to keep tests reliable.

The evolution of automation testing reflects the evolution of software engineering itself. Modern frameworks must now provide:

Intelligent Synchronization

Automation tools should understand when applications are ready for interaction instead of relying on fixed delays or manual waiting mechanisms.

Reliable Cross-Browser Testing

Applications must behave consistently across Chromium, Firefox, and WebKit while maintaining high execution stability.

Seamless CI/CD Integration

Automation should fit naturally into continuous testing pipelines, enabling rapid feedback for developers after every code change.

Scalable Parallel Execution

Large enterprise test suites should execute efficiently across multiple browsers and environments without unnecessary complexity.

Enhanced Debugging Capabilities

When failures occur, engineers require comprehensive diagnostics including screenshots, videos, execution traces, network logs, and browser state information.

Playwright addresses each of these requirements through its modern architecture, enabling QA teams to create automation frameworks that remain stable even as applications evolve.

Challenges of Modern Web Applications

Understanding why Playwright is valuable begins with understanding the challenges presented by contemporary web applications.

Unlike traditional websites, modern applications behave almost like desktop software running inside the browser. They continuously communicate with backend services, update user interfaces dynamically, and execute significant amounts of client-side JavaScript.

These characteristics introduce several automation challenges.

Dynamic User Interfaces

Elements frequently appear, disappear, or change position based on user interactions, API responses, or background processing. Tests that depend on static page structures often become unreliable.

Asynchronous Rendering

Many frameworks render components only after receiving asynchronous data. Automation scripts that interact with elements before rendering completes can fail unpredictably.

Single Page Applications (SPAs)

Modern applications frequently navigate between views without performing full page reloads. Traditional navigation assumptions no longer apply, requiring smarter automation strategies.

Frequent UI Changes

Development teams continuously improve interfaces, rename CSS classes, restructure components, and redesign layouts. Automation frameworks relying on implementation-specific selectors require constant maintenance.

Distributed Architectures

Applications communicate with multiple backend services, third-party APIs, authentication providers, analytics platforms, and microservices. Effective testing requires visibility into these interactions.

Increased Release Velocity

Organizations deploying multiple times per day cannot afford unstable or flaky automation suites that generate false failures and delay releases.

These realities demand an automation framework that understands modern browser behavior rather than simply controlling browser actions.

Why Playwright Was Created

Playwright was developed by Microsoft to address the limitations experienced by automation engineers working with increasingly complex web applications.

Rather than extending older automation models, the Playwright team designed a framework around modern browser capabilities and developer expectations. The objective was clear: create an automation platform that delivers reliability, simplicity, and enterprise scalability without requiring engineers to write excessive synchronization code.

Several core design principles influenced Playwright’s creation.

Built-In Browser Intelligence

Playwright automatically verifies that elements are visible, enabled, stable, attached to the DOM, and capable of receiving user interactions before performing actions. These actionability checks significantly reduce flaky tests.

Unified Cross-Browser Automation

Instead of maintaining different automation strategies for different browsers, engineers can execute the same test suite across Chromium, Firefox, and WebKit using a consistent API.

Modern Developer Experience

Playwright embraces asynchronous programming, TypeScript support, rich debugging tools, and developer-friendly APIs that integrate naturally into contemporary software engineering workflows.

First-Class Testing Capabilities

Beyond browser automation, Playwright includes features such as API testing, network interception, authentication state management, trace recording, video capture, mobile emulation, geolocation simulation, and accessibility-focused locators.

These capabilities transform Playwright from a browser automation library into a comprehensive quality engineering platform suitable for enterprise environments.

Why This Guide Is Different from the Official Documentation

The official Playwright documentation is an outstanding technical reference. It accurately explains APIs, provides concise examples, and serves as the authoritative source for framework behavior.

However, documentation and practical engineering guidance serve different purposes.

Documentation typically answers questions such as:

  • What does this command do?
  • What parameters does it accept?
  • What value does it return?
  • How should the syntax be written?

Professional QA Engineers often require additional context.

They need to understand:

  • Why should this command be used instead of another?
  • Which approach scales best in enterprise projects?
  • What mistakes commonly cause flaky tests?
  • How does this command compare with Selenium?
  • What performance considerations should influence implementation?
  • How should this API be integrated into Page Object Models and automation frameworks?
  • What interview questions are associated with this topic?
  • How do experienced SDETs use this command in production environments?

This guide focuses on those practical engineering questions.

Every major command discussed throughout this series will include detailed explanations, production-ready TypeScript examples, enterprise scenarios, best practices, performance recommendations, migration guidance, common pitfalls, and interview insights. The objective is not simply to teach syntax—it is to help you think like an experienced automation engineer.

Why QA Engineers Should Master Playwright Commands

Learning individual commands is easy. Mastering how those commands work together to create reliable automation is what differentiates exceptional QA Engineers from average automation testers.

Playwright commands form the foundation of every successful automation framework. They control browser sessions, manage isolated contexts, interact with user interfaces, validate application behavior, intercept network traffic, execute JavaScript, capture diagnostics, and integrate seamlessly into enterprise CI/CD pipelines.

Engineers who understand these commands deeply gain several advantages.

Build Stable Automation Frameworks

Intelligent command selection reduces flaky tests, improves maintainability, and minimizes long-term framework maintenance.

Improve Test Execution Speed

Playwright’s efficient architecture and built-in parallelism enable organizations to execute large automation suites significantly faster than many traditional approaches.

Strengthen Enterprise Automation Skills

Understanding browser contexts, advanced locators, tracing, API testing, and network interception prepares engineers for complex enterprise projects rather than basic demonstrations.

Increase Career Opportunities

Playwright expertise is increasingly requested in QA, SDET, automation engineering, and software quality roles. Mastery of modern browser automation technologies strengthens technical profiles and improves long-term career growth.

Future-Proof Your Automation Knowledge

As organizations continue modernizing testing strategies, Playwright adoption continues to grow across startups, technology companies, financial institutions, healthcare platforms, retail businesses, and large enterprise organizations. Learning Playwright today equips QA professionals with skills that remain relevant as browser automation continues to evolve.

By the end of this guide, you will understand not only how to use Playwright commands but also why experienced automation engineers rely on them to build robust, scalable, and production-ready test automation frameworks.

What is Playwright?

Playwright is a modern, open-source end-to-end (E2E) automation framework developed by Microsoft for testing and automating web applications across multiple browsers. It enables QA Engineers, Software Development Engineers in Test (SDETs), developers, and automation architects to interact with web applications just as real users do—clicking buttons, filling forms, uploading files, intercepting network requests, validating APIs, handling authentication, and much more.

Playwright Command Ecosystem
Playwright Command Ecosystem

Unlike traditional browser automation tools that rely heavily on external drivers or manual synchronization, Playwright communicates directly with modern browser engines through their native automation protocols. This architectural approach allows Playwright to provide faster execution, intelligent auto-waiting, superior browser stability, and highly reliable cross-browser automation.

Playwright was designed for the modern web. Today’s applications are powered by technologies such as React, Angular, Vue.js, Svelte, Next.js, Nuxt, Remix, Astro, and numerous client-side JavaScript frameworks. These applications dynamically render components, fetch data asynchronously, and update the DOM without full page refreshes. Playwright understands these behaviors and provides built-in mechanisms to interact with them reliably, significantly reducing flaky tests and maintenance overhead.

Another defining characteristic of Playwright is its unified developer experience. Instead of learning different APIs for different browsers, engineers write a single automation script that executes consistently across Chromium, Firefox, and WebKit. This consistency simplifies cross-browser testing while ensuring applications behave correctly for users regardless of their browser choice.

More importantly, Playwright is not just a browser automation library—it is a complete testing ecosystem. It includes browser automation, API testing, network interception, authentication management, mobile emulation, tracing, debugging, screenshots, video recording, parallel execution, accessibility-friendly locators, and seamless CI/CD integration.

For modern Quality Engineering teams, Playwright has become a comprehensive platform rather than merely another testing framework.

Playwright Commands: Browser & Context Commands

Every Playwright test starts by creating a browser session. Before interacting with buttons, forms, or APIs, Playwright must launch a browser and prepare an isolated environment for the test. Browser and Context commands are the foundation of every automation framework, whether you’re running a simple login test or a large-scale regression suite with thousands of test cases.

Command 1: chromium.launch()

What it does

The chromium.launch() command launches a new Chromium browser instance. Chromium is the open-source browser engine that powers Google Chrome, Microsoft Edge, Brave, Opera, and many other modern browsers.

Most Playwright projects use Chromium as the default browser because it closely represents the browsing environment used by the majority of internet users. Once the browser is launched, Playwright can create browser contexts and pages to perform automated interactions.

This command is typically the first executable statement in a Playwright test when manually managing browser instances.

Syntax

const browser = await chromium.launch(options);

Parameters

ParameterTypeRequiredDescription
optionsLaunchOptionsNoOptional configuration used to control browser startup.

Some frequently used launch options are:

OptionDescription
headlessRuns the browser without opening a visible window.
channelLaunches a specific browser channel such as Chrome or Edge.
slowMoAdds a delay between Playwright actions for debugging.
timeoutMaximum time allowed for launching the browser.
argsPasses additional Chromium command-line arguments.
executablePathLaunches a custom Chromium executable instead of the bundled browser.

TypeScript Example

import { chromium } from '@playwright/test';

async function launchBrowser() {
    const browser = await chromium.launch({
        headless: false
    });

    const page = await browser.newPage();

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

    console.log(await page.title());

    await browser.close();
}

launchBrowser();

Enterprise Use Case

Imagine an online banking application where every code commit triggers a regression pipeline. The automation framework launches a Chromium browser, authenticates users with different roles, validates account balances, performs fund transfers, verifies transaction history, and generates execution reports.

Since most customers access the banking portal using Chromium-based browsers, QA teams execute the majority of smoke, regression, and sanity suites using chromium.launch() before extending validation to Firefox and WebKit.

Command 2: firefox.launch()

What it does

The firefox.launch() command starts a Mozilla Firefox browser instance. It enables QA engineers to execute the same Playwright tests on Firefox without modifying the automation code.

Cross-browser compatibility is a critical quality requirement for enterprise applications. Rendering engines differ between browsers, and subtle variations in JavaScript execution, CSS rendering, fonts, scrolling behavior, or accessibility implementation can introduce browser-specific defects. Running tests with Firefox helps identify these issues before software reaches production.

Syntax

const browser = await firefox.launch(options);

Parameters

ParameterTypeRequiredDescription
optionsLaunchOptionsNoOptional browser launch configuration.

Commonly used options include:

OptionDescription
headlessExecutes Firefox in headless mode.
slowMoSlows execution to simplify debugging.
timeoutMaximum time allowed for browser startup.
firefoxUserPrefsApplies custom Firefox preferences during launch.
executablePathUses a custom Firefox installation.

TypeScript Example

import { firefox } from '@playwright/test';

async function launchFirefox() {

    const browser = await firefox.launch({
        headless: true
    });

    const page = await browser.newPage();

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

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

    await browser.close();
}

launchFirefox();

Enterprise Use Case

A healthcare platform is used by hospitals, clinics, and insurance providers across different regions. While most users rely on Chromium-based browsers, a significant percentage of medical staff use Firefox due to organizational policies.

The QA team includes Firefox execution in every nightly regression suite to verify appointment scheduling, electronic health records, billing workflows, and patient dashboards. By using firefox.launch(), the same automation framework validates functionality across multiple browser engines, ensuring a consistent experience for all users regardless of their browser choice.

Command 3: webkit.launch()

What it does

The webkit.launch() command launches a new WebKit browser instance. WebKit is the browser engine behind Apple’s Safari browser and is used on macOS, iOS, and iPadOS.

While Chromium dominates the browser market, many enterprise applications still have a significant percentage of Safari users. Running automated tests on WebKit helps ensure that layouts, JavaScript execution, CSS rendering, animations, and user interactions behave consistently for Apple users.

Playwright’s WebKit implementation allows QA engineers to validate Safari compatibility using the same automation framework and test scripts, reducing the need to maintain separate browser-specific automation suites.

Syntax

const browser = await webkit.launch(options);

Parameters

ParameterTypeRequiredDescription
optionsLaunchOptionsNoOptional configuration used to customize browser startup.

Commonly used launch options:

OptionDescription
headlessRuns WebKit without displaying the browser window.
slowMoAdds a delay between Playwright actions.
timeoutMaximum time allowed for launching the browser.
executablePathLaunches a custom WebKit executable.

TypeScript Example

import { webkit } from '@playwright/test';

async function launchWebKit() {
    const browser = await webkit.launch({
        headless: true
    });

    const page = await browser.newPage();

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

    console.log(await page.title());

    await browser.close();
}

launchWebKit();

Enterprise Use Case

Consider an airline booking platform where thousands of customers book flights using Safari on MacBooks, iPhones, and iPads. Before every production deployment, the QA team executes the complete regression suite on WebKit to validate flight search, seat selection, payment processing, boarding pass generation, and booking confirmation pages.

Using webkit.launch() helps identify Safari-specific compatibility issues early, ensuring a consistent booking experience across Apple devices.

Browser Launch Comparison

Browser CommandBrowser EngineCommon Usage
chromium.launch()ChromiumChrome, Edge, Brave, Opera testing
firefox.launch()GeckoFirefox compatibility testing
webkit.launch()WebKitSafari compatibility testing

Although the commands are nearly identical, each launches a different browser engine, allowing the same Playwright test suite to provide comprehensive cross-browser coverage.

Command 4: browser.newContext()

What it does

The browser.newContext() command creates a new Browser Context inside an existing browser instance. A Browser Context is an isolated browser session with its own cookies, local storage, session storage, permissions, cache, and authentication state.

Instead of launching a completely new browser for every test, Playwright recommends creating multiple browser contexts. This approach is faster, consumes fewer system resources, and enables parallel execution while keeping each test independent.

Think of a Browser Context as a brand-new browser profile. Two contexts running inside the same browser cannot access each other’s cookies, sessions, or stored data.

Syntax

const context = await browser.newContext(options);

Parameters

ParameterTypeRequiredDescription
optionsBrowserContextOptionsNoConfigures the browser context before it is created.

Frequently used context options:

OptionDescription
viewportSets the browser window dimensions.
localeDefines the browser language.
timezoneIdSimulates different geographic time zones.
geolocationSets a virtual GPS location.
permissionsGrants browser permissions such as camera or notifications.
storageStateLoads previously saved authentication data.
colorSchemeSimulates light or dark mode.
userAgentUses a custom browser user agent string.

TypeScript Example

import { chromium } from '@playwright/test';

async function createContext() {

    const browser = await chromium.launch();

    const context = await browser.newContext({
        viewport: {
            width: 1440,
            height: 900
        },
        locale: 'en-US'
    });

    const page = await context.newPage();

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

    await browser.close();
}

createContext();

Enterprise Use Case

Imagine an online marketplace where one automated scenario requires both a buyer and a seller.

Instead of launching two browsers, the automation framework creates two independent browser contexts:

  • Buyer Context
  • Seller Context

Each context maintains its own authentication session, allowing both users to interact with the application simultaneously without affecting each other’s data.

Chromium Browser
       │
       ├───────────────┐
       │               │
       ▼               ▼
Buyer Context     Seller Context
       │               │
       ▼               ▼
 Buyer Page       Seller Page

This architecture enables QA teams to automate real-world collaboration scenarios such as order placement, approval workflows, live chat, inventory updates, and administrative actions efficiently.

Command 5: context.newPage()

What it does

The context.newPage() command creates a new browser tab (Page) inside an existing Browser Context. Every interaction in Playwright—such as navigating to a website, clicking buttons, filling forms, uploading files, or validating content—is performed on a Page object.

A Browser Context can contain one or more pages, making it possible to automate scenarios involving multiple tabs or windows while maintaining the same user session.

Unlike browser.newPage(), which creates a page using a default context, context.newPage() ensures that the page inherits all the settings, permissions, authentication state, cookies, and configurations defined for that specific Browser Context. This makes it the recommended approach for enterprise automation.

Syntax

const page = await context.newPage();

Parameters

The context.newPage() command does not accept any parameters. It creates a new page using the configuration of its parent Browser Context.

TypeScript Example

import { chromium } from '@playwright/test';

async function openNewPage() {

    const browser = await chromium.launch();

    const context = await browser.newContext();

    const page = await context.newPage();

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

    console.log(await page.title());

    await browser.close();
}

openNewPage();

Enterprise Use Case

Suppose you’re testing an HR Management System. An HR administrator logs into the application and opens employee records in separate browser tabs to compare payroll information.

Using context.newPage(), the automation framework can create multiple tabs within the same authenticated session.

Browser Context
       │
       ├──────────────┐
       │              │
       ▼              ▼
Employee Tab     Payroll Tab
       │              │
       ▼              ▼
Compare Records  Update Salary

Because both pages belong to the same Browser Context, they share authentication, cookies, and local storage, accurately simulating real user behavior.

Command 6: browser.close()

What it does

The browser.close() command closes the entire browser instance and releases all associated resources.

When this command executes, Playwright terminates every Browser Context and Page created within that browser. This marks the end of the automation session.

Closing the browser is essential to ensure that memory, CPU resources, and browser processes are properly released after test execution. It is commonly placed in test teardown logic or executed automatically by the Playwright Test Runner.

Syntax

await browser.close();

Parameters

The browser.close() command does not require any parameters.

TypeScript Example

import { chromium } from '@playwright/test';

async function browserLifecycle() {

    const browser = await chromium.launch();

    const context = await browser.newContext();

    const page = await context.newPage();

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

    console.log("Test completed.");

    await browser.close();
}

browserLifecycle();

Enterprise Use Case

A SaaS company’s CI/CD pipeline executes more than 3,000 automated Playwright tests every night.

Each test suite launches a browser, creates isolated Browser Contexts, executes test scenarios, generates reports, and finally calls browser.close().

This ensures that every pipeline starts with a clean browser environment and prevents orphan browser processes from consuming build server resources.

Browser Lifecycle

Launch Browser
       │
       ▼
Create Context
       │
       ▼
Create Page
       │
       ▼
Execute Tests
       │
       ▼
Generate Report
       │
       ▼
browser.close()
       │
       ▼
Browser Process Ends

browser.close() vs context.close()

Featurebrowser.close()context.close()
Closes Browser
Closes Browser ContextsOnly the selected context
Closes PagesOnly pages in that context
Ends Browser Process
Typical UsageEnd of complete test executionClean up a single user session

Command 7: context.close()

What it does

The context.close() command closes a specific Browser Context while keeping the browser instance running. Since a Browser Context represents an isolated browser session, closing it removes all associated pages, cookies, local storage, session storage, cache, and permissions belonging to that session.

Unlike browser.close(), this command does not terminate the entire browser. It only cleans up the selected Browser Context, making it particularly useful when multiple users or sessions are running simultaneously within the same browser.

Syntax

await context.close();

Parameters

The context.close() command does not require any parameters.

TypeScript Example

import { chromium } from '@playwright/test';

async function closeContext() {

    const browser = await chromium.launch();

    const adminContext = await browser.newContext();
    const customerContext = await browser.newContext();

    const adminPage = await adminContext.newPage();
    await adminPage.goto('https://example.com/admin');

    const customerPage = await customerContext.newPage();
    await customerPage.goto('https://example.com');

    await adminContext.close();

    // Customer session is still active
    await customerPage.reload();

    await customerContext.close();
    await browser.close();
}

closeContext();

Enterprise Use Case

Imagine an insurance application where three different users participate in a claim approval process:

  • Customer submits a claim.
  • Claims Officer reviews the request.
  • Manager approves the claim.

Each user operates within a separate Browser Context.

Once the Claims Officer completes the review, the automation closes only that Browser Context while allowing the Customer and Manager sessions to continue uninterrupted.

Browser
   │
   ├──────────────┬──────────────┐
   │              │              │
Customer      Claims Officer    Manager
Context         Context         Context
   │              │              │
   ▼              ▼              ▼
 Running       Closed         Running

This approach enables efficient multi-user workflow testing without launching multiple browser instances.

Command 8: storageState()

What it does

The storageState() command captures the current browser session and stores authentication-related data such as cookies and local storage. The saved session can later be loaded into a new Browser Context, allowing tests to bypass repetitive login steps.

Authentication is one of the most time-consuming operations in UI automation. Instead of logging in before every test, QA engineers can authenticate once, save the session, and reuse it across hundreds of test cases.

This significantly reduces execution time while improving test stability.

Syntax

Save Storage State

await context.storageState({
    path: 'auth.json'
});

Load Storage State

const context = await browser.newContext({
    storageState: 'auth.json'
});

Parameters

Saving Session

ParameterTypeRequiredDescription
pathstringYesFile path where the authentication state will be stored.

Loading Session

ParameterTypeRequiredDescription
storageStatestringYesPath to the previously saved authentication file.

TypeScript Example

Saving Authentication

import { chromium } from '@playwright/test';

async function saveLoginState() {

    const browser = await chromium.launch();

    const context = await browser.newContext();

    const page = await context.newPage();

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

    await page.fill('#username', 'qauser');
    await page.fill('#password', 'Password123');
    await page.click('button[type="submit"]');

    await context.storageState({
        path: 'auth.json'
    });

    await browser.close();
}

saveLoginState();

Reusing Authentication

import { chromium } from '@playwright/test';

async function reuseLogin() {

    const browser = await chromium.launch();

    const context = await browser.newContext({
        storageState: 'auth.json'
    });

    const page = await context.newPage();

    await page.goto('https://example.com/dashboard');

    await browser.close();
}

reuseLogin();

Enterprise Use Case

A banking application contains more than 1,500 automated regression tests. Logging in before every test would significantly increase execution time and put unnecessary load on the authentication service.

Instead, the QA framework performs login once during the setup phase, saves the authenticated session using storageState(), and reuses it across all remaining test cases.

Login Once
     │
     ▼
Save auth.json
     │
     ▼
Regression Suite
     │
     ├───────────────┐
     │               │
     ▼               ▼
Test 1          Test 2
     │               │
     ▼               ▼
Reuse auth.json  Reuse auth.json

This approach speeds up execution, reduces dependency on authentication services, and makes large regression suites more efficient.

Browser & Context Commands Summary

CommandPurpose
chromium.launch()Launches a Chromium browser instance.
firefox.launch()Launches a Firefox browser instance.
webkit.launch()Launches a WebKit browser instance for Safari compatibility.
browser.newContext()Creates an isolated browser session.
context.newPage()Opens a new page within a Browser Context.
browser.close()Closes the browser and all associated contexts.
context.close()Closes a specific Browser Context while leaving the browser running.
storageState()Saves and restores authentication state for faster test execution.

Playwright Commands: Navigation & Page Commands

After launching a browser and creating a browser context, the next step in every Playwright test is interacting with web pages. Navigation commands allow QA engineers to open URLs, refresh pages, move through browser history, and synchronize test execution with page loading.

Command 9: page.goto()

What it does

The page.goto() command navigates the current browser page to a specified URL. It is one of the most frequently used Playwright commands because every UI automation scenario starts by opening a webpage.

Whether you’re testing a login screen, an e-commerce product page, an admin dashboard, or a REST API documentation site, page.goto() is typically the first page-level action performed after creating a new page.

By default, Playwright waits for the page to reach a load state before continuing execution, reducing synchronization issues compared to traditional automation frameworks.

Syntax

await page.goto(url, options);

Parameters

ParameterTypeRequiredDescription
urlstringYesThe URL to navigate to.
optionsPageGotoOptionsNoOptional navigation settings such as timeout and wait conditions.

Common navigation options:

OptionDescription
waitUntilDefines when navigation is considered complete (load, domcontentloaded, networkidle, commit).
timeoutMaximum navigation time before Playwright throws an error.
refererSends a custom HTTP Referer header during navigation.

TypeScript Example

import { test } from '@playwright/test';

test('Open Playwright Website', async ({ page }) => {

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

    console.log(await page.title());

});

Navigating to a Local Application

await page.goto('http://localhost:3000');

Opening a Specific Page

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

Enterprise Use Case

A retail company maintains an online shopping platform with separate environments for development, staging, and production.

During every CI/CD pipeline, Playwright opens the staging application using page.goto(), performs user authentication, validates product searches, completes checkout workflows, and verifies payment confirmation before deployment is approved.

Because the application URL changes across environments, QA teams often store the base URL in Playwright configuration files instead of hardcoding it within test scripts.

Command 10: page.reload()

What it does

The page.reload() command refreshes the currently opened webpage. It behaves similarly to pressing the browser’s Refresh button or using the keyboard shortcut (F5 or Ctrl+R).

Reloading a page is useful when testing applications that update content dynamically after server-side processing, background jobs, scheduled tasks, or asynchronous events.

Playwright waits for the page to reload completely before executing the next command, making test execution more reliable.

Syntax

await page.reload(options);

Parameters

ParameterTypeRequiredDescription
optionsPageReloadOptionsNoOptional settings controlling reload behavior and timeout.

Common reload options:

OptionDescription
waitUntilDetermines the page load event that Playwright waits for.
timeoutMaximum time allowed for the reload operation.

TypeScript Example

import { test } from '@playwright/test';

test('Reload Current Page', async ({ page }) => {

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

    await page.reload();

    console.log(await page.url());

});

Reloading After an Update

await page.reload({
    waitUntil: 'networkidle'
});

Enterprise Use Case

Consider a warehouse management system where inventory levels are updated after an order is processed.

A QA engineer submits an order through the application, waits for the backend service to update stock quantities, and then refreshes the inventory dashboard using page.reload() to verify that the product count has changed correctly.

This command is also commonly used when validating:

  • Live dashboards
  • Analytics reports
  • Monitoring portals
  • Stock trading applications
  • Order management systems
  • Administrative dashboards

where data changes without requiring users to navigate away from the current page.

Command 11: page.goBack()

What it does

The page.goBack() command navigates the browser to the previous page in its history, just like clicking the Back button in a web browser.

This command is particularly useful when testing user journeys that involve moving between multiple pages. Instead of opening the previous page again with page.goto(), page.goBack() validates whether the browser history behaves correctly.

If there is no previous page in the browser history, the command returns null.

Syntax

await page.goBack(options);

Parameters

ParameterTypeRequiredDescription
optionsPageGoBackOptionsNoOptional settings for timeout and page load synchronization.

Common options:

OptionDescription
waitUntilSpecifies when navigation is considered complete.
timeoutMaximum navigation time before throwing an error.

TypeScript Example

import { test } from '@playwright/test';

test('Navigate Back', async ({ page }) => {

    await page.goto('https://example.com');

    await page.goto('https://example.com/products');

    await page.goto('https://example.com/products/laptop');

    await page.goBack();

    console.log(await page.url());

});

Enterprise Use Case

An online retail application allows customers to browse products, view product details, and return to the product listing.

A QA engineer verifies that clicking the browser’s Back button correctly returns the user to the previously filtered product list without losing applied filters, sorting preferences, or pagination state.

This command is commonly used while testing:

  • Product browsing
  • Knowledge base navigation
  • Learning Management Systems
  • Banking transaction history
  • Insurance claim workflows
  • Multi-step business applications

Command 12: page.goForward()

What it does

The page.goForward() command moves the browser to the next page in its history, similar to clicking the browser’s Forward button.

It is generally used after executing page.goBack() to verify that browser history navigation functions correctly.

This command is especially valuable when validating multi-step workflows where users frequently move backward to review information before continuing.

Syntax

await page.goForward(options);

Parameters

ParameterTypeRequiredDescription
optionsPageGoForwardOptionsNoOptional navigation configuration.

Frequently used options:

OptionDescription
waitUntilDetermines the navigation completion event.
timeoutMaximum navigation timeout.

TypeScript Example

import { test } from '@playwright/test';

test('Navigate Forward', async ({ page }) => {

    await page.goto('https://example.com');

    await page.goto('https://example.com/products');

    await page.goBack();

    await page.goForward();

    console.log(await page.url());

});

Enterprise Use Case

A travel booking platform allows customers to search flights, review available options, compare fares, and complete reservations.

During testing, a QA engineer navigates backward to modify travel dates and then moves forward again to ensure that selected flights, passenger information, and pricing remain accurate throughout the booking process.

Testing browser history is particularly important for:

  • Airline reservation systems
  • Hotel booking platforms
  • University admission portals
  • Government service websites
  • Online loan applications
  • Healthcare appointment systems

Browser History Flow

Home Page
     │
     ▼
Products
     │
     ▼
Product Details
     │
     ▼
Shopping Cart

goBack()
     ▲
     │
Product Details

goForward()
     ▼
Shopping Cart

Command 13: page.waitForURL()

What it does

The page.waitForURL() command pauses test execution until the current page URL matches the expected value or pattern. It is commonly used after user actions that trigger navigation, such as logging in, submitting forms, clicking menu items, or completing checkout processes.

Unlike using static waits such as waitForTimeout(), page.waitForURL() waits intelligently for the navigation to complete, making tests more stable and less prone to timing issues.

This command supports exact URLs, wildcard patterns, regular expressions, and custom predicate functions, making it suitable for both simple and dynamic applications.

Syntax

await page.waitForURL(url, options);

Parameters

ParameterTypeRequiredDescription
urlstring | RegExp | functionYesExpected URL, wildcard pattern, regular expression, or predicate function.
optionsWaitForURLOptionsNoControls timeout and navigation completion behavior.

Common options:

OptionDescription
timeoutMaximum waiting time before throwing an error.
waitUntilSpecifies the navigation event to wait for (load, domcontentloaded, networkidle, or commit).

TypeScript Example

Waiting for an Exact URL

await page.click('#loginButton');

await page.waitForURL('https://example.com/dashboard');

Using Wildcards

await page.waitForURL('**/dashboard');

Using a Regular Expression

await page.waitForURL(/dashboard/);

Enterprise Use Case

A banking application redirects users to different dashboards based on their roles.

After authentication:

  • Customers navigate to /customer/dashboard
  • Managers navigate to /manager/dashboard
  • Administrators navigate to /admin/dashboard

The automation framework waits for the correct destination URL before validating account information, menus, and permissions.

Using page.waitForURL() ensures that verification begins only after the application has completed its navigation.

Command 14: page.waitForLoadState()

What it does

The page.waitForLoadState() command waits until the current page reaches a specific loading state before continuing test execution.

Although Playwright automatically waits for many actions, there are situations where additional synchronization is required. Applications that load data asynchronously, fetch API responses after rendering, or update components dynamically may require waiting for a particular load state.

This command improves test stability by ensuring the page is ready before interacting with its elements.

Syntax

await page.waitForLoadState(state, options);

Parameters

ParameterTypeRequiredDescription
state'load' | 'domcontentloaded' | 'networkidle'NoSpecifies the desired page load state.
optionsWaitForLoadStateOptionsNoOptional timeout configuration.

Available Load States

Load StateDescription
loadWaits until the page and its resources finish loading.
domcontentloadedWaits until the HTML document has been parsed.
networkidleWaits until network activity has been idle for a short period. Useful for SPA applications.

TypeScript Example

Wait for Complete Page Load

await page.goto('https://example.com');

await page.waitForLoadState('load');

Wait for Dynamic Content

await page.goto('https://example.com/dashboard');

await page.waitForLoadState('networkidle');

Wait After Clicking

await page.click('#submitOrder');

await page.waitForLoadState('networkidle');

Enterprise Use Case

A logistics company uses a dashboard that displays live shipment information.

When a dispatcher signs in, the page loads immediately, but shipment details continue loading through multiple background API requests.

Instead of using arbitrary delays, the automation suite waits for the networkidle state before validating shipment status, delivery routes, and tracking information. This approach produces more reliable and maintainable tests.

Waiting Strategy Comparison

CommandPrimary PurposeBest Used For
page.waitForURL()Wait for URL changesLogin, redirects, navigation, route validation
page.waitForLoadState()Wait for page readinessDynamic pages, dashboards, SPAs, asynchronous loading

Real-World Navigation Flow

User Clicks Login
         │
         ▼
Authentication Request
         │
         ▼
Redirect to Dashboard
         │
         ▼
page.waitForURL()
         │
         ▼
Dashboard Starts Loading
         │
         ▼
Background API Calls
         │
         ▼
page.waitForLoadState('networkidle')
         │
         ▼
Validate Dashboard Elements

Command 15: page.title()

What it does

The page.title() command returns the title of the currently loaded webpage. The value is retrieved from the HTML <title> element and is commonly used to verify that users have successfully navigated to the correct page.

Although validating page titles may seem simple, it provides an effective way to confirm successful navigation, detect unexpected redirects, and ensure SEO-critical pages display the correct metadata.

Many automation frameworks include title verification immediately after navigation to quickly confirm that the application has reached the expected destination before executing additional validations.

Syntax

const title = await page.title();

Parameters

The page.title() command does not accept any parameters.

TypeScript Example

import { test, expect } from '@playwright/test';

test('Verify Homepage Title', async ({ page }) => {

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

    const title = await page.title();

    expect(title).toContain('Playwright');

});

Enterprise Use Case

An insurance company maintains separate portals for customers, agents, and administrators.

After login, the automation framework retrieves the page title to verify that users are redirected to the correct portal.

Examples include:

  • Customer Portal
  • Agent Dashboard
  • Claims Management
  • Administration Console

Incorrect page titles may indicate failed navigation, improper routing, or configuration issues that require investigation.

Command 16: page.url()

What it does

The page.url() command returns the complete URL of the currently active page.

Unlike page.waitForURL(), which waits for navigation to complete, page.url() simply retrieves the current browser address. It is frequently used for assertions, logging, debugging, and reporting.

QA engineers often combine page.url() with Playwright assertions to validate successful navigation after user actions.

Syntax

const currentUrl = page.url();

Parameters

The page.url() command does not accept any parameters.

TypeScript Example

import { test, expect } from '@playwright/test';

test('Verify Current URL', async ({ page }) => {

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

    const currentUrl = page.url();

    expect(currentUrl).toContain('playwright.dev');

});

Logging the Current URL

console.log(page.url());

Enterprise Use Case

Consider a banking application with role-based dashboards.

After authentication:

  • Customers navigate to /customer/dashboard
  • Employees navigate to /employee/dashboard
  • Managers navigate to /manager/dashboard
  • Administrators navigate to /admin/dashboard

Instead of relying solely on UI elements, the automation framework retrieves the current URL to verify that users have landed on the correct route before validating page-specific functionality.

This technique also helps identify unexpected redirects caused by authentication failures, expired sessions, or authorization issues.

page.waitForURL() vs page.url()

CommandPurposeWaits for NavigationReturns Value
page.waitForURL()Waits until the expected URL is reached✅ YesNo
page.url()Retrieves the current page URL❌ No✅ String

Navigation & Page Commands Summary

CommandPurpose
page.goto()Opens a specified URL in the current page.
page.reload()Refreshes the current webpage.
page.goBack()Navigates to the previous page in browser history.
page.goForward()Navigates to the next page in browser history.
page.waitForURL()Waits until the page reaches a specific URL or URL pattern.
page.waitForLoadState()Waits for a specified page loading state.
page.title()Returns the title of the current webpage.
page.url()Returns the current page URL.

Choosing the Right Navigation Command

ScenarioRecommended Command
Open a new pagepage.goto()
Refresh updated datapage.reload()
Validate browser back buttonpage.goBack()
Validate browser forward buttonpage.goForward()
Wait for redirectspage.waitForURL()
Synchronize with page loadingpage.waitForLoadState()
Verify page titlepage.title()
Verify current routepage.url()

Playwright Commands: Locator Commands

Locating web elements accurately is one of the most critical aspects of UI automation. Even the best test scripts can become unstable if they rely on fragile locators. Playwright introduces a modern locator engine that prioritizes reliability, accessibility, and maintainability over traditional XPath and CSS selector-heavy approaches.

Command 17: locator()

What it does

The locator() command creates a Locator object that identifies one or more elements on a webpage. Unlike older automation frameworks that immediately search for an element, Playwright locators are lazy. They resolve the element only when an action such as click(), fill(), or textContent() is performed.

This design makes Playwright tests significantly more reliable because locators automatically re-evaluate the DOM before every interaction. If the page changes due to JavaScript rendering or AJAX updates, Playwright interacts with the latest version of the element instead of a stale reference.

The locator() command supports CSS selectors, XPath expressions, text selectors, and Playwright-specific selector engines, making it the most flexible way to locate elements.

Syntax

const locator = page.locator(selector);

Parameters

ParameterTypeRequiredDescription
selectorstringYesCSS, XPath, text selector, or any Playwright-supported selector.

TypeScript Example

import { test, expect } from '@playwright/test';

test('Locate Login Button', async ({ page }) => {

    await page.goto('https://example.com');

    const loginButton = page.locator('#loginButton');

    await loginButton.click();

});

Locating Multiple Elements

const products = page.locator('.product-card');

await expect(products).toHaveCount(20);

Chaining Locators

const submitButton = page
    .locator('#loginForm')
    .locator('button[type="submit"]');

await submitButton.click();

Enterprise Use Case

An e-commerce website displays hundreds of products on a category page.

Instead of writing long XPath expressions for every product card, the QA team creates reusable locators for product containers, prices, ratings, and “Add to Cart” buttons. Whenever the frontend layout changes, only the locator definition needs updating, while the remaining automation code remains unchanged.

This approach improves maintainability across large automation projects.

Command 18: getByRole()

What it does

The getByRole() command locates elements based on their ARIA (Accessible Rich Internet Applications) role.

Rather than identifying elements using CSS classes or IDs, Playwright searches for semantic roles such as buttons, links, checkboxes, headings, textboxes, menus, dialogs, and navigation regions.

This is Playwright’s recommended locator strategy because it closely reflects how assistive technologies interact with web applications.

Using accessibility roles makes automation scripts more resilient and simultaneously encourages better accessibility practices within development teams.

Syntax

const locator = page.getByRole(role, options);

Parameters

ParameterTypeRequiredDescription
rolestringYesARIA role of the target element.
optionsobjectNoFilters elements using properties such as accessible name.

Common options include:

OptionDescription
nameMatches the accessible name of the element.
exactPerforms an exact name match.
checkedFilters checkboxes or radio buttons.
disabledFilters disabled controls.
expandedFilters expandable elements.
selectedFilters selected items.

TypeScript Example

import { test } from '@playwright/test';

test('Login Using Accessible Button', async ({ page }) => {

    await page.goto('https://example.com');

    await page.getByRole('textbox', {
        name: 'Email'
    }).fill('qa@example.com');

    await page.getByRole('textbox', {
        name: 'Password'
    }).fill('Password123');

    await page.getByRole('button', {
        name: 'Sign In'
    }).click();

});

Common ARIA Roles

RoleExample
buttonSubmit, Login, Save
linkHome, Contact Us
textboxUsername, Search
checkboxAccept Terms
radioGender Selection
comboboxCountry Dropdown
headingPage Title
dialogConfirmation Popup
navigationNavigation Menu

Enterprise Use Case

A government services portal follows WCAG accessibility standards.

Instead of locating elements using CSS classes that frequently change during UI redesigns, the QA automation framework uses getByRole() throughout the project.

As long as the application’s accessibility implementation remains consistent, tests continue to work even if frontend styling, CSS frameworks, or HTML structures change. This significantly reduces locator maintenance while ensuring the application remains accessible to users with assistive technologies.

Locator Comparison

Featurelocator()getByRole()
Uses CSS/XPath selectors✅ Yes❌ No
Uses Accessibility Roles❌ No✅ Yes
Recommended for Accessible Applications⚪ Good✅ Excellent
Supports Chaining✅ Yes✅ Yes
Ideal ForFlexible element selectionUser-centric and accessibility-first testing

Command 19: getByText()

What it does

The getByText() command locates an element based on its visible text content. Instead of relying on CSS selectors, IDs, or XPath expressions, Playwright searches for the text that users actually see on the screen.

This approach makes test scripts easier to read and maintain because they closely resemble real user interactions. It is particularly useful for buttons, links, notifications, menu items, headings, and validation messages.

The command supports exact text matching, partial text matching, and regular expressions, making it flexible enough for both static and dynamic applications.

Syntax

const locator = page.getByText(text, options);

Parameters

ParameterTypeRequiredDescription
textstring | RegExpYesThe visible text or regular expression to search for.
optionsobjectNoOptional matching configuration.

Common options:

OptionDescription
exactPerforms an exact text match instead of a partial match.

TypeScript Example

Locate a Button by Text

await page.getByText('Login').click();

Partial Text Match

await page.getByText('Welcome').click();

Regular Expression

await page.getByText(/Welcome/i).click();

Validate a Success Message

import { expect } from '@playwright/test';

await expect(
    page.getByText('Profile updated successfully')
).toBeVisible();

Enterprise Use Case

An online banking application displays confirmation messages after users complete transactions.

After transferring funds, the QA automation verifies that the success message “Transaction completed successfully” appears on the screen before validating the updated account balance.

Using getByText() closely mirrors the end-user experience and eliminates dependence on implementation-specific selectors.

Command 20: getByLabel()

What it does

The getByLabel() command locates form controls using the text of their associated HTML <label> element.

Rather than identifying input fields through IDs or CSS selectors, Playwright uses the relationship between labels and form controls. This produces cleaner, more maintainable tests while encouraging accessible web development.

It is commonly used for login forms, registration pages, search boxes, payment forms, profile updates, and any interface containing labeled input fields.

Syntax

const locator = page.getByLabel(text, options);

Parameters

ParameterTypeRequiredDescription
textstring | RegExpYesThe text of the associated label.
optionsobjectNoOptional matching configuration.

Common option:

OptionDescription
exactMatches the complete label text exactly.

TypeScript Example

Fill Login Form

await page.getByLabel('Email').fill('qa@example.com');

await page.getByLabel('Password').fill('Password123');

await page.getByRole('button', {
    name: 'Login'
}).click();

Registration Form

await page.getByLabel('First Name').fill('John');

await page.getByLabel('Last Name').fill('Doe');

await page.getByLabel('Phone Number').fill('1234567890');

Using Regular Expressions

await page.getByLabel(/email/i).fill('qa@example.com');

Enterprise Use Case

A healthcare management system contains large patient registration forms with dozens of input fields.

Instead of depending on dynamically generated element IDs, the QA team uses getByLabel() to populate patient details, insurance information, emergency contacts, and medical history.

Because labels rarely change during frontend updates, the automation suite remains stable even when HTML structures or CSS classes are modified.

Locator Comparison

FeaturegetByText()getByLabel()
Searches Visible Text✅ Yes❌ No
Targets Form Controls❌ No✅ Yes
Accessibility Friendly✅ Yes✅ Yes
Best ForButtons, links, headings, messagesInput fields, textareas, form controls

Choosing the Right Locator

ScenarioRecommended Command
Click a button with visible textgetByText()
Verify a confirmation messagegetByText()
Fill an email fieldgetByLabel()
Populate registration formsgetByLabel()
Interact with accessible form elementsgetByLabel()

Command 21: getByPlaceholder()

What it does

The getByPlaceholder() command locates input fields using their placeholder text. A placeholder is the hint displayed inside an input box before the user enters any value.

This locator is particularly useful for modern web applications where placeholders are used instead of visible labels. It improves test readability by allowing QA engineers to interact with elements the same way users identify them.

However, if both a label and a placeholder are available, Playwright recommends using getByLabel() because it aligns better with accessibility standards.

Syntax

const locator = page.getByPlaceholder(text, options);

Parameters

ParameterTypeRequiredDescription
textstring | RegExpYesPlaceholder text used to identify the element.
optionsobjectNoOptional matching configuration.

Common option:

OptionDescription
exactMatches the placeholder text exactly.

TypeScript Example

Fill Search Box

await page.getByPlaceholder('Search products').fill('Laptop');

Login Form

await page.getByPlaceholder('Enter your email')
    .fill('qa@example.com');

await page.getByPlaceholder('Enter password')
    .fill('Password123');

Using a Regular Expression

await page.getByPlaceholder(/search/i)
    .fill('Playwright');

Enterprise Use Case

A SaaS CRM platform includes a global search box on every page. The input field has no visible label but displays the placeholder “Search customers, invoices, or opportunities”.

The QA automation framework uses getByPlaceholder() to validate search functionality across multiple modules, ensuring users can quickly locate records regardless of where they are in the application.

Command 22: getByTestId()

What it does

The getByTestId() command locates elements using a dedicated test ID attribute. Test IDs are specifically added by developers to create stable and automation-friendly selectors.

Unlike CSS classes or HTML structures, test IDs are not affected by UI redesigns or styling changes. This makes them one of the most reliable locator strategies for large enterprise automation projects.

By default, Playwright looks for the data-testid attribute, although the attribute name can be customized through Playwright configuration.

Syntax

const locator = page.getByTestId(testId);

Parameters

ParameterTypeRequiredDescription
testIdstringYesValue of the configured test ID attribute.

Example HTML

<button data-testid="login-button">
    Login
</button>

TypeScript Example

await page.getByTestId('login-button').click();

Fill a Form

await page.getByTestId('email-input')
    .fill('qa@example.com');

await page.getByTestId('password-input')
    .fill('Password123');

await page.getByTestId('login-button')
    .click();

Custom Test ID Attribute

// playwright.config.ts

export default defineConfig({

    use: {
        testIdAttribute: 'data-qa'
    }

});

Example HTML:

<button data-qa="save-button">
    Save
</button>

Automation:

await page.getByTestId('save-button').click();

Enterprise Use Case

A multinational insurance company has more than 8,000 automated Playwright tests covering policy management, claims processing, billing, and customer portals.

Frontend developers assign a unique data-testid attribute to every interactive component. Even when CSS frameworks, layouts, or component libraries change, the automation suite remains stable because test IDs are preserved.

This practice significantly reduces maintenance effort and minimizes flaky tests caused by UI changes.

Locator Comparison

FeaturegetByPlaceholder()getByTestId()
Uses Placeholder Text✅ Yes❌ No
Uses Test Attribute❌ No✅ Yes
Recommended for Forms✅ Yes✅ Yes
Resistant to UI Changes⚪ Moderate✅ Excellent
Enterprise Friendly✅ Yes⭐ Highly Recommended

Choosing the Right Locator

ScenarioRecommended Command
Search input with placeholdergetByPlaceholder()
Login form without labelsgetByPlaceholder()
Stable enterprise automationgetByTestId()
Frequently changing UIgetByTestId()
CI/CD regression suitesgetByTestId()

Command 23: getByAltText()

What it does

The getByAltText() command locates images and other supported elements using their alternative (alt) text. The alt attribute is primarily intended for accessibility, allowing screen readers to describe images to users who cannot see them.

For QA engineers, this command provides a reliable way to verify that important images, logos, icons, banners, and product thumbnails are present on the page without relying on CSS selectors or XPath expressions.

It is especially useful when testing accessibility compliance and SEO-critical pages where descriptive image alt text is required.

Syntax

const locator = page.getByAltText(text, options);

Parameters

ParameterTypeRequiredDescription
textstring | RegExpYesThe image’s alternative text.
optionsobjectNoOptional matching configuration.

Common option:

OptionDescription
exactPerforms an exact match on the alt text.

TypeScript Example

Verify Company Logo

import { expect } from '@playwright/test';

const logo = page.getByAltText('Company Logo');

await expect(logo).toBeVisible();

Validate Product Image

await expect(
    page.getByAltText('Apple iPhone 17 Pro')
).toBeVisible();

Using Regular Expressions

await page.getByAltText(/company/i);

Enterprise Use Case

An e-commerce company maintains thousands of product pages where every product image must contain descriptive alternative text for accessibility and SEO.

The automation framework verifies that:

  • Product images are displayed.
  • Brand logos are visible.
  • Promotional banners load correctly.
  • Every critical image contains the expected alt text.

This helps ensure compliance with accessibility standards while preventing broken or incorrectly labeled images from reaching production.

Command 24: getByTitle()

What it does

The getByTitle() command locates elements using their HTML title attribute. The title attribute commonly provides additional information when users hover over an element, such as tooltips, icons, shortcuts, or descriptive text.

This locator is particularly useful for applications that rely on icon-only buttons where visible text is not available.

Syntax

const locator = page.getByTitle(title, options);

Parameters

ParameterTypeRequiredDescription
titlestring | RegExpYesValue of the HTML title attribute.
optionsobjectNoOptional matching configuration.

TypeScript Example

Click an Icon

await page.getByTitle('Settings').click();

Validate Tooltip

import { expect } from '@playwright/test';

await expect(
    page.getByTitle('Download Report')
).toBeVisible();

Regular Expression

await page.getByTitle(/download/i);

Enterprise Use Case

A business intelligence dashboard uses icons instead of text labels to maximize screen space.

Buttons such as Export, Refresh, Notifications, Settings, and Download Report are identified through their title attributes.

Using getByTitle() allows the automation suite to interact with these controls without depending on fragile CSS selectors or image recognition.

Command 25: frameLocator()

What it does

The frameLocator() command is used to locate and interact with elements inside an iframe.

An iframe (Inline Frame) embeds one webpage inside another. Since iframe content belongs to a separate document, Playwright cannot access its elements directly using standard locators. The frameLocator() command provides a clean and reliable way to work with embedded content.

This command is commonly used when automating payment gateways, embedded reports, document viewers, customer support widgets, maps, and third-party integrations.

Syntax

const frame = page.frameLocator(selector);

Parameters

ParameterTypeRequiredDescription
selectorstringYesCSS selector that identifies the iframe element.

TypeScript Example

Fill a Field Inside an iFrame

await page
    .frameLocator('#payment-frame')
    .getByLabel('Card Number')
    .fill('4111111111111111');

Click a Button Inside an iFrame

await page
    .frameLocator('#payment-frame')
    .getByRole('button', {
        name: 'Pay Now'
    })
    .click();

Verify Text Inside an iFrame

import { expect } from '@playwright/test';

await expect(
    page
        .frameLocator('#help-frame')
        .getByText('Support Center')
).toBeVisible();

Enterprise Use Case

An online payment platform integrates a third-party payment gateway hosted inside an iframe.

The QA automation suite uses frameLocator() to:

  • Enter credit card information.
  • Verify payment forms.
  • Complete secure checkout.
  • Validate transaction confirmations.

Because Playwright automatically scopes subsequent locators to the selected iframe, the automation code remains clean and easy to maintain.

Locator Commands Summary

CommandPrimary Purpose
locator()Locate elements using CSS, XPath, or Playwright selectors
getByRole()Locate elements by ARIA role
getByText()Locate elements using visible text
getByLabel()Locate form controls by associated labels
getByPlaceholder()Locate input fields using placeholder text
getByTestId()Locate elements using dedicated test IDs
getByAltText()Locate images using alternative text
getByTitle()Locate elements using the HTML title attribute
frameLocator()Locate and interact with elements inside iframes

Which Locator Should You Use?

ScenarioRecommended Command
General-purpose element selectionlocator()
Accessibility-first automationgetByRole()
Buttons, links, and messagesgetByText()
Forms with labelsgetByLabel()
Inputs with placeholdersgetByPlaceholder()
Enterprise-grade stable selectorsgetByTestId()
Images and logosgetByAltText()
Icons and tooltipsgetByTitle()
Embedded iframesframeLocator()

Playwright Commands: Action Commands

Once you’ve located an element, the next step is interacting with it. Action commands simulate real user behavior such as clicking buttons, entering text, selecting options, uploading files, and pressing keyboard keys.

One of Playwright’s biggest strengths is that its action commands are auto-waiting. Before performing an action, Playwright automatically verifies that the target element is visible, stable, enabled, and capable of receiving user interaction. This intelligent behavior eliminates many synchronization issues that were common in older automation frameworks.

Command 26: click()

What it does

The click() command performs a mouse click on the specified element. It is the most frequently used action command in Playwright and is essential for automating almost every web application.

QA engineers use click() to trigger navigation, submit forms, open dialogs, expand menus, select items, initiate downloads, and perform countless other user interactions.

Before executing the click, Playwright automatically waits until the element:

  • Is attached to the DOM.
  • Is visible on the page.
  • Is enabled.
  • Is stable and not moving.
  • Can receive pointer events.

This built-in auto-waiting greatly reduces flaky tests caused by timing issues.

Syntax

await locator.click(options);

Parameters

ParameterTypeRequiredDescription
optionsClickOptionsNoConfigures how the click operation is performed.

Commonly used options:

OptionDescription
buttonMouse button to click (left, right, middle).
clickCountNumber of mouse clicks.
delayDelay (milliseconds) between mouse down and mouse up.
forceClicks even if Playwright’s actionability checks fail.
modifiersKeyboard modifiers such as Shift, Alt, or Control.
positionClicks a specific position within the element.
timeoutMaximum time to wait before the click operation fails.

TypeScript Example

Click a Button

await page.getByRole('button', {
    name: 'Login'
}).click();

Click a Link

await page.getByRole('link', {
    name: 'Products'
}).click();

Right Mouse Click

await page.locator('.file-item').click({
    button: 'right'
});

Forced Click

await page.locator('#submit').click({
    force: true
});

Enterprise Use Case

A digital banking platform requires customers to approve a money transfer.

The automation workflow performs the following steps:

  1. Clicks Transfer Funds.
  2. Selects the recipient.
  3. Confirms the transfer.
  4. Opens the transaction receipt.
  5. Downloads the confirmation PDF.

Each step depends on successful click actions, making click() one of the most heavily used commands in enterprise automation suites.

Command 27: dblclick()

What it does

The dblclick() command performs a double-click on an element, equivalent to rapidly clicking the left mouse button twice.

Although used less frequently than click(), double-click interactions are common in desktop-style web applications where opening folders, editing records, expanding tree structures, or launching detailed views requires two consecutive clicks.

Playwright performs both clicks while applying the same actionability checks used by the click() command.

Syntax

await locator.dblclick(options);

Parameters

ParameterTypeRequiredDescription
optionsDblClickOptionsNoConfigures how the double-click is executed.

Frequently used options:

OptionDescription
buttonMouse button to use.
delayDelay between mouse actions.
forceBypasses actionability checks.
modifiersKeyboard modifiers during the action.
positionClick location inside the element.
timeoutMaximum waiting time before failure.

TypeScript Example

Double Click a Table Row

await page.locator('.employee-row').dblclick();

Open a Folder

await page.locator('.folder').dblclick();

Double Click an Image

await page.locator('.thumbnail').dblclick();

Enterprise Use Case

An enterprise document management system displays thousands of files and folders in a web-based interface.

Users double-click folders to navigate deeper into the directory structure and double-click documents to open them for review.

The Playwright automation framework validates that:

  • Folders open correctly.
  • Documents load successfully.
  • User permissions are enforced.
  • Preview windows display the correct content.

Using dblclick() accurately reproduces real user behavior and ensures the application’s interaction model functions as intended.

Action Command Comparison

Featureclick()dblclick()
Single mouse click✅ Yes❌ No
Double mouse click❌ No✅ Yes
Supports auto-waiting✅ Yes✅ Yes
Supports force option✅ Yes✅ Yes
Common usageButtons, links, menusFile explorers, grids, desktop-style applications

Command 28: check()

What it does

The check() command selects a checkbox by changing its state to checked. Unlike using click(), this command is specifically designed for checkbox elements and first verifies their current state before performing any action.

If the checkbox is already checked, Playwright does nothing. This makes check() an idempotent operation, ensuring consistent behavior regardless of the checkbox’s initial state.

As with other Playwright actions, the framework automatically waits until the checkbox is visible, enabled, attached to the DOM, and ready for interaction.

Syntax

await locator.check(options);

Parameters

ParameterTypeRequiredDescription
optionsCheckOptionsNoOptional configuration for the check operation.

Common options:

OptionDescription
forcePerforms the action even if actionability checks fail.
positionClicks a specific position within the checkbox.
timeoutMaximum waiting time before failure.
trialPerforms actionability checks without actually checking the element.

TypeScript Example

Check a Checkbox

await page
    .getByLabel('Accept Terms and Conditions')
    .check();

Verify Checkbox State

import { expect } from '@playwright/test';

const checkbox = page.getByLabel('Receive Newsletter');

await checkbox.check();

await expect(checkbox).toBeChecked();

Forced Check

await page
    .locator('#subscribe')
    .check({
        force: true
    });

Enterprise Use Case

An insurance portal contains policy configuration forms where administrators enable optional features such as:

  • Email notifications
  • SMS alerts
  • Automatic renewals
  • Multi-factor authentication
  • Premium coverage

Instead of clicking each checkbox manually, the automation framework uses check() to ensure every required option is enabled before submitting the form.

Because the command verifies the existing state first, repeated executions always produce consistent results.

Command 29: uncheck()

What it does

The uncheck() command clears a checkbox by changing its state to unchecked.

Similar to check(), this command is state-aware. If the checkbox is already unchecked, Playwright performs no additional action.

Using uncheck() is preferred over click() because it guarantees the final checkbox state regardless of its initial condition.

Syntax

await locator.uncheck(options);

Parameters

ParameterTypeRequiredDescription
optionsUncheckOptionsNoOptional configuration for the uncheck operation.

Frequently used options:

OptionDescription
forceBypasses actionability checks.
positionSpecifies the click position.
timeoutMaximum waiting time.
trialPerforms validation without changing the checkbox state.

TypeScript Example

Uncheck a Checkbox

await page
    .getByLabel('Receive Promotional Emails')
    .uncheck();

Validate the State

import { expect } from '@playwright/test';

const newsletter = page.getByLabel('Newsletter');

await newsletter.uncheck();

await expect(newsletter).not.toBeChecked();

Remove Multiple Preferences

await page.getByLabel('Email Alerts').uncheck();

await page.getByLabel('SMS Alerts').uncheck();

await page.getByLabel('Marketing Notifications').uncheck();

Enterprise Use Case

A cloud management platform allows administrators to configure security policies for enterprise customers.

Before testing default security settings, the automation framework removes previously enabled options such as:

  • Debug logging
  • Beta features
  • Email alerts
  • Automatic backups
  • Experimental modules

Using uncheck() guarantees that every test begins from a predictable configuration, improving repeatability across regression suites.

check() vs click()

Featurecheck()click()
Designed specifically for checkboxes✅ Yes❌ No
Ensures final checked state✅ Yes❌ No
Ignores already checked elements✅ Yes❌ No
Auto-wait support✅ Yes✅ Yes
Recommended for checkbox automation⭐ Yes⚠️ Only when appropriate

uncheck() vs click()

Featureuncheck()click()
Clears checkbox safely✅ Yes❌ No
Guarantees unchecked state✅ Yes❌ No
Ignores already unchecked elements✅ Yes❌ No
Prevents accidental state toggling✅ Yes❌ No

Action Commands Covered So Far

CommandPurpose
click()Performs a single mouse click.
dblclick()Performs a double mouse click.
check()Selects a checkbox if it is not already selected.
uncheck()Clears a checkbox if it is currently selected.

Command 30: fill()

What it does

The fill() command enters text into an <input>, <textarea>, or editable form field. Before inserting new text, Playwright automatically clears any existing value, ensuring the field contains exactly the text you provide.

Unlike typing character by character, fill() directly sets the value of the field, making it faster and more reliable for most form automation scenarios.

Playwright automatically waits until the target element is visible, editable, enabled, and ready to receive input before performing the operation.

Syntax

await locator.fill(value);

Parameters

ParameterTypeRequiredDescription
valuestringYesThe text to insert into the input field.
optionsFillOptionsNoOptional timeout and action configuration.

TypeScript Example

Fill a Username

await page
    .getByLabel('Username')
    .fill('qa.engineer');

Login Form

await page.getByLabel('Email')
    .fill('qa@example.com');

await page.getByLabel('Password')
    .fill('Password123');

Search Products

await page
    .getByPlaceholder('Search products')
    .fill('Wireless Mouse');

Enterprise Use Case

A healthcare management system requires staff to register new patients.

The Playwright automation framework uses fill() to populate:

  • Patient name
  • Email address
  • Phone number
  • National ID
  • Insurance number
  • Address
  • Medical history

Because fill() replaces any existing value, the automation remains consistent even when forms contain previously saved data or default values.

Command 31: press()

What it does

The press() command simulates pressing one or more keyboard keys while an element is focused.

It supports individual keys such as Enter, Tab, Escape, and Space, as well as keyboard combinations like Control+A, Control+C, Control+V, Shift+Tab, and Control+Shift+P.

This command is essential for testing keyboard navigation, accessibility, shortcuts, search functionality, and applications that respond to specific key events.

Syntax

await locator.press(key);

Parameters

ParameterTypeRequiredDescription
keystringYesKeyboard key or key combination to press.
optionsPressOptionsNoOptional timeout configuration.

Common Keyboard Keys

KeyPurpose
EnterSubmit forms or confirm actions
TabMove focus to the next field
Shift+TabMove focus to the previous field
EscapeClose dialogs or menus
SpaceToggle buttons or checkboxes
ArrowDownNavigate lists or menus
ArrowUpNavigate upward in lists
Control+ASelect all text
Control+CCopy selected text
Control+VPaste text

TypeScript Example

Submit a Search

await page
    .getByPlaceholder('Search')
    .fill('Playwright');

await page
    .getByPlaceholder('Search')
    .press('Enter');

Move to the Next Field

await page
    .getByLabel('First Name')
    .press('Tab');

Select All Text

await page
    .getByLabel('Description')
    .press('Control+A');

Close a Dialog

await page
    .locator('body')
    .press('Escape');

Enterprise Use Case

A customer relationship management (CRM) application is designed for users who rely heavily on keyboard shortcuts.

The QA automation suite validates workflows such as:

  • Pressing Enter to submit forms.
  • Using Tab to navigate between fields.
  • Closing popups with Escape.
  • Selecting text using Control+A.
  • Triggering quick search with keyboard shortcuts.

Testing keyboard interactions ensures the application remains accessible, efficient, and compliant with enterprise usability standards.

fill() vs press()

Featurefill()press()
Enters text✅ Yes❌ No
Simulates keyboard keys❌ No✅ Yes
Clears existing value automatically✅ Yes❌ No
Supports keyboard shortcuts❌ No✅ Yes
Common UsageForms, search fields, textareasNavigation, shortcuts, form submission

Action Commands Covered So Far

CommandPurpose
click()Performs a single mouse click.
dblclick()Performs a double mouse click.
check()Selects a checkbox.
uncheck()Clears a checkbox.
fill()Enters text into editable fields.
press()Simulates keyboard input and shortcuts.

Command 32: selectOption()

What it does

The selectOption() command selects one or more options from an HTML <select> dropdown element. Instead of clicking the dropdown and manually choosing an option, Playwright interacts directly with the underlying select element, making tests faster and more reliable.

The command supports selecting options by:

  • Value
  • Visible label
  • Index
  • Multiple values (for multi-select dropdowns)

Before performing the selection, Playwright automatically waits until the dropdown is attached to the DOM, visible, enabled, and ready for interaction.

Syntax

await locator.selectOption(values);

Parameters

ParameterTypeRequiredDescription
valuesstring | object | arrayYesOption value, label, index, or multiple selections.

TypeScript Example

Select by Value

await page
    .getByLabel('Country')
    .selectOption('PK');

Select by Label

await page
    .getByLabel('Country')
    .selectOption({
        label: 'Pakistan'
    });

Select by Index

await page
    .locator('#country')
    .selectOption({
        index: 3
    });

Select Multiple Options

await page
    .locator('#skills')
    .selectOption([
        'Playwright',
        'TypeScript',
        'API Testing'
    ]);

Enterprise Use Case

An HR management application contains employee onboarding forms with numerous dropdowns for:

  • Department
  • Office location
  • Employment type
  • Job grade
  • Reporting manager
  • Country

The automation framework uses selectOption() to populate these fields during regression testing, ensuring dropdown values are selected accurately without depending on mouse interactions.

Command 33: setInputFiles()

What it does

The setInputFiles() command uploads one or more files to an HTML file input element (<input type="file">).

Instead of interacting with the operating system’s file picker dialog, Playwright uploads files directly to the input element. This makes file upload automation fully compatible with local execution, CI/CD pipelines, Docker containers, and cloud-based testing environments.

The command supports:

  • Single file uploads
  • Multiple file uploads
  • Uploading files from memory
  • Clearing previously selected files

Syntax

await locator.setInputFiles(files);

Parameters

ParameterTypeRequiredDescription
filesstring | array | objectYesFile path, multiple file paths, or file objects.

TypeScript Example

Upload a Single File

await page
    .locator('input[type="file"]')
    .setInputFiles('documents/resume.pdf');

Upload Multiple Files

await page
    .locator('input[type="file"]')
    .setInputFiles([
        'images/logo.png',
        'documents/report.pdf'
    ]);

Clear Uploaded Files

await page
    .locator('input[type="file"]')
    .setInputFiles([]);

Upload a File from Memory

await page
    .locator('input[type="file"]')
    .setInputFiles({
        name: 'sample.txt',
        mimeType: 'text/plain',
        buffer: Buffer.from('Hello Playwright')
    });

Enterprise Use Case

An insurance claims portal allows customers to upload supporting documents before submitting a claim.

The Playwright automation framework validates uploads for:

  • National ID
  • Passport
  • Insurance certificate
  • Medical reports
  • Accident photographs
  • Claim forms

The test suite verifies successful uploads, validates supported file formats, checks maximum file size restrictions, and ensures uploaded documents appear correctly before final submission.

Because setInputFiles() bypasses native file dialogs, the same tests execute reliably on developer machines, CI/CD servers, and cloud-based execution platforms.

selectOption() vs fill()

FeatureselectOption()fill()
Works with HTML <select> elements✅ Yes❌ No
Selects predefined options✅ Yes❌ No
Enters free-form text❌ No✅ Yes
Supports multiple selections✅ Yes❌ No

setInputFiles() vs Manual Upload

FeaturesetInputFiles()Manual File Picker
Works in automation✅ Yes❌ No
Requires OS interaction❌ No✅ Yes
CI/CD friendly✅ Yes❌ Limited
Supports multiple files✅ Yes✅ Yes
Supports in-memory files✅ Yes❌ No

Action Commands Summary

CommandPrimary Purpose
click()Perform a single mouse click
dblclick()Perform a double mouse click
check()Check a checkbox
uncheck()Uncheck a checkbox
fill()Enter text into input fields
press()Simulate keyboard input
selectOption()Select values from dropdowns
setInputFiles()Upload files to file input controls

When Should You Use Each Action Command?

ScenarioRecommended Command
Click a button or linkclick()
Open an item with a double-clickdblclick()
Enable a checkboxcheck()
Disable a checkboxuncheck()
Fill login or registration formsfill()
Trigger keyboard shortcutspress()
Select a country or departmentselectOption()
Upload documents or imagessetInputFiles()

Playwright Commands: Waiting & Assertion Commands

Reliable automation isn’t just about performing actions—it also requires verifying that the application responds correctly. Modern web applications load data asynchronously, render UI components dynamically, and communicate continuously with backend APIs. Without proper waiting strategies and assertions, even well-written tests can become flaky.

Playwright addresses this challenge through intelligent waiting mechanisms and a powerful assertion library. Together, they help QA engineers synchronize test execution with application behavior and validate expected outcomes with confidence.

Command 34: waitForSelector()

What it does

The waitForSelector() command pauses test execution until an element matching the specified selector reaches a desired state.

Although Playwright automatically waits before most actions, there are situations where explicit waiting is useful—for example, when validating dynamic content, loading indicators, modal dialogs, or elements that appear after asynchronous operations.

The command can wait for an element to become:

  • Attached to the DOM
  • Visible
  • Hidden
  • Detached from the DOM

Syntax

await page.waitForSelector(selector, options);

Parameters

ParameterTypeRequiredDescription
selectorstringYesCSS or Playwright selector used to locate the element.
optionsWaitForSelectorOptionsNoControls waiting behavior and timeout.

Common options:

OptionDescription
stateExpected element state (attached, visible, hidden, detached).
timeoutMaximum waiting time before throwing an error.

TypeScript Example

Wait Until an Element Becomes Visible

await page.waitForSelector('#dashboard', {
    state: 'visible'
});

Wait Until a Loader Disappears

await page.waitForSelector('.loading-spinner', {
    state: 'hidden'
});

Wait for a Modal Dialog

await page.waitForSelector('#confirmationModal');

Enterprise Use Case

A financial reporting dashboard loads charts only after several API requests complete.

Instead of using fixed delays, the automation framework waits for the chart container to become visible before validating graph data, filters, and export functionality. This approach improves execution speed while minimizing flaky test failures.

Command 35: waitForTimeout()

What it does

The waitForTimeout() command pauses test execution for a fixed number of milliseconds.

Unlike intelligent waiting commands, this method does not monitor application state—it simply waits for the specified duration.

Although useful for debugging and demonstrations, Playwright recommends avoiding waitForTimeout() in production automation because fixed delays can unnecessarily increase execution time and still fail if the application takes longer than expected.

Whenever possible, prefer commands such as waitForSelector(), waitForURL(), or Playwright assertions.

Syntax

await page.waitForTimeout(milliseconds);

Parameters

ParameterTypeRequiredDescription
millisecondsnumberYesDuration to pause execution.

TypeScript Example

Wait for Two Seconds

await page.waitForTimeout(2000);

Pause Before Capturing a Screenshot

await page.waitForTimeout(1000);

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

Slow Down Test Execution During Debugging

await page.click('#submit');

await page.waitForTimeout(3000);

Enterprise Use Case

During automation development, a QA engineer investigates an intermittent issue where a notification disappears too quickly.

By temporarily adding waitForTimeout(), the engineer can inspect the application manually, capture screenshots, or observe browser behavior before replacing the fixed delay with a more reliable synchronization strategy.

In production test suites, the temporary wait is removed in favor of intelligent Playwright waits.

waitForSelector() vs waitForTimeout()

FeaturewaitForSelector()waitForTimeout()
Waits for application state✅ Yes❌ No
Intelligent synchronization✅ Yes❌ No
Fixed delay❌ No✅ Yes
Recommended for production✅ Yes⚠️ Debugging only
Reduces flaky tests✅ Yes❌ No

Waiting Commands Covered So Far

CommandPurpose
waitForSelector()Waits until an element reaches a specified state.
waitForTimeout()Pauses execution for a fixed duration.

Command 36: expect().toBeVisible()

What it does

The expect().toBeVisible() assertion verifies that an element is visible to the user.

Unlike a simple existence check, this assertion confirms that the element:

  • Exists in the DOM.
  • Is not hidden.
  • Has a visible size.
  • Can be rendered on the page.

One of Playwright’s biggest advantages is its auto-retry mechanism. Instead of failing immediately, toBeVisible() repeatedly checks the element until it becomes visible or the configured timeout expires.

This makes the assertion highly reliable for modern applications where elements appear after API calls, animations, or asynchronous rendering.

Syntax

await expect(locator).toBeVisible();

Parameters

ParameterTypeRequiredDescription
locatorLocatorYesThe Playwright locator to validate.
optionsExpectOptionsNoOptional timeout configuration.

TypeScript Example

Verify Login Button

import { expect } from '@playwright/test';

await expect(
    page.getByRole('button', {
        name: 'Login'
    })
).toBeVisible();

Validate Success Message

await expect(
    page.getByText('Profile updated successfully')
).toBeVisible();

Verify Modal Dialog

await expect(
    page.locator('#confirmationModal')
).toBeVisible();

Enterprise Use Case

A cloud-based HR system displays a confirmation dialog after an employee record is successfully saved.

Instead of adding artificial delays, the automation framework waits for the dialog to become visible before verifying its content and proceeding with additional workflow validation.

This reduces flaky failures caused by variable server response times.

Command 37: expect().toHaveText()

What it does

The expect().toHaveText() assertion verifies that an element contains the expected text.

Playwright automatically retries the assertion until the correct text appears or the timeout expires. This is particularly valuable for applications where UI text updates after API responses or JavaScript execution.

The assertion supports:

  • Exact text matching
  • Partial matching
  • Regular expressions
  • Arrays of expected values for multiple elements

Syntax

await expect(locator).toHaveText(expectedText);

Parameters

ParameterTypeRequiredDescription
locatorLocatorYesElement whose text will be verified.
expectedTextstring | RegExp | string[]YesExpected text value.
optionsExpectOptionsNoOptional timeout and matching configuration.

TypeScript Example

Verify Page Heading

await expect(
    page.getByRole('heading')
).toHaveText('Dashboard');

Validate Notification

await expect(
    page.getByTestId('notification')
).toHaveText('Payment Successful');

Using a Regular Expression

await expect(
    page.getByText(/welcome/i)
).toHaveText(/Welcome/i);

Verify Multiple Items

await expect(
    page.locator('.menu-item')
).toHaveText([
    'Home',
    'Products',
    'Services',
    'Contact'
]);

Enterprise Use Case

An online banking platform displays transaction status after each payment.

The Playwright regression suite verifies messages such as:

  • Transaction Successful
  • Payment Declined
  • Insufficient Balance
  • Session Expired
  • OTP Verified

By validating the exact text presented to customers, the automation framework ensures both functional correctness and a consistent user experience.

toBeVisible() vs toHaveText()

FeaturetoBeVisible()toHaveText()
Verifies visibility✅ Yes❌ No
Verifies displayed text❌ No✅ Yes
Auto-retries until success✅ Yes✅ Yes
Supports regular expressions❌ No✅ Yes
Common UsageButtons, dialogs, formsMessages, headings, labels, notifications

Assertion Commands Covered So Far

CommandPurpose
waitForSelector()Waits until an element reaches the desired state.
waitForTimeout()Pauses execution for a fixed duration.
expect().toBeVisible()Verifies that an element is visible.
expect().toHaveText()Verifies that an element contains the expected text.

Command 38: expect().toHaveURL()

What it does

The expect().toHaveURL() assertion verifies that the current browser page has navigated to the expected URL.

Unlike manually retrieving the URL using page.url() and comparing strings, this assertion automatically retries until the expected URL is reached or the configured timeout expires. This makes it ideal for applications that perform redirects after login, form submissions, payment processing, or role-based navigation.

The assertion supports:

  • Exact URL matching
  • Partial URL matching
  • Regular expressions

Syntax

await expect(page).toHaveURL(expectedURL);

Parameters

ParameterTypeRequiredDescription
pagePageYesThe Playwright page instance.
expectedURLstring | RegExpYesExpected URL or URL pattern.
optionsExpectOptionsNoOptional timeout configuration.

TypeScript Example

Verify Dashboard URL

import { expect } from '@playwright/test';

await expect(page).toHaveURL(
    'https://example.com/dashboard'
);

Verify Using Wildcard

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

Validate Profile Page

await page.getByRole('link', {
    name: 'Profile'
}).click();

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

Enterprise Use Case

A banking application redirects users based on their roles after authentication.

Examples include:

  • /customer/dashboard
  • /employee/dashboard
  • /manager/dashboard
  • /admin/dashboard

The automation framework validates the destination URL before executing role-specific test cases, ensuring users are routed to the correct application module.

Command 39: expect().toHaveTitle()

What it does

The expect().toHaveTitle() assertion verifies the title of the currently loaded webpage.

The page title is defined within the HTML <title> element and is important for navigation, usability, browser tabs, accessibility, and search engine optimization.

Like other Playwright assertions, toHaveTitle() automatically retries until the expected title appears, making it reliable for applications where titles update dynamically after navigation.

Syntax

await expect(page).toHaveTitle(expectedTitle);

Parameters

ParameterTypeRequiredDescription
pagePageYesCurrent Playwright page instance.
expectedTitlestring | RegExpYesExpected page title.
optionsExpectOptionsNoOptional timeout configuration.

TypeScript Example

Verify Homepage Title

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

Regular Expression

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

Validate Dashboard Title

await page.goto(
    'https://example.com/dashboard'
);

await expect(page).toHaveTitle(
    'Customer Dashboard'
);

Enterprise Use Case

A SaaS project management platform provides separate dashboards for customers, project managers, developers, and administrators.

The automation suite validates page titles such as:

  • Customer Dashboard
  • Project Overview
  • Sprint Board
  • Administration Portal
  • Reports & Analytics

Verifying page titles ensures users have reached the correct module while also validating SEO-critical metadata for publicly accessible pages.

toHaveURL() vs toHaveTitle()

FeaturetoHaveURL()toHaveTitle()
Validates page URL✅ Yes❌ No
Validates page title❌ No✅ Yes
Supports regular expressions✅ Yes✅ Yes
Auto-retries✅ Yes✅ Yes
Best ForNavigation, redirects, routingMetadata, browser titles, SEO validation

Assertion Commands Covered So Far

CommandPurpose
waitForSelector()Waits until an element reaches a specific state.
waitForTimeout()Pauses execution for a fixed duration.
expect().toBeVisible()Verifies that an element is visible.
expect().toHaveText()Verifies displayed text.
expect().toHaveURL()Verifies the current page URL.
expect().toHaveTitle()Verifies the current page title.

Command 40: expect().toBeChecked()

What it does

The expect().toBeChecked() assertion verifies that a checkbox or radio button is currently selected.

Instead of manually retrieving the element state, Playwright automatically checks whether the control is selected and continuously retries until the expected state is reached or the timeout expires.

This assertion is particularly useful after using the check() command or after user actions that automatically enable certain options.

Syntax

await expect(locator).toBeChecked();

Parameters

ParameterTypeRequiredDescription
locatorLocatorYesCheckbox or radio button to validate.
optionsExpectOptionsNoOptional timeout configuration.

TypeScript Example

Verify Checkbox

import { expect } from '@playwright/test';

const termsCheckbox = page.getByLabel(
    'Accept Terms & Conditions'
);

await termsCheckbox.check();

await expect(termsCheckbox).toBeChecked();

Verify Radio Button

const paymentMethod = page.getByLabel(
    'Credit Card'
);

await paymentMethod.check();

await expect(paymentMethod).toBeChecked();

Enterprise Use Case

An enterprise ERP application contains a system configuration page with dozens of feature toggles.

The automation suite validates that critical options such as:

  • Enable MFA
  • Enable Audit Logs
  • Automatic Backups
  • Email Notifications
  • Session Timeout

remain enabled after configuration changes and software upgrades.

Using toBeChecked() ensures that configuration settings are persisted correctly across deployments.

Command 41: expect().toHaveValue()

What it does

The expect().toHaveValue() assertion verifies that an input, textarea, or other form control contains the expected value.

Unlike checking visible text, this assertion validates the actual value stored within the element, making it ideal for forms, search boxes, filters, and editable fields.

Playwright automatically retries until the expected value appears, making the assertion reliable even when values are populated asynchronously.

Syntax

await expect(locator).toHaveValue(expectedValue);

Parameters

ParameterTypeRequiredDescription
locatorLocatorYesForm element to validate.
expectedValuestring | RegExpYesExpected input value.
optionsExpectOptionsNoOptional timeout configuration.

TypeScript Example

Verify Username

await page
    .getByLabel('Username')
    .fill('Shahnawaz');

await expect(
    page.getByLabel('Username')
).toHaveValue('Shahnawaz');

Verify Search Box

await page
    .getByPlaceholder('Search')
    .fill('Playwright');

await expect(
    page.getByPlaceholder('Search')
).toHaveValue('Playwright');

Using Regular Expressions

await expect(
    page.getByLabel('Email')
).toHaveValue(/@gmail\.com$/);

Enterprise Use Case

A customer onboarding portal automatically populates profile information retrieved from an internal API.

The automation framework verifies that fields such as:

  • Customer Name
  • Email Address
  • Phone Number
  • Employee ID
  • Policy Number

contain the expected values before allowing users to continue with the onboarding workflow.

This validation helps detect issues caused by failed API responses, incorrect data mapping, or frontend rendering problems.

Assertion Comparison

FeaturetoBeChecked()toHaveValue()
Verifies checkbox state✅ Yes❌ No
Verifies radio button state✅ Yes❌ No
Verifies form field values❌ No✅ Yes
Supports regular expressions❌ No✅ Yes
Auto-retries until success✅ Yes✅ Yes

Waiting & Assertion Commands Summary

CommandPrimary Purpose
waitForSelector()Wait for an element to reach a specific state
waitForTimeout()Pause execution for a fixed duration
expect().toBeVisible()Verify element visibility
expect().toHaveText()Verify displayed text
expect().toHaveURL()Verify current page URL
expect().toHaveTitle()Verify page title
expect().toBeChecked()Verify checkbox or radio button state
expect().toHaveValue()Verify form field values

Choosing the Right Waiting or Assertion Command

ScenarioRecommended Command
Wait for a loading spinner to disappearwaitForSelector()
Pause execution while debuggingwaitForTimeout()
Verify a dialog or button is displayedexpect().toBeVisible()
Validate success or error messagesexpect().toHaveText()
Confirm navigation after loginexpect().toHaveURL()
Validate browser tab titleexpect().toHaveTitle()
Verify selected checkboxesexpect().toBeChecked()
Validate input field contentsexpect().toHaveValue()

Playwright Commands: Network & API Commands

Modern web applications constantly communicate with backend services through REST APIs, GraphQL endpoints, WebSockets, and third-party integrations. UI validation alone is often insufficient because many defects originate in network requests, incorrect API responses, or failed backend communication.

Playwright provides powerful network interception and API testing capabilities that allow QA engineers to inspect, modify, mock, and validate HTTP traffic without relying on external tools. These features make it possible to test frontend and backend behavior together within a single automation framework.

Command 42: page.route()

What it does

The page.route() command intercepts network requests that match a specified URL pattern before they reach the server.

Once intercepted, the request can be:

  • Continued without modification.
  • Blocked completely.
  • Modified before being sent.
  • Fulfilled with mocked response data.

This capability enables QA engineers to simulate server responses, isolate frontend testing from backend dependencies, validate error handling, and test scenarios that are difficult or expensive to reproduce in production environments.

Syntax

await page.route(url, handler);

Parameters

ParameterTypeRequiredDescription
urlstring | RegExpYesURL pattern that identifies requests to intercept.
handlerRouteHandlerYesCallback executed whenever a matching request is intercepted.

TypeScript Example

Continue the Request

await page.route('**/api/users', async route => {

    await route.continue();

});

Mock an API Response

await page.route('**/api/users', async route => {

    await route.fulfill({

        status: 200,

        contentType: 'application/json',

        body: JSON.stringify({
            id: 1,
            name: 'John Doe'
        })

    });

});

Block Image Requests

await page.route('**/*.{png,jpg,jpeg}', async route => {

    await route.abort();

});

Enterprise Use Case

A retail company’s frontend team wants to validate checkout functionality while the payment service is undergoing maintenance.

Instead of waiting for the backend to become available, the automation suite intercepts payment API requests and returns predefined success, failure, timeout, and validation responses.

This approach enables continuous UI testing while backend services are still under development or temporarily unavailable.

Command 43: page.waitForResponse()

What it does

The page.waitForResponse() command waits until a network response matching a specified URL or condition is received.

Unlike arbitrary delays, this command synchronizes test execution with actual backend activity. It is especially valuable when validating API-driven applications where data appears only after a successful server response.

QA engineers frequently combine this command with user actions such as clicking buttons, submitting forms, or applying filters.

Syntax

const response = await page.waitForResponse(urlOrPredicate);

Parameters

ParameterTypeRequiredDescription
urlOrPredicatestring | RegExp | functionYesURL pattern or callback used to identify the desired response.

TypeScript Example

Wait for an API Response

const response = await page.waitForResponse(
    '**/api/users'
);

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

Wait While Clicking a Button

const responsePromise = page.waitForResponse(
    '**/api/orders'
);

await page.getByRole('button', {
    name: 'Load Orders'
}).click();

const response = await responsePromise;

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

Wait Using a Predicate

await page.waitForResponse(response =>

    response.url().includes('/products') &&
    response.status() === 200

);

Enterprise Use Case

An investment management platform loads portfolio information through multiple REST APIs.

Instead of validating UI elements immediately after clicking Portfolio Summary, the automation framework waits for the portfolio API response, verifies the HTTP status code, and only then confirms that charts, balances, and investment details appear correctly on the page.

This strategy significantly improves test stability and reduces failures caused by slow backend responses.

Network Command Comparison

Featurepage.route()page.waitForResponse()
Intercepts requests✅ Yes❌ No
Mocks responses✅ Yes❌ No
Waits for server responses❌ No✅ Yes
Validates API completion❌ No✅ Yes
Common UsageMocking, interception, offline testingAPI synchronization, response validation

Command 44: page.waitForRequest()

What it does

The page.waitForRequest() command waits until the browser sends a network request that matches a specified URL or custom condition.

Unlike page.waitForResponse(), which waits for the server’s reply, this command focuses on the outgoing HTTP request. It is especially useful when validating that the frontend sends the correct API request after a user action.

QA engineers commonly use this command to verify:

  • API endpoints
  • HTTP methods
  • Request payloads
  • Query parameters
  • Request timing
  • Authentication headers

Because Playwright waits for the actual request instead of using fixed delays, tests remain fast and reliable.

Syntax

const request = await page.waitForRequest(urlOrPredicate);

Parameters

ParameterTypeRequiredDescription
urlOrPredicatestring | RegExp | functionYesURL pattern or callback used to identify the request.

TypeScript Example

Wait for an API Request

const request = await page.waitForRequest(
    '**/api/users'
);

expect(request.method()).toBe('GET');

Wait While Clicking a Button

const requestPromise = page.waitForRequest(
    '**/api/orders'
);

await page.getByRole('button', {
    name: 'Load Orders'
}).click();

const request = await requestPromise;

expect(request.method()).toBe('GET');

Wait Using a Predicate

await page.waitForRequest(request =>

    request.url().includes('/products') &&
    request.method() === 'POST'

);

Enterprise Use Case

An online banking application sends a secure POST request whenever a customer initiates a fund transfer.

The automation suite validates that:

  • The correct API endpoint is called.
  • The request uses the POST method.
  • Authentication headers are present.
  • The transaction payload contains the expected account number and transfer amount.

This ensures the frontend communicates correctly with backend financial services before validating the server response.

Command 45: page.on('request')

What it does

The page.on('request') event listener is triggered every time the browser sends an HTTP request.

Unlike waitForRequest(), which waits for a single matching request, this event continuously listens for all outgoing requests during the page session.

It is useful for monitoring network activity, logging API calls, collecting performance data, and debugging complex applications that communicate with multiple backend services simultaneously.

Syntax

page.on('request', callback);

Parameters

ParameterTypeRequiredDescription
eventstringYesNetwork event name (request).
callbackfunctionYesFunction executed whenever a request is sent.

TypeScript Example

Log Every Request

page.on('request', request => {

    console.log(request.method());

    console.log(request.url());

});

Log Only POST Requests

page.on('request', request => {

    if (request.method() === 'POST') {

        console.log(request.url());

    }

});

Monitor API Traffic

page.on('request', request => {

    if (request.url().includes('/api/')) {

        console.log(
            `${request.method()} ${request.url()}`
        );

    }

});

Enterprise Use Case

A logistics management platform communicates with dozens of backend microservices for shipment tracking, warehouse inventory, customer notifications, billing, and route optimization.

During regression testing, the automation framework listens to every outgoing request and records:

  • API endpoint
  • HTTP method
  • Request timestamp
  • Response correlation
  • Failed requests

These logs help QA engineers identify missing API calls, duplicate requests, and unexpected backend communication during large-scale enterprise testing.

waitForRequest() vs page.on('request')

FeaturewaitForRequest()page.on('request')
Waits for one request✅ Yes❌ No
Monitors all requests❌ No✅ Yes
Supports filtering✅ Yes✅ Yes
Suitable for assertions✅ Yes⚪ Indirectly
Best ForValidating specific API callsNetwork monitoring and debugging

Command 46: page.on('response')

What it does

The page.on('response') event listener is triggered whenever the browser receives an HTTP response from the server.

While page.waitForResponse() waits for a single matching response, page.on('response') continuously monitors every response throughout the lifetime of the page.

This command is valuable for:

  • Monitoring API health
  • Logging HTTP status codes
  • Measuring backend activity
  • Detecting failed API calls
  • Debugging microservice communication
  • Collecting network diagnostics

It enables QA engineers to understand how the frontend communicates with backend services without interrupting the application’s execution.

Syntax

page.on('response', callback);

Parameters

ParameterTypeRequiredDescription
eventstringYesResponse event name (response).
callbackfunctionYesFunction executed whenever a response is received.

TypeScript Example

Log Every Response

page.on('response', response => {

    console.log(response.status());

    console.log(response.url());

});

Log Failed Requests

page.on('response', response => {

    if (response.status() >= 400) {

        console.log(
            `Failed: ${response.status()} - ${response.url()}`
        );

    }

});

Monitor API Responses Only

page.on('response', response => {

    if (response.url().includes('/api/')) {

        console.log(
            `${response.status()} ${response.url()}`
        );

    }

});

Enterprise Use Case

A multinational airline booking platform communicates with numerous backend services for:

  • Flight availability
  • Seat selection
  • Fare calculation
  • Payment processing
  • Loyalty rewards
  • Booking confirmation

During regression testing, the automation framework listens to every response and automatically reports API failures, slow endpoints, and unexpected HTTP status codes, enabling QA teams to identify backend issues before they affect customers.

Command 47: APIRequestContext

What it does

APIRequestContext is Playwright’s built-in HTTP client that allows QA engineers to test REST APIs without launching a browser.

Unlike page-based commands that interact with the UI, APIRequestContext communicates directly with backend services, making API tests significantly faster and ideal for validating endpoints independently.

It supports all common HTTP operations, including:

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • HEAD

It also provides support for:

  • Authentication
  • Custom headers
  • Cookies
  • Request bodies
  • File uploads
  • JSON serialization

Syntax

const requestContext =
    await request.newContext(options);

Parameters

ParameterTypeRequiredDescription
optionsAPIRequestNewContextOptionsNoConfiguration such as base URL, headers, authentication, cookies, and timeout.

TypeScript Example

Create an API Context

import { request } from '@playwright/test';

const api = await request.newContext({

    baseURL: 'https://api.example.com'

});

Add Authentication Header

const api = await request.newContext({

    baseURL: 'https://api.example.com',

    extraHTTPHeaders: {

        Authorization: 'Bearer TOKEN'

    }

});

Use Cookies

const api = await request.newContext({

    storageState: 'auth.json'

});

Enterprise Use Case

A healthcare management platform exposes hundreds of REST APIs for patient registration, appointment scheduling, prescriptions, billing, and laboratory reports.

Instead of validating these APIs through the browser, the QA team creates an APIRequestContext and executes API tests directly.

Benefits include:

  • Faster execution
  • Reduced infrastructure costs
  • Independent backend validation
  • Easier CI/CD integration
  • Early defect detection before UI testing begins

Many enterprise organizations execute thousands of API tests using APIRequestContext before launching browser-based end-to-end tests.

page.on('response') vs APIRequestContext

Featurepage.on('response')APIRequestContext
Monitors browser traffic✅ Yes❌ No
Performs standalone API testing❌ No✅ Yes
Requires browser interaction✅ Yes❌ No
Suitable for backend validation⚪ Limited✅ Excellent
Best ForNetwork monitoring and debuggingREST API automation

Command 48: request.get()

What it does

The request.get() command sends an HTTP GET request using Playwright’s APIRequestContext. It is primarily used to retrieve data from REST APIs without launching a browser, making API validation significantly faster than UI-driven testing.

QA engineers commonly use request.get() to verify:

  • API availability
  • HTTP status codes
  • JSON responses
  • Authentication
  • Response headers
  • Performance baselines

Because the request is executed directly against the backend, it eliminates browser rendering overhead and enables rapid API regression testing.

Syntax

const response = await request.get(url, options);

Parameters

ParameterTypeRequiredDescription
urlstringYesAPI endpoint to call.
optionsAPIRequestOptionsNoRequest configuration including headers, query parameters, timeout, and authentication.

TypeScript Example

Send a GET Request

import { request, expect } from '@playwright/test';

const api = await request.newContext();

const response = await api.get(
    'https://api.example.com/users'
);

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

Read JSON Response

const data = await response.json();

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

Send Headers

await api.get(
    'https://api.example.com/profile',
    {
        headers: {
            Authorization: 'Bearer TOKEN'
        }
    }
);

Enterprise Use Case

A digital banking platform exposes customer profile APIs that are consumed by web and mobile applications.

Before executing UI automation, the QA pipeline validates that:

  • Customer information is returned successfully.
  • Authentication tokens are accepted.
  • Required response fields exist.
  • The API responds with HTTP 200.

This allows backend defects to be identified before browser-based regression tests begin.

Command 49: request.post()

What it does

The request.post() command sends an HTTP POST request to create or submit data to a backend service.

It is one of the most frequently used API commands because enterprise applications constantly create new resources such as users, orders, transactions, support tickets, and product records.

The command supports:

  • JSON request bodies
  • Form data
  • Multipart file uploads
  • Custom headers
  • Authentication
  • Cookies

Syntax

const response = await request.post(url, options);

Parameters

ParameterTypeRequiredDescription
urlstringYesAPI endpoint.
optionsAPIRequestOptionsNoRequest body, headers, authentication, timeout, and other options.

TypeScript Example

Create a New User

const response = await api.post(
    'https://api.example.com/users',
    {
        data: {
            name: 'John Doe',
            email: 'john@example.com'
        }
    }
);

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

Submit JSON Data

await api.post(
    'https://api.example.com/orders',
    {
        data: {
            productId: 101,
            quantity: 2
        }
    }
);

Send Authorization Header

await api.post(
    'https://api.example.com/payments',
    {
        headers: {
            Authorization: 'Bearer TOKEN'
        },
        data: {
            amount: 500
        }
    }
);

Enterprise Use Case

An insurance company provides REST APIs for claim submission.

Instead of manually creating claims through the user interface, the automation framework sends POST requests to:

  • Create customer profiles.
  • Register insurance policies.
  • Submit claims.
  • Upload claim metadata.
  • Generate reference numbers.

Using request.post() dramatically reduces execution time while enabling precise validation of backend business logic.

request.get() vs request.post()

Featurerequest.get()request.post()
Retrieves data✅ Yes❌ No
Creates or submits data❌ No✅ Yes
Supports request body❌ No✅ Yes
Supports custom headers✅ Yes✅ Yes
Common UsageFetch resources, validate APIsCreate records, submit forms, transactions

Network & API Commands Summary

CommandPrimary Purpose
page.route()Intercept, modify, or mock network requests
page.waitForResponse()Wait for a matching server response
page.waitForRequest()Wait for an outgoing request
page.on('request')Monitor all outgoing requests
page.on('response')Monitor all incoming responses
APIRequestContextCreate an isolated HTTP client for API testing
request.get()Retrieve data from REST APIs
request.post()Submit or create data using REST APIs

Choosing the Right Network & API Command

ScenarioRecommended Command
Mock backend servicespage.route()
Wait for an API responsepage.waitForResponse()
Verify an outgoing requestpage.waitForRequest()
Log all outgoing requestspage.on('request')
Monitor all server responsespage.on('response')
Build browser-independent API testsAPIRequestContext
Read resources from an APIrequest.get()
Create records or submit datarequest.post()

Command 50: page.pause()

What it does

The page.pause() command temporarily pauses test execution and opens the Playwright Inspector.

While execution is paused, QA engineers can:

  • Inspect page elements.
  • View generated locators.
  • Execute commands step by step.
  • Resume execution manually.
  • Analyze browser state.
  • Debug failing automation scenarios.

This command is intended for development and debugging and should typically be removed or disabled before running automated regression suites in CI/CD pipelines.

Syntax

await page.pause();

Parameters

This command does not accept any parameters.

TypeScript Example

Pause Before Login

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

await page.pause();

Pause Before Clicking Submit

await page.fill('#username', 'admin');

await page.fill('#password', 'Password123');

await page.pause();

await page.click('#login');

Enterprise Use Case

A QA engineer investigates an intermittent failure in a procurement application where a dynamically generated menu occasionally fails to appear.

By inserting page.pause(), the engineer launches Playwright Inspector, verifies locator accuracy, inspects the DOM, and steps through the execution flow to identify timing issues without modifying the application code.

People Asked Questions

What are the most important Playwright commands?

The most important Playwright commands include chromium.launch(), browser.newContext(), page.goto(), locator(), click(), fill(), expect().toBeVisible(), page.route(), and page.screenshot(). These commands cover browser automation, element interaction, assertions, network interception, and debugging.

How many Playwright commands should a QA engineer know?

A QA engineer should be comfortable with at least 50 core Playwright commands covering browser management, navigation, locators, actions, assertions, API testing, debugging, and utility functions to build reliable end-to-end automation frameworks.

Are Playwright commands different from Selenium commands?

Yes. Playwright commands provide built-in auto-waiting, powerful locators, browser contexts, network interception, and integrated API testing. Selenium often requires additional synchronization and third-party libraries to achieve similar functionality.

Which Playwright command is used for element locators?

Playwright offers several locator commands, including locator(), getByRole(), getByText(), getByLabel(), getByPlaceholder(), getByTestId(), getByAltText(), getByTitle(), and frameLocator().

Can Playwright test REST APIs?

Yes. Using APIRequestContext, request.get(), request.post(), and other HTTP methods, Playwright can perform standalone API testing without launching a browser, making backend validation faster and more efficient.

Which programming languages support Playwright?

Playwright officially supports TypeScript, JavaScript, Python, Java, and .NET, allowing QA teams to choose the language that best fits their automation ecosystem.

Internal Links:

External Resources

More Related Blogs

Conclusion

This comprehensive guide covered 50 Playwright Commands that every QA Engineer, SDET, and Test Automation Engineer should understand—from browser management and navigation to locators, actions, assertions, network interception, API testing, and debugging. Mastering these commands will help you build faster, more reliable, and maintainable automation frameworks while preparing you for enterprise projects and technical interviews.

Whether you’re beginning your Playwright journey or enhancing an existing automation framework, keeping these commands readily available as a reference will significantly improve your productivity and code quality.


Enjoyed this article? Explore more in-depth guides on AI engineering, automation testing, Model Context Protocol, Playwright, and intelligent software quality at www.skakarh.com. Follow QAPulse by SK for practical, production-focused tutorials designed for QA engineers, SDETs, and AI developers.

Frequently Asked Questions

What are the key expectations for modern QA Engineers?
Today's QA Engineers are expected to deliver reliable software at an unprecedented speed. They must support Agile development, DevOps practices, CI/CD, cloud-native applications, and AI-assisted software development.
Why has automated testing become a critical pillar of modern software delivery?
The rapid pace of modern software releases makes manual testing alone insufficient for maintaining software quality. Automated testing enables teams to validate functionality, detect regressions early, and release updates with confidence.
What makes Playwright a significant browser automation framework for QA Engineers?
Playwright intelligently handles browser interactions, automatically waits for elements to become actionable, and supports multiple browsers from a unified API. It provides powerful debugging capabilities, allowing QA Engineers to focus on validating business functionality.
Advertisement
Found this helpful? Clap to let Shahnawaz know — you can clap up to 50 times.