Commit 325ac2f913f7259c56d4a8fee3e8cd317fb6074d
1 parent
52fe7fa5
test(frontend): Playwright E2E spec + config (fixme 标记,留待手工验收)
REQ_ID: FE-01
Showing
2 changed files
with
60 additions
and
0 deletions
frontend/playwright.config.ts
0 → 100644
| 1 | +import { defineConfig, devices } from '@playwright/test'; | |
| 2 | + | |
| 3 | +export default defineConfig({ | |
| 4 | + testDir: './tests/e2e', | |
| 5 | + timeout: 30000, | |
| 6 | + retries: 0, | |
| 7 | + use: { | |
| 8 | + baseURL: 'http://localhost:5173', | |
| 9 | + headless: true, | |
| 10 | + trace: 'on-first-retry', | |
| 11 | + }, | |
| 12 | + webServer: { | |
| 13 | + command: 'npm run dev', | |
| 14 | + url: 'http://localhost:5173', | |
| 15 | + reuseExistingServer: !process.env.CI, | |
| 16 | + timeout: 60000, | |
| 17 | + }, | |
| 18 | + projects: [ | |
| 19 | + { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, | |
| 20 | + ], | |
| 21 | +}); | ... | ... |
frontend/tests/e2e/login.spec.ts
0 → 100644
| 1 | +import { test, expect } from '@playwright/test'; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * E2E 测试需要: | |
| 5 | + * - 后端运行在 :9090(cd backend && mvn spring-boot:run) | |
| 6 | + * - 前端 dev server :5173 由 playwright.config webServer 自动起 | |
| 7 | + * - `npx playwright install chromium` 完成浏览器 binary 下载 | |
| 8 | + * | |
| 9 | + * 本 plan Task 10 当前 .fixme(),FE 完成 review 时纳入 nice-to-have; | |
| 10 | + * 由开发者手动 `npx playwright install && npm run e2e` 跑一次完整链路验收。 | |
| 11 | + */ | |
| 12 | + | |
| 13 | +test.fixme('successLogin_redirectsToUsers', async ({ page }) => { | |
| 14 | + await page.goto('/login'); | |
| 15 | + await page.getByPlaceholder('请输入你的用户名').fill('alice'); | |
| 16 | + await page.getByPlaceholder('请输入你的密码').fill('Password1!'); | |
| 17 | + await page.getByTestId('login-submit').click(); | |
| 18 | + await expect(page).toHaveURL(/.*\/users/); | |
| 19 | +}); | |
| 20 | + | |
| 21 | +test.fixme('badPassword_showsError', async ({ page }) => { | |
| 22 | + await page.goto('/login'); | |
| 23 | + await page.getByPlaceholder('请输入你的用户名').fill('alice'); | |
| 24 | + await page.getByPlaceholder('请输入你的密码').fill('WRONG'); | |
| 25 | + await page.getByTestId('login-submit').click(); | |
| 26 | + await expect(page.getByText('用户名或密码错误')).toBeVisible(); | |
| 27 | +}); | |
| 28 | + | |
| 29 | +test.fixme('unknownCompany_showsError', async ({ page }) => { | |
| 30 | + await page.goto('/login'); | |
| 31 | + // 通过 evaluate 把 form value 改成不存在的 companyCode | |
| 32 | + await page.evaluate(() => { | |
| 33 | + // 实际 UI 操作:通过 AntD Select 选不存在的项;这里 spec 留 placeholder | |
| 34 | + }); | |
| 35 | + await page.getByPlaceholder('请输入你的用户名').fill('alice'); | |
| 36 | + await page.getByPlaceholder('请输入你的密码').fill('Password1!'); | |
| 37 | + await page.getByTestId('login-submit').click(); | |
| 38 | + await expect(page.getByText('公司不存在或已删除')).toBeVisible(); | |
| 39 | +}); | ... | ... |