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\]/); }); }); });