Skip to content

Commit 21d75fe

Browse files
authored
test: set up playwright (#83)
1 parent 83c89b3 commit 21d75fe

File tree

12 files changed

+269
-32
lines changed

12 files changed

+269
-32
lines changed

.github/workflows/e2e.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: E2E Tests
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
branches: ["**"]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
e2e:
14+
name: Playwright E2E
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 15
17+
env:
18+
API_BASE_URL: http://localhost:9090
19+
OIDC_ISSUER_URL: http://localhost:4000
20+
OIDC_CLIENT_ID: test-only-not-a-real-id
21+
OIDC_CLIENT_SECRET: test-only-not-a-real-secret
22+
NEXT_PUBLIC_OIDC_PROVIDER_ID: oidc
23+
BETTER_AUTH_URL: http://localhost:3000
24+
BETTER_AUTH_SECRET: test-only-not-a-real-better-auth-secret
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup
30+
uses: ./.github/actions/setup
31+
32+
- name: Install Playwright browsers
33+
run: pnpm exec playwright install --with-deps chromium
34+
35+
- name: Run Playwright tests
36+
run: pnpm test:e2e
37+
38+
- name: Upload test artifacts
39+
uses: actions/upload-artifact@v4
40+
if: failure()
41+
with:
42+
name: playwright-report
43+
path: |
44+
test-results/
45+
playwright-report/
46+
retention-days: 7

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212

1313
# testing
1414
/coverage
15+
# Playwright/Cucumber E2E artifacts
16+
test-results/
17+
playwright-report/
18+
blob-report/
1519

1620
# next.js
1721
/.next/

CLAUDE.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pnpm generate-client:nofetch # Regenerate without fetching
155155

156156
### Backend API
157157

158-
- **Base URL**: Configured via `NEXT_PUBLIC_API_URL`
158+
- **Base URL**: Configured via `API_BASE_URL` (server-side only)
159159
- **Format**: Official MCP Registry API (upstream compatible)
160160
- **Endpoints**:
161161
- `GET /api/v0/servers` - List all MCP servers
@@ -178,7 +178,7 @@ pnpm generate-client:nofetch # Regenerate without fetching
178178
### Production
179179

180180
1. User accesses protected route
181-
2. Redirected to `/sign-in`
181+
2. Redirected to `/signin`
182182
3. Better Auth initiates OIDC flow with configured provider
183183
4. Provider redirects back with authorization code
184184
5. Better Auth exchanges code for tokens
@@ -222,6 +222,19 @@ pnpm generate-client:nofetch # Regenerate without fetching
222222
- **Testing Library** - Component testing
223223
- **jsdom** - DOM simulation
224224

225+
### E2E Tests (Playwright)
226+
227+
- End-to-end tests live under `tests/e2e` and run against a live dev stack.
228+
- Commands:
229+
- `pnpm dev` – starts Next.js (3000), mock OIDC (4000), and MSW mock API (9090)
230+
- `pnpm run test:e2e` – runs Playwright tests (headless)
231+
- `pnpm run test:e2e:ui` – opens Playwright UI mode for interactive debugging
232+
- `pnpm run test:e2e:debug` – runs with Playwright Inspector
233+
- CI runs E2E tests via `.github/workflows/bdd.yml` and installs Playwright browsers.
234+
- Install browsers locally once: `pnpm exec playwright install`
235+
236+
Tests use custom fixtures for authentication. The `authenticatedPage` fixture handles login automatically.
237+
225238
### Example Test
226239

227240
```typescript
@@ -278,7 +291,10 @@ git push origin v0.x.x
278291

279292
### Authentication Not Working
280293

281-
- **Development**: Ensure OIDC mock is running (`pnpm oidc`)
294+
- **Development**:
295+
- Ensure OIDC mock is running (`pnpm oidc`) or start the full stack with `pnpm dev`
296+
- Dev provider issues refresh tokens unconditionally and uses a short AccessToken TTL (15s) to exercise the refresh flow
297+
- If you see origin errors (403), ensure `BETTER_AUTH_URL` matches the port you use (default `http://localhost:3000`) or include it in `TRUSTED_ORIGINS`
282298
- **Production**: Check environment variables:
283299
- `OIDC_ISSUER_URL` - OIDC provider URL
284300
- `OIDC_CLIENT_ID` - OAuth2 client ID
@@ -289,7 +305,7 @@ git push origin v0.x.x
289305

290306
### API Calls Failing
291307

292-
- Check `NEXT_PUBLIC_API_URL` environment variable
308+
- Check `API_BASE_URL` environment variable
293309
- Verify backend API is running
294310
- Check browser console for CORS errors
295311

README.md

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pnpm dev
5151
# Application will be available at http://localhost:3000
5252
```
5353

54+
Authentication: the dev stack also starts a local OIDC provider (on :4000) and MSW mock API (on :9090). The `/signin` page initiates the OIDC flow and redirects back to `/catalog` on success.
55+
5456
### Available Commands
5557

5658
#### Development Commands (pnpm)
@@ -273,25 +275,26 @@ BETTER_AUTH_URL=http://localhost:3000
273275

274276
### Testing
275277

278+
#### Unit/Component Tests
279+
276280
```bash
277-
# Run all tests
278-
pnpm test
281+
pnpm test # Run all tests
282+
pnpm test --watch # Watch mode
283+
pnpm test --coverage # With coverage
284+
```
279285

280-
# Run tests in watch mode
281-
pnpm test --watch
286+
Uses Vitest + Testing Library + MSW.
282287

283-
# Run tests with coverage
284-
pnpm test --coverage
288+
#### E2E Tests (Playwright)
285289

286-
# Run specific test file
287-
pnpm test src/components/navbar.test.tsx
290+
```bash
291+
pnpm exec playwright install # One-time browser install
292+
pnpm test:e2e # Run tests (auto-starts dev server if needed)
293+
pnpm test:e2e:ui # Playwright UI mode
294+
pnpm test:e2e:debug # With Playwright Inspector
288295
```
289296

290-
Tests use:
291-
292-
- **Vitest** - Test runner
293-
- **Testing Library** - React component testing
294-
- **MSW** - API mocking
297+
Tests automatically start the dev stack if it's not already running. If you prefer to start it manually first, run `pnpm dev` before the tests.
295298

296299
### Mock Server
297300

@@ -467,6 +470,7 @@ For detailed information about the project:
467470
- [shadcn/ui Components](https://ui.shadcn.com)
468471
- [MCP Registry Official](https://github.com/modelcontextprotocol/registry)
469472

473+
470474
## Deploy on Vercel
471475

472476
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
"lint": "biome check",
1414
"format": "biome format --write",
1515
"test": "vitest",
16+
"test:e2e": "playwright test",
17+
"test:e2e:ui": "playwright test --ui",
18+
"test:e2e:debug": "playwright test --debug",
1619
"type-check": "tsc --noEmit",
1720
"prepare": "husky",
1821
"oidc": "node dev-auth/oidc-provider.mjs",
@@ -51,6 +54,7 @@
5154
"@hey-api/client-next": "0.5.1",
5255
"@hey-api/openapi-ts": "0.89.0",
5356
"@mswjs/http-middleware": "^0.10.2",
57+
"@playwright/test": "^1.56.1",
5458
"@tailwindcss/postcss": "^4",
5559
"@testing-library/dom": "^10.4.1",
5660
"@testing-library/jest-dom": "^6.9.1",

playwright.config.mts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { defineConfig, devices } from "@playwright/test";
2+
3+
const BASE_URL = process.env.BASE_URL || "http://localhost:3000";
4+
5+
async function isServerRunning(): Promise<boolean> {
6+
try {
7+
await fetch(BASE_URL, { signal: AbortSignal.timeout(2000) });
8+
return true;
9+
} catch {
10+
return false;
11+
}
12+
}
13+
14+
const serverAlreadyRunning = await isServerRunning();
15+
16+
export default defineConfig({
17+
testDir: "./tests/e2e",
18+
fullyParallel: true,
19+
forbidOnly: !!process.env.CI,
20+
retries: process.env.CI ? 2 : 0,
21+
workers: process.env.CI ? 1 : undefined,
22+
reporter: process.env.CI ? "github" : "list",
23+
timeout: 30_000,
24+
use: {
25+
baseURL: BASE_URL,
26+
trace: "on-first-retry",
27+
screenshot: "only-on-failure",
28+
},
29+
projects: [
30+
{
31+
name: "chromium",
32+
use: { ...devices["Desktop Chrome"] },
33+
},
34+
],
35+
webServer: serverAlreadyRunning
36+
? undefined
37+
: {
38+
command: "pnpm dev",
39+
url: BASE_URL,
40+
timeout: 120_000,
41+
stdout: "pipe",
42+
stderr: "pipe",
43+
env: {
44+
API_BASE_URL: "http://localhost:9090",
45+
OIDC_ISSUER_URL: "http://localhost:4000",
46+
OIDC_CLIENT_ID: "better-auth-dev",
47+
OIDC_CLIENT_SECRET: "dev-secret-change-in-production",
48+
NEXT_PUBLIC_OIDC_PROVIDER_ID: "okta",
49+
BETTER_AUTH_URL: "http://localhost:3000",
50+
BETTER_AUTH_SECRET: "e2e-test-secret-at-least-32-chars-long",
51+
},
52+
},
53+
});

0 commit comments

Comments
 (0)