feat: 为主导航菜单和页面区块添加ARIA属性 fix: 解决工作时间信息获取问题 perf: 优化页面滚动功能实现 fix: 修正联系页面标题显示问题 test: 运行完整测试套件验证修复效果 docs: 添加修复完成报告
14 KiB
测试套件修复计划
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
目标: 修复表单测试中的元素定位、CSS选择器和Toast组件处理问题,使所有9个失败的表单测试通过。
架构: 通过在系统代码中添加data-testid属性、修正测试代码的CSS选择器、更新Toast组件处理逻辑,实现测试与实际UI的同步。
技术栈: Playwright测试框架、React组件、TypeScript、CSS选择器
问题分析
当前9个表单测试失败的根本原因:
- 元素定位器不匹配 - 测试使用了不存在的
data-testid属性 - CSS选择器转义错误 - 错误消息选择器使用了双转义
- Toast组件处理不当 - 测试没有正确处理动态Toast显示
- 缺少等待机制 - 没有等待异步UI更新完成
Task 1: 在系统代码中添加data-testid属性
目标: 为表单元素添加data-testid属性,使测试能够正确定位元素。
文件:
- 修改:
/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/src/components/sections/contact-section.tsx
Step 1: 为姓名输入框添加data-testid
<Input
label="姓名"
id="name"
placeholder="请输入您的姓名"
required
data-testid="name-input"
value={formData.name}
onChange={(e) => handleChange('name', e.target.value)}
onBlur={(e) => handleBlur('name', e.target.value)}
error={errors.name}
/>
Step 2: 为电话输入框添加data-testid
<Input
label="电话"
id="phone"
type="tel"
placeholder="请输入您的电话"
required
data-testid="phone-input"
value={formData.phone}
onChange={(e) => handleChange('phone', e.target.value)}
onBlur={(e) => handleBlur('phone', e.target.value)}
error={errors.phone}
/>
Step 3: 为邮箱输入框添加data-testid
<Input
label="邮箱"
id="email"
type="email"
placeholder="请输入您的邮箱"
required
data-testid="email-input"
value={formData.email}
onChange={(e) => handleChange('email', e.target.value)}
onBlur={(e) => handleBlur('email', e.target.value)}
error={errors.email}
/>
Step 4: 为留言输入框添加data-testid
<Textarea
label="留言内容"
id="message"
placeholder="请输入您想咨询的内容"
rows={5}
required
data-testid="message-input"
value={formData.message}
onChange={(e) => handleChange('message', e.target.value)}
onBlur={(e) => handleBlur('message', e.target.value)}
error={errors.message}
/>
Step 5: 为提交按钮添加data-testid
<Button
type="submit"
size="lg"
className="w-full group mt-auto min-h-[52px] md:min-h-0"
disabled={isSubmitting}
data-testid="submit-button"
>
Step 6: 为成功消息添加data-testid
{isSubmitted ? (
<div className="text-center py-12 flex-1 flex items-center justify-center" data-testid="success-message">
<div className="w-16 h-16 bg-[#C41E3A] rounded-full flex items-center justify-center mx-auto mb-4 animate-stamp-in">
<CheckCircle2 className="w-8 h-8 text-white" />
</div>
<h4 className="text-xl font-semibold text-[#1A1A2E] mb-2">消息已发送</h4>
<p className="text-[#718096]">感谢您的留言,我们会尽快与您联系!</p>
</div>
) : (
Step 7: 为Toast组件添加data-testid
{showToast && (
<Toast
message={toastMessage}
type={toastType}
onClose={() => setShowToast(false)}
data-testid="toast-notification"
/>
)}
Step 8: 为错误消息容器添加data-testid
在Input组件中,为错误消息添加data-testid:
{error && (
<p id={errorId} className="mt-1 text-sm text-[#C41E3A]" role="alert" data-testid="error-message">
{error}
</p>
)}
Step 9: 验证data-testid属性已正确添加
运行: cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website && npm run dev
预期: 开发服务器正常启动,无编译错误
Step 10: 提交更改
git add src/components/sections/contact-section.tsx src/components/ui/input.tsx src/components/ui/textarea.tsx
git commit -m "feat: add data-testid attributes for form elements to improve testability"
Task 2: 修正测试代码中的CSS选择器
目标: 修正ContactPage中的CSS选择器,使用正确的转义和data-testid定位。
文件:
- 修改:
/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/test-framework/shared/pages/ContactPage.ts
Step 1: 修正getFormErrorMessage方法
async getFormErrorMessage(): Promise<string> {
const errorElement = await this.page.locator('[data-testid="error-message"]').first();
return await errorElement.textContent() || '';
}
Step 2: 修正getFormSuccessMessage方法
async getFormSuccessMessage(): Promise<string> {
await this.page.waitForTimeout(1000);
const successElement = await this.page.locator('[data-testid="success-message"]');
if (await successElement.count() > 0) {
return await successElement.textContent() || '';
}
return '';
}
Step 3: 添加getToastMessage方法
async getToastMessage(): Promise<{ message: string; type: 'success' | 'error' }> {
const toastElement = await this.page.locator('[data-testid="toast-notification"]');
if (await toastElement.count() > 0) {
const message = await toastElement.textContent() || '';
const type = await toastElement.getAttribute('data-type') as 'success' | 'error';
return { message, type };
}
return { message: '', type: 'success' };
}
Step 4: 添加waitForToast方法
async waitForToast(timeout: number = 5000): Promise<boolean> {
try {
await this.page.waitForSelector('[data-testid="toast-notification"]', { timeout });
return true;
} catch {
return false;
}
}
Step 5: 添加waitForToastHidden方法
async waitForToastHidden(timeout: number = 5000): Promise<boolean> {
try {
await this.page.waitForSelector('[data-testid="toast-notification"]', { state: 'hidden', timeout });
return true;
} catch {
return false;
}
}
Step 6: 运行表单测试验证选择器修复
运行: cd test-framework && npm run test:dev-audit:forms
预期: 部分测试通过,元素定位错误减少
Step 7: 提交更改
git add test-framework/shared/pages/ContactPage.ts
git commit -m "fix: correct CSS selectors and add toast handling methods in ContactPage"
Task 3: 更新表单测试以正确处理Toast组件
目标: 修改测试用例,正确处理Toast组件的异步显示和消失。
文件:
- 修改:
/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/test-framework/dev-audit/forms/forms.spec.ts
Step 1: 修改"联系表单 - 有效数据提交"测试
test('联系表单 - 有效数据提交', async ({ page }) => {
const contactPage = new ContactPage(page);
await page.route('**/api/contact', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ success: true, message: '消息已发送' })
});
});
await contactPage.navigate();
await contactPage.fillContactForm({
name: formData.valid.name,
email: formData.valid.email,
phone: formData.valid.phone,
message: formData.valid.message,
subject: '测试主题'
});
await contactPage.submitForm();
await contactPage.waitForToast();
const toastMessage = await contactPage.getToastMessage();
expect(toastMessage.message).toContain('成功');
expect(toastMessage.type).toBe('success');
await contactPage.waitForToastHidden();
});
Step 2: 修改"联系表单 - 必填字段验证"测试
test('联系表单 - 必填字段验证', async ({ page }) => {
const contactPage = new ContactPage(page);
await contactPage.navigate();
await contactPage.fillContactForm({
name: '',
email: '',
phone: '',
message: '',
subject: ''
});
await contactPage.submitForm();
await page.waitForTimeout(500);
const errorMessage = await contactPage.getFormErrorMessage();
expect(errorMessage).toBeTruthy();
});
Step 3: 修改"联系表单 - 邮箱格式验证"测试
test('联系表单 - 邮箱格式验证', async ({ page }) => {
const contactPage = new ContactPage(page);
await contactPage.navigate();
await contactPage.fillContactForm({
name: '测试用户',
email: formData.invalid.email,
phone: '13800138000',
message: '测试消息',
subject: '测试主题'
});
await contactPage.submitForm();
await page.waitForTimeout(500);
const errorMessage = await contactPage.getFormErrorMessage();
expect(errorMessage).toContain('邮箱');
});
Step 4: 修改"联系表单 - API错误处理"测试
test('联系表单 - API错误处理', async ({ page }) => {
const contactPage = new ContactPage(page);
await page.route('**/api/contact', async route => {
await route.fulfill({
status: 500,
contentType: 'application/json',
body: JSON.stringify({ success: false, message: '服务器错误' })
});
});
await contactPage.navigate();
await contactPage.fillContactForm({
name: formData.valid.name,
email: formData.valid.email,
phone: formData.valid.phone,
message: formData.valid.message,
subject: '测试主题'
});
await contactPage.submitForm();
await contactPage.waitForToast();
const toastMessage = await contactPage.getToastMessage();
expect(toastMessage.message).toContain('失败');
expect(toastMessage.type).toBe('error');
await contactPage.waitForToastHidden();
});
Step 5: 运行表单测试验证Toast处理
运行: cd test-framework && npm run test:dev-audit:forms
预期: 所有表单测试通过,Toast组件正确处理
Step 6: 提交更改
git add test-framework/dev-audit/forms/forms.spec.ts
git commit -m "fix: update form tests to properly handle toast component and async UI updates"
Task 4: 更新Input和Textarea组件以支持data-testid
目标: 确保UI组件正确传递data-testid属性。
文件:
- 修改:
/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/src/components/ui/input.tsx - 修改:
/Users/zhangxiang/Codes/Gitee/home-page/novalon-website/src/components/ui/textarea.tsx
Step 1: 更新Input组件接口
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string
error?: string
'data-testid'?: string
}
Step 2: 在Input组件中使用data-testid
<input
type={type}
id={inputId}
data-slot="input"
data-testid={props['data-testid']}
className={cn(
// ... existing className
)}
ref={ref}
aria-required={props.required ? "true" : undefined}
aria-invalid={error ? "true" : "false"}
aria-describedby={error ? errorId : undefined}
{...props}
/>
Step 3: 更新Textarea组件接口
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
label?: string
error?: string
'data-testid'?: string
}
Step 4: 在Textarea组件中使用data-testid
<textarea
id={textareaId}
data-slot="textarea"
data-testid={props['data-testid']}
className={cn(
// ... existing className
)}
ref={ref}
aria-required={props.required ? "true" : undefined}
aria-invalid={error ? "true" : "false"}
aria-describedby={error ? errorId : undefined}
{...props}
/>
Step 5: 验证组件正确传递data-testid
运行: cd /Users/zhangxiang/Codes/Gitee/home-page/novalon-website && npm run dev
预期: 开发服务器正常启动,组件正确编译
Step 6: 提交更改
git add src/components/ui/input.tsx src/components/ui/textarea.tsx
git commit -m "feat: add data-testid support to Input and Textarea components"
Task 5: 运行完整测试套件验证修复
目标: 运行所有测试验证修复效果。
文件:
- 无需修改
Step 1: 运行表单测试
运行: cd test-framework && npm run test:dev-audit:forms
预期: 所有表单测试通过(20/20)
Step 2: 运行性能测试
运行: cd test-framework && npm run test:dev-audit:performance
预期: 所有性能测试通过(35/35)
Step 3: 运行完整测试套件
运行: cd test-framework && npm run test:dev-audit
预期: 所有测试通过(85/85),通过率100%
Step 4: 生成测试报告
运行: cd test-framework && npx ts-node scripts/generate-report.ts
预期: 生成完整的测试报告,显示所有测试通过
Step 5: 查看测试结果
运行: cat test-framework/reports/results.json | jq '.stats'
预期输出:
{
"startTime": "2026-03-06T...",
"duration": ...,
"expected": 85,
"skipped": 0,
"unexpected": 0,
"flaky": 0
}
Step 6: 提交最终验证
git add test-framework/reports/
git commit -m "test: verify all tests passing after test suite fixes"
验收标准
- 所有表单测试通过(20/20)
- 所有性能测试通过(35/35)
- 所有SEO测试通过
- 所有可访问性测试通过
- 完整测试套件通过率100%(85/85)
- 测试报告显示所有测试通过
- 无测试超时错误
- 无元素定位错误
风险与注意事项
- Toast组件时序问题 - 需要确保测试等待足够时间让Toast显示和消失
- 移动端兼容性 - 某些测试在移动设备上可能需要额外的等待时间
- 并发测试冲突 - 多个测试同时运行可能导致状态污染,确保每个测试独立运行
- API模拟准确性 - 确保API模拟响应与真实API响应格式一致
后续优化建议
- 添加视觉回归测试 - 使用Percy或Applitools进行UI视觉测试
- 增加测试覆盖率 - 添加更多边界条件和异常场景测试
- 性能基准测试 - 建立性能基准,监控性能回归
- 测试数据管理 - 使用测试数据工厂生成更多样化的测试数据
- CI/CD集成 - 将测试集成到持续集成流程中