Skip to main content

E2E Testing with Playwright

The Ever Works template includes a comprehensive end-to-end testing suite built with Playwright. The E2E tests live in a dedicated workspace package (@ever-works/web-e2e) at apps/web-e2e/ within the Turborepo monorepo. The suite covers admin workflows, client features, public pages, authentication flows, API endpoints, internationalization, and smoke tests.

Test Suite Overview

The E2E suite contains 62 spec files organized across 7 test categories:

CategorySpec FilesDescription
Admin21Dashboard, items (CRUD, filter, review), categories, clients, collections, comments, companies, data export, featured items, notifications, reports, roles, settings, sponsorships, surveys, tags, users, bulk actions
Client7Dashboard, favorites (list + toggle), profile, settings, submissions, submit-and-manage, trash
Public18Discover, categories, collections, tags, item detail, search, sort, star rating, share button, view toggle, scroll-to-top, newsletter, pricing, legal pages, language switcher, login modal, error pages, form validation, surveys, votes-and-comments
Auth3Register, sign-in, sign-out
API4Health check, items API, comments API, favorites API
i18n2Locale switching, locale depth testing
Smoke2Health check, navigation

Project Structure

apps/web-e2e/                     # @ever-works/web-e2e workspace package
package.json # Workspace package manifest
playwright.config.ts # Playwright configuration
global-setup.ts # Pre-test authentication setup
global-teardown.ts # Post-test cleanup
fixtures/
auth.fixture.ts # Custom test fixtures (adminPage, clientPage)
index.ts # Fixture barrel export
helpers/
test-data.ts # Test data generators and constants
page-objects/
base.page.ts # Base page object class
admin/ # 17 admin page objects
client/ # 6 client page objects
auth/ # Sign-in page object
public/ # 13 public page objects
tests/
admin/ # 21 admin spec files
client/ # 7 client spec files
public/ # 18 public spec files
auth/ # 3 auth spec files
api/ # 4 API spec files
i18n/ # 2 i18n spec files
smoke/ # 2 smoke spec files

Configuration

The Playwright config is at apps/web-e2e/playwright.config.ts:

export default defineConfig({
testDir: './tests',
outputDir: './test-results',
fullyParallel: true,
workers: isCI ? 2 : 1,
retries: isCI ? 2 : 0,
timeout: 60_000,
expect: { timeout: 30_000 },

globalSetup: './global-setup.ts',
globalTeardown: './global-teardown.ts',

use: {
baseURL, // from BASE_URL env var or localhost:3000
trace: isCI ? 'on-first-retry' : 'retain-on-failure',
screenshot: 'only-on-failure',
video: isCI ? 'on-first-retry' : 'off',
navigationTimeout: 60_000,
actionTimeout: 30_000,
locale: 'en-US',
timezoneId: 'America/New_York',
},

projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],

webServer: {
command: isCI ? 'pnpm build && pnpm start' : 'pnpm dev',
url: baseURL,
reuseExistingServer: !isCI,
timeout: isCI ? 300_000 : 120_000,
},
});

Key Configuration Details

  • Three browser projects: Chromium, Firefox, WebKit
  • CI optimizations: 2 workers, 2 retries, trace on first retry, video on first retry
  • Local optimizations: 1 worker, no retries, retain trace on failure, no video
  • Web server: Automatically starts dev server locally or builds for CI

Authentication Fixtures

The test suite uses custom Playwright fixtures to handle authentication. Defined in apps/web-e2e/fixtures/auth.fixture.ts:

export const test = base.extend<AuthFixtures>({
adminContext: async ({ browser }, use) => {
const context = await browser.newContext({
storageState: requireAuthState(ADMIN_STATE_PATH)
});
await use(context);
await context.close();
},
adminPage: async ({ adminContext }, use) => {
const page = await adminContext.newPage();
await use(page);
await page.close();
},
clientContext: async ({ browser }, use) => {
const context = await browser.newContext({
storageState: requireAuthState(CLIENT_STATE_PATH)
});
await use(context);
await context.close();
},
clientPage: async ({ clientContext }, use) => {
const page = await clientContext.newPage();
await use(page);
await page.close();
},
});

This provides four fixtures:

  • adminContext / adminPage -- Pre-authenticated admin browser context
  • clientContext / clientPage -- Pre-authenticated client browser context

Auth state files are generated during global setup and stored in apps/web-e2e/auth-states/.

Page Object Model

All page interactions are encapsulated in page objects extending base.page.ts:

Admin Page Objects (17)

Page ObjectFileCovers
DashboardPageadmin/dashboard.page.tsDashboard navigation and stats
ItemsPageadmin/items.page.tsItem listing and actions
ItemFormPageadmin/item-form.page.tsMulti-step item creation
CategoriesPageN/A (covered in specs)Category CRUD
ClientsPageadmin/clients.page.tsClient search and management
CollectionsPageadmin/collections.page.tsCollection management
CommentsPageadmin/comments.page.tsComment moderation
CompaniesPageadmin/companies.page.tsCompany CRUD
DataExportPageadmin/data-export.page.tsExport operations
FeaturedItemsPageadmin/featured-items.page.tsFeatured item curation
NotificationsPageadmin/notifications.page.tsNotification system
ReportsPageadmin/reports.page.tsReport review
RolesPageadmin/roles.page.tsRole management
SettingsPageadmin/settings.page.tsSettings configuration
SponsorshipsPageadmin/sponsorships.page.tsSponsor management
SurveysPageadmin/surveys.page.tsSurvey management
TagsPageadmin/tags.page.tsTag management
BulkActionsPageadmin/bulk-actions.page.tsMulti-select operations

Client Page Objects (6)

dashboard.page.ts, profile.page.ts, settings.page.ts, submissions.page.ts, submit.page.ts, trash.page.ts

Public Page Objects (13)

discover.page.ts, item-detail.page.ts, search-bar.page.ts, sort-menu.page.ts, view-toggle.page.ts, star-rating.page.ts, share-button.page.ts, scroll-to-top.page.ts, newsletter.page.ts, language-switcher.page.ts, profile-dropdown.page.ts, public-pages.page.ts, theme-toggle.page.ts

Test Data Helpers

Located in apps/web-e2e/helpers/test-data.ts:

export const TEST_DATA = {
get ADMIN_EMAIL() { return requireEnv('SEED_ADMIN_EMAIL'); },
get ADMIN_PASSWORD() { return requireEnv('SEED_ADMIN_PASSWORD'); },
CLIENT_PASSWORD: 'TestClient123!',
generateClientEmail: () => `e2e-client-${Date.now()}-${random}@test.local`,
generateItemName: () => `E2E Test Item ${Date.now()}-${random}`,
generateItemUrl: () => `https://e2e-test-${Date.now()}.example.com`,
};

export const PUBLIC_ROUTES = [
{ path: '/', name: 'Home' },
{ path: '/discover/1', name: 'Discover Page 1' },
{ path: '/categories', name: 'Categories' },
// ... 12 public routes total
];

Running Tests

# From the monorepo root — run via the workspace filter
pnpm run --filter @ever-works/web-e2e test:e2e

# Or change into the E2E workspace directory
cd apps/web-e2e

# Run all tests (starts dev server automatically)
pnpm exec playwright test

# Run specific category
pnpm exec playwright test tests/admin/
pnpm exec playwright test tests/client/
pnpm exec playwright test tests/public/

# Run a single spec file
pnpm exec playwright test tests/admin/items-crud.spec.ts

# Run with specific browser
pnpm exec playwright test --project=chromium

# Run with UI mode (interactive)
pnpm exec playwright test --ui

# Run with headed browser (visible)
pnpm exec playwright test --headed

# View last test report
pnpm exec playwright show-report

Environment Requirements

Required environment variables for test execution:

SEED_ADMIN_EMAIL=admin@changeme.com
SEED_ADMIN_PASSWORD=changeme_password
BASE_URL=http://localhost:3000 # Optional, defaults to localhost:3000

CI Integration

The configuration supports CI environments with:

  • HTML + GitHub reporters for CI, HTML + list for local
  • Automatic trace collection on first retry
  • Video recording on first retry
  • 2 parallel workers to balance speed and stability
  • 5-minute build timeout for web server startup
  • Output artifacts in apps/web-e2e/test-results/ and apps/web-e2e/playwright-report/
  • apps/web-e2e/playwright.config.ts -- Main configuration
  • apps/web-e2e/fixtures/auth.fixture.ts -- Authentication fixtures
  • apps/web-e2e/helpers/test-data.ts -- Test data and route constants
  • apps/web-e2e/global-setup.ts -- Pre-test setup (authentication state)
  • apps/web-e2e/global-teardown.ts -- Post-test cleanup
  • apps/web-e2e/page-objects/ -- All page object classes
  • apps/web-e2e/tests/ -- All spec files