feat: 添加面包屑导航组件并优化页面布局
refactor: 重构页面结构和导航逻辑 fix: 修复移动端菜单导航和滚动行为 perf: 优化图片加载性能和资源请求 test: 添加端到端测试和性能测试用例 docs: 更新.gitignore文件 chore: 更新依赖和配置 style: 优化代码格式和类型安全 ci: 调整Playwright测试超时时间 build: 更新Next.js配置和构建选项
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
import { test, expect } from '../../fixtures/base.fixture';
|
||||
|
||||
test.describe('Error Handling E2E Tests', () => {
|
||||
test.describe('404 Page', () => {
|
||||
test('404 page displays correctly for non-existent routes', async ({ page }) => {
|
||||
await page.goto('/this-page-does-not-exist');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await expect(page.locator('h1')).toContainText('404');
|
||||
await expect(page.locator('h2')).toContainText('页面未找到');
|
||||
|
||||
const returnHomeButton = page.getByRole('link', { name: '返回首页' });
|
||||
await expect(returnHomeButton).toBeVisible();
|
||||
|
||||
await returnHomeButton.click();
|
||||
await page.waitForURL('/');
|
||||
await expect(page).toHaveURL('/');
|
||||
});
|
||||
|
||||
test('404 page provides helpful navigation links', async ({ page }) => {
|
||||
await page.goto('/non-existent-page');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const aboutLink = page.getByRole('link', { name: '关于我们' });
|
||||
const servicesLink = page.getByRole('link', { name: '核心业务' });
|
||||
const productsLink = page.getByRole('link', { name: '产品服务' });
|
||||
const casesLink = page.getByRole('link', { name: '成功案例' });
|
||||
|
||||
await expect(aboutLink).toBeVisible();
|
||||
await expect(servicesLink).toBeVisible();
|
||||
await expect(productsLink).toBeVisible();
|
||||
await expect(casesLink).toBeVisible();
|
||||
|
||||
await aboutLink.click();
|
||||
await page.waitForURL('/about');
|
||||
await expect(page).toHaveURL('/about');
|
||||
});
|
||||
|
||||
test('404 page back button works correctly', async ({ page }) => {
|
||||
await page.goto('/about');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.goto('/non-existent-page');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const backButton = page.getByRole('button', { name: '返回上一页' });
|
||||
await backButton.click();
|
||||
|
||||
await page.waitForURL('/about');
|
||||
await expect(page).toHaveURL('/about');
|
||||
});
|
||||
|
||||
test('404 page contact link works', async ({ page }) => {
|
||||
await page.goto('/another-404-page');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const contactLink = page.getByRole('link', { name: '联系我们' });
|
||||
await contactLink.click();
|
||||
|
||||
await page.waitForURL('/contact');
|
||||
await expect(page).toHaveURL('/contact');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Error Page', () => {
|
||||
test('Error page displays correctly when error occurs', async ({ page }) => {
|
||||
await page.goto('/error-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await expect(page.locator('h1')).toContainText('出现了一些问题');
|
||||
await expect(page.getByRole('button', { name: '重试' })).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: '返回首页' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('Error page retry button works', async ({ page }) => {
|
||||
await page.goto('/error-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const retryButton = page.getByRole('button', { name: '重试' });
|
||||
await retryButton.click();
|
||||
|
||||
await page.waitForLoadState('load');
|
||||
await expect(page).toHaveURL('/error-test');
|
||||
});
|
||||
|
||||
test('Error page home button works', async ({ page }) => {
|
||||
await page.goto('/error-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const homeButton = page.getByRole('link', { name: '返回首页' });
|
||||
await homeButton.click();
|
||||
|
||||
await page.waitForURL('/');
|
||||
await expect(page).toHaveURL('/');
|
||||
});
|
||||
|
||||
test('Error page provides helpful links', async ({ page }) => {
|
||||
await page.goto('/error-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const contactLink = page.getByRole('link', { name: '联系我们' });
|
||||
const servicesLink = page.getByRole('link', { name: '核心业务' });
|
||||
|
||||
await expect(contactLink).toBeVisible();
|
||||
await expect(servicesLink).toBeVisible();
|
||||
|
||||
await contactLink.click();
|
||||
await page.waitForURL('/contact');
|
||||
await expect(page).toHaveURL('/contact');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Error Boundary Integration', () => {
|
||||
test('Error boundary catches client-side errors', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.evaluate(() => {
|
||||
throw new Error('Test error for error boundary');
|
||||
});
|
||||
|
||||
await page.waitForLoadState('load');
|
||||
await expect(page.locator('h1')).toContainText('出现了一些问题');
|
||||
});
|
||||
|
||||
test('Error boundary provides recovery options', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.evaluate(() => {
|
||||
throw new Error('Test error for recovery');
|
||||
});
|
||||
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const retryButton = page.getByRole('button', { name: '重试' });
|
||||
await expect(retryButton).toBeVisible();
|
||||
|
||||
const homeButton = page.getByRole('link', { name: '返回首页' });
|
||||
await expect(homeButton).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Navigation Error Recovery', () => {
|
||||
test('Broken links redirect to 404 page', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.evaluate(() => {
|
||||
const link = document.createElement('a');
|
||||
link.href = '/broken-link';
|
||||
link.textContent = 'Broken Link';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
});
|
||||
|
||||
await page.waitForLoadState('load');
|
||||
await expect(page.locator('h1')).toContainText('404');
|
||||
});
|
||||
|
||||
test('Users can navigate away from error pages', async ({ page }) => {
|
||||
await page.goto('/non-existent');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.goto('/about');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await expect(page.locator('h1')).toContainText('关于我们');
|
||||
await expect(page).toHaveURL('/about');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Error Page Accessibility', () => {
|
||||
test('404 page is keyboard navigable', async ({ page }) => {
|
||||
await page.goto('/404-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
await expect(page.getByRole('link', { name: '返回首页' })).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForURL('/');
|
||||
await expect(page).toHaveURL('/');
|
||||
});
|
||||
|
||||
test('Error page is keyboard navigable', async ({ page }) => {
|
||||
await page.goto('/error-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
await expect(page.getByRole('button', { name: '重试' })).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForLoadState('load');
|
||||
});
|
||||
|
||||
test('Error pages have proper ARIA labels', async ({ page }) => {
|
||||
await page.goto('/404-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const main = page.locator('main');
|
||||
await expect(main).toHaveAttribute('role', 'main');
|
||||
|
||||
const heading = page.locator('h1');
|
||||
await expect(heading).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Error Page Performance', () => {
|
||||
test('404 page loads quickly', async ({ page }) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
await page.goto('/fast-404');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const loadTime = Date.now() - startTime;
|
||||
expect(loadTime).toBeLessThan(3000);
|
||||
});
|
||||
|
||||
test('Error page loads quickly', async ({ page }) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
await page.goto('/error-test');
|
||||
await page.waitForLoadState('load');
|
||||
|
||||
const loadTime = Date.now() - startTime;
|
||||
expect(loadTime).toBeLessThan(3000);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user