Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
07d6e48
test: set up BDD/E2E test support
kantord Nov 21, 2025
079aa97
Merge branch 'main' into set-up-playwright
kantord Nov 21, 2025
ce5a53d
add inspector mode
kantord Nov 21, 2025
8a2da1f
add tracing mode
kantord Nov 21, 2025
a3c2cd7
automate all aria roles for cucumber tests
kantord Nov 21, 2025
f70d24a
simplify some stuff
kantord Nov 21, 2025
9da119c
.
kantord Nov 21, 2025
a188a5e
.
kantord Nov 21, 2025
2f96c6f
.
kantord Nov 21, 2025
90d40bb
Merge branch 'main' into set-up-playwright
kantord Nov 25, 2025
6cc0279
fixes
kantord Nov 25, 2025
4fd4ff0
login "fixture"
kantord Nov 25, 2025
f44313f
do not hang after successful run
kantord Nov 25, 2025
d5264ac
cookie injection to keep authentication fast
kantord Nov 25, 2025
d10417b
fix ci failure
kantord Nov 25, 2025
cc0d781
.
kantord Nov 25, 2025
4e43d58
.
kantord Nov 25, 2025
30fb891
Merge branch 'main' into set-up-playwright
kantord Nov 25, 2025
5430b64
.
kantord Nov 25, 2025
acdc496
implement review suggestions
kantord Nov 25, 2025
fe563b7
cleanup
kantord Nov 25, 2025
123250d
cleanup
kantord Nov 25, 2025
2cd7547
remove unused rule definition
kantord Nov 25, 2025
d3ddb4c
stricted path for healthcheck url
kantord Nov 25, 2025
d6dea31
Merge branch 'main' into set-up-playwright
kantord Dec 12, 2025
61b26fa
remove cucumber
kantord Dec 12, 2025
80eb323
auto run dev server if it's not already runnging
kantord Dec 12, 2025
d32f206
fix vitest config
kantord Dec 12, 2025
df8c2d1
rename gh workload file
kantord Dec 12, 2025
0085ce5
.
kantord Dec 12, 2025
11926e6
much cleaner ci
kantord Dec 12, 2025
0b6e69c
remove duplicated documentation
kantord Dec 12, 2025
8a8ddc4
use obviously fake env vars
kantord Dec 12, 2025
8eb9147
remove leftofver
kantord Dec 12, 2025
50ac1d1
test that mcp servers are rendered
kantord Dec 12, 2025
5c78df4
Merge branch 'main' into set-up-playwright
kantord Dec 12, 2025
56c13ed
Merge branch 'main' into set-up-playwright
kantord Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: E2E Tests

on:
push:
branches: ["**"]
pull_request:
branches: ["**"]

permissions:
contents: read

jobs:
e2e:
name: Playwright E2E
runs-on: ubuntu-latest
timeout-minutes: 15
env:
API_BASE_URL: http://localhost:9090
OIDC_ISSUER_URL: http://localhost:4000
OIDC_CLIENT_ID: test-only-not-a-real-id
OIDC_CLIENT_SECRET: test-only-not-a-real-secret
NEXT_PUBLIC_OIDC_PROVIDER_ID: oidc
BETTER_AUTH_URL: http://localhost:3000
BETTER_AUTH_SECRET: test-only-not-a-real-better-auth-secret
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup
uses: ./.github/actions/setup

- name: Install Playwright browsers
run: pnpm exec playwright install --with-deps chromium

- name: Run Playwright tests
run: pnpm test:e2e

- name: Upload test artifacts
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: |
test-results/
playwright-report/
retention-days: 7
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

# testing
/coverage
# Playwright/Cucumber E2E artifacts
test-results/
playwright-report/
blob-report/

# next.js
/.next/
Expand Down
24 changes: 20 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pnpm generate-client:nofetch # Regenerate without fetching

### Backend API

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

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

### E2E Tests (Playwright)

- End-to-end tests live under `tests/e2e` and run against a live dev stack.
- Commands:
- `pnpm dev` – starts Next.js (3000), mock OIDC (4000), and MSW mock API (9090)
- `pnpm run test:e2e` – runs Playwright tests (headless)
- `pnpm run test:e2e:ui` – opens Playwright UI mode for interactive debugging
- `pnpm run test:e2e:debug` – runs with Playwright Inspector
- CI runs E2E tests via `.github/workflows/bdd.yml` and installs Playwright browsers.
- Install browsers locally once: `pnpm exec playwright install`

Tests use custom fixtures for authentication. The `authenticatedPage` fixture handles login automatically.

### Example Test

```typescript
Expand Down Expand Up @@ -278,7 +291,10 @@ git push origin v0.x.x

### Authentication Not Working

- **Development**: Ensure OIDC mock is running (`pnpm oidc`)
- **Development**:
- Ensure OIDC mock is running (`pnpm oidc`) or start the full stack with `pnpm dev`
- Dev provider issues refresh tokens unconditionally and uses a short AccessToken TTL (15s) to exercise the refresh flow
- 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`
- **Production**: Check environment variables:
- `OIDC_ISSUER_URL` - OIDC provider URL
- `OIDC_CLIENT_ID` - OAuth2 client ID
Expand All @@ -289,7 +305,7 @@ git push origin v0.x.x

### API Calls Failing

- Check `NEXT_PUBLIC_API_URL` environment variable
- Check `API_BASE_URL` environment variable
- Verify backend API is running
- Check browser console for CORS errors

Expand Down
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pnpm dev
# Application will be available at http://localhost:3000
```

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.

### Available Commands

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

### Testing

#### Unit/Component Tests

```bash
# Run all tests
pnpm test
pnpm test # Run all tests
pnpm test --watch # Watch mode
pnpm test --coverage # With coverage
```

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

# Run tests with coverage
pnpm test --coverage
#### E2E Tests (Playwright)

# Run specific test file
pnpm test src/components/navbar.test.tsx
```bash
pnpm exec playwright install # One-time browser install
pnpm test:e2e # Run tests (auto-starts dev server if needed)
pnpm test:e2e:ui # Playwright UI mode
pnpm test:e2e:debug # With Playwright Inspector
```

Tests use:

- **Vitest** - Test runner
- **Testing Library** - React component testing
- **MSW** - API mocking
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.

### Mock Server

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


## Deploy on Vercel

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.
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"lint": "biome check",
"format": "biome format --write",
"test": "vitest",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:debug": "playwright test --debug",
"type-check": "tsc --noEmit",
"prepare": "husky",
"oidc": "node dev-auth/oidc-provider.mjs",
Expand Down Expand Up @@ -51,6 +54,7 @@
"@hey-api/client-next": "0.5.1",
"@hey-api/openapi-ts": "0.89.0",
"@mswjs/http-middleware": "^0.10.2",
"@playwright/test": "^1.56.1",
"@tailwindcss/postcss": "^4",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
Expand Down
53 changes: 53 additions & 0 deletions playwright.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { defineConfig, devices } from "@playwright/test";

const BASE_URL = process.env.BASE_URL || "http://localhost:3000";

async function isServerRunning(): Promise<boolean> {
try {
await fetch(BASE_URL, { signal: AbortSignal.timeout(2000) });
return true;
} catch {
return false;
}
}

const serverAlreadyRunning = await isServerRunning();

export default defineConfig({
testDir: "./tests/e2e",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? "github" : "list",
timeout: 30_000,
use: {
baseURL: BASE_URL,
trace: "on-first-retry",
screenshot: "only-on-failure",
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
webServer: serverAlreadyRunning
? undefined
: {
command: "pnpm dev",
url: BASE_URL,
timeout: 120_000,
stdout: "pipe",
stderr: "pipe",
env: {
API_BASE_URL: "http://localhost:9090",
OIDC_ISSUER_URL: "http://localhost:4000",
OIDC_CLIENT_ID: "better-auth-dev",
OIDC_CLIENT_SECRET: "dev-secret-change-in-production",
NEXT_PUBLIC_OIDC_PROVIDER_ID: "okta",
BETTER_AUTH_URL: "http://localhost:3000",
BETTER_AUTH_SECRET: "e2e-test-secret-at-least-32-chars-long",
},
},
});
Loading
Loading