Introduction: What Is a Playwright First Test Script?
If you are new to Playwright, the best way to understand the framework is to write a small working test from scratch.
A Playwright first test script is a simple automated test that opens a web page, performs an action, and verifies an expected result.
For example, your first test might:
- Open a website.
- Locate a button or link.
- Click it.
- Verify that the expected page or text appears.
A basic Playwright Test looks like this:
import { test, expect } from ‘@playwright/test’;
test(‘verify Playwright homepage’, async ({ page }) => {
await page.goto(‘https://playwright.dev/’);
await expect(page).toHaveTitle(/Playwright/);
});
This is enough to demonstrate the fundamental workflow of Playwright automation testing:
Test
↓
Open browser page
↓
Navigate
↓
Interact
↓
Assert expected result
↓
Pass or fail
This Playwright first test script tutorial starts from installation and project setup and gradually introduces locators, assertions, auto-waiting, debugging, screenshots, reports, browsers, and CI/CD.
Prerequisites for Writing Your First Playwright Test
Before creating your Playwright first test script, you should have a few basic tools installed.
Required
- Node.js
- npm
- A code editor such as VS Code
- Basic JavaScript or TypeScript knowledge
- Basic understanding of software testing
You do not need previous Playwright experience.
If you are coming from Selenium, concepts such as browser navigation, locators, clicks, form filling, and assertions will already feel familiar.
However, Playwright has its own modern architecture and synchronization features.
Installing Playwright and Creating a Project
Step 1: Verify Node.js
Open a terminal:
node –version
npm –version
If both commands return versions, Node.js and npm are available.
Step 2: Create a Playwright Project
Run:
npm init playwright@latest
The Playwright setup wizard will ask you several questions.
For this tutorial, select:
TypeScript
You can use:
tests
as the test directory.
When asked whether to install Playwright browsers, select the option to install them.
You can also install browsers later:
Step 3: Verify Playwright
Run:
npx playwright –version
You are now ready to create your first Playwright test.
Understanding the Playwright Project Structure
A newly created project generally contains files similar to:
playwright-project/
│
├── tests/
│ └── example.spec.ts
│
├── tests-examples/
│ └── demo-todo-app.spec.ts
│
├── playwright.config.ts
├── package.json
├── package-lock.json
└── node_modules/
The important files are:
| File/Folder | Purpose |
| tests/ | Stores test files |
| .spec.ts | TypeScript test file |
| playwright.config.ts | Playwright configuration |
| package.json | Project dependencies and scripts |
| node_modules/ | Installed packages |
A Playwright test file normally ends with:
.spec.ts
For example:
login.spec.ts
homepage.spec.ts
checkout.spec.ts
search.spec.ts
Creating the First Playwright Test File
Create:
tests/first-test.spec.ts
Add the following:
import { test, expect } from ‘@playwright/test’;
test(‘verify Playwright homepage’, async ({ page }) => {
await page.goto(‘https://playwright.dev/’);
await expect(page).toHaveTitle(/Playwright/);
});
This is your Playwright first test script example.
Let’s understand exactly what it does.
Writing a Basic Playwright Test Script
Concept
Every beginner should understand the three major parts:
Test definition
↓
Browser action
↓
Assertion
Code
import { test, expect } from ‘@playwright/test’;
test(‘verify Playwright homepage’, async ({ page }) => {
await page.goto(‘https://playwright.dev/’);
await expect(page).toHaveTitle(/Playwright/);
});
Line-by-Line Explanation
Line 1
import { test, expect } from ‘@playwright/test’;
This imports Playwright Test functions.
test is used to define a test.
expect is used to validate expected behavior.
Line 2
test(‘verify Playwright homepage’, async ({ page }) => {
This creates a test case.
The test name is:
verify Playwright homepage
The page object is provided by Playwright’s built-in fixture.
A page represents a browser tab.
Line 3
await page.goto(‘https://playwright.dev/’);
goto() navigates to the specified URL.
The await keyword waits for the asynchronous operation to complete.
Line 4
await expect(page).toHaveTitle(/Playwright/);
This verifies the page title.
If the title contains Playwright, the assertion passes.
Line 5
});
This closes the test.
Expected Result
You should see the test pass when you run it.
Best Practice
Keep your first tests simple.
Do not start by building a huge framework. Learn the basic flow first:
Navigate → Locate → Act → Assert
How to Run a Playwright Test Script
Open the project terminal and run:
npx playwright test
Playwright executes the tests in headless mode by default.
You may see output similar to:
Running 1 test using 1 worker
✓ tests/first-test.spec.ts
1 passed
Run in Headed Mode
To see the browser:
npx playwright test –headed
Run One Test File
npx playwright test tests/first-test.spec.ts
Run With Debugging
npx playwright test –debug
Run a Specific Browser
npx playwright test –project=chromium
These commands answer one of the most common beginner questions:
How to run a Playwright test script?
Use:
npx playwright test
Understanding Locators in Your First Playwright Test
A locator tells Playwright which element you want to interact with.
For example:
page.getByRole(‘button’, { name: ‘Login’ })
means:
Find a button whose accessible name is Login.
Locators are fundamental to a reliable Playwright test script.
Using getByRole()
Concept
Use roles to identify elements according to how users and assistive technologies understand them.
Code
await page.getByRole(‘button’, { name: ‘Login’ }).click();
Explanation
Playwright searches for a button named Login and clicks it.
Expected Result
The Login button is clicked.
Best Practice
Prefer role-based locators when they accurately describe the element.
Using getByText()
Concept
Use getByText() when visible text is the most useful identifier.
Code
await page.getByText(‘Welcome to our application’).click();
Explanation
Playwright finds the matching visible text and interacts with it.
Expected Result
The matching element is clicked.
Best Practice
Avoid overly broad text locators when several elements contain the same text.
Using getByLabel()
This locator is particularly useful for forms.
Code
await page.getByLabel(‘Username’).fill(‘admin’);
Explanation
Playwright finds the form field associated with the Username label and enters admin.
For a password field:
await page.getByLabel(‘Password’).fill(‘Password123’);
Best Practice
Use accessible labels whenever the application provides them.
Adding Assertions With expect()
A test without an assertion may perform an action without actually verifying the application.
Assertions turn actions into meaningful tests.
Page Title
await expect(page).toHaveTitle(/Dashboard/);
URL
await expect(page).toHaveURL(/dashboard/);
Visibility
await expect(page.getByText(‘Welcome’)).toBeVisible();
Text
await expect(page.getByRole(‘heading’)).toHaveText(‘Dashboard’);
Enabled State
await expect(page.getByRole(‘button’, { name: ‘Submit’ }))
.toBeEnabled();
A strong Playwright test usually follows:
Action
↓
Expected result
↓
Assertion
Understanding Playwright Auto-Waiting
Auto-waiting is one of the most useful features for beginners.
Suppose a button appears only after an API request finishes.
Instead of writing:
await page.waitForTimeout(5000);
await page.getByRole(‘button’, { name: ‘Submit’ }).click();
prefer:
await page.getByRole(‘button’, { name: ‘Submit’ }).click();
Playwright automatically waits for the element to become actionable.
For verification:
await expect(page.getByText(‘Order submitted’)).toBeVisible();
Assertions can also retry until the expected condition is satisfied or the configured timeout is reached.
Best Practice
Avoid arbitrary waits such as:
await page.waitForTimeout(3000);
Use locators and web-first assertions whenever possible.
Real-World Playwright First Test Script: Login Automation
A login test is one of the best practical examples for someone learning their first automation script.
Concept
The workflow is:
Open Login Page
↓
Enter Username
↓
Enter Password
↓
Click Login
↓
Verify Dashboard
Code
import { test, expect } from ‘@playwright/test’;
test(‘valid user can log in’, async ({ page }) => {
await page.goto(‘https://example.com/login’);
await page.getByLabel(‘Username’).fill(‘testuser’);
await page.getByLabel(‘Password’).fill(‘Password123’);
await page.getByRole(‘button’, { name: ‘Login’ }).click();
await expect(
page.getByRole(‘heading’, { name: ‘Dashboard’ })
).toBeVisible();
});
Line-by-Line Explanation
Navigate
await page.goto(‘https://example.com/login’);
Opens the login page.
Fill Username
await page.getByLabel(‘Username’).fill(‘testuser’);
Finds the Username field and enters data.
Fill Password
await page.getByLabel(‘Password’).fill(‘Password123’);
Enters the password.
Click Login
await page.getByRole(‘button’, { name: ‘Login’ }).click();
Clicks the Login button.
Verify Dashboard
await expect(
page.getByRole(‘heading’, { name: ‘Dashboard’ })
).toBeVisible();
Confirms that the Dashboard is displayed.
Expected Result
The test passes when a valid user reaches the Dashboard.
Best Practice
Never store real credentials directly in your test source code.
For real projects, use environment variables or CI/CD secrets.
Handling Dynamic Elements With Auto-Waiting
Modern web applications frequently display elements dynamically.
For example:
await page.getByRole(‘button’, { name: ‘Load Orders’ }).click();
await expect(
page.getByText(‘Order #1001’)
).toBeVisible();
The test does not need an arbitrary delay between the click and assertion.
This approach is more reliable than:
await page.getByRole(‘button’, { name: ‘Load Orders’ }).click();
await page.waitForTimeout(5000);
await expect(page.getByText(‘Order #1001’)).toBeVisible();
The second approach waits five seconds whether the application needs five seconds or 500 milliseconds.
Taking Screenshots From Your First Playwright Test
Screenshots are useful when investigating failures.
Concept
Capture the page after an important action.
Code
await page.screenshot({
path: ‘screenshots/homepage.png’,
fullPage: true
});
Explanation
The screenshot is saved to:
screenshots/homepage.png
Expected Result
A PNG image of the page is created.
Best Practice
For larger test suites, configure screenshots automatically on failures:
use: {
screenshot: ‘only-on-failure’
}
This keeps test artifacts useful without generating unnecessary files for every passing test.
Generating and Viewing Playwright Reports
After running tests, Playwright can generate an HTML report.
Run:
npx playwright test
Then:
npx playwright show-report
The report can help you investigate:
- Passed tests
- Failed tests
- Test duration
- Errors
- Screenshots
- Traces
- Test steps
Reporting is an important skill for QA Automation Engineers because test execution results must be understandable to developers, QA leads, and CI/CD systems.
Debugging Your First Playwright Test
Even your first test can fail.
Learning debugging early is better than simply copying code until it passes.
Playwright Inspector
Run:
npx playwright test –debug
The Playwright Inspector helps you step through test actions and inspect locators.
Headed Mode
You can also see what the browser is doing:
npx playwright test –headed
Trace Viewer
Tracing provides detailed information about test execution.
A common configuration is:
use: {
trace: ‘on-first-retry’
}
Then, when a test fails and retries, Playwright can capture a trace that can be inspected later.
Debugging Checklist
When your first test fails, check:
- Is the URL correct?
- Is the locator correct?
- Is the element inside an iframe?
- Is the element dynamically rendered?
- Is the test running against the correct environment?
- Are credentials valid?
- Does the test depend on another test?
- Does the failure occur only in CI?
Running Your First Test Across Browsers
Playwright supports Chromium, Firefox, and WebKit.
A simple configuration is:
import { defineConfig, devices } from ‘@playwright/test’;
export default defineConfig({
testDir: ‘./tests’,
projects: [
{
name: ‘chromium’,
use: { …devices[‘Desktop Chrome’] },
},
{
name: ‘firefox’,
use: { …devices[‘Desktop Firefox’] },
},
{
name: ‘webkit’,
use: { …devices[‘Desktop Safari’] },
},
],
});
Run Chromium:
npx playwright test –project=chromium
Run Firefox:
npx playwright test –project=firefox
Run WebKit:
npx playwright test –project=webkit
Or run all configured projects:
npx playwright test
Career Tip
Cross-browser testing is a useful skill to discuss during QA Automation and SDET interviews.
Basic CI/CD Execution
A Playwright test should eventually run automatically whenever application code changes.
A basic CI workflow looks like:
↓
CI starts
↓
Install dependencies
↓
Install Playwright browsers
↓
Run tests
↓
↓
Publish artifacts
For example, a GitHub Actions workflow can look like:
name: Playwright Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v6
– uses: actions/setup-node@v6
with:
node-version: lts/*
– run: npm ci
– run: npx playwright install –with-deps
– run: npx playwright test
– uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
You do not need to memorize this workflow when writing your first test. Understand the concept first, then learn CI/CD configuration as your framework develops.
Common First-Test Errors and Solutions
1. Browser executable is missing
If Playwright cannot find a browser:
npx playwright install
In Linux CI environments, you may need:
npx playwright install –with-deps
2. Locator cannot find an element
Check whether:
- The locator is correct.
- The accessible name is correct.
- The element exists on the current page.
- The element is inside an iframe.
- The page has navigated to the expected URL.
Debug with:
npx playwright test –debug
3. Strict mode violation
This commonly occurs when a locator matches multiple elements.
Instead of:
page.getByText(‘Submit’)
use a more specific locator:
page.getByRole(‘button’, { name: ‘Submit’ })
4. Test is flaky
Look for:
- Fragile locators
- Hard-coded waits
- Shared state
- Test dependency
- Unstable external services
- Incorrect synchronization
5. Test passes locally but fails in CI
Check:
- Browser installation
- Environment variables
- Base URL
- Authentication
- Operating-system differences
- Timing
- Network dependencies
Use traces and screenshots to understand the CI failure.
Playwright First Test Script Best Practices
Use these practices from the beginning.
Use meaningful test names
Good:
test(‘valid customer can submit order’, async ({ page }) => {});
Avoid:
test(‘test1’, async ({ page }) => {});
Prefer user-facing locators
Use:
getByRole()
getByLabel()
getByText()
getByTestId()
when appropriate.
Use assertions
Do not stop after clicking.
Bad:
await page.getByRole(‘button’, { name: ‘Login’ }).click();
Better:
await page.getByRole(‘button’, { name: ‘Login’ }).click();
await expect(page.getByText(‘Dashboard’)).toBeVisible();
Avoid hard waits
Do not use waitForTimeout() as your normal synchronization strategy.
Keep tests independent
A test should not require another test to run first.
Keep secrets outside source code
Use environment variables and CI/CD secret stores.
Start small
Do not build a complex framework before understanding basic test execution.
Playwright Interview Questions With Answers
1. How do I write my first Playwright test?
Create a .spec.ts file, import test and expect, use the page fixture, navigate with page.goto(), perform an action, and validate the result with expect().
Example:
import { test, expect } from ‘@playwright/test’;
test(‘first test’, async ({ page }) => {
await page.goto(‘https://playwright.dev/’);
await expect(page).toHaveTitle(/Playwright/);
});
2. What is a Playwright test file?
A test file contains one or more test cases. Playwright TypeScript test files commonly use the .spec.ts extension.
3. What is the page object?
The page object represents a browser tab and provides APIs for navigation and interaction.
4. What is a locator?
A locator identifies a web element for interaction or validation.
Example:
page.getByRole(‘button’, { name: ‘Login’ })
5. What is expect()?
expect() is used to verify expected application behavior.
Example:
await expect(page).toHaveTitle(/Dashboard/);
6. What is auto-waiting?
Auto-waiting allows Playwright to wait for elements to become actionable before performing supported actions.
7. How do you run a Playwright test?
npx playwright test
8. How do you run a Playwright test in headed mode?
npx playwright test –headed
9. How do you debug a Playwright test?
Use:
npx playwright test –debug
You can also use screenshots, traces, HTML reports, and headed execution.
10. Can Playwright test multiple browsers?
Yes. Playwright supports Chromium, Firefox, and WebKit.
Learning Roadmap After Your First Playwright Test
Writing a Playwright first test script is only the beginning.
Follow this progression.
Level 1: Playwright Fundamentals
Learn:
- Installation
- Project structure
- Configuration
- Test files
- test()
- page
- goto()
- Actions
- Assertions
Level 2: Locators
Learn:
- getByRole()
- getByText()
- getByLabel()
- getByPlaceholder()
- getByTestId()
- CSS selectors
- XPath
Level 3: Web Automation
Practice:
- Login
- Forms
- Dropdowns
- Checkboxes
- Tables
- Dynamic elements
- Alerts
- Popups
- Frames
- Multiple pages
Level 4: Framework Design
Learn:
- Page Object Model
- Fixtures
- Hooks
- Test data
- Utilities
- Environment configuration
Level 5: Advanced Playwright
Move into:
- API testing
- Authentication
- Network interception
- Parallel execution
- Visual testing
- Advanced reporting
Level 6: DevOps
Learn:
- Git
- GitHub Actions
- CI/CD
- Docker
- Test artifacts
- Pipeline troubleshooting
For SDET and QA Automation roles, combine Playwright with TypeScript, API testing, SQL, Git, CI/CD, and core testing concepts.
Related Playwright Tutorials to Learn Next
After completing your first Playwright test, continue with:
- Playwright Basics
- Playwright for Beginners
- Playwright Tutorial
- Playwright Tutorial Step by Step
- Playwright TypeScript Tutorial
- Playwright Python Tutorial
- Playwright Java Tutorial
- Playwright Locators
- Playwright Auto Waiting
- Playwright Page Object Model
- Playwright Fixtures Tutorial
- Playwright API Testing
- Playwright Authentication Tutorial
- Playwright Reporting Tutorial
- Playwright Parallel Execution Tutorial
- Playwright CI/CD Tutorial
- Playwright GitHub Actions Tutorial
- Playwright Docker Tutorial
- Playwright Interview Questions
These topics take you from a simple test script to a complete Playwright testing framework.
FAQs About Playwright First Test Script
What is a Playwright first test script?
A Playwright first test script is a basic automated test that opens a webpage, performs browser actions, and validates expected application behavior using Playwright Test.
How do I write my first Playwright test?
Create a .spec.ts file and write:
import { test, expect } from ‘@playwright/test’;
test(‘first test’, async ({ page }) => {
await page.goto(‘https://playwright.dev/’);
await expect(page).toHaveTitle(/Playwright/);
});
Then run:
npx playwright test
How do I run a Playwright test script?
Use:
npx playwright test
For visible browser execution:
npx playwright test –headed
For debugging:
npx playwright test –debug
What is the .spec.ts file in Playwright?
A .spec.ts file is a TypeScript test file that contains Playwright test cases.
What is page.goto() used for?
page.goto() navigates the browser page to a specified URL.
What is the difference between a locator and an assertion?
A locator identifies an element. An assertion verifies expected behavior or state.
For example:
const loginButton = page.getByRole(‘button’, { name: ‘Login’ });
await loginButton.click();
await expect(loginButton).toBeVisible();
Does Playwright automatically wait?
Yes. Playwright automatically waits for supported actionability conditions, and its web-first assertions can retry until the expected condition is satisfied or times out.
Can beginners learn Playwright with TypeScript?
Yes. Playwright TypeScript is a good combination for beginners who want to build modern automation frameworks.
Can the first Playwright test run in Firefox and WebKit?
Yes. Playwright supports Chromium, Firefox, and WebKit, and projects can be configured for each browser.
What should I learn after writing my first Playwright test?
Learn locators, assertions, auto-waiting, forms, dynamic elements, Page Object Model, fixtures, reporting, API testing, parallel execution, and CI/CD.
