diff --git a/README.md b/README.md index 06fa17b..877068d 100644 --- a/README.md +++ b/README.md @@ -113,9 +113,9 @@ pnpm dev # 并行启动 api(3000) / web(5173) / worker ```bash pnpm lint && pnpm typecheck && pnpm test # 本地门禁 -pnpm build && pnpm test:e2e # 构建与端到端冒烟 +VITE_PUBLIC_DEMO_SESSION=true pnpm test:e2e # 构建 + 端到端冒烟(demo 会话) pnpm openapi:export && pnpm openapi:diff # 契约快照与破坏性变更检查 -pnpm ci:local # 本地跑完整 CI 门禁 +pnpm ci:local # 本地跑完整 CI 门禁(已内置 e2e 所需 env) ``` > Gitea 暂未部署 Actions runner,推送后远程 CI 会停留在 queued;当前以 `pnpm ci:local` 为准,runner 就绪后 `.gitea/workflows/ci.yml` 会自动接管。 diff --git a/e2e/smoke.spec.ts b/e2e/smoke.spec.ts index d69ff94..c32c9f3 100644 --- a/e2e/smoke.spec.ts +++ b/e2e/smoke.spec.ts @@ -2,7 +2,7 @@ import { expect, type Page, test } from '@playwright/test'; async function signIn(page: Page): Promise { await page.goto('/login'); - await page.getByPlaceholder('请输入账号或邮箱').fill('admin'); + await page.getByPlaceholder('请输入账号或手机号').fill('admin'); await page.getByPlaceholder('请输入密码').fill('demo1234'); await page.getByTestId('login-submit').click(); await expect(page.getByTestId('app-shell')).toBeVisible(); @@ -12,6 +12,9 @@ test('登录页打开并进入工作台', async ({ page }) => { await page.goto('/login'); await expect(page.getByRole('heading', { name: '登录灵犀' })).toBeVisible(); await signIn(page); + // A1 起登录默认落地 /system/users,再从顶部模块导航进入工作台 + await expect(page).toHaveURL(/\/system\/users/); + await page.getByRole('button', { name: '工作台', exact: true }).click(); await expect(page).toHaveURL('/'); await expect(page.getByRole('heading', { name: '工作台', exact: true })).toBeVisible(); await expect(page.getByRole('navigation', { name: '模块导航' })).toBeVisible(); diff --git a/scripts/ci-local.mjs b/scripts/ci-local.mjs index 819ff67..e0112fa 100644 --- a/scripts/ci-local.mjs +++ b/scripts/ci-local.mjs @@ -7,26 +7,35 @@ import { spawnSync } from 'node:child_process'; const pnpm = process.env.npm_execpath ? [process.execPath, process.env.npm_execpath] : ['pnpm']; -/** 每一步可包含多条 pnpm 命令,任一失败立即退出。 */ +/** + * 端到端冒烟走 vite preview + demo 会话,需与 .gitea/workflows/ci.yml 的 job env 对齐; + * 只加在构建与 e2e 步骤,避免影响单测里对真实登录流程的断言。 + */ +const e2eEnv = { + VITE_PUBLIC_API_BASE_URL: process.env.VITE_PUBLIC_API_BASE_URL ?? 'http://127.0.0.1:3000/api/v1', + VITE_PUBLIC_DEMO_SESSION: process.env.VITE_PUBLIC_DEMO_SESSION ?? 'true', +}; + +/** 每一步可包含多条 pnpm 命令,任一失败立即退出;env 为该步骤追加的环境变量。 */ const steps = [ { label: '检查本地依赖(PG / Redis)', commands: [['check:dev']] }, { label: '格式化检查', commands: [['format:check']] }, { label: 'Lint', commands: [['lint']] }, { label: '类型检查', commands: [['typecheck']] }, { label: '单元测试', commands: [['test']] }, - { label: '构建', commands: [['build']] }, + { label: '构建', commands: [['build']], env: e2eEnv }, { label: '数据库迁移与种子', commands: [['exec', 'prisma', 'migrate', 'deploy'], ['db:seed']], }, { label: '集成测试', commands: [['test:int']] }, { label: 'OpenAPI 导出与契约检查', commands: [['openapi:export'], ['openapi:diff']] }, - { label: '端到端测试', commands: [['test:e2e']] }, + { label: '端到端测试', commands: [['test:e2e']], env: e2eEnv }, ]; -function runPnpm(args) { +function runPnpm(args, env = {}) { const result = spawnSync(pnpm[0], [...pnpm.slice(1), ...args], { - env: process.env, + env: { ...process.env, ...env }, stdio: 'inherit', }); if (result.error) { @@ -43,7 +52,7 @@ const startedAt = Date.now(); for (const [index, step] of steps.entries()) { console.log(`\n[${index + 1}/${steps.length}] ${step.label}`); for (const args of step.commands) { - runPnpm(args); + runPnpm(args, step.env); } } const seconds = ((Date.now() - startedAt) / 1000).toFixed(1); diff --git a/turbo.json b/turbo.json index 288ec5f..f0adc43 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,7 @@ { "$schema": "https://turbo.build/schema.json", "ui": "stream", + "globalEnv": ["VITE_PUBLIC_API_BASE_URL", "VITE_PUBLIC_DEMO_SESSION"], "tasks": { "build": { "dependsOn": ["^build"],