Files
novalon-website/e2e/src/tests/contact-form-security.spec.ts
T
2026-03-24 11:41:20 +08:00

255 lines
8.2 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { ContactFormPage } from '../pages/ContactFormPage';
test.describe('Contact Form Security E2E Tests', () => {
let contactPage: ContactFormPage;
test.beforeEach(async ({ page }) => {
contactPage = new ContactFormPage(page);
await contactPage.goto();
});
test.describe('Captcha Functionality', () => {
test('should display captcha question', async () => {
const question = await contactPage.getCaptchaQuestion();
expect(question).toMatch(/\d+\s*[+\-×÷]\s*\d+\s*=/);
});
test('should refresh captcha when refresh button is clicked', async () => {
const firstQuestion = await contactPage.getCaptchaQuestion();
await contactPage.refreshCaptcha();
const secondQuestion = await contactPage.getCaptchaQuestion();
expect(secondQuestion).toBeTruthy();
});
test('should submit form with correct captcha', async ({ page }) => {
const formData = {
name: '张三',
phone: '13800138000',
email: 'test@example.com',
message: '这是一条测试留言内容',
};
await contactPage.submitForm(formData);
await expect(page).toHaveURL(/\/contact/);
const successMessage = await contactPage.getSuccessMessage();
expect(successMessage).toContain('成功');
});
test('should show error for incorrect captcha', async ({ page }) => {
const formData = {
name: '张三',
phone: '13800138000',
email: 'test@example.com',
message: '这是一条测试留言内容',
};
await contactPage.fillForm(formData);
await contactPage.captchaInput.fill('999');
await contactPage.submit();
const captchaError = await contactPage.getCaptchaErrorMessage();
expect(captchaError).toContain('验证码错误');
});
});
test.describe('Form Validation', () => {
test('should validate name field', async ({ page }) => {
await contactPage.nameInput.fill('');
await contactPage.nameInput.blur();
const errorMessage = await contactPage.getErrorMessage();
expect(errorMessage).toBeTruthy();
});
test('should validate phone field', async ({ page }) => {
await contactPage.phoneInput.fill('123');
await contactPage.phoneInput.blur();
const errorMessage = await contactPage.getErrorMessage();
expect(errorMessage).toBeTruthy();
});
test('should validate email field', async ({ page }) => {
await contactPage.emailInput.fill('invalid-email');
await contactPage.emailInput.blur();
const errorMessage = await contactPage.getErrorMessage();
expect(errorMessage).toBeTruthy();
});
test('should validate message field', async ({ page }) => {
await contactPage.messageInput.fill('太短');
await contactPage.messageInput.blur();
const errorMessage = await contactPage.getErrorMessage();
expect(errorMessage).toBeTruthy();
});
});
test.describe('Security Features', () => {
test('should prevent XSS attacks in form fields', async ({ page }) => {
const xssPayload = '<script>alert("XSS")</script>';
await contactPage.nameInput.fill(xssPayload);
await contactPage.messageInput.fill(xssPayload);
await contactPage.solveCaptcha();
await contactPage.submit();
await expect(page.locator('script')).not.toBeAttached();
});
test('should handle SQL injection attempts', async ({ page }) => {
const sqlPayload = "'; DROP TABLE users; --";
await contactPage.nameInput.fill(sqlPayload);
await contactPage.messageInput.fill(sqlPayload);
await contactPage.solveCaptcha();
await contactPage.submit();
const successMessage = await contactPage.getSuccessMessage();
expect(successMessage).toBeNull();
});
test('should sanitize malicious content', async ({ page }) => {
const maliciousContent = '<img src=x onerror=alert(1)>';
await contactPage.messageInput.fill(maliciousContent);
await contactPage.solveCaptcha();
await contactPage.submit();
await expect(page.locator('img[onerror]')).not.toBeAttached();
});
});
test.describe('Rate Limiting', () => {
test('should enforce rate limiting on rapid submissions', async ({ page }) => {
const formData = {
name: '张三',
phone: '13800138000',
email: 'test@example.com',
message: '这是一条测试留言内容',
};
let submissionCount = 0;
let rateLimited = false;
for (let i = 0; i < 15; i++) {
await contactPage.goto();
await contactPage.fillForm(formData);
await contactPage.solveCaptcha();
await contactPage.submit();
const errorMessage = await contactPage.getErrorMessage();
if (errorMessage && errorMessage.includes('过于频繁')) {
rateLimited = true;
break;
}
submissionCount++;
await page.waitForTimeout(100);
}
expect(rateLimited).toBe(true);
});
test('should allow submissions after rate limit window', async ({ page }) => {
const formData = {
name: '张三',
phone: '13800138000',
email: 'test@example.com',
message: '这是一条测试留言内容',
};
await contactPage.submitForm(formData);
await page.waitForTimeout(61000);
await contactPage.goto();
await contactPage.submitForm(formData);
const successMessage = await contactPage.getSuccessMessage();
expect(successMessage).toContain('成功');
});
});
test.describe('Accessibility', () => {
test('should have proper form labels', async () => {
await expect(contactPage.nameInput).toBeVisible();
await expect(contactPage.phoneInput).toBeVisible();
await expect(contactPage.emailInput).toBeVisible();
await expect(contactPage.messageInput).toBeVisible();
await expect(contactPage.captchaInput).toBeVisible();
});
test('should be keyboard navigable', async ({ page }) => {
await contactPage.nameInput.focus();
await page.keyboard.press('Tab');
await expect(contactPage.phoneInput).toBeFocused();
await page.keyboard.press('Tab');
await expect(contactPage.emailInput).toBeFocused();
await page.keyboard.press('Tab');
await expect(contactPage.messageInput).toBeFocused();
await page.keyboard.press('Tab');
await expect(contactPage.captchaInput).toBeFocused();
await page.keyboard.press('Tab');
await expect(contactPage.submitButton).toBeFocused();
});
});
test.describe('Responsive Design', () => {
test('should work on mobile devices', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await contactPage.goto();
await expect(contactPage.nameInput).toBeVisible();
await expect(contactPage.submitButton).toBeVisible();
});
test('should work on tablet devices', async ({ page }) => {
await page.setViewportSize({ width: 768, height: 1024 });
await contactPage.goto();
await expect(contactPage.nameInput).toBeVisible();
await expect(contactPage.submitButton).toBeVisible();
});
});
test.describe('User Flow', () => {
test('should complete full contact form submission flow', async ({ page }) => {
await test.step('Navigate to contact page', async () => {
await contactPage.goto();
await expect(page).toHaveURL(/\/contact/);
});
await test.step('Fill in all required fields', async () => {
const formData = {
name: '李四',
phone: '13900139000',
email: 'lisi@example.com',
message: '我想咨询贵公司的服务详情,请尽快联系我。',
};
await contactPage.fillForm(formData);
});
await test.step('Solve captcha', async () => {
await contactPage.solveCaptcha();
});
await test.step('Submit form', async () => {
await contactPage.submit();
});
await test.step('Verify success message', async () => {
await contactPage.waitForSuccessMessage();
const successMessage = await contactPage.getSuccessMessage();
expect(successMessage).toContain('成功');
});
});
});
});