feat: 建立完整的测试数据管理体系
- 创建测试数据文件test-data.ts,包含所有测试场景数据 - 增强TestDataGenerator,添加边界、安全、性能等测试数据生成方法 - 支持XSS、SQL注入、路径遍历等安全测试 - 支持WCAG可访问性测试数据 - 支持Core Web Vitals性能测试数据 - 支持响应式断点测试数据
This commit is contained in:
@@ -0,0 +1,216 @@
|
|||||||
|
export const VALID_CONTACT_DATA = {
|
||||||
|
name: '张三',
|
||||||
|
email: 'zhangsan@example.com',
|
||||||
|
phone: '13800138000',
|
||||||
|
subject: '产品咨询',
|
||||||
|
message: '您好,我对贵公司的产品很感兴趣,希望能了解更多信息。',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const INVALID_EMAIL_CASES = [
|
||||||
|
{ email: 'invalid-email', description: '无@符号' },
|
||||||
|
{ email: '@example.com', description: '无用户名' },
|
||||||
|
{ email: 'user@', description: '无域名' },
|
||||||
|
{ email: 'user@domain', description: '无顶级域名' },
|
||||||
|
{ email: 'user domain.com', description: '包含空格' },
|
||||||
|
{ email: 'user@domain..com', description: '连续点号' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const INVALID_PHONE_CASES = [
|
||||||
|
{ phone: '123', description: '过短' },
|
||||||
|
{ phone: '123456789012345', description: '过长' },
|
||||||
|
{ phone: 'abcdefghijk', description: '纯字母' },
|
||||||
|
{ phone: '123-456-7890', description: '包含连字符' },
|
||||||
|
{ phone: '138 0013 8000', description: '包含空格' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const SPECIAL_CHARACTER_CASES = [
|
||||||
|
{ name: '!@#$%^&*()', description: '特殊符号' },
|
||||||
|
{ name: '<script>alert("XSS")</script>', description: 'XSS脚本' },
|
||||||
|
{ name: "'; DROP TABLE users; --", description: 'SQL注入' },
|
||||||
|
{ name: '../../../etc/passwd', description: '路径遍历' },
|
||||||
|
{ name: '{{template}}', description: '模板注入' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const LONG_CONTENT_CASES = [
|
||||||
|
{ message: 'A'.repeat(500), description: '500字符消息' },
|
||||||
|
{ message: 'A'.repeat(1000), description: '1000字符消息' },
|
||||||
|
{ message: 'A'.repeat(1001), description: '超长消息' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const BOUNDARY_CASES = {
|
||||||
|
name: {
|
||||||
|
minLength: '张',
|
||||||
|
maxLength: '张三李四王五赵六钱七孙八周九吴十',
|
||||||
|
empty: '',
|
||||||
|
whitespace: ' ',
|
||||||
|
},
|
||||||
|
phone: {
|
||||||
|
minLength: '1380013800',
|
||||||
|
maxLength: '138001380001',
|
||||||
|
validFormat: '13800138000',
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
minLength: 'a@b.c',
|
||||||
|
maxLength: `${'a'.repeat(64)}@${'b'.repeat(63)}.com`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PERFORMANCE_THRESHOLDS = {
|
||||||
|
loadTime: 5000,
|
||||||
|
firstContentfulPaint: 1800,
|
||||||
|
largestContentfulPaint: 2500,
|
||||||
|
timeToInteractive: 3800,
|
||||||
|
cumulativeLayoutShift: 0.1,
|
||||||
|
firstInputDelay: 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RESPONSIVE_BREAKPOINTS = [
|
||||||
|
{ name: 'mobile-small', width: 320, height: 568 },
|
||||||
|
{ name: 'mobile-medium', width: 375, height: 667 },
|
||||||
|
{ name: 'mobile-large', width: 414, height: 896 },
|
||||||
|
{ name: 'tablet-small', width: 768, height: 1024 },
|
||||||
|
{ name: 'tablet-large', width: 1024, height: 768 },
|
||||||
|
{ name: 'desktop-small', width: 1280, height: 720 },
|
||||||
|
{ name: 'desktop-medium', width: 1366, height: 768 },
|
||||||
|
{ name: 'desktop-large', width: 1920, height: 1080 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const NAVIGATION_ITEMS = [
|
||||||
|
{ label: '首页', href: '#home', expectedUrl: '/' },
|
||||||
|
{ label: '关于我们', href: '#about', expectedUrl: '/' },
|
||||||
|
{ label: '服务', href: '#services', expectedUrl: '/' },
|
||||||
|
{ label: '产品', href: '#products', expectedUrl: '/' },
|
||||||
|
{ label: '案例', href: '#cases', expectedUrl: '/' },
|
||||||
|
{ label: '新闻', href: '#news', expectedUrl: '/' },
|
||||||
|
{ label: '联系我们', href: '#contact', expectedUrl: '/' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const COMPANY_INFO = {
|
||||||
|
name: '四川睿新致远科技有限公司',
|
||||||
|
address: '四川省成都市高新区天府大道中段1268号天府软件园E区1栋',
|
||||||
|
phone: '028-88888888',
|
||||||
|
email: 'contact@ruixin.com',
|
||||||
|
workHours: [
|
||||||
|
{ day: '周一至周五', hours: '9:00 - 18:00' },
|
||||||
|
{ day: '周六', hours: '9:00 - 12:00' },
|
||||||
|
{ day: '周日', hours: '休息' },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SERVICES = [
|
||||||
|
{
|
||||||
|
id: 'service-1',
|
||||||
|
title: '企业数字化转型',
|
||||||
|
description: '帮助企业实现数字化升级',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'service-2',
|
||||||
|
title: '智能制造解决方案',
|
||||||
|
description: '提供智能化生产线解决方案',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'service-3',
|
||||||
|
title: '数据分析服务',
|
||||||
|
description: '专业的数据分析与可视化服务',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const PRODUCTS = [
|
||||||
|
{
|
||||||
|
id: 'product-1',
|
||||||
|
title: '智能生产管理系统',
|
||||||
|
description: '一体化生产管理平台',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'product-2',
|
||||||
|
title: '数据分析平台',
|
||||||
|
description: '企业级数据分析工具',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'product-3',
|
||||||
|
title: '物联网监控平台',
|
||||||
|
description: '实时设备监控与管理',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const NEWS_ITEMS = [
|
||||||
|
{
|
||||||
|
id: 'news-1',
|
||||||
|
title: '公司获得ISO9001认证',
|
||||||
|
date: '2024-01-15',
|
||||||
|
summary: '公司成功通过ISO9001质量管理体系认证',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'news-2',
|
||||||
|
title: '新产品发布会圆满成功',
|
||||||
|
date: '2024-02-20',
|
||||||
|
summary: '智能生产管理系统2.0版本正式发布',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const SECURITY_TEST_CASES = {
|
||||||
|
xssPayloads: [
|
||||||
|
'<script>alert("XSS")</script>',
|
||||||
|
'<img src=x onerror=alert("XSS")>',
|
||||||
|
'<svg onload=alert("XSS")>',
|
||||||
|
'javascript:alert("XSS")',
|
||||||
|
'<body onload=alert("XSS")>',
|
||||||
|
],
|
||||||
|
sqlInjectionPayloads: [
|
||||||
|
"'; DROP TABLE users; --",
|
||||||
|
"' OR '1'='1",
|
||||||
|
"' UNION SELECT * FROM users --",
|
||||||
|
"1; INSERT INTO users VALUES ('hacker')",
|
||||||
|
],
|
||||||
|
pathTraversalPayloads: [
|
||||||
|
'../../../etc/passwd',
|
||||||
|
'..\\..\\..\\windows\\system32\\config\\sam',
|
||||||
|
'....//....//....//etc/passwd',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ACCESSIBILITY_TEST_CASES = {
|
||||||
|
colorContrastRatios: {
|
||||||
|
normalText: 4.5,
|
||||||
|
largeText: 3.0,
|
||||||
|
uiComponents: 3.0,
|
||||||
|
},
|
||||||
|
touchTargetSize: 44,
|
||||||
|
focusIndicatorVisible: true,
|
||||||
|
keyboardNavigationRequired: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ERROR_MESSAGES = {
|
||||||
|
requiredField: '此字段为必填项',
|
||||||
|
invalidEmail: '请输入有效的邮箱地址',
|
||||||
|
invalidPhone: '请输入有效的手机号码',
|
||||||
|
messageTooShort: '消息内容至少需要10个字符',
|
||||||
|
messageTooLong: '消息内容不能超过1000个字符',
|
||||||
|
submissionFailed: '提交失败,请稍后重试',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SUCCESS_MESSAGES = {
|
||||||
|
formSubmitted: '消息已发送',
|
||||||
|
thankYou: '感谢您的留言,我们会尽快与您联系',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TEST_USERS = {
|
||||||
|
admin: {
|
||||||
|
username: 'admin',
|
||||||
|
password: 'admin123',
|
||||||
|
role: 'administrator',
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
username: 'testuser',
|
||||||
|
password: 'test123',
|
||||||
|
role: 'user',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const API_ENDPOINTS = {
|
||||||
|
contactForm: '/api/contact',
|
||||||
|
newsletter: '/api/newsletter',
|
||||||
|
services: '/api/services',
|
||||||
|
products: '/api/products',
|
||||||
|
news: '/api/news',
|
||||||
|
};
|
||||||
@@ -251,4 +251,210 @@ export class TestDataGenerator {
|
|||||||
## Message
|
## Message
|
||||||
${this.generateMessage()}`;
|
${this.generateMessage()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static generateBoundaryTestData(): {
|
||||||
|
name: { minLength: string; maxLength: string; empty: string; whitespace: string };
|
||||||
|
phone: { minLength: string; maxLength: string; validFormat: string };
|
||||||
|
email: { minLength: string; maxLength: string };
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
name: {
|
||||||
|
minLength: '张',
|
||||||
|
maxLength: '张三李四王五赵六钱七孙八周九吴十',
|
||||||
|
empty: '',
|
||||||
|
whitespace: ' ',
|
||||||
|
},
|
||||||
|
phone: {
|
||||||
|
minLength: '1380013800',
|
||||||
|
maxLength: '138001380001',
|
||||||
|
validFormat: '13800138000',
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
minLength: 'a@b.c',
|
||||||
|
maxLength: `${'a'.repeat(64)}@${'b'.repeat(63)}.com`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateSecurityTestData(): {
|
||||||
|
xssPayloads: string[];
|
||||||
|
sqlInjectionPayloads: string[];
|
||||||
|
pathTraversalPayloads: string[];
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
xssPayloads: [
|
||||||
|
'<script>alert("XSS")</script>',
|
||||||
|
'<img src=x onerror=alert("XSS")>',
|
||||||
|
'<svg onload=alert("XSS")>',
|
||||||
|
'javascript:alert("XSS")',
|
||||||
|
'<body onload=alert("XSS")>',
|
||||||
|
],
|
||||||
|
sqlInjectionPayloads: [
|
||||||
|
"'; DROP TABLE users; --",
|
||||||
|
"' OR '1'='1",
|
||||||
|
"' UNION SELECT * FROM users --",
|
||||||
|
"1; INSERT INTO users VALUES ('hacker')",
|
||||||
|
],
|
||||||
|
pathTraversalPayloads: [
|
||||||
|
'../../../etc/passwd',
|
||||||
|
'..\\..\\..\\windows\\system32\\config\\sam',
|
||||||
|
'....//....//....//etc/passwd',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateAccessibilityTestData(): {
|
||||||
|
colorContrastRatios: { normalText: number; largeText: number; uiComponents: number };
|
||||||
|
touchTargetSize: number;
|
||||||
|
focusIndicatorVisible: boolean;
|
||||||
|
keyboardNavigationRequired: boolean;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
colorContrastRatios: {
|
||||||
|
normalText: 4.5,
|
||||||
|
largeText: 3.0,
|
||||||
|
uiComponents: 3.0,
|
||||||
|
},
|
||||||
|
touchTargetSize: 44,
|
||||||
|
focusIndicatorVisible: true,
|
||||||
|
keyboardNavigationRequired: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generatePerformanceTestData(): {
|
||||||
|
thresholds: {
|
||||||
|
loadTime: number;
|
||||||
|
firstContentfulPaint: number;
|
||||||
|
largestContentfulPaint: number;
|
||||||
|
timeToInteractive: number;
|
||||||
|
cumulativeLayoutShift: number;
|
||||||
|
firstInputDelay: number;
|
||||||
|
};
|
||||||
|
budgets: {
|
||||||
|
totalPageSize: number;
|
||||||
|
imageSize: number;
|
||||||
|
scriptSize: number;
|
||||||
|
stylesheetSize: number;
|
||||||
|
};
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
thresholds: {
|
||||||
|
loadTime: 5000,
|
||||||
|
firstContentfulPaint: 1800,
|
||||||
|
largestContentfulPaint: 2500,
|
||||||
|
timeToInteractive: 3800,
|
||||||
|
cumulativeLayoutShift: 0.1,
|
||||||
|
firstInputDelay: 100,
|
||||||
|
},
|
||||||
|
budgets: {
|
||||||
|
totalPageSize: 1600000,
|
||||||
|
imageSize: 500000,
|
||||||
|
scriptSize: 300000,
|
||||||
|
stylesheetSize: 100000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateResponsiveTestData(): Array<{
|
||||||
|
name: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}> {
|
||||||
|
return [
|
||||||
|
{ name: 'mobile-small', width: 320, height: 568 },
|
||||||
|
{ name: 'mobile-medium', width: 375, height: 667 },
|
||||||
|
{ name: 'mobile-large', width: 414, height: 896 },
|
||||||
|
{ name: 'tablet-small', width: 768, height: 1024 },
|
||||||
|
{ name: 'tablet-large', width: 1024, height: 768 },
|
||||||
|
{ name: 'desktop-small', width: 1280, height: 720 },
|
||||||
|
{ name: 'desktop-medium', width: 1366, height: 768 },
|
||||||
|
{ name: 'desktop-large', width: 1920, height: 1080 },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateNavigationTestData(): Array<{
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
expectedUrl: string;
|
||||||
|
}> {
|
||||||
|
return [
|
||||||
|
{ label: '首页', href: '#home', expectedUrl: '/' },
|
||||||
|
{ label: '关于我们', href: '#about', expectedUrl: '/' },
|
||||||
|
{ label: '服务', href: '#services', expectedUrl: '/' },
|
||||||
|
{ label: '产品', href: '#products', expectedUrl: '/' },
|
||||||
|
{ label: '案例', href: '#cases', expectedUrl: '/' },
|
||||||
|
{ label: '新闻', href: '#news', expectedUrl: '/' },
|
||||||
|
{ label: '联系我们', href: '#contact', expectedUrl: '/' },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateCompanyInfoTestData(): {
|
||||||
|
name: string;
|
||||||
|
address: string;
|
||||||
|
phone: string;
|
||||||
|
email: string;
|
||||||
|
workHours: Array<{ day: string; hours: string }>;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
name: '四川睿新致远科技有限公司',
|
||||||
|
address: '四川省成都市高新区天府大道中段1268号天府软件园E区1栋',
|
||||||
|
phone: '028-88888888',
|
||||||
|
email: 'contact@ruixin.com',
|
||||||
|
workHours: [
|
||||||
|
{ day: '周一至周五', hours: '9:00 - 18:00' },
|
||||||
|
{ day: '周六', hours: '9:00 - 12:00' },
|
||||||
|
{ day: '周日', hours: '休息' },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateErrorTestData(): {
|
||||||
|
requiredField: string;
|
||||||
|
invalidEmail: string;
|
||||||
|
invalidPhone: string;
|
||||||
|
messageTooShort: string;
|
||||||
|
messageTooLong: string;
|
||||||
|
submissionFailed: string;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
requiredField: '此字段为必填项',
|
||||||
|
invalidEmail: '请输入有效的邮箱地址',
|
||||||
|
invalidPhone: '请输入有效的手机号码',
|
||||||
|
messageTooShort: '消息内容至少需要10个字符',
|
||||||
|
messageTooLong: '消息内容不能超过1000个字符',
|
||||||
|
submissionFailed: '提交失败,请稍后重试',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateSuccessTestData(): {
|
||||||
|
formSubmitted: string;
|
||||||
|
thankYou: string;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
formSubmitted: '消息已发送',
|
||||||
|
thankYou: '感谢您的留言,我们会尽快与您联系',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateRandomEmail(): string {
|
||||||
|
const domains = ['gmail.com', 'outlook.com', 'yahoo.com', 'qq.com', '163.com'];
|
||||||
|
const username = this.generateAlphanumeric(8);
|
||||||
|
const domain = domains[Math.floor(Math.random() * domains.length)]!;
|
||||||
|
return `${username}@${domain}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateRandomChineseName(): string {
|
||||||
|
const surnames = ['张', '李', '王', '刘', '陈', '杨', '赵', '黄', '周', '吴'];
|
||||||
|
const names = ['伟', '芳', '娜', '秀英', '敏', '静', '丽', '强', '磊', '军'];
|
||||||
|
const surname = surnames[Math.floor(Math.random() * surnames.length)]!;
|
||||||
|
const name = names[Math.floor(Math.random() * names.length)]!;
|
||||||
|
return `${surname}${name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateRandomChinesePhone(): string {
|
||||||
|
const prefixes = ['138', '139', '136', '137', '158', '159', '186', '187', '150', '151'];
|
||||||
|
const prefix = prefixes[Math.floor(Math.random() * prefixes.length)]!;
|
||||||
|
const suffix = Math.floor(Math.random() * 90000000 + 10000000);
|
||||||
|
return `${prefix}${suffix}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user