Your First Playwright Test

By Syncfusion®, Inc. · Last updated

The parts of a test (import, test(), the page fixture, page.goto()), writing a test that acts and checks, running tests from the command line in one file or one browser, headless and headed mode, reading results (passed, failed, flaky, skipped), the HTML report, and recording tests with Codegen.

Your First Playwright Test

  • Now you will write a test yourself, line by line.
  • Every Playwright test has the same small shape. Once you know it, you can read any test.
  • Then you will run tests in different ways, read the results and record a test with Codegen.

Simple lesson: a test opens a page, does what a user does, and checks the result.

A Real-World Example

  • Priya adds a "mark as done" feature to her to-do app.
  • She wants a test for it: add a task, tick it, and check that the counter says 0 items left.
  • Here is her test. Press ▶ Run tests, then open the Steps tab to see each action.
  • What happened: the test typed a task, ticked its checkbox and checked the counter.
  • The Steps tab lists each action with its time.

What You Will Learn

  1. The parts of a test.
  2. How to write a test that acts and checks.
  3. How to run all tests, one file, or one browser.
  4. Headless and headed mode.
  5. How to read the results and the HTML report.
  6. How to record a test with Codegen.

Anatomy of a Test

  • Every test file has the same building blocks. The animation points at each one.

Animation: the parts of a test are highlighted one by one: the import line, test with its title, the page fixture, page.goto, an action, and an assertion

import test, expect from '@playwright/test'; test('has a title', async ( page ) => await page.goto('https://…'); await page.getByRole('link').click(); await expect(page).toHaveTitle(/Shop/); );

1. Import test and expect 2. test(title, body) 3. The page fixture 4. Open a page 5. Act like a user 6. Check the result

Six parts: import, test, page, goto, an action, and an assertion.

Importing test and expect

  • import { test, expect } from '@playwright/test'; is the first line of almost every test file.
  • test declares a test. expect checks a result.

The test() Function

  • test('title', async ({ page }) => { ... }) declares one test.
  • The title is a short sentence about what the test proves. It appears in every report.
  • The body is an async function. Playwright calls it when the test runs.
  • async = a function that can wait. Inside it, await waits for each step to finish.

The page Fixture (First Look)

  • { page } asks Playwright for a page: a fresh browser tab, made just for this test.
  • Fixture = something Playwright prepares for your test and cleans up after it.
  • You never start or close the browser yourself. Fixtures explains how this works.

Navigating with page.goto()

  • await page.goto(url) opens a web address and waits for the page to load.
  • Always await it. Without await, the test moves on before the page is there.

Test File Naming

  • Playwright runs files whose names end in .spec.ts or .test.ts (or .js).
  • Name the file after the feature it tests: login.spec.ts, cart.spec.ts.
  • A file called login.ts is not a test file. Playwright skips it.

await = "wait until this step is done". Every Playwright action and every web-first assertion returns a promise. Put await in front of each one.

Simple lesson: import, test(), { page }, page.goto(), then actions and checks.

Writing a Test

Writing a Simple Test

  • The smallest useful test opens a page and checks one thing.
  • This one opens the Practice Shop and checks the page title.
  • /Practice Shop/ is a regular expression. It means "the title contains Practice Shop".
  • A plain string, 'Home | Practice Shop', would need the whole title to match.

Interacting with the Page and Adding an Assertion

  • A real test does something, then checks the result.
  • Below, the test searches the product list, then checks how many products are left.
  • Assertion = a check that must be true. If it is false, the test fails.
  • Good tests follow three steps: arrange (open the page), act (click, type), assert (check).

Simple lesson: open the page, act like a user, then assert what the user should see.

Running Tests

npx playwright test

  • npx playwright test runs every test file, in every browser listed in the config.
  • In the labs, the command line sits under the editor. You can edit it like a real terminal.
  • Two files, two tests, three browsers: six results.
  • Now change the command and run it again:
CommandWhat it runs
npx playwright testEvery test, in every project
npx playwright test cartOnly files whose name contains cart
npx playwright test tests/cart.spec.tsOne file
npx playwright test --project=chromiumEvery test, in Chromium only
npx playwright test cart --project=firefoxOne file, in Firefox only
  • Each browser in the config is a project. Playwright Configuration explains projects.

Headless vs Headed Mode

  • Headless = the browser runs with no window. This is the default. It is fast and works on servers.
  • Headed = you see the browser window. Add --headed to watch your test run.
  • In the lab, the Browser tab always shows the page, so you can watch every run.

Reading Terminal Output

  • Each line of the output is one test in one browser:
  ✓  1 [chromium] › tests/cart.spec.ts:3:1 › adding a product updates the cart count (612ms)
  • ✓ = the result. 1 = the order. [chromium] = the project. Then the file, the line and column, the title and the time.

Passed, Failed, Flaky and Skipped

  • Run this file. It has one test of each kind. The command adds --retries=1, so a failed test gets one more try.
ResultMarkMeaning
Passed✓Every step worked and every check was true
Failed✘A step or a check failed, on every try
Flaky✘ then ✓It failed first, then passed on a retry. Something is unreliable
Skipped-The test did not run, because you told Playwright to skip it

A flaky test is a warning, not a success. Find out why it failed the first time. Playwright Configuration shows how retries work.

Simple lesson: npx playwright test runs everything. Add a file name or --project to run less.

Viewing Results

Opening the HTML Report

  • A new project uses the HTML reporter. After each run, it writes playwright-report/index.html.
  • npx playwright show-report opens it in your browser.
  • When a test fails, the report opens by itself.

Sketch of an HTML report: filter tabs All, Passed, Failed, Flaky, Skipped, then a list of tests with their browser and time

Search tests

All 6 Passed 4 Failed 1 Flaky 1 Skipped 0

✘ checkout shows the totalchromium · cart.spec.ts:125.2s

± sync completesfirefox · sync.spec.ts:31.6s

✓ home page has the shop namewebkit · home.spec.ts:30.9s

Click a test to see its steps, its error and its trace.

A sketch of the HTML report. Filter by result, then open a test to see what happened.

  • The lab shows the same facts in the Terminal and Steps tabs. Reporting covers the HTML report in depth.

Simple lesson: npx playwright show-report opens a clickable report of the last run.

Recording Tests with Codegen

  • Codegen = a tool that writes test code while you click around a page.
  • In a real project, npx playwright codegen https://example.com opens two windows: a browser and the Inspector, which shows the code.
  • Try the practice version below. Add two tasks, tick one, then click Assert text and click the counter.

Codegen

Recording Actions and Assertions

  • Every click, fill and key press becomes one line of code.
  • The assertion buttons add checks: Assert visibility, Assert text and Assert value.
  • Codegen picks good locators for you: roles, labels and test ids first.

Copying Generated Locators

  • The Inspector also has a Pick locator button. Click any element, and it shows the best locator for it.
  • Locators has a practice picker.

Codegen Options

OptionExampleWhat it does
--devicenpx playwright codegen --device="iPhone 13" <url>Records on an emulated phone
--viewport-sizenpx playwright codegen --viewport-size="800,600" <url>Sets the window size
--targetnpx playwright codegen --target=python <url>Writes code in another language
--outputnpx playwright codegen -o tests/new.spec.ts <url>Saves the code to a file

Cleaning Up Generated Tests

  • Recorded code is a draft. Before you keep it:
  1. Give the test a real title. Codegen calls every test 'test'.
  2. Delete extra clicks you made by accident.
  3. Add assertions. A test with no expect() proves almost nothing.
  4. Move repeated steps into a helper. Page Object Model shows how.

Limits of Generated Code

  • Codegen records what you did, not why. It cannot know what result matters.
  • It may pick a weak locator, such as one based on text that changes.
  • Use it to start fast. Then edit the test like any code you write.

Codegen is great for learning. Record a flow, then read the code. You will learn locators quickly.

Simple lesson: Codegen writes a first draft. You add a title, assertions and clean-up.

Try It in Your Project

  • These steps take the lesson from the lab to your own app.
  • Record one flow of your app with npx playwright codegen <your-url>.
  • Clean the recording: rename the test, replace weak locators, add a real assertion at the end.
  • Run it headed once, then headless, and open the HTML report.

Simple lesson: use one idea from this lesson on your own app this week.

TL;DR

  • A test has an import, test(), the page fixture, page.goto(), actions and assertions.
  • Put await before every action and web-first assertion.
  • Test files end in .spec.ts or .test.ts.
  • npx playwright test runs everything. Add a file name or --project to run less.
  • Results are passed, failed, flaky or skipped.
  • npx playwright show-report opens the HTML report.
  • npx playwright codegen records a draft test.

Common mistakes

MistakeWhat happensFix
Forgetting await before page.goto()The next step runs before the page loadsPut await before every Playwright call
Naming the file login.tsPlaywright finds no tests in itName it login.spec.ts
A test with no expect()It passes even when the feature is brokenAdd at least one assertion
Keeping Codegen's test('test', ...)Reports are full of tests called "test"Give each test a clear title
Ignoring flaky testsReal bugs hide behind retriesFix the cause of the first failure

Check Yourself

Exercises

What to Remember

  • A test is: import, test(), { page }, goto, act, assert.
  • await every Playwright call.
  • Run less with a file name or --project.
  • Flaky means "unreliable", even if it passed in the end.
  • Codegen gives you a draft. You add the meaning.

Next: Locators