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 see how to write an real example test on a simple Tic Tac Toe game

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

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

  // Launch the browser
  const browser = await chromium.launch();
  const page = await browser.newPage();

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

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

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

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

  // Player 1 makes their moves (X)
  await makeMove(0, "X");

  // Player 2 makes their move (O)
  await makeMove(1, "O");

  // Player 1 makes another move (X)
  await makeMove(3, "X");

  // Player 2 makes another move (O)
  await makeMove(4, "O");

  // Player 1 makes the last move to win (X)
  await makeMove(6, "X");

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

  // Close the browser
  await browser.close();
});

Selecting Elements

By following below order—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