Deep dive into Playwright

Introduction

Playwright is a powerful, open-source automation library for web applications, developed by Microsoft and launched in January 2020. It enables developers to write scripts that automate web browsers for a wide range of tasks, including testing, web scraping, and browser-based automation workflows.

Key Features

Playwright’s Architecture

It’s built around the following core components:

Real Example

Let’s see how to write a real example test on a simple Tic Tac Toe game

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

test("Tic Tac Toe game play", async ({ page }) => {
  const player1Name = "Razvan";
  const player2Name = "Cosmin";

  // Navigate to the game page
  await page.goto("https://razvantimis.github.io/tic-tac-toe/");

  // Start the game by entering player names
  await page.locator("#name1").fill(player1Name);
  await page.locator("#name2").fill(player2Name);
  await page.getByRole("button", { name: "Confirm" }).click();

  // Wait for the names dialog to disappear
  await page.locator(".names-dialog").waitFor({ state: "hidden" });

  // Helper to simulate a player move
  const makeMove = async (position: number, expectedText: string) => {
    const cell = page.getByTestId(`game-cell-${position}`);
    await cell.click();
    await expect(cell).toHaveText(expectedText);
  };

  // Player 1 (X) and Player 2 (O) take turns
  await makeMove(0, "X");
  await makeMove(1, "O");
  await makeMove(3, "X");
  await makeMove(4, "O");
  await makeMove(6, "X"); // Winning move

  // Verify the winning condition
  await expect(page.locator(".result-dialog")).toBeVisible();
  await expect(
    page.getByRole("heading", { name: `${player1Name} Wins!` })
  ).toBeVisible();
});

Selecting Elements

By following the order below — focusing on accessibility first and then stability — you can create more robust and maintainable tests in Playwright.

  1. page.getByRole(role, options): Targets elements by their ARIA role, enhancing accessibility in tests.
await page.getByRole("button", { name: "Confirm" }).click();
  1. page.getByTestId(testId): Using a data-testid attribute for selecting elements in tests provides stability and clarity
await page.getByTestId(`game-cell-${position}`).click();
  1. page.locator(selector): Selects elements using CSS selectors.
await expect(page.locator('.gamecell[data-position="0"]')).toHaveText("X");

Conclusion

Playwright is a game-changer in browser automation, offering a fast, flexible framework for complex web testing scenarios. With multi-browser support, parallel execution, and modern APIs, it’s an ideal choice for developers and QA engineers looking to create reliable and maintainable test suites.

References