import { test, expect } from '@playwright/test'; test.describe('网站全面测试验收', () => { test.beforeEach(async ({ page }) => { await page.goto('/'); }); test('首页加载正常', async ({ page }) => { await expect(page).toHaveTitle(/四川睿新致远科技有限公司/); await expect(page.locator('header')).toBeVisible(); await expect(page.locator('[data-testid="footer"]')).toBeVisible(); }); test('公司Logo可见且不被覆盖', async ({ page }) => { const logo = page.locator('header img[alt*="睿新致远"], [data-testid="logo"]'); const logoCount = await logo.count(); if (logoCount === 0) { const allImages = page.locator('header img'); expect(await allImages.count()).toBeGreaterThan(0); const firstLogo = allImages.first(); await expect(firstLogo).toBeVisible(); const logoBox = await firstLogo.boundingBox(); expect(logoBox).not.toBeNull(); const header = page.locator('header'); const headerBox = await header.boundingBox(); expect(headerBox).not.toBeNull(); if (logoBox && headerBox) { expect(logoBox.x).toBeGreaterThanOrEqual(headerBox.x); expect(logoBox.y).toBeGreaterThanOrEqual(headerBox.y); expect(logoBox.x + logoBox.width).toBeLessThanOrEqual(headerBox.x + headerBox.width); expect(logoBox.y + logoBox.height).toBeLessThanOrEqual(headerBox.y + headerBox.height); } } else { await expect(logo.first()).toBeVisible(); const logoBox = await logo.first().boundingBox(); expect(logoBox).not.toBeNull(); const header = page.locator('header'); const headerBox = await header.boundingBox(); expect(headerBox).not.toBeNull(); if (logoBox && headerBox) { expect(logoBox.x).toBeGreaterThanOrEqual(headerBox.x); expect(logoBox.y).toBeGreaterThanOrEqual(headerBox.y); expect(logoBox.x + logoBox.width).toBeLessThanOrEqual(headerBox.x + headerBox.width); expect(logoBox.y + logoBox.height).toBeLessThanOrEqual(headerBox.y + headerBox.height); } } }); test('导航菜单功能正常', async ({ page }) => { const navLinks = page.locator('[data-testid="desktop-navigation"] a, nav a'); const count = await navLinks.count(); expect(count).toBeGreaterThan(0); await navLinks.nth(0).click(); await page.waitForURL(/\/.+/, { timeout: 10000 }); }); test('联系我们页面没有显示公司电话', async ({ page }) => { await page.goto('/contact', { waitUntil: 'load' }); await page.waitForTimeout(2000); const contactInfoSection = page.locator('[data-testid="contact-info"]'); if (await contactInfoSection.isVisible()) { const phoneInContactInfo = contactInfoSection.locator('text=/电话|028-88888888|联系电话/'); const phoneCount = await phoneInContactInfo.count(); expect(phoneCount).toBe(0); } }); test('联系我们页面表单正常显示', async ({ page }) => { await page.goto('/contact', { waitUntil: 'load' }); // 等待 React 客户端渲染完成 await page.waitForTimeout(2000); await expect(page.locator('[data-testid="name-input"]')).toBeVisible(); await expect(page.locator('[data-testid="phone-input"]')).toBeVisible(); await expect(page.locator('[data-testid="email-input"]')).toBeVisible(); await expect(page.locator('[data-testid="subject-input"]')).toBeVisible(); await expect(page.locator('[data-testid="message-input"]')).toBeVisible(); await expect(page.locator('[data-testid="submit-button"]')).toBeVisible(); }); test('ICP备案号正确显示', async ({ page }) => { const footer = page.locator('[data-testid="footer"], footer'); await expect(footer).toBeVisible(); const icpText = await footer.textContent(); expect(icpText).toContain('蜀ICP备2026013658号'); }); test('关于我们页面没有显示公司电话', async ({ page }) => { await page.goto('/about', { waitUntil: 'load' }); await page.waitForTimeout(2000); const contactTexts = page.locator('text=/联系我们|联系方式|Contact/'); const contactCount = await contactTexts.count(); if (contactCount > 0) { for (let i = 0; i < contactCount; i++) { const contactElement = contactTexts.nth(i); const parent = contactElement.locator('..'); if (await parent.isVisible()) { const phoneText = parent.locator('text=/联系电话|028-88888888|电话:/'); const phoneCount = await phoneText.count(); expect(phoneCount).toBe(0); break; } } } }); test('响应式设计正常工作', async ({ page }) => { await page.setViewportSize({ width: 375, height: 667 }); await expect(page.locator('header')).toBeVisible(); await expect(page.locator('[data-testid="footer"], footer')).toBeVisible(); const mobileMenuButton = page.locator('[data-testid="mobile-menu-button"]'); await expect(mobileMenuButton).toBeVisible({ timeout: 5000 }); await mobileMenuButton.click(); await expect(page.locator('[data-testid="mobile-navigation"]')).toBeVisible({ timeout: 5000 }); }); test('页面跳转功能正常', async ({ page }) => { const contactLink = page.locator('text=联系我们').first(); if (await contactLink.isVisible()) { await contactLink.click(); await page.waitForURL(/\/contact/, { timeout: 10000 }); } const homeLink = page.locator('text=首页').first(); if (await homeLink.isVisible()) { await homeLink.click(); await page.waitForURL(/\//, { timeout: 10000 }); } }); test('Footer链接正常工作', async ({ page }) => { const footer = page.locator('footer').first(); await expect(footer).toBeVisible({ timeout: 10000 }); // Check footer contains expected links and legal info const footerText = await footer.textContent(); expect(footerText).toContain('ICP'); expect(footerText).toContain('隐私'); }); test('表单验证功能正常', async ({ page }) => { await page.goto('/contact', { waitUntil: 'load' }); // 等待 React 客户端渲染完成 await page.waitForTimeout(2000); const submitButton = page.locator('[data-testid="submit-button"]'); await expect(submitButton).toBeVisible({ timeout: 10000 }); await submitButton.click(); // 等待 Zod 验证错误渲染 const errorMessages = page.locator('[data-testid="error-message"]'); await expect(errorMessages.first()).toBeVisible({ timeout: 10000 }); const errorCount = await errorMessages.count(); expect(errorCount).toBeGreaterThan(0); }); test('页面加载性能良好', async ({ page }) => { const performanceMetrics = await page.evaluate(() => { const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming; return { domContentLoaded: navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart, loadComplete: navigation.loadEventEnd - navigation.loadEventStart, }; }); expect(performanceMetrics.domContentLoaded).toBeLessThan(3000); expect(performanceMetrics.loadComplete).toBeLessThan(10000); }); test('无障碍访问正常', async ({ page }) => { const htmlLang = await page.locator('html').getAttribute('lang'); expect(htmlLang).toBeTruthy(); const skipLink = page.locator('[data-skip-to-content]'); await expect(skipLink).toBeVisible(); expect(await skipLink.textContent()).toContain('跳转到主要内容'); const main = page.locator('main').first(); await expect(main).toBeVisible({ timeout: 10000 }); // Check for navigation and footer existence (structure may vary) const footer = page.locator('footer').first(); await expect(footer).toBeVisible({ timeout: 5000 }); const focusableElements = page.locator('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])'); const focusCount = await focusableElements.count(); expect(focusCount).toBeGreaterThan(0); }); test('联系我们页面没有返回按钮覆盖logo', async ({ page }) => { await page.goto('/contact', { waitUntil: 'load' }); await page.waitForTimeout(2000); const logoSelectors = [ 'header img[alt*="睿新致远"]', 'header img[alt*="novalon"]', '[data-testid="logo"]', 'header img' ]; let logo = null; for (const selector of logoSelectors) { const element = page.locator(selector).first(); if (await element.isVisible().catch(() => false)) { logo = element; break; } } if (!logo) { const allLogos = page.locator('header img'); expect(await allLogos.count()).toBeGreaterThan(0); logo = allLogos.first(); } await expect(logo).toBeVisible(); const logoBox = await logo.boundingBox(); expect(logoBox).not.toBeNull(); const header = page.locator('header'); const headerBox = await header.boundingBox(); expect(headerBox).not.toBeNull(); if (logoBox && headerBox) { const logoCenterX = logoBox.x + logoBox.width / 2; const logoCenterY = logoBox.y + logoBox.height / 2; expect(logoCenterX).toBeGreaterThan(headerBox.x); expect(logoCenterX).toBeLessThan(headerBox.x + headerBox.width); expect(logoCenterY).toBeGreaterThan(headerBox.y); expect(logoCenterY).toBeLessThan(headerBox.y + headerBox.height); } }); });