You can get Playwright up and running for end-to-end testing in under five minutes, and the most surprising part is how little configuration it actually needs to start.
Here’s a quick look at Playwright in action, running a simple test against a local web server. First, you’ll need a basic test file. Let’s call it example.spec.js:
// example.spec.js
import { test, expect } from '@playwright/test';
test('basic page load', async ({ page }) => {
await page.goto('http://localhost:3000'); // Assuming your app runs on port 3000
const heading = page.locator('h1');
await expect(heading).toHaveText('Welcome to My App');
});
To run this, you first install Playwright and its browsers. If you haven’t already, create a package.json file (if you don’t have one) and run:
npm init -y
npm install --save-dev @playwright/test
npx playwright install
The npx playwright install command downloads the necessary browser binaries (Chromium, Firefox, WebKit) for your operating system. You don’t need to manually download or configure anything; Playwright handles it all.
Now, you can execute the test:
npx playwright test example.spec.js
Playwright will launch an instance of Chromium, navigate to http://localhost:3000, find the h1 element, and assert that its text content is "Welcome to My App". If it matches, the test passes. If not, or if the page fails to load, the test fails, and Playwright provides a screenshot and a trace of the execution.
Playwright’s core strength lies in its ability to manage browser lifecycles and interactions seamlessly. When you run npx playwright test, it spins up a test runner, which in turn orchestrates the browser instances. The page object you get in your test function is a handle to a specific browser context and tab. page.goto() tells the browser to navigate, and await expect(heading).toHaveText(...) is Playwright’s assertion library, which automatically retries the check for a short period, making tests more resilient to minor timing issues.
The main levers you control are within your test files:
page.goto(url): Determines which URL your test starts from. This is your entry point.- Selectors:
page.locator(selector)is how you target elements. Playwright supports a rich set of selectors, including text, IDs, CSS, and XPath. For example,page.locator('text=Submit')orpage.locator('#user-email'). - Actions: Methods like
page.click(),page.fill(value),page.press(key)simulate user interactions. - Assertions:
expect(locator).toBeVisible(),expect(page).toHaveURL(url),expect(locator).toHaveValue(value)are used to verify the state of your application.
The default configuration is often enough because Playwright’s test runner automatically discovers your test files (usually those ending in .spec.js, .spec.ts, .test.js, or .test.ts in a tests or e2e directory). It also defaults to running tests in parallel using the installed browsers. You can customize this behavior by creating a playwright.config.js or playwright.config.ts file, but for a quick start, it’s not required.
The npx playwright install command is crucial because it ensures you have the exact browser versions that Playwright was tested against, minimizing "it works on my machine" scenarios. This bundled approach to browser management is a significant reason for Playwright’s ease of setup.
When you run tests without a specific configuration file, Playwright defaults to a set of sensible options: running tests in parallel, using the Chromium browser by default, and a timeout of 30 seconds for each test. The expect assertions have built-in retry mechanisms, which is why you don’t typically need to write explicit waits. This automatic retrying is a key differentiator that makes tests more stable out-of-the-box compared to older testing frameworks where you’d manually manage sleep() calls or complex waitFor conditions.
The next step is usually to explore Playwright’s powerful tracing feature, which generates detailed reports of your test runs, including screenshots, DOM snapshots, and network logs.