Skip to content

Commit 4737c94

Browse files
authored
chore(e2e): pin anthropic for api e2e, servers, and ci (#143)
* chore(e2e): pin anthropic for api e2e, servers, and ci * ci(e2e): fail fast when anthropic key missing for AI E2E
1 parent 0687c1c commit 4737c94

File tree

7 files changed

+49
-2
lines changed

7 files changed

+49
-2
lines changed

.github/workflows/api-e2e.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ env:
2323
PGLITE: true
2424
DATABASE_URL: postgresql://localhost/test
2525
JWT_SECRET: e2e-jwt-secret-min-32-chars-for-tests
26+
AI_PROVIDER: anthropic
2627
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
2728

2829
jobs:
@@ -53,6 +54,16 @@ jobs:
5354
run: pnpm turbo run test --filter=@repo/api
5455
- name: Install Playwright
5556
run: pnpm --filter @repo/api exec playwright install chromium --with-deps
57+
- name: Verify ANTHROPIC_API_KEY for E2E (AI_PROVIDER=anthropic)
58+
shell: bash
59+
env:
60+
AI_PROVIDER: ${{ env.AI_PROVIDER }}
61+
ANTHROPIC_API_KEY: ${{ env.ANTHROPIC_API_KEY }}
62+
run: |
63+
if [[ "${AI_PROVIDER}" == "anthropic" && -z "${ANTHROPIC_API_KEY}" ]]; then
64+
echo "::error::AI_PROVIDER is anthropic but ANTHROPIC_API_KEY is empty or unset. Set the ANTHROPIC_API_KEY repository secret; required before E2E tests (local)." >&2
65+
exit 1
66+
fi
5667
- name: E2E tests (local)
5768
run: pnpm --filter @repo/api test:e2e:local
5869
- name: Upload Playwright report

.github/workflows/web-e2e.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ env:
2727
DATABASE_URL: postgresql://localhost/test
2828
JWT_SECRET: e2e-jwt-secret-min-32-chars-for-tests
2929
NEXT_PUBLIC_API_URL: http://localhost:3001
30+
AI_PROVIDER: anthropic
3031
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
3132

3233
jobs:
@@ -57,6 +58,16 @@ jobs:
5758
run: pnpm turbo run test --filter=@repo/web
5859
- name: Install Playwright
5960
run: pnpm --filter @repo/web exec playwright install chromium --with-deps
61+
- name: Verify ANTHROPIC_API_KEY for E2E (AI_PROVIDER=anthropic)
62+
shell: bash
63+
env:
64+
AI_PROVIDER: ${{ env.AI_PROVIDER }}
65+
ANTHROPIC_API_KEY: ${{ env.ANTHROPIC_API_KEY }}
66+
run: |
67+
if [[ "${AI_PROVIDER}" == "anthropic" && -z "${ANTHROPIC_API_KEY}" ]]; then
68+
echo "::error::AI_PROVIDER is anthropic but ANTHROPIC_API_KEY is empty or unset. Set the ANTHROPIC_API_KEY repository secret; required before E2E tests (local)." >&2
69+
exit 1
70+
fi
6071
- name: E2E tests (local)
6172
env:
6273
SKIP_BUILD: '1'

apps/api/.env.test.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ DATABASE_URL=postgresql://localhost/test
2828
# AI
2929
# -----------------------------------------------------------------------------
3030
ANTHROPIC_API_KEY=sk-ant-xxx
31+
AI_PROVIDER=anthropic
3132
# OPEN_ROUTER_API_KEY=
3233
# OLLAMA_BASE_URL=http://localhost:11434
3334
# AI_DEFAULT_MODEL=claude-sonnet-4-20250514

apps/api/scripts/run-e2e-local.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/**
33
* E2E local: spawn Fastify API, poll until healthy, run Playwright, cleanup on exit.
44
* No wait-on. Uses ALLOW_TEST, PGLITE, NODE_ENV=test.
5+
* Forces AI_PROVIDER=anthropic and strips Open Router/Ollama/AI_DEFAULT_MODEL (parity with Vitest + web E2E).
56
*/
67
import { spawn, spawnSync } from 'node:child_process'
78
import { existsSync, readFileSync } from 'node:fs'
@@ -67,14 +68,26 @@ async function main() {
6768
)
6869
process.exit(1)
6970
}
71+
const anthropicApiKey = loaded.ANTHROPIC_API_KEY ?? process.env.ANTHROPIC_API_KEY
72+
if (!anthropicApiKey) {
73+
process.stderr.write(
74+
'E2E local: ANTHROPIC_API_KEY must be set in .env.test or process.env when AI_PROVIDER is anthropic. Refusing to run without it.\n',
75+
)
76+
process.exit(1)
77+
}
7078
const env = {
7179
...process.env,
7280
...loaded,
7381
ALLOW_TEST: 'true',
7482
PGLITE: 'true',
7583
NODE_ENV: 'test',
7684
JWT_SECRET: jwtSecret,
85+
AI_PROVIDER: 'anthropic',
86+
ANTHROPIC_API_KEY: anthropicApiKey,
7787
}
88+
delete env.OPEN_ROUTER_API_KEY
89+
delete env.OLLAMA_BASE_URL
90+
delete env.AI_DEFAULT_MODEL
7891

7992
const fastify = spawn(process.execPath, ['--import', 'tsx', 'server.ts'], {
8093
cwd: fastifyDir,

apps/docu/content/docs/testing/frontend-testing.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ test.describe('Magic Link Auth E2E', () => {
5858

5959
- **workers: 1** — Required for PGlite (Fastify test DB) to avoid concurrent writer issues
6060
- **Test order** — Auth project first (magic-link-auth: error tests, login/logout; ends with logout). Chromium: unauth badge tests first, then first authed test triggers fixture and confirms session, then remaining authed tests run consecutively
61-
- **Chat E2E** — Requires `OPEN_ROUTER_API_KEY`; see [E2E Testing](/docs/testing/e2e-testing) for env vars. If UNAUTHORIZED, session/Bearer propagation to Fastify `/ai/chat` needs debugging.
61+
- **Chat E2E** — Requires `ANTHROPIC_API_KEY` (Anthropic Sonnet); see [E2E Testing](/docs/testing/e2e-testing) for env vars. If UNAUTHORIZED, session/Bearer propagation to Fastify `/ai/chat` needs debugging.
6262
- **Session model** — One login per worker via `authenticatedStorageState` fixture; cookies/storage saved to `test-results/.auth/user.json` (gitignored); each authed test gets a new context created with that storageState. No per-test login
6363
- **Login/logout tests** — Import from `@playwright/test`, use `page`; need fresh contexts to verify the flow
6464
- **Authed feature tests** — Import from `e2e/fixtures`, use `authenticatedPage`; no `loginAsTestUser` in test body. Each test gets a fresh context with saved storageState; navigate to target route (e.g. `goto('/')`) before asserting

apps/web/e2e/chat-assistant.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ test.describe('Chat Assistant', () => {
3232
if (
3333
/insufficient_quota|insufficient_credits|quota_exceeded|credits_exceeded/i.test(errorText)
3434
) {
35-
test.skip(true, 'OpenRouter 402 insufficient credits')
35+
test.skip(true, 'AI provider quota/credits (402)')
3636
return
3737
}
3838
if (/invalid x-api-key|authentication_error|invalid.*api.*key|401/i.test(errorText)) {

apps/web/scripts/start-e2e-servers.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Run in one terminal, then in another: pnpm test:e2e
55
*
66
* Use when Playwright's webServer spawns processes that get OOM killed (exit 137) on constrained VMs.
7+
* Pins AI to Anthropic for API (same as test:e2e:local).
78
*/
89
import { spawn } from 'node:child_process'
910
import { dirname } from 'node:path'
@@ -18,7 +19,17 @@ const env = {
1819
PGLITE: 'true',
1920
NODE_ENV: 'test',
2021
NEXT_PUBLIC_API_URL: 'http://localhost:3001',
22+
AI_PROVIDER: 'anthropic',
2123
}
24+
if (env.AI_PROVIDER === 'anthropic' && !String(env.ANTHROPIC_API_KEY ?? '').trim()) {
25+
process.stderr.write(
26+
'start-e2e-servers: ANTHROPIC_API_KEY is required when AI_PROVIDER is anthropic. Set it in the environment (e.g. .env.local) before starting E2E servers.\n',
27+
)
28+
process.exit(1)
29+
}
30+
delete env.OPEN_ROUTER_API_KEY
31+
delete env.OLLAMA_BASE_URL
32+
delete env.AI_DEFAULT_MODEL
2233

2334
const api = spawn('pnpm', ['--filter', '@repo/api', 'start:ci'], {
2435
cwd: repoRoot,

0 commit comments

Comments
 (0)