const { chromium } = require('playwright'); const fs = require('fs'); class FormTester { constructor() { this.results = []; } async testContactForm() { const browser = await chromium.launch(); const page = await browser.newPage(); try { await page.goto('http://localhost:3000/contact', { waitUntil: 'networkidle' }); const form = { nameInput: page.locator('[data-testid="name-input"]'), phoneInput: page.locator('[data-testid="phone-input"]'), emailInput: page.locator('[data-testid="email-input"]'), subjectInput: page.locator('[data-testid="subject-input"]'), messageInput: page.locator('[data-testid="message-input"]'), submitButton: page.locator('[data-testid="submit-button"]') }; console.log(' 📝 测试表单字段可见性...'); const visibilityTests = [ { name: '姓名输入框', element: form.nameInput }, { name: '电话输入框', element: form.phoneInput }, { name: '邮箱输入框', element: form.emailInput }, { name: '主题输入框', element: form.subjectInput }, { name: '消息输入框', element: form.messageInput }, { name: '提交按钮', element: form.submitButton } ]; const visibilityResults = []; for (const test of visibilityTests) { try { await test.element.waitFor({ state: 'visible', timeout: 5000 }); visibilityResults.push({ name: test.name, passed: true }); console.log(` ✅ ${test.name} 可见`); } catch (error) { visibilityResults.push({ name: test.name, passed: false, error: error.message }); console.log(` ❌ ${test.name} 不可见: ${error.message}`); } } console.log(' 📝 测试表单验证...'); const validationTests = [ { name: '必填字段验证', test: async () => { await form.submitButton.click(); const errorMessages = await page.locator('[data-testid*="error"]').count(); return errorMessages > 0; } }, { name: '邮箱格式验证', test: async () => { await form.emailInput.fill('invalid-email'); await form.emailInput.blur(); const error = await page.locator('[data-testid="email-input"] + [data-testid*="error"]').isVisible(); return error; } }, { name: '电话格式验证', test: async () => { await form.phoneInput.fill('123'); await form.phoneInput.blur(); const error = await page.locator('[data-testid="phone-input"] + [data-testid*="error"]').isVisible(); return error; } } ]; const validationResults = []; for (const test of validationTests) { try { await page.reload(); await page.waitForLoadState('networkidle'); const passed = await test.test(); validationResults.push({ name: test.name, passed }); console.log(` ${passed ? '✅' : '❌'} ${test.name}`); } catch (error) { validationResults.push({ name: test.name, passed: false, error: error.message }); console.log(` ❌ ${test.name}: ${error.message}`); } } console.log(' 📝 测试表单提交...'); const submitTest = { name: '表单提交', test: async () => { await form.nameInput.fill('测试用户'); await form.phoneInput.fill('13800138000'); await form.emailInput.fill('test@example.com'); await form.subjectInput.fill('测试主题'); await form.messageInput.fill('这是一条测试消息'); await form.submitButton.click(); await page.waitForTimeout(2000); const successMessage = await page.locator('[data-testid*="success"]').isVisible(); const errorMessage = await page.locator('[data-testid*="error"]').isVisible(); if (successMessage) { return { passed: true, message: '提交成功' }; } else if (errorMessage) { return { passed: false, message: '提交失败' }; } else { return { passed: true, message: '表单已提交(需后端验证)' }; } } }; let submitResult; try { submitResult = await submitTest.test(); console.log(` ${submitResult.passed ? '✅' : '❌'} ${submitResult.name}: ${submitResult.message}`); } catch (error) { submitResult = { passed: false, error: error.message }; console.log(` ❌ ${submitTest.name}: ${error.message}`); } await browser.close(); return { page: '联系我们', url: 'http://localhost:3000/contact', visibility: visibilityResults, validation: validationResults, submit: submitResult }; } catch (error) { await browser.close(); throw new Error(`表单测试失败: ${error.message}`); } } getSummary() { const totalTests = this.results.reduce((sum, r) => sum + r.visibility.length + r.validation.length + 1, 0); const passedTests = this.results.reduce((sum, r) => sum + r.visibility.filter(t => t.passed).length + r.validation.filter(t => t.passed).length + (r.submit?.passed ? 1 : 0), 0); return { totalForms: this.results.length, totalTests, passedTests, passRate: ((passedTests / totalTests) * 100).toFixed(1) }; } } module.exports = { FormTester };