import { test, expect } from '@playwright/test'; test.describe('地点管理E2E测试', () => { test.beforeEach(async ({ page }) => { // 登录到管理后台 await page.goto('/admin/login'); await page.fill('input[name="username"]', 'admin'); await page.fill('input[name="password"]', 'admin'); await page.click('button[type="submit"]'); // 等待登录完成并跳转到仪表板 await page.waitForURL('/admin/dashboard'); // 导航到地点管理页面 await page.goto('/admin/locations'); await page.waitForLoadState('networkidle'); }); test('应该正确显示地点管理页面', async ({ page }) => { // 验证页面标题 await expect(page.getByRole('heading', { name: '地点管理' })).toBeVisible(); // 验证新建地点按钮 await expect(page.getByRole('button', { name: '新建地点' })).toBeVisible(); // 验证搜索框 await expect(page.getByPlaceholder('搜索地点名称或地址...')).toBeVisible(); // 验证筛选器 await expect(page.getByPlaceholder('选择区域')).toBeVisible(); await expect(page.getByPlaceholder('状态筛选')).toBeVisible(); // 验证表格列标题 await expect(page.getByText('地点名称')).toBeVisible(); await expect(page.getByText('地址')).toBeVisible(); await expect(page.getByText('所属区域')).toBeVisible(); await expect(page.getByText('坐标')).toBeVisible(); await expect(page.getByText('状态')).toBeVisible(); await expect(page.getByText('创建时间')).toBeVisible(); await expect(page.getByText('操作')).toBeVisible(); }); test('应该能够搜索地点', async ({ page }) => { // 在搜索框中输入关键词 const searchInput = page.getByPlaceholder('搜索地点名称或地址...'); await searchInput.fill('北京'); // 等待搜索结果加载 await page.waitForTimeout(500); // 验证搜索结果包含相关地点 await expect(page.getByText('北京')).toBeVisible(); }); test('应该能够按区域筛选地点', async ({ page }) => { // 点击区域筛选器 const areaFilter = page.getByPlaceholder('选择区域'); await areaFilter.click(); // 等待选项加载 await page.waitForTimeout(500); // 验证区域选项存在 await expect(page.getByText('全部区域')).toBeVisible(); // 选择第一个区域选项 const firstAreaOption = page.locator('[role="option"]').first(); if (await firstAreaOption.isVisible()) { await firstAreaOption.click(); // 等待筛选结果加载 await page.waitForTimeout(500); // 验证筛选后的结果 await expect(page.locator('tbody tr')).toBeVisible(); } }); test('应该能够按状态筛选地点', async ({ page }) => { // 点击状态筛选器 const statusFilter = page.getByPlaceholder('状态筛选'); await statusFilter.click(); // 等待选项加载 await page.waitForTimeout(500); // 验证状态选项存在 await expect(page.getByText('全部状态')).toBeVisible(); await expect(page.getByText('启用')).toBeVisible(); await expect(page.getByText('禁用')).toBeVisible(); // 选择"启用"状态 await page.getByText('启用').click(); // 等待筛选结果加载 await page.waitForTimeout(500); // 验证筛选后的结果 await expect(page.locator('tbody tr')).toBeVisible(); }); test('应该能够打开新建地点模态框', async ({ page }) => { // 点击新建地点按钮 await page.getByRole('button', { name: '新建地点' }).click(); // 验证模态框显示 await expect(page.getByRole('heading', { name: '新建地点' })).toBeVisible(); // 验证表单字段存在 await expect(page.getByLabel('地点名称')).toBeVisible(); await expect(page.getByLabel('地址')).toBeVisible(); await expect(page.getByLabel('经度')).toBeVisible(); await expect(page.getByLabel('纬度')).toBeVisible(); // 关闭模态框 await page.keyboard.press('Escape'); // 验证模态框关闭 await expect(page.getByRole('heading', { name: '新建地点' })).not.toBeVisible(); }); test('应该能够查看地点详情', async ({ page }) => { // 等待地点列表加载 await page.waitForSelector('tbody tr'); // 获取第一个地点的名称 const firstLocationName = page.locator('tbody tr td').first(); const locationName = await firstLocationName.textContent(); // 验证地点名称显示 expect(locationName).toBeTruthy(); // 验证地址显示 const addressCell = page.locator('tbody tr td:nth-child(2)').first(); const address = await addressCell.textContent(); expect(address).toBeTruthy(); // 验证区域信息显示 const areaCell = page.locator('tbody tr td:nth-child(3)').first(); await expect(areaCell.locator('[data-radix-collection-item]')).toBeVisible(); // 验证状态显示 const statusCell = page.locator('tbody tr td:nth-child(5)').first(); await expect(statusCell.getByText(/启用|禁用/)).toBeVisible(); }); test('应该能够分页浏览地点', async ({ page }) => { // 等待分页控件加载 await page.waitForSelector('button:has-text("上一页"), button:has-text("下一页")'); // 验证分页信息显示 await expect(page.getByText(/显示第.*条,共.*条记录/)).toBeVisible(); // 尝试点击下一页(如果可用) const nextButton = page.getByRole('button', { name: '下一页' }); if (await nextButton.isEnabled()) { await nextButton.click(); // 等待下一页数据加载 await page.waitForTimeout(500); // 验证页面更新 await expect(page.locator('tbody tr')).toBeVisible(); } }); test('应该能够编辑地点', async ({ page }) => { // 等待地点列表加载 await page.waitForSelector('tbody tr'); // 查找编辑按钮并点击 const editButtons = page.locator('button').filter({ has: page.locator('svg[data-lucide="edit"]') }); if (await editButtons.first().isVisible()) { await editButtons.first().click(); // 验证编辑模态框显示 await expect(page.getByRole('heading', { name: '编辑地点' })).toBeVisible(); // 关闭模态框 await page.keyboard.press('Escape'); } }); test('应该能够切换地点状态', async ({ page }) => { // 等待地点列表加载 await page.waitForSelector('tbody tr'); // 查找启用/禁用按钮 const toggleButtons = page.getByRole('button').filter({ hasText: /禁用|启用/ }); if (await toggleButtons.first().isVisible()) { // 点击切换状态按钮 await toggleButtons.first().click(); // 处理确认对话框 page.on('dialog', dialog => dialog.accept()); // 等待状态更新 await page.waitForTimeout(500); // 验证状态可能已更新(按钮文本可能改变) const newButtonText = await toggleButtons.first().textContent(); expect(newButtonText).toBeTruthy(); } }); test('应该能够删除地点', async ({ page }) => { // 等待地点列表加载 await page.waitForSelector('tbody tr'); // 查找删除按钮 const deleteButtons = page.locator('button').filter({ has: page.locator('svg[data-lucide="trash-2"]') }); if (await deleteButtons.first().isVisible()) { // 设置对话框处理 page.on('dialog', dialog => dialog.accept()); // 点击删除按钮 await deleteButtons.first().click(); // 等待删除操作完成 await page.waitForTimeout(500); // 验证删除成功(可能显示成功消息) await expect(page.getByText('地点已成功删除')).toBeVisible(); } }); test('应该显示空状态当没有地点时', async ({ page }) => { // 使用一个不存在的搜索词来模拟空状态 const searchInput = page.getByPlaceholder('搜索地点名称或地址...'); await searchInput.fill('不存在的搜索词'); // 等待搜索结果 await page.waitForTimeout(500); // 验证可能显示空状态或"暂无地点数据" const emptyState = page.getByText('暂无地点数据'); if (await emptyState.isVisible()) { await expect(emptyState).toBeVisible(); } }); test('应该处理网络错误场景', async ({ page }) => { // 模拟网络错误 - 通过无效搜索触发 const searchInput = page.getByPlaceholder('搜索地点名称或地址...'); await searchInput.fill('error-test'); // 等待可能的错误处理 await page.waitForTimeout(500); // 验证页面仍然可用 await expect(page.getByRole('heading', { name: '地点管理' })).toBeVisible(); await expect(page.getByRole('button', { name: '新建地点' })).toBeVisible(); }); });