import { test, expect } from '@playwright/test' /** * Project Management E2E Tests * Tests for the UI redesigned project list and detail pages */ test.describe('Project Management (New UI)', () => { test.beforeEach(async ({ page }) => { await page.goto('/') // Wait for the page to fully load await page.waitForLoadState('networkidle') // Wait for content to render await page.waitForTimeout(1000) }) test('should display project list with mock data', async ({ page }) => { // Verify that projects are displayed await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) await expect(page.locator('text=项目二').first()).toBeVisible({ timeout: 5000 }) await expect(page.locator('text=项目三').first()).toBeVisible({ timeout: 5000 }) }) test('should navigate to project detail page when clicking a project card', async ({ page }) => { // Wait for project to be visible await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) // Click on the project card (large card with background image) // The new UI uses a carousel with ProjectCard components const projectCards = page.locator('.group.relative.h-\\[420px\\]') await projectCards.first().click() // Verify navigation to project detail await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) }) test('should display stats cards with correct counts', async ({ page }) => { // Wait for projects to load await expect(page.locator('text=个项目').first()).toBeVisible({ timeout: 15000 }) // Check stats cards are visible await expect(page.locator('text=个项目').first()).toBeVisible({ timeout: 5000 }) await expect(page.locator('text=份报告').first()).toBeVisible({ timeout: 5000 }) await expect(page.locator('text=文件类型').first()).toBeVisible({ timeout: 5000 }) }) test('should display project carousel with navigation arrows', async ({ page }) => { // Wait for projects to load await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) // Check carousel navigation arrows exist const leftArrow = page.locator('button').filter({ has: page.locator('svg path[d*="M15 19l-7-7 7-7"]') }) const rightArrow = page.locator('button').filter({ has: page.locator('svg path[d*="M9 5l7 7-7 7"]') }) // At least one navigation button should be visible await expect(page.locator('button').first()).toBeVisible({ timeout: 5000 }) }) test('should display project cards with report count badges', async ({ page }) => { // Check that project cards show report count await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) // Report count badge should be visible in cards await expect(page.locator('text=份报告').first()).toBeVisible({ timeout: 5000 }) }) test('should navigate to project detail and show reports', async ({ page }) => { // Navigate to a project await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) // Click on a project card const projectCards = page.locator('.group.relative.h-\\[420px\\]') await projectCards.first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Should show the project name in detail page await expect(page.locator('h2').first()).toBeVisible({ timeout: 5000 }) }) test('should navigate back to project list from project detail', async ({ page }) => { // Navigate to a project await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) const projectCards = page.locator('.group.relative.h-\\[420px\\]') await projectCards.first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Click back button (router-link to="/") await page.locator('a[href="/"]').click() // Verify we're back on the project list await expect(page.locator('text=选择项目').first()).toBeVisible({ timeout: 10000 }) }) test('should display glass effect sidebar in project detail', async ({ page }) => { // Navigate to a project await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) const projectCards = page.locator('.group.relative.h-\\[420px\\]') await projectCards.first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Check that the sidebar has glass effect class const sidebar = page.locator('.glass-light') await expect(sidebar).toBeVisible({ timeout: 5000 }) }) test('should display report cards in project detail sidebar', async ({ page }) => { // Navigate to a project await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) const projectCards = page.locator('.group.relative.h-\\[420px\\]') await projectCards.first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Wait for reports to load (look for report file type badges) await expect(page.locator('text=HTML').first()).toBeVisible({ timeout: 5000 }) }) test('should show loading state while fetching', async ({ page }) => { // The loading spinner should appear briefly // But we can verify the content eventually loads await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) }) test('should display correct report count from backend', async ({ page }) => { // Wait for projects to load await expect(page.locator('text=个项目').first()).toBeVisible({ timeout: 15000 }) // Stats cards show actual report counts from backend await expect(page.locator('.text-4xl').first()).toBeVisible({ timeout: 5000 }) }) test('should display cover image on project cards when available', async ({ page }) => { // Wait for project cards to load await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) // ProjectCard should render with background image style when coverImage is set // Cards with cover image will have background-image CSS property const projectCards = page.locator('.group.relative.h-\\[420px\\]') const cardCount = await projectCards.count() expect(cardCount).toBeGreaterThan(0) }) })