Playwright Codegen: Record Tests, Pick Locators and Generate Code

Playwright Codegen records your clicks and typing and turns them into test code. In this lesson you will use it from the terminal and VS Code, add assertions while recording, record logged-in flows, and refactor the generated code into a clean, reliable test.

Advertisement

πŸ“– What You’ll Learn: starting codegen, the Inspector toolbar, assertions while recording, options for devices, browsers and test ids, saving and loading sessions, recording in VS Code, page.pause(), and a refactoring checklist for recorded code.


πŸŽ₯ What Is Playwright Codegen?

Codegen is Playwright’s built-in test recorder. You use the website normally in a browser window, and Playwright writes the test code for every click, fill and navigation in real time. It also helps you:

  • Find the best locator for any element (“Pick locator”).
  • Add assertions by clicking elements (visible, text, value).
  • Learn the Playwright API quickly by watching what code each action produces.

It is a learning and productivity tool, not a replacement for designing tests. You will record, then refactor the code into clean tests.


▢️ Start Codegen from the Terminal

From your Playwright project folder (see Install Playwright):

npx playwright codegen https://www.saucedemo.com

Two windows open:

  1. A browser window where you interact with the site.
  2. The Playwright Inspector, which shows the generated code and a toolbar.

Now log in with standard_user / secret_sauce and add a product to the cart. The Inspector writes code like this:

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

test('test', async ({ page }) => {
  await page.goto('https://www.saucedemo.com/');
  await page.locator('[data-test="username"]').click();
  await page.locator('[data-test="username"]').fill('standard_user');
  await page.locator('[data-test="password"]').click();
  await page.locator('[data-test="password"]').fill('secret_sauce');
  await page.locator('[data-test="login-button"]').click();
  await page.locator('[data-test="add-to-cart-sauce-labs-backpack"]').click();
});

The exact locators depend on your Playwright version and the page, but Codegen always prefers stable, user-facing locators: roles, labels, placeholders, text and test ids.


🧰 The Inspector Toolbar

ButtonWhat it does
RecordStart or stop recording actions
Pick locatorHover and click any element to get its locator
Assert visibilityClick an element to add toBeVisible()
Assert textClick an element to add toContainText()
Assert valueClick an input to add toHaveValue()
CopyCopy the generated code
ClearStart a fresh recording
Target dropdownChoose the output language (Playwright Test TypeScript, Python, Java, C#…)

πŸ’‘ Tip: Use Assert text and Assert visibility while recording. A recorded test without assertions only proves that clicks did not crash; it does not prove that the application worked.


βš™οΈ Useful Codegen Options

# Save the code straight to a file
npx playwright codegen -o tests/recorded.spec.ts https://www.saucedemo.com

# Emulate a mobile device
npx playwright codegen --device="iPhone 13" https://www.saucedemo.com

# Choose the browser: cr (Chromium), ff (Firefox), wk (WebKit)
npx playwright codegen -b wk https://www.saucedemo.com

# Set the window size, color scheme, language or time zone
npx playwright codegen --viewport-size="1280,720" --color-scheme=dark --lang="en-IN" --timezone="Asia/Kolkata" https://example.com

# Use your own test id attribute in generated locators
npx playwright codegen --test-id-attribute=data-test https://www.saucedemo.com

Record once logged in

Save the session after you log in, then start later recordings already authenticated:

# 1. Log in manually, then close the browser: cookies and storage are saved
npx playwright codegen --save-storage=auth.json https://www.saucedemo.com

# 2. Next recordings start logged in
npx playwright codegen --load-storage=auth.json https://www.saucedemo.com/inventory.html

The same storageState idea is used in real test suites: see save and reuse login sessions.

⚠️ Common mistake: Files like auth.json contain real session cookies. Add them to .gitignore and never commit them.


πŸ§‘β€πŸ’» Record from VS Code

With the Playwright Test for VSCode extension:

  • Record new: creates a new test file and opens a browser; actions are written directly into the file.
  • Record at cursor: inserts recorded actions where your cursor is in an existing test.
  • Pick locator: click an element in the browser and the locator is copied into the editor’s locator box.

This is often faster than the terminal, because code lands straight in your project.


⏸️ Record in the Middle of a Test with page.pause()

Add await page.pause() to any test and run it headed. The test stops there and opens the Inspector, where you can record new steps from the current state of the page:

test('extend an existing flow', async ({ page }) => {
  await page.goto('https://www.saucedemo.com/');
  await page.getByPlaceholder('Username').fill('standard_user');
  await page.getByPlaceholder('Password').fill('secret_sauce');
  await page.getByRole('button', { name: 'Login' }).click();

  await page.pause(); // Inspector opens here; click Record to capture the next steps
});
npx playwright test tests/extend.spec.ts --headed

Remove page.pause() before committing the test.


🧹 From Recording to a Real Test: Refactor Checklist

Recorded code is a draft. Turn it into a maintainable test:

  1. Give the test a real name instead of 'test'.
  2. Remove redundant steps such as a click() right before a fill() on the same field.
  3. Add assertions for the outcome of each important step.
  4. Use baseURL and page.goto('/') instead of the full URL (config file).
  5. Move test data out of the code (credentials, product names) into variables or files.
  6. Replace fragile locators like nth(3) with role or text locators (locators, CSS and XPath).
  7. Extract repeated flows (login) into helpers or page objects.

The recorded test above, refactored:

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

const user = { username: 'standard_user', password: 'secret_sauce' };

test('standard user can add a backpack to the cart', async ({ page }) => {
  await page.goto('https://www.saucedemo.com/');
  await page.getByPlaceholder('Username').fill(user.username);
  await page.getByPlaceholder('Password').fill(user.password);
  await page.getByRole('button', { name: 'Login' }).click();
  await expect(page.locator('.title')).toHaveText('Products');

  await page.locator('[data-test="add-to-cart-sauce-labs-backpack"]').click();
  await expect(page.locator('.shopping_cart_badge')).toHaveText('1');
});

βš–οΈ Codegen: Strengths and Limits

Good forNot good for
Learning the API and locatorsDesigning test structure and coverage
Quickly drafting a happy pathData-driven and negative scenarios
Finding locators on complex pagesReusable code (no page objects or fixtures)
Reproducing a bug reportComplex logic, loops and conditions

πŸ“ Assignment

  1. Run npx playwright codegen https://www.saucedemo.com and record: log in, add two products, open the cart. Save the code to tests/recorded-cart.spec.ts with -o.
  2. While recording, add at least two assertions using Assert text and Assert visibility.
  3. Refactor the recording using the seven-step checklist above, and make it pass headless.
  4. Record the same flow with --device="Pixel 5" and compare any differences in the generated code.
  5. Use --save-storage to save a logged-in session, then start a new recording with --load-storage directly on the inventory page.
  6. Bonus: add page.pause() to your test, record one more step from the Inspector, then remove pause().

❓ FAQ

πŸ€” What is Playwright codegen?

A built-in recorder that generates Playwright test code while you interact with a website. Start it with npx playwright codegen <url>.

πŸ€” How do I record a test in Playwright?

Run npx playwright codegen https://your-site.com, perform the actions in the browser, and copy the generated code from the Inspector, or use Record new in the VS Code extension.

πŸ€” Can Playwright codegen generate TypeScript?

Yes. The default target for Playwright Test is TypeScript/JavaScript, and you can switch to Python, Java or C# in the Inspector’s target dropdown.

πŸ€” Is codegen code good enough for production tests?

Treat it as a first draft. Rename tests, add assertions, remove redundant steps, move test data out and use page objects before adding it to your suite.

πŸ€” How do I get a locator for one element without recording?

Use Pick locator in the Inspector or the VS Code extension, then hover and click the element.


🎯 Next Steps

🎬 Watch the full Playwright tutorial series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

1 thought on “Playwright Codegen: Record Tests, Pick Locators and Generate Code”

Leave a Comment