End-to-end and API integration tests for AccountabilityAtlas.
| Type | Location | Purpose | Status |
|---|---|---|---|
| E2E | e2e/ |
Full browser-to-database user journeys | Active |
| API | api/ |
Service contract validation | Active |
- Framework: Playwright
- Language: TypeScript
- Browsers: Chromium, Firefox, WebKit (E2E only)
- Linting: ESLint with eslint-plugin-playwright
- Formatting: Prettier
- CI: GitHub Actions
- Node.js 20+
- Docker and Docker Compose (for local full-stack testing)
- Full stack running (see AccountabilityAtlas)
From the AccountabilityAtlas root:
docker-compose --profile backend --profile frontend up -dnpm run test:api # Run API tests only
npm run test:e2e # Run E2E tests only
npm run test:all # Run all tests (API + E2E)
# E2E with browser visible
npm run test:e2e:headed # Run with browser visible
npm run test:e2e:ui # Run with Playwright UI
npm run test:e2e:debug # Run with debugger
# API debug mode
npm run test:api:debug # Run API tests with debuggernpm run check # Run all quality checks (format + lint)
npm run lint # Check for linting errors
npm run lint:fix # Auto-fix linting errors
npm run format # Auto-format all files with Prettier
npm run format:check # Check formatting without modifying filesTip: Run
npm run checkbefore pushing to catch formatting and lint issues that will fail CI.
npm run report # View E2E test report
npm run report:api # View API test report# Run tests in a specific file
npm run test:e2e -- e2e/tests/auth/login.spec.ts
npm run test:api -- api/tests/health.spec.ts
# Run tests matching a pattern
npm run test:e2e -- --grep "valid credentials"
npm run test:api -- --grep "health"
# Run E2E on a specific browser
npm run test:e2e -- --project=chromiumTests run automatically on:
- Push to
master/main - Pull requests to
master/main - Manual trigger via
workflow_dispatch
The CI workflow:
- Spins up the full stack via
docker-compose - Runs API tests (no browser needed)
- Runs E2E tests on Chromium, Firefox, and WebKit
- Uploads HTML reports as artifacts (retained 14 days)
AcctAtlas-integration-tests/
├── api/
│ ├── tests/ # API test files by service
│ │ ├── health.spec.ts # Service health checks
│ │ ├── user-service.spec.ts # User/auth API tests
│ │ ├── location-service.spec.ts # Location API tests
│ │ ├── video-service.spec.ts # Video API tests
│ │ ├── moderation-service.spec.ts
│ │ └── search-service.spec.ts
│ ├── fixtures/ # API test helpers
│ │ └── api-helpers.ts # User creation, auth helpers
│ └── playwright.config.ts
├── e2e/
│ ├── tests/ # E2E test files by feature
│ │ ├── auth/ # Authentication tests
│ │ ├── videos/ # Video submission tests
│ │ └── moderation/ # Moderation workflow tests
│ ├── fixtures/ # E2E test helpers
│ ├── seeds/ # SQL scripts for test data
│ └── playwright.config.ts
├── package.json
└── tsconfig.json
Tests run in dependency order: health → user-service → other services
| Service | Passing | Skipped | Coverage |
|---|---|---|---|
| Health | 6 | 0 | All service health endpoints |
| User | 19 | 11 | Registration, login, profile, trust tiers |
| Location | 9 | 1 | CRUD, spatial queries, clustering |
| Video | 14 | 0 | CRUD, access control, locations |
| Moderation | 5 | 0 | Queue access, abuse reports |
| Search | 8 | 0 | Filters, pagination, public access |
Skipped tests are for unimplemented endpoints:
- Token refresh (#22)
- Logout (#23)
- Profile update (#24)
- Password reset (#25)
- Location auth requirement (#3)
| Feature | Test Cases | Coverage |
|---|---|---|
| Auth | 3 | Login flow (valid/invalid credentials, accessibility) |
| Map | 7 | Map browsing, markers, filters, search, list interaction |
| Video | 6 | Video detail page, navigation, YouTube link, 404 |
Tests run on Chromium, Firefox, and WebKit browsers.
See the Playwright documentation for general guidance.
Using test helpers:
import { createTestUser, authHeaders } from "../fixtures/api-helpers";
test("creates a resource", async ({ request }) => {
const user = await createTestUser(request);
const response = await request.post(`${API_URL}/resources`, {
data: { name: "Test" },
headers: authHeaders(user.accessToken),
});
expect(response.status()).toBe(201);
});Semantic locators (layout-resilient):
await page.getByLabel("Email").fill("test@example.com");
await page.getByRole("button", { name: /log in/i }).click();API-based test setup:
import { createTestUser } from "../../fixtures/test-data";
test("example", async ({ page, request }) => {
const user = await createTestUser(request);
// ... test with the created user
});SQL seeds for edge cases:
// For states not creatable via API (e.g., moderator users)
// Run SQL seed before tests, then use known credentials