Introduction
Duration: 3
End-to-End (E2E) testing validates that your entire application functions correctly from a user’s perspective, covering everything from the database to the front-end layout.
In this workshop, you will learn how to set up Playwright—a modern, fast, and highly reliable E2E testing framework developed by Microsoft. We will build a test suite, write selectors that survive layout refactors, and integrate tests into a CI/CD pipeline.
[!NOTE] Why Playwright? Playwright runs in isolated browser contexts, auto-waits for elements to become actionable, and runs tests concurrently across Chromium, Firefox, and WebKit.
- I understand the goals of this workshop
- I have Node.js 20+ ready on my machine
Project Initialization
Duration: 7
Let’s begin by initializing a new project and installing Playwright. Run the following command in a clean directory:
mkdir playwright-workshop
cd playwright-workshop
pnpm init
pnpm create playwright
During initialization, the CLI will ask you a few questions:
- Do you want to use TypeScript or JavaScript? TypeScript
- Where do you want to put your end-to-end tests? tests
- Add a GitHub Actions workflow? Yes
- Install Playwright browsers? Yes
[!TIP] Always install Playwright browsers via the official installer, as they are custom binaries optimized for automation.
- Created the project directory
- Initialized Playwright successfully
- Verified that
playwright.config.tswas generated
Writing Your First Test
Duration: 15
Now that the directory is prepared, let’s write our first smoke test. Delete the default examples and create a new test file:
rm -rf tests-examples/
touch tests/smoke.spec.ts
Open tests/smoke.spec.ts in your code editor and add the following script:
import { test, expect } from '@playwright/test';
test('homepage loads and displays core elements', async ({ page }) => {
// Navigate to target URL
await page.goto('https://adurancastillo.com');
// Verify the page title
await expect(page).toHaveTitle(/Antony Duran/);
// Assert navbar is visible
const nav = page.locator('nav');
await expect(nav).toBeVisible();
});
To run your new test, execute the CLI runner:
pnpm playwright test
[!WARNING] By default, Playwright runs tests in headless mode (no browser window pops up). To watch the execution, pass the
--headedflag.
- Created
tests/smoke.spec.ts - Wrote the title and navbar assertions
- Executed the tests successfully and saw a passing result
Handling Asynchronous Assertions
Duration: 12
Modern applications are highly dynamic, modifying elements asynchronously without reloading. If you assert on elements before they load, tests fail. Playwright solves this using Auto-waiting and Web-first Assertions.
Let’s write a test that interacts with a search box:
test('user can search for workshops', async ({ page }) => {
await page.goto('https://adurancastillo.com/workshops');
// Locate the search pill input
const searchInput = page.locator('input[type="text"]');
await searchInput.fill('Playwright');
// Select matching card title
const cardTitle = page.locator('.workshop-card h3').first();
// Web-first assertion: Playwright will retry until the card title contains the text
await expect(cardTitle).toContainText('Playwright');
});
Because expect(locator).toContainText() is a web-first assertion, it will automatically poll the DOM for up to 5 seconds before throwing an error.
- Wrote the dynamic search test
- Ran the tests to confirm auto-waiting handles the input delay
Setting Up CI/CD Gates
Duration: 6
A test suite is only useful if it runs automatically on every code change, preventing broken features from reaching production.
When you selected “Yes” to the GitHub Actions question during setup, Playwright generated .github/workflows/playwright.yml. Let’s inspect its structure:
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm install -g pnpm && pnpm install
- name: Install Playwright Browsers
run: pnpm playwright install --with-deps
- name: Run Playwright tests
run: pnpm playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
This configuration spins up an Ubuntu VM, pulls your code, installs dependencies, installs browser engines, runs the tests, and uploads the HTML report if a run fails.
- Inspected
.github/workflows/playwright.yml - Confirmed the runner node-version aligns with your project setup
Summary & Next Steps
Duration: 2
Congratulations! 🎉 You have successfully completed the Playwright E2E testing workshop.
You are now equipped to:
- Initialize test suites in TypeScript.
- Utilize web-first assertions to resolve asynchronous test flakes.
- Automatically execute tests inside your GitHub Actions pipeline.
For further reading, check out the official Playwright Documentation.