Installing Playwright and Building Our Test Foundation
category: "E2E Testing"
Installing Playwright and Building Our Test Foundation
What We're Building
In this article, we'll set up the complete Playwright test infrastructure from scratch. By the end, you'll have a working test environment with:
- Playwright installed and configured
- TypeScript support
- Project configuration for API and UI testing
- Our first baseline test (the "long way" - before we add builders)
Prerequisites
- Node.js 18+ installed
- npm or yarn
- A code editor (VS Code recommended)
Step 1: Initialize the Project
First, let's create a new directory for our E2E tests and initialize it:
mkdir e2e-testing && cd e2e-testing
npm init -yStep 2: Install Playwright
Install Playwright and its dependencies:
npm install -D @playwright/test
npx playwright install --with-deps chromiumStep 3: Configure TypeScript
Install TypeScript and create a tsconfig:
npm install -D typescript
npx tsc --initConfigure tsconfig.json for Playwright:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"types": ["node", "@playwright/test"]
}
}Step 4: Configure Playwright
Create playwright.config.ts:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'https://demo.realworld.io',
trace: 'on-first-retry',
},
projects: [
{
name: 'api',
testMatch: /.*\.api\.spec\.ts/,
},
{
name: 'ui-chromium',
use: { ...devices['Desktop Chrome'] },
testMatch: /.*\.ui\.spec\.ts/,
},
],
});Step 5: Create Test Directory Structure
e2e-testing/
tests/
api/
sample.api.spec.ts
ui/
sample.ui.spec.ts
src/
playwright.config.ts
tsconfig.json
package.jsonStep 6: Create Our First Baseline Test
Let's write a test the "long way" - no builders, no abstractions. This is what we're starting from:
// tests/ui/sample.ui.spec.ts
import { test, expect } from '@playwright/test';
test.describe('RealWorld Application', () => {
test('user can register a new account', async ({ page }) => {
// Navigate to the app
await page.goto('https://demo.realworld.io');
// Click sign up
await page.click('text=Sign up');
// Fill in registration form
await page.fill('input[placeholder="Username"]', 'testuser123');
await page.fill('input[placeholder="Email"]', 'test@example.com');
await page.fill('input[placeholder="Password"]', 'password123');
// Submit
await page.click('button:has-text("Sign up")');
// Verify we're logged in
await expect(page.locator('text=Your Feed')).toBeVisible();
await expect(page.locator('text=testuser123')).toBeVisible();
});
});Step 7: Run the Test
npx playwright testYou should see Playwright launch a browser, navigate to the app, and execute the test.
What We've Learned
In this article we:
- Installed Playwright with TypeScript
- Configured projects for API and UI testing
- Created our first baseline test
Current state: Tests are verbose, 30+ lines each, with manual setup.
Next: We'll build the foundation for our builders with TestDefaults and TestDataHelper.
Previous: Why We're Building a 2-Line E2E Testing Framework Next: The Foundation: TestDefaults & TestDataHelper ->