245 lines
8.8 KiB
TypeScript
245 lines
8.8 KiB
TypeScript
|
|
/**
|
|||
|
|
* 学校端 E2E 测试 - 阅读任务模块(只读模式)
|
|||
|
|
*
|
|||
|
|
* 核心验证:
|
|||
|
|
* 1. 学校端不能创建/编辑/删除任务
|
|||
|
|
* 2. 学校端可以查看任务列表和详情
|
|||
|
|
* 3. 多维度筛选功能正常
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { test, expect } from '@playwright/test';
|
|||
|
|
|
|||
|
|
const BASE_URL = 'http://localhost:5173';
|
|||
|
|
|
|||
|
|
test.describe('学校端阅读任务 - 只读模式验证', () => {
|
|||
|
|
test.beforeEach(async ({ page }) => {
|
|||
|
|
// 登录
|
|||
|
|
await page.goto(`${BASE_URL}/login`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
|
|||
|
|
// 选择学校角色
|
|||
|
|
await page.click('.role-btn:has-text("学校")');
|
|||
|
|
await page.waitForTimeout(300);
|
|||
|
|
|
|||
|
|
// 填写账号密码
|
|||
|
|
await page.fill('input[placeholder*="账号"]', 'school1');
|
|||
|
|
await page.fill('input[placeholder*="密码"]', '123456');
|
|||
|
|
|
|||
|
|
// 点击登录
|
|||
|
|
await page.click('button.login-btn');
|
|||
|
|
await page.waitForURL(/\/school/, { timeout: 15000 });
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-READONLY-01: 验证无创建按钮', async ({ page }) => {
|
|||
|
|
// 导航到阅读任务页面
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 验证没有"新建任务"按钮
|
|||
|
|
const createBtn = page.locator('button:has-text("新建"), button:has-text("创建任务"), button:has-text("新增")');
|
|||
|
|
const count = await createBtn.count();
|
|||
|
|
|
|||
|
|
console.log(`创建按钮数量: ${count}`);
|
|||
|
|
expect(count).toBe(0);
|
|||
|
|
|
|||
|
|
// 截图
|
|||
|
|
await page.screenshot({ path: 'test-results/school-readonly-no-create.png', fullPage: true });
|
|||
|
|
console.log('✅ S-READONLY-01 通过: 学校端无创建任务按钮');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-READONLY-02: 验证无编辑按钮', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 查找任务卡片
|
|||
|
|
const taskCards = page.locator('.ant-card, [class*="task-card"], .task-item');
|
|||
|
|
const count = await taskCards.count();
|
|||
|
|
|
|||
|
|
if (count > 0) {
|
|||
|
|
// 点击第一个任务查看详情
|
|||
|
|
await taskCards.first().click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
|
|||
|
|
// 验证详情页/弹窗没有编辑按钮
|
|||
|
|
const editBtn = page.locator('button:has-text("编辑"), button:has-text("修改")');
|
|||
|
|
const editCount = await editBtn.count();
|
|||
|
|
expect(editCount).toBe(0);
|
|||
|
|
|
|||
|
|
console.log('✅ S-READONLY-02 通过: 任务详情页无编辑按钮');
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ S-READONLY-02: 暂无任务数据');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-READONLY-03: 验证无删除按钮', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 验证列表页没有删除按钮
|
|||
|
|
const deleteBtn = page.locator('button:has-text("删除"), button:has-text("移除")');
|
|||
|
|
const count = await deleteBtn.count();
|
|||
|
|
expect(count).toBe(0);
|
|||
|
|
|
|||
|
|
console.log('✅ S-READONLY-03 通过: 学校端无删除按钮');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-READONLY-04: 验证无发布按钮', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 验证没有发布按钮
|
|||
|
|
const publishBtn = page.locator('button:has-text("发布"), button:has-text("下发")');
|
|||
|
|
const count = await publishBtn.count();
|
|||
|
|
expect(count).toBe(0);
|
|||
|
|
|
|||
|
|
console.log('✅ S-READONLY-04 通过: 学校端无发布按钮');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-LIST-01: 任务列表展示', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 验证统计卡片
|
|||
|
|
const statsCards = page.locator('.ant-card, .stat-card, [class*="stats"]');
|
|||
|
|
const statsCount = await statsCards.count();
|
|||
|
|
|
|||
|
|
// 验证任务卡片
|
|||
|
|
const taskCards = page.locator('.ant-card, [class*="task"]');
|
|||
|
|
const taskCount = await taskCards.count();
|
|||
|
|
|
|||
|
|
console.log(`统计卡片数: ${statsCount}, 任务卡片数: ${taskCount}`);
|
|||
|
|
|
|||
|
|
// 至少应该有统计或任务显示
|
|||
|
|
expect(statsCount + taskCount).toBeGreaterThan(0);
|
|||
|
|
|
|||
|
|
await page.screenshot({ path: 'test-results/school-task-list.png', fullPage: true });
|
|||
|
|
console.log('✅ S-LIST-01 通过: 任务列表正常展示');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-FILTER-01: 多维度筛选功能', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 测试关键字搜索
|
|||
|
|
const searchInput = page.locator('input[placeholder*="搜索"], input[placeholder*="关键字"]');
|
|||
|
|
if (await searchInput.count() > 0) {
|
|||
|
|
await searchInput.first().fill('阅读');
|
|||
|
|
await page.waitForTimeout(500);
|
|||
|
|
|
|||
|
|
// 验证搜索触发
|
|||
|
|
await page.screenshot({ path: 'test-results/school-filter-search.png' });
|
|||
|
|
console.log('✅ S-FILTER-01: 关键字搜索功能可用');
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ S-FILTER-01: 未找到搜索输入框');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试类型筛选
|
|||
|
|
const typeSelect = page.locator('.ant-select').filter({ hasText: /类型/ });
|
|||
|
|
if (await typeSelect.count() > 0) {
|
|||
|
|
console.log('✅ S-FILTER-02: 类型筛选器存在');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试状态筛选
|
|||
|
|
const statusSelect = page.locator('.ant-select').filter({ hasText: /状态/ });
|
|||
|
|
if (await statusSelect.count() > 0) {
|
|||
|
|
console.log('✅ S-FILTER-03: 状态筛选器存在');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-DETAIL-01: 任务详情查看', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
const taskCards = page.locator('.ant-card:not(.stat-card), [class*="task-card"]');
|
|||
|
|
const count = await taskCards.count();
|
|||
|
|
|
|||
|
|
if (count > 0) {
|
|||
|
|
// 点击第一个任务
|
|||
|
|
await taskCards.first().click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
|
|||
|
|
// 验证详情弹窗或页面
|
|||
|
|
const modal = page.locator('.ant-modal, .ant-drawer');
|
|||
|
|
const detailPage = page.locator('[class*="detail"]');
|
|||
|
|
|
|||
|
|
if (await modal.isVisible() || await detailPage.isVisible()) {
|
|||
|
|
console.log('✅ S-DETAIL-01 通过: 任务详情可以查看');
|
|||
|
|
|
|||
|
|
// 验证关联绘本字段显示
|
|||
|
|
const bookNameLabel = page.locator('text=/绘本|关联/');
|
|||
|
|
if (await bookNameLabel.count() > 0) {
|
|||
|
|
console.log('✅ S-DETAIL-02 通过: 关联绘本字段显示');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await page.screenshot({ path: 'test-results/school-task-detail.png' });
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ S-DETAIL-01: 任务详情未显示');
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ S-DETAIL-01: 暂无任务数据');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('S-COMPLETION-01: 完成情况列表(只读)', async ({ page }) => {
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 查找"查看完成情况"按钮
|
|||
|
|
const viewCompletionsBtn = page.locator('button:has-text("完成情况"), button:has-text("查看完成")');
|
|||
|
|
if (await viewCompletionsBtn.count() > 0) {
|
|||
|
|
await viewCompletionsBtn.first().click();
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
|
|||
|
|
// 验证弹窗显示
|
|||
|
|
const modal = page.locator('.ant-modal');
|
|||
|
|
if (await modal.isVisible()) {
|
|||
|
|
// 验证没有评价按钮(只读)
|
|||
|
|
const feedbackBtn = page.locator('button:has-text("评价"), button:has-text("反馈")');
|
|||
|
|
const feedbackCount = await feedbackBtn.count();
|
|||
|
|
expect(feedbackCount).toBe(0);
|
|||
|
|
|
|||
|
|
console.log('✅ S-COMPLETION-01 通过: 完成情况列表只读');
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ S-COMPLETION-01: 未找到查看完成情况按钮');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test.describe('学校端阅读任务 - 数据一致性验证', () => {
|
|||
|
|
test('S-DATA-01: 验证任务数据来源正确', async ({ page }) => {
|
|||
|
|
// 登录
|
|||
|
|
await page.goto(`${BASE_URL}/login`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.click('.role-btn:has-text("学校")');
|
|||
|
|
await page.fill('input[placeholder*="账号"]', 'school1');
|
|||
|
|
await page.fill('input[placeholder*="密码"]', '123456');
|
|||
|
|
await page.click('button.login-btn');
|
|||
|
|
await page.waitForURL(/\/school/, { timeout: 15000 });
|
|||
|
|
|
|||
|
|
// 进入任务页面
|
|||
|
|
await page.goto(`${BASE_URL}/school/reading-tasks`);
|
|||
|
|
await page.waitForLoadState('networkidle');
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 统计任务数量
|
|||
|
|
const taskCards = page.locator('.ant-card:not(.stat-card), [class*="task-card"]');
|
|||
|
|
const taskCount = await taskCards.count();
|
|||
|
|
|
|||
|
|
console.log(`学校端显示任务数: ${taskCount}`);
|
|||
|
|
|
|||
|
|
// 验证任务数量 > 0(应该能看到教师创建的任务)
|
|||
|
|
expect(taskCount).toBeGreaterThanOrEqual(0);
|
|||
|
|
|
|||
|
|
await page.screenshot({ path: 'test-results/school-data-consistency.png', fullPage: true });
|
|||
|
|
});
|
|||
|
|
});
|