Introduction
If you’re learning browser automation, one of the best ways to master Playwright is through practical coding examples. This guide on Playwright JavaScript Examples covers everything from your first automation script to advanced enterprise testing techniques.
Playwright is Microsoft’s modern automation framework for testing web applications across Chromium, Firefox, and WebKit. Combined with JavaScript, it enables developers and QA engineers to write reliable, maintainable, and fast automation tests.
In this article, you’ll find Playwright JavaScript examples for beginners, complete runnable code, real-world automation scenarios, interview-focused explanations, and best practices for building production-ready automation frameworks.
Why Use Playwright with JavaScript?
JavaScript is the native language of Playwright, making it an excellent choice for browser automation.
Benefits
- Easy to learn
- Excellent documentation
- Fast execution
- Cross-browser testing
- Built-in auto-waiting
- API testing support
- Parallel execution
- HTML reporting
- Large JavaScript ecosystem
Playwright vs Selenium
| Feature | Playwright | Selenium |
| Auto-waiting | Built-in | Manual waits often required |
| Browser support | Chromium, Firefox, WebKit | Multiple browsers |
| Parallel execution | Built-in | Requires additional configuration |
| API testing | Built-in | External libraries needed |
| Trace Viewer | Yes | No built-in support |
Prerequisites (Node.js, npm, VS Code)
Before running these Playwright JavaScript code examples, install:
- Node.js (LTS recommended)
- npm
- Visual Studio Code
- Git (optional)
Verify your installation:
node -v
npm -v
Installing Playwright
Create a new project:
mkdir playwright-js-demo
cd playwright-js-demo
npm init -y
Install Playwright:
npm init playwright@latest
This command:
- Installs Playwright
- Downloads browser binaries
- Creates sample tests
- Generates a Playwright configuration file
Project Structure for JavaScript
A clean project structure improves maintainability.
playwright-js-project
│
├── pages
├── tests
├── fixtures
├── utils
├── test-data
├── screenshots
├── reports
├── traces
├── playwright.config.js
├── package.json
└── .env
Folder Purpose
| Folder | Description |
| pages | Page Object Model classes |
| tests | Test files |
| utils | Reusable helper functions |
| fixtures | Shared setup and teardown |
| reports | HTML reports |
| screenshots | Failure screenshots |
| traces | Trace Viewer files |
Your First Playwright JavaScript Test
const { test, expect } = require(‘@playwright/test’);
test(‘Verify homepage title’, async ({ page }) => {
await page.goto(‘https://example.com’);
await expect(page).toHaveTitle(‘Example Domain’);
});
Explanation
This test:
- Opens a browser.
- Navigates to the website.
- Waits for the page to load.
- Verifies the page title.
- Closes automatically after execution.
Run the test:
npx playwright test
Playwright Locators with Examples
Choosing stable locators is essential for reliable automation.
getByRole()
await page.getByRole(‘button’, {
name: ‘Login’
}).click();
Best for buttons, links, and accessible elements.
getByLabel()
await page.getByLabel(‘Email’)
.fill(‘user@example.com’);
Perfect for forms with associated labels.
getByText()
await page.getByText(‘Sign Out’)
.click();
Useful for visible text elements.
locator()
await page.locator(‘.product-card’)
.first()
.click();
Flexible for CSS-based selection.
getByTestId()
await page.getByTestId(‘submit-button’)
.click();
Ideal when developers provide stable test IDs.
Recommended Locator Order
- getByRole()
- getByLabel()
- getByPlaceholder()
- getByText()
- getByTestId()
- locator()
- XPath (only when necessary)
Assertions and Auto-Waiting Examples
Playwright automatically waits until elements are ready.
await expect(page)
.toHaveURL(/dashboard/);
await expect(
page.getByRole(‘heading’, {
name: ‘Dashboard’
})
).toBeVisible();
Why Auto-Waiting Matters
Playwright waits until elements are:
- Visible
- Stable
- Enabled
- Ready for interaction
This significantly reduces flaky tests.
Handling Forms, Alerts, Frames, Windows, and File Uploads
Login Form
await page.getByLabel(‘Username’)
.fill(‘admin’);
await page.getByLabel(‘Password’)
.fill(‘password’);
await page.getByRole(‘button’, {
name: ‘Login’
}).click();
JavaScript Alert
page.on(‘dialog’, async dialog => {
console.log(dialog.message());
await dialog.accept();
});
Working with Frames
const frame = page.frameLocator(‘#payment-frame’);
await frame.getByLabel(‘Card Number’)
.fill(‘4111111111111111’);
Multiple Tabs
const pagePromise = context.waitForEvent(‘page’);
await page.getByText(‘Open New Tab’).click();
const newPage = await pagePromise;
await newPage.waitForLoadState();
File Upload
await page.locator(‘input[type=file]’)
.setInputFiles(‘documents/resume.pdf’);
Screenshots, Videos, and Trace Viewer Examples
Screenshot
await page.screenshot({
path: ‘screenshots/homepage.png’
});
Configure Tracing
use: {
screenshot: ‘only-on-failure’,
video: ‘retain-on-failure’,
trace: ‘retain-on-failure’
}
Why Use Trace Viewer?
Trace Viewer records:
- Screenshots
- DOM snapshots
- Console logs
- Network requests
- Timeline of user actions
It is one of the most effective tools for debugging failed tests.
API Testing with Playwright
Playwright supports API testing alongside UI automation.
const { test, expect } = require(‘@playwright/test’);
test(‘Verify API’, async ({ request }) => {
const response = await request.get(
‘https://jsonplaceholder.typicode.com/posts/1’
);
expect(response.ok()).toBeTruthy();
});
Combined Workflow
API Login
│
▼
Receive Token
│
▼
Open Browser
│
▼
Verify Dashboard
Using API calls for setup can reduce UI execution time and simplify end-to-end tests.
Page Object Model (POM) Example
LoginPage.js
class LoginPage {
constructor(page) {
this.page = page;
}
async login(username, password) {
await this.page.getByLabel(‘Username’)
.fill(username);
await this.page.getByLabel(‘Password’)
.fill(password);
await this.page.getByRole(‘button’, {
name: ‘Login’
}).click();
}
}
module.exports = { LoginPage };
Benefits
- Cleaner tests
- Reusable methods
- Easier maintenance
- Better scalability
Parallel Execution and Cross-Browser Testing
Configure parallel execution:
module.exports = {
workers: 4
};
Enable multiple browsers:
projects: [
{ name: ‘Chromium’ },
{ name: ‘Firefox’ },
{ name: ‘WebKit’ }
]
Workflow
Tests
│
├── Chromium
├── Firefox
└── WebKit
│
▼
Consolidated Report
Real-Time Automation Project Examples
1. Login Automation
- Open application
- Enter username
- Enter password
- Verify dashboard
2. Registration Form
- Fill all fields
- Upload profile image
- Submit form
- Validate confirmation message
3. E-commerce Search
await page.getByPlaceholder(‘Search’)
.fill(‘Laptop’);
await page.keyboard.press(‘Enter’);
await expect(
page.locator(‘.product-card’)
).toHaveCount(10);
4. Table Validation
const rows = page.locator(‘table tbody tr’);
await expect(rows)
.toHaveCount(5);
5. File Download
const downloadPromise = page.waitForEvent(‘download’);
await page.getByText(‘Download’).click();
const download = await downloadPromise;
6. Responsive Testing
await page.setViewportSize({
width: 390,
height: 844
});
This simulates a mobile-sized viewport for responsive UI validation.
Enterprise Best Practices
To build a scalable Playwright JavaScript automation framework:
- Use the Page Object Model.
- Prefer semantic locators.
- Keep tests independent.
- Externalize environment variables using .env.
- Store reusable utilities separately.
- Enable screenshots, videos, and traces for failures.
- Integrate with GitHub Actions or Jenkins.
- Use HTML reporting.
- Review flaky tests regularly.
- Write descriptive test names.
Common Errors and Troubleshooting
| Problem | Solution |
| Browser not installed | Run npx playwright install |
| Element not found | Verify locator strategy and page state |
| Flaky tests | Rely on auto-waiting instead of fixed delays |
| File upload fails | Confirm file path exists |
| Frame interaction fails | Use frameLocator() correctly |
| API authentication error | Verify request headers and tokens |
Troubleshooting Workflow
Test Failure
│
▼
Check Locator
│
▼
Review Trace
│
▼
Inspect Logs
│
▼
Fix & Re-run
Playwright JavaScript Interview Questions
- What is Playwright?
- Why use Playwright with JavaScript?
- How do you install Playwright?
- What is the Playwright Test runner?
- What are semantic locators?
- Why use getByRole()?
- What is auto-waiting?
- How do assertions work?
- What is the Page Object Model?
- How do you handle frames?
- How do you upload files?
- How do you download files?
- How do you handle multiple tabs?
- How do you capture screenshots?
- What is Trace Viewer?
- How do you perform API testing?
- How do you run tests in parallel?
- How do you enable cross-browser testing?
- How do you integrate Playwright with GitHub Actions?
- How do you integrate with Jenkins?
- How do you debug failed tests?
- How do you organize an enterprise framework?
- How do you manage environment variables?
- What are common Playwright best practices?
- How would you explain your automation framework in an interview?
FAQs
Is Playwright JavaScript suitable for beginners?
Yes. Playwright has a clean API, built-in auto-waiting, and excellent documentation, making it approachable for beginners.
Can I use JavaScript instead of TypeScript?
Absolutely. Playwright fully supports JavaScript. TypeScript adds static type checking, which can be helpful for larger projects.
Does Playwright support API testing?
Yes. Playwright includes a built-in API testing client, allowing you to combine API and UI testing in the same project.
What is the best locator strategy?
Prefer semantic locators such as getByRole() and getByLabel() whenever possible. They tend to be more stable and reflect how users interact with the application.
Can Playwright run tests in parallel?
Yes. Playwright supports parallel execution and cross-browser testing out of the box.
Is Playwright suitable for enterprise automation?
Yes. Features such as reporting, tracing, parallel execution, CI/CD integration, and Page Object Model support make it a strong choice for enterprise web automation.
