Playwright Playground - Interactive Testing Lab

Practise the Playwright API the way you will write it at work: every step is an awaited page action and every check is a web-first expect() assertion. The playground runs your steps one by one on our demo shop, so you can see each fill, click and assertion land. It runs in your browser and supports the Playwright commands listed on this page, not the full Playwright test runner.

Open the Playwright playground

Await Every Step
Write async steps with await page.goto(), page.fill() and page.click(), then run them with one button
Watch It Happen
Each step acts on the demo shop next to the editor, so a wrong selector is easy to spot
Seven Ready-made Flows
Login, sorting, cart, checkout and logout tests to load, run and change

How to Practise Playwright Here

Step 1: Load a Flow

Pick a test from the "Test Cases" dropdown. The Full Checkout Flow is the longest: it logs in, adds the backpack to the cart, fills in the checkout form and checks that the Back Home button appears on the confirmation page.

Step 2: Write Steps with await

Every Playwright action returns a promise, so each line starts with await. The playground supports these forms:

await page.goto('/')
await page.fill('[data-test="username"]', 'standard_user')
await page.click('[data-test="login-button"]')
await page.selectOption('[data-test="product-sort-container"]', 'price-asc')
await expect(page.locator('[data-test="error"]')).toHaveText(/Username and password/)

Every element in the demo shop has a data-test attribute, which makes a stable selector.

Step 3: Run and Read the Report

Click "Run Test". The results panel numbers each step, marks it PASS or FAIL and shows how long the run took. The first failing step stops the run, just as a failed assertion stops a real Playwright test.

Step 4: Fix the Failing Step

The log says which step failed and why. The usual causes:

  • Element not found: compare the selector with the data-test value in the demo shop (right-click the element and choose Inspect)
  • Text mismatch: the log shows the text it found; copy it, or match part of it with a /regex/
  • Page not ready: after a click that loads a new page, add await page.waitForTimeout(1000); real Playwright waits on its own, this playground runs each step once

Playwright Commands This Playground Runs

This is the part of the Playwright API the playground carries out. A selector is a CSS selector such as '[data-test="username"]'.

await page.goto('/') Opens the demo shop (the only address available here)
await page.fill(selector, 'text') Replaces the field's value in one step
await page.click(selector) Clicks a button or link
await page.selectOption(selector, 'price-asc') Picks a value in a select box, such as the sort order
await page.waitForTimeout(1000) Pauses for the given number of milliseconds
await expect(page.locator(selector)).toBeVisible() Passes when the element is shown
await expect(page.locator(selector)).toHaveText('text') Checks the text; also accepts a /regex/, and .first() when several elements match

Anything else, such as getByRole() or toHaveURL(), stops the run with a message naming the command, so a test never shows as passed for steps that did not run.

Playwright Skills to Practise

fill() Instead of Typing

page.fill() clears a field and sets its value in one step. Use it on the username, password and checkout fields.

Choosing from a Select Box

Sort the products by price with page.selectOption() and the value price-asc, then check a price with toHaveText(/\$/).

Web-first Assertions

expect(locator).toBeVisible() and toHaveText() describe what the user sees, which keeps a test easy to read.

Negative Login Tests

Log in with a wrong password and assert that the error banner appears with the right message.

Cart Badge Checks

Add the backpack to the cart and assert that the cart badge shows 1.

A Complete User Journey

Chain login, cart, the checkout form and Finish into one test that ends on the Back Home button.

Playwright Habits for Your Own Projects

Prefer user-facing locators

In real projects, getByRole(), getByLabel() and getByTestId() survive markup changes better than CSS selectors. This playground uses CSS selectors only.

Let Playwright wait for you

Actions and expect() assertions retry until the element is ready, so fixed waits like waitForTimeout() are rarely needed outside this playground.

Await every call

A missing await lets the test move on before the action finishes, which causes failures that come and go and are hard to trace.

Keep tests independent

Playwright gives every test a fresh browser context, so tests can run in parallel. Log in inside each test, or reuse a saved session with storageState.

Run in more than one browser

The same test can run in Chromium, Firefox and WebKit by adding projects in playwright.config.ts.

Frequently Asked Questions

Is this the real Playwright test runner?

No. Playwright runs on Node.js and drives real browsers. This page carries out the core page actions and assertions in your browser so you can practise the syntax and the flow of a test. To run full suites, install it with npm init playwright@latest.

Why do the examples use waitForTimeout()?

Real Playwright waits automatically for elements before acting on them. This playground runs each step once, so the examples pause briefly after logging in. In your own tests, leave these waits out.

How do I find the right selector?

Right-click an element in the demo shop and choose Inspect. Every element you need has a data-test attribute, such as data-test="login-button", which you can use as '[data-test="login-button"]'.

Can Playwright test APIs too?

Yes. A Playwright test can call an API through the request fixture, for example const response = await request.get('/api/items'), and check it with await expect(response).toBeOK(). This playground focuses on the user interface.

The Tech World Labs Demo

Playwright Test Editor
Test Results

Run a test to see results