Files
panda b9137204a0 fix: FilePreview fileType case + Tailwind v4 gradient transparent bug
- FilePreview.vue: add normalizedFileType computed to handle backend
  returning uppercase HTML/MD/PPTX (fixes preview/download buttons)
- FilePreview.vue: bg-gradient-to-r from-orange-500 -> bg-orange-500
  (Tailwind v4 gradient + CSS variable = transparent)
- ReportCard.vue: bg-gradient-to-r -> bg-orange-600 for selected state
- Add .opencode/, node_modules/, dist/ to .gitignore
- Initial git setup for publish project
2026-05-24 20:09:42 +08:00

141 lines
6.2 KiB
JavaScript

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)
})
})