14448af731
- 添加案例、新闻、产品详情页面的E2E测试 - 优化详情页面的客户端组件和页面逻辑 - 添加高性能Docker配置和Nginx配置 - 更新API服务和常量配置 - 添加性能优化文档和任务进度更新 - 修复ESLint错误和类型问题
262 lines
9.5 KiB
TypeScript
262 lines
9.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('News Detail Page E2E Tests', () => {
|
|
test.describe('Page Loading', () => {
|
|
test('should load news detail page successfully', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page).toHaveURL(/\/news\/1/);
|
|
await expect(page.getByRole('main')).toBeVisible();
|
|
});
|
|
|
|
test('should display news title', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
await expect(page.getByRole('heading', { level: 1 })).toContainText(/.+/);
|
|
});
|
|
|
|
test('should display news excerpt', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.locator('p').first()).toBeVisible();
|
|
});
|
|
|
|
test('should display news category badge', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.locator('.inline-block').first()).toBeVisible();
|
|
});
|
|
|
|
test('should display news date', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.getByText(/\d{4}-\d{2}-\d{2}/)).toBeVisible();
|
|
});
|
|
|
|
test('should display back button', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.getByRole('button', { name: /back|返回/i })).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Content Sections', () => {
|
|
test('should display news content', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.locator('article')).toBeVisible();
|
|
await expect(page.locator('.prose')).toBeVisible();
|
|
});
|
|
|
|
test('should display news image placeholder', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.locator('.aspect-video').first()).toBeVisible();
|
|
});
|
|
|
|
test('should display news excerpt highlight', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.locator('.border-l-4')).toBeVisible();
|
|
});
|
|
|
|
test('should display full news content', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.locator('.whitespace-pre-line')).toBeVisible();
|
|
const content = page.locator('.whitespace-pre-line');
|
|
await expect(content).toContainText(/.+/);
|
|
});
|
|
});
|
|
|
|
test.describe('Related News', () => {
|
|
test('should display related news section when available', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
const relatedSection = page.locator('h2:has-text("相关新闻")');
|
|
const isVisible = await relatedSection.isVisible().catch(() => false);
|
|
|
|
if (isVisible) {
|
|
await expect(relatedSection).toBeVisible();
|
|
await expect(page.locator('.grid.md\\:grid-cols-3')).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('should display related news cards', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
const relatedSection = page.locator('h2:has-text("相关新闻")');
|
|
const isVisible = await relatedSection.isVisible().catch(() => false);
|
|
|
|
if (isVisible) {
|
|
const relatedCards = page.locator('.group');
|
|
const count = await relatedCards.count();
|
|
expect(count).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
test('should navigate to related news when clicked', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
const relatedSection = page.locator('h2:has-text("相关新闻")');
|
|
const isVisible = await relatedSection.isVisible().catch(() => false);
|
|
|
|
if (isVisible) {
|
|
const firstRelatedCard = page.locator('.group').first();
|
|
await firstRelatedCard.click();
|
|
await expect(page).toHaveURL(/\/news\//);
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Navigation', () => {
|
|
test('should navigate back to news list', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await page.getByRole('link', { name: /返回新闻列表/i }).click();
|
|
await expect(page).toHaveURL(/\/news/);
|
|
});
|
|
|
|
test('should navigate to contact page via CTA', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await page.getByRole('link', { name: /联系我们/i }).click();
|
|
await expect(page).toHaveURL(/\/contact/);
|
|
});
|
|
|
|
test('should navigate back using back button', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await page.getByRole('button', { name: /back|返回/i }).click();
|
|
await expect(page).toHaveURL(/\/news/);
|
|
});
|
|
});
|
|
|
|
test.describe('Call to Action', () => {
|
|
test('should display back to news list button', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.getByRole('link', { name: /返回新闻列表/i })).toBeVisible();
|
|
});
|
|
|
|
test('should display contact us button', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.getByRole('link', { name: /联系我们/i })).toBeVisible();
|
|
});
|
|
|
|
test('should have proper button styling', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
const contactButton = page.getByRole('link', { name: /联系我们/i });
|
|
await expect(contactButton).toHaveClass(/bg-\[#C41E3A\]/);
|
|
});
|
|
});
|
|
|
|
test.describe('Responsive Design', () => {
|
|
test('should work on mobile devices', async ({ page }) => {
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
await page.goto('/news/1');
|
|
|
|
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
await expect(page.locator('article')).toBeVisible();
|
|
await expect(page.getByRole('link', { name: /联系我们/i })).toBeVisible();
|
|
});
|
|
|
|
test('should work on tablet devices', async ({ page }) => {
|
|
await page.setViewportSize({ width: 768, height: 1024 });
|
|
await page.goto('/news/1');
|
|
|
|
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
await expect(page.locator('article')).toBeVisible();
|
|
await expect(page.getByRole('link', { name: /联系我们/i })).toBeVisible();
|
|
});
|
|
|
|
test('should work on desktop devices', async ({ page }) => {
|
|
await page.setViewportSize({ width: 1920, height: 1080 });
|
|
await page.goto('/news/1');
|
|
|
|
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
await expect(page.locator('article')).toBeVisible();
|
|
await expect(page.getByRole('link', { name: /联系我们/i })).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Accessibility', () => {
|
|
test('should have proper heading hierarchy', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
|
|
const headings = page.locator('h1, h2, h3');
|
|
const count = await headings.count();
|
|
|
|
expect(count).toBeGreaterThan(0);
|
|
|
|
const firstHeading = await headings.first().textContent();
|
|
expect(firstHeading).toBeTruthy();
|
|
});
|
|
|
|
test('should have proper ARIA attributes', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
await expect(page.getByRole('main')).toBeVisible();
|
|
await expect(page.getByRole('article')).toBeVisible();
|
|
});
|
|
|
|
test('should be keyboard navigable', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
|
|
await page.keyboard.press('Tab');
|
|
await expect(page.getByRole('button', { name: /back|返回/i })).toBeFocused();
|
|
|
|
await page.keyboard.press('Tab');
|
|
await expect(page.getByRole('link', { name: /返回新闻列表/i })).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('User Flow', () => {
|
|
test('should complete full news detail user flow', async ({ page }) => {
|
|
await test.step('Navigate to news detail page', async () => {
|
|
await page.goto('/news/1');
|
|
await expect(page).toHaveURL(/\/news\/1/);
|
|
});
|
|
|
|
await test.step('Read news content', async () => {
|
|
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
await expect(page.locator('article')).toBeVisible();
|
|
});
|
|
|
|
await test.step('Check related news', async () => {
|
|
const relatedSection = page.locator('h2:has-text("相关新闻")');
|
|
const isVisible = await relatedSection.isVisible().catch(() => false);
|
|
|
|
if (isVisible) {
|
|
await expect(relatedSection).toBeVisible();
|
|
}
|
|
});
|
|
|
|
await test.step('Navigate to contact page', async () => {
|
|
await page.getByRole('link', { name: /联系我们/i }).click();
|
|
await expect(page).toHaveURL(/\/contact/);
|
|
});
|
|
});
|
|
});
|
|
|
|
test.describe('Error Handling', () => {
|
|
test('should handle non-existent news ID', async ({ page }) => {
|
|
await page.goto('/news/999999');
|
|
await expect(page).toHaveURL(/\/404/);
|
|
});
|
|
|
|
test('should handle invalid news ID format', async ({ page }) => {
|
|
await page.goto('/news/invalid-slug');
|
|
await expect(page).toHaveURL(/\/404/);
|
|
});
|
|
});
|
|
|
|
test.describe('Content Validation', () => {
|
|
test('should display news metadata correctly', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
|
|
await expect(page.locator('.inline-block')).toBeVisible();
|
|
await expect(page.getByText(/\d{4}-\d{2}-\d{2}/)).toBeVisible();
|
|
});
|
|
|
|
test('should display news content with proper formatting', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
|
|
const content = page.locator('.whitespace-pre-line');
|
|
await expect(content).toBeVisible();
|
|
const contentText = await content.textContent();
|
|
expect(contentText?.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test('should display news excerpt with highlight', async ({ page }) => {
|
|
await page.goto('/news/1');
|
|
|
|
const excerpt = page.locator('.border-l-4');
|
|
await expect(excerpt).toBeVisible();
|
|
await expect(excerpt).toHaveClass(/border-\[#C41E3A\]/);
|
|
});
|
|
});
|
|
}); |