This directory contains end-to-end tests for the CARE frontend using Playwright.
Install Playwright browsers:
npm run playwright:install# Run all tests
npm run playwright:test
# Run tests in UI mode (interactive)
npm run playwright:test:ui
# Run tests in headed mode (see the browser)
npm run playwright:test:headed
# Run specific test file
npx playwright test tests/auth/login.spec.ts
# Run tests in a specific browser
npx playwright test --project=chromium
# View HTML report
npm run playwright:show-reportBefore running tests, ensure:
- Backend is running - See CARE Backend Setup
- Environment variables - Create
.env.localwith:REACT_CARE_API_URL=http://127.0.0.1:9000
Note: The Playwright configuration is set to automatically start a production server using npm run preview via the webServer command. You do not need to have npm run dev running in a separate terminal to execute tests.
tests/
├── admin/ # Administrative (Patient ID, Questionnaire, Tags) tests
├── auth/ # Authentication and landing page tests
│ ├── authenticated.spec.ts
│ ├── homepage.spec.ts
│ └── login.spec.ts
├── billing/ # Billing and financial workflow tests
├── facility/ # Extensive patient, encounter, and settings tests
├── organization/ # Organization-level management tests
├── setup/ # Test setup projects for different roles
│ ├── auth.setup.ts
│ ├── facilityAdmin.setup.ts
│ ├── patientAccount.setup.ts
│ └── ... # Includes nurse, facility, and patient setups
├── .auth/ # Stored authentication state (gitignored)
├── globalSetup.ts # Global configuration at the root level
└── ... # Other domain-specific suites (helper/, support/, etc.)
import { test, expect } from "@playwright/test";
test("should display page title", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle(/CARE/);
});Playwright recommends using role-based selectors:
// ✅ Good - Use role-based selectors
await page.getByRole("button", { name: /login/i }).click();
await page.getByRole("textbox", { name: /username/i }).fill("user");
await page.getByLabel(/password/i).fill("pass");
// ✅ Good - Use text selectors
await page.getByText("Submit").click();
// ⚠️ Avoid - Don't use CSS selectors unless necessary
await page.locator(".submit-button").click();Tests in authenticated.spec.ts use a stored authentication state:
import { test, expect } from "@playwright/test";
// Use stored auth state
test.use({ storageState: "tests/.auth/user.json" });
test("authenticated test", async ({ page }) => {
// Test runs with user already logged in
await page.goto("/dashboard");
// ...
});- Use Auto-waiting: Playwright automatically waits for elements
- Use Web-First Assertions:
expect(locator).toBeVisible()instead of manual waits - Use Role Selectors: More resilient than CSS selectors
- Avoid Hard-coded Waits: Use
waitForLoadState()or element visibility - Test User Flows: Test complete user journeys, not just individual functions
# Debug all tests
npx playwright test --debug
# Debug specific test
npx playwright test tests/auth/login.spec.ts --debugInstall the Playwright Test for VSCode extension for:
- Running tests from the editor
- Setting breakpoints
- Viewing test results inline
View traces for failed tests:
npx playwright show-trace trace.zipSee playwright.config.ts for configuration options:
- baseURL: http://localhost:4000
- Browsers: Runs tests on Chromium by default (as configured in
playwright.config.ts) - Retries: 2 on CI, 0 locally
- Trace: Captured on first retry
Tests run automatically on GitHub Actions. See .github/workflows/playwright.yaml.