import { test, expect } from '@playwright/test' /** * Cover Image Upload E2E Tests * Tests for the cover image upload functionality on ProjectDetail page */ test.describe('Cover Image Upload', () => { test.beforeEach(async ({ page }) => { await page.goto('/') await page.waitForLoadState('networkidle') await page.waitForTimeout(1000) }) test('should navigate to project detail page', async ({ page }) => { await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) // Click the first project card by text await page.locator('text=项目一').first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) }) test('should enter project edit mode by clicking project name', async ({ page }) => { await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) await page.locator('text=项目一').first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Click on project name to enter edit mode const projectName = page.locator('h2').first() await expect(projectName).toBeVisible({ timeout: 5000 }) await projectName.click() // Should show edit form with file input await expect(page.locator('input[type="file"]').first()).toBeVisible({ timeout: 5000 }) }) test('should show save and cancel buttons in edit mode', async ({ page }) => { await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) await page.locator('text=项目一').first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Enter edit mode const projectName = page.locator('h2').first() await projectName.click() await page.waitForTimeout(300) // Should show save button const saveButton = page.locator('button:has-text("保存")') await expect(saveButton).toBeVisible({ timeout: 5000 }) // Should show cancel button const cancelButton = page.locator('button:has-text("取消")') await expect(cancelButton).toBeVisible({ timeout: 5000 }) }) test('should have image file input accepting image types', async ({ page }) => { await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) await page.locator('text=项目一').first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Enter edit mode const projectName = page.locator('h2').first() await projectName.click() await page.waitForTimeout(300) // File input should accept images const fileInput = page.locator('input[type="file"]').first() await expect(fileInput).toBeVisible({ timeout: 5000 }) const accept = await fileInput.getAttribute('accept') expect(accept).toBe('image/*') }) test('should cancel edit mode and restore original state', async ({ page }) => { await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) await page.locator('text=项目一').first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Enter edit mode const projectName = page.locator('h2').first() await projectName.click() await page.waitForTimeout(300) // Click cancel const cancelButton = page.locator('button:has-text("取消")') await cancelButton.click() await page.waitForTimeout(300) // Edit form should be hidden, back to display mode const fileInput = page.locator('input[type="file"]') await expect(fileInput).toHaveCount(0, { timeout: 5000 }) }) }) /** * Cover Image Refresh E2E Tests * Tests that cover image changes reflect on project list after saving */ test.describe('Cover Image - List Refresh', () => { test.beforeEach(async ({ page }) => { await page.goto('/') await page.waitForLoadState('networkidle') await page.waitForTimeout(1000) }) test('should refresh project list after navigating back from detail', async ({ page }) => { // Get initial project count await expect(page.locator('text=个项目').first()).toBeVisible({ timeout: 15000 }) // Navigate to a project await expect(page.locator('text=项目一').first()).toBeVisible({ timeout: 15000 }) await page.locator('text=项目一').first().click() await expect(page).toHaveURL(/\/project\/\d+/, { timeout: 10000 }) // Navigate back to project list await page.locator('a[href="/"]').click() await expect(page.locator('text=选择项目').first()).toBeVisible({ timeout: 10000 }) // Should still show correct project count (list refreshed) await expect(page.locator('text=个项目').first()).toBeVisible({ timeout: 5000 }) }) test('should display report count on stats cards', async ({ page }) => { // Stats cards should show actual counts 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 }) // Check that the stats numbers are visible (4xl font size) const statsNumbers = page.locator('.text-4xl') const count = await statsNumbers.count() expect(count).toBeGreaterThanOrEqual(3) }) })