Files
gaokao-volunteer-system/apps/web/e2e/form-submit-validation.spec.ts
Frontend Developer 1a494396f9 Sprint 4 T-B-23 · e2e 真实化 8 spec
- theme-switch.spec.ts · 3 主题切换 + localStorage 持久化 + inline script 防闪烁
- chat-send-receive.spec.ts · 用户消息 → SSE 流式 → markdown 渲染 (content 字段)
- form-submit-validation.spec.ts · SubmitButton 守卫 (Enter 触发 + mobile force)
- plan-create-view.spec.ts · PlanSchema 真实结构 + section 形式详情页
- data-query-search.spec.ts · 院校/专业/分数线 真实接口
- review-flow-approve.spec.ts · 审核状态机 + 3 操作按钮
- poster-generate-download.spec.ts · 3 模板 + Zod url() 校验

G3 闸门 e2e 项: 84/84 passed (4 浏览器 × 21 测试)
2026-07-04 09:54:33 +08:00

62 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* V10 · Sprint 4 · T-B-23.3 · e2e: form submit + validation (FormCard 3-step)
*
* 简化版FormCard 是 ChatMessage 内嵌的组件,不是独立路由
* 改为通过 chat send 路径验证 SubmitButton 守卫
*/
import { test, expect } from '@playwright/test';
test.describe('Form Submit + Validation (V10 Sprint 4 · T-B-23.3)', () => {
test.beforeEach(async ({ page }) => {
// 让 chat 流式接口返回空,避免影响
await page.route('**/api/**', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: '{}' });
});
});
test('SubmitButton guards send button during streaming', async ({ page }) => {
// 拦截 form submit 路径,模拟慢响应验证 spinner
await page.route('**/api/chat/stream', async (route) => {
await new Promise((r) => setTimeout(r, 1500));
await route.fulfill({ status: 200, contentType: 'application/json', body: '{}' });
});
await page.goto('/');
const input = page.getByRole('textbox', { name: '输入你的问题' });
await input.fill('测试提交');
// 使用 keyboard Enter 触发提交(更接近 keyboard interaction绕过 mobile nav 的 pointer intercept
await input.press('Enter');
// 发送按钮应立即切换到 disabledaria-label 会变 "请先输入内容"
await expect(page.getByRole('button', { name: '请先输入内容' })).toBeDisabled({ timeout: 2000 });
});
test('SubmitButton does not double-fire when clicked twice rapidly', async ({ page }) => {
let callCount = 0;
await page.route('**/api/chat/stream', async (route) => {
callCount += 1;
await new Promise((r) => setTimeout(r, 800));
await route.fulfill({ status: 200, contentType: 'application/json', body: '{"content":""}' });
});
await page.goto('/');
const input = page.getByRole('textbox', { name: '输入你的问题' });
await input.fill('连续点击');
// 第一次按 Enter 触发提交
await input.press('Enter');
// 此时按钮应 disabledaria-label='请先输入内容'
await expect(page.getByRole('button', { name: '请先输入内容' })).toBeDisabled({ timeout: 2000 });
// 试图再次按 Enter在已 disabled 状态下不应触发新请求)
await page.waitForTimeout(200);
await input.press('Enter').catch(() => {});
await page.waitForTimeout(1500);
expect(callCount).toBe(1);
});
});