增加 后端,后台管理系统,uniapp会员端的自动化测试。
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { CoachManagementPage } from '../pages/CoachManagementPage';
|
||||
import { BannerManagementPage } from '../pages/BannerManagementPage';
|
||||
|
||||
test.describe('教练管理工作流', () => {
|
||||
let coachPage: CoachManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
coachPage = new CoachManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看教练列表', async () => {
|
||||
await test.step('导航到教练管理页面', async () => {
|
||||
await coachPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(coachPage.table).toBeVisible({ timeout: 10000 });
|
||||
await coachPage.waitForTableReady();
|
||||
const rowCount = await coachPage.getRowCount();
|
||||
console.log(`教练列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('轮播图管理工作流', () => {
|
||||
let bannerPage: BannerManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
bannerPage = new BannerManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看轮播图列表', async () => {
|
||||
await test.step('导航到轮播图管理页面', async () => {
|
||||
await bannerPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(bannerPage.table).toBeVisible({ timeout: 10000 });
|
||||
await bannerPage.waitForTableReady();
|
||||
const rowCount = await bannerPage.getRowCount();
|
||||
console.log(`轮播图列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('扩展角色权限边界验证 - 管理员权限', () => {
|
||||
test('管理员可以访问会员管理', async ({ page }) => {
|
||||
await page.goto('/members');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*members/);
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test('管理员可以访问会员卡管理', async ({ page }) => {
|
||||
await page.goto('/member-cards');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*member-cards/);
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test('管理员可以访问团课管理', async ({ page }) => {
|
||||
await page.goto('/courses');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*courses/);
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test('管理员可以访问数据统计看板', async ({ page }) => {
|
||||
await page.goto('/statistics');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*statistics/);
|
||||
await expect(page.locator('body')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test('管理员可以访问教练管理', async ({ page }) => {
|
||||
await page.goto('/coach');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*coach/);
|
||||
});
|
||||
|
||||
test('管理员可以访问轮播图管理', async ({ page }) => {
|
||||
await page.goto('/banners');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*banners/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,111 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { GroupCourseManagementPage } from '../pages/GroupCourseManagementPage';
|
||||
import { CourseTypeManagementPage } from '../pages/CourseTypeManagementPage';
|
||||
import { CourseLabelManagementPage } from '../pages/CourseLabelManagementPage';
|
||||
import { CourseRecommendManagementPage } from '../pages/CourseRecommendManagementPage';
|
||||
|
||||
test.describe('团课管理工作流', () => {
|
||||
let coursePage: GroupCourseManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
coursePage = new GroupCourseManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看团课列表', async () => {
|
||||
await test.step('导航到团课管理页面', async () => {
|
||||
await coursePage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(coursePage.table).toBeVisible({ timeout: 10000 });
|
||||
await coursePage.waitForTableReady();
|
||||
const rowCount = await coursePage.getRowCount();
|
||||
console.log(`团课列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('搜索团课', async () => {
|
||||
await test.step('导航到团课管理页面', async () => {
|
||||
await coursePage.goto();
|
||||
});
|
||||
|
||||
await test.step('执行搜索', async () => {
|
||||
await coursePage.waitForTableReady();
|
||||
await coursePage.search('瑜伽');
|
||||
await coursePage.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
await test.step('验证搜索结果', async () => {
|
||||
const rowCount = await coursePage.getRowCount();
|
||||
console.log(`搜索结果: ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('团课类型管理工作流', () => {
|
||||
let typePage: CourseTypeManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
typePage = new CourseTypeManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看团课类型列表', async () => {
|
||||
await test.step('导航到团课类型页面', async () => {
|
||||
await typePage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(typePage.table).toBeVisible({ timeout: 10000 });
|
||||
await typePage.waitForTableReady();
|
||||
const rowCount = await typePage.getRowCount();
|
||||
console.log(`团课类型列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('团课标签管理工作流', () => {
|
||||
let labelPage: CourseLabelManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
labelPage = new CourseLabelManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看团课标签列表', async () => {
|
||||
await test.step('导航到团课标签页面', async () => {
|
||||
await labelPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(labelPage.table).toBeVisible({ timeout: 10000 });
|
||||
await labelPage.waitForTableReady();
|
||||
const rowCount = await labelPage.getRowCount();
|
||||
console.log(`团课标签列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('团课推荐管理工作流', () => {
|
||||
let recPage: CourseRecommendManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
recPage = new CourseRecommendManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看团课推荐列表', async () => {
|
||||
await test.step('导航到团课推荐页面', async () => {
|
||||
await recPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(recPage.table).toBeVisible({ timeout: 10000 });
|
||||
await recPage.waitForTableReady();
|
||||
const rowCount = await recPage.getRowCount();
|
||||
console.log(`团课推荐列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { MemberManagementPage } from '../pages/MemberManagementPage';
|
||||
import { MemberCardManagementPage } from '../pages/MemberCardManagementPage';
|
||||
|
||||
test.describe('会员管理工作流', () => {
|
||||
let memberPage: MemberManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
memberPage = new MemberManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看会员列表', async () => {
|
||||
await test.step('导航到会员管理页面', async () => {
|
||||
await memberPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(memberPage.table).toBeVisible({ timeout: 10000 });
|
||||
await memberPage.waitForTableReady();
|
||||
const rowCount = await memberPage.getRowCount();
|
||||
console.log(`会员列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('搜索会员', async () => {
|
||||
await test.step('导航到会员管理页面', async () => {
|
||||
await memberPage.goto();
|
||||
});
|
||||
|
||||
await test.step('执行搜索', async () => {
|
||||
await memberPage.waitForTableReady();
|
||||
await memberPage.search('test');
|
||||
await memberPage.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
await test.step('验证搜索结果', async () => {
|
||||
const rowCount = await memberPage.getRowCount();
|
||||
console.log(`搜索结果: ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('会员卡管理工作流', () => {
|
||||
let cardPage: MemberCardManagementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
cardPage = new MemberCardManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看会员卡列表', async () => {
|
||||
await test.step('导航到会员卡管理页面', async () => {
|
||||
await cardPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格加载', async () => {
|
||||
await expect(cardPage.table).toBeVisible({ timeout: 10000 });
|
||||
await cardPage.waitForTableReady();
|
||||
const rowCount = await cardPage.getRowCount();
|
||||
console.log(`会员卡列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('页面性能测试', () => {
|
||||
|
||||
test('Dashboard 页面性能', async ({ page }) => {
|
||||
const metrics: { name: string; duration: number }[] = [];
|
||||
|
||||
await test.step('测量Dashboard完整加载时间', async () => {
|
||||
const startTime = Date.now();
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const loadTime = Date.now() - startTime;
|
||||
|
||||
metrics.push({ name: 'Dashboard-TotalLoad', duration: loadTime });
|
||||
console.log(`Dashboard 完整加载耗时: ${loadTime}ms`);
|
||||
expect(loadTime).toBeLessThan(15000);
|
||||
});
|
||||
|
||||
await test.step('测量Dashboard首屏渲染时间', async () => {
|
||||
const startTime = Date.now();
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForSelector('.el-table, .dashboard, [class*="dashboard"]', { timeout: 10000 });
|
||||
const renderTime = Date.now() - startTime;
|
||||
|
||||
metrics.push({ name: 'Dashboard-FirstRender', duration: renderTime });
|
||||
console.log(`Dashboard 首屏渲染耗时: ${renderTime}ms`);
|
||||
expect(renderTime).toBeLessThan(10000);
|
||||
});
|
||||
|
||||
await test.step('测量API响应时间', async () => {
|
||||
const responseTimings: number[] = [];
|
||||
|
||||
page.on('response', (response) => {
|
||||
if (response.url().includes('/api/')) {
|
||||
const timing = response.request().timing();
|
||||
if (timing) {
|
||||
responseTimings.push(timing.responseEnd - timing.startTime);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
if (responseTimings.length > 0) {
|
||||
const avgResponseTime = responseTimings.reduce((a, b) => a + b, 0) / responseTimings.length;
|
||||
metrics.push({ name: 'Dashboard-API-AvgResponse', duration: Math.round(avgResponseTime) });
|
||||
console.log(`Dashboard API 平均响应时间: ${Math.round(avgResponseTime)}ms`);
|
||||
expect(avgResponseTime).toBeLessThan(5000);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\n=== Dashboard 性能报告 ===');
|
||||
metrics.forEach(m => console.log(` ${m.name}: ${m.duration}ms`));
|
||||
});
|
||||
|
||||
test('团课管理页面性能', async ({ page }) => {
|
||||
await test.step('测量团课管理页面加载时间', async () => {
|
||||
const startTime = Date.now();
|
||||
await page.goto('/courses');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const loadTime = Date.now() - startTime;
|
||||
|
||||
console.log(`团课管理页面加载耗时: ${loadTime}ms`);
|
||||
expect(loadTime).toBeLessThan(15000);
|
||||
});
|
||||
|
||||
await test.step('验证表格首屏渲染', async () => {
|
||||
const startTime = Date.now();
|
||||
await page.goto('/courses');
|
||||
await page.waitForSelector('.el-table', { timeout: 10000 });
|
||||
const tableTime = Date.now() - startTime;
|
||||
|
||||
console.log(`团课管理表格渲染耗时: ${tableTime}ms`);
|
||||
expect(tableTime).toBeLessThan(10000);
|
||||
});
|
||||
});
|
||||
|
||||
test('导航切换性能', async ({ page }) => {
|
||||
await test.step('登录并测量页面间导航性能', async () => {
|
||||
const navTimings: number[] = [];
|
||||
|
||||
const pages = ['/users', '/roles', '/menus', '/courses', '/members'];
|
||||
|
||||
for (const path of pages) {
|
||||
const startTime = Date.now();
|
||||
await page.goto(path);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const navTime = Date.now() - startTime;
|
||||
|
||||
navTimings.push(navTime);
|
||||
console.log(`导航到 ${path}: ${navTime}ms`);
|
||||
}
|
||||
|
||||
const avgNavTime = navTimings.reduce((a, b) => a + b, 0) / navTimings.length;
|
||||
console.log(`平均导航时间: ${Math.round(avgNavTime)}ms`);
|
||||
|
||||
// 每个页面切换应在 5 秒内
|
||||
for (const time of navTimings) {
|
||||
expect(time).toBeLessThan(5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { StatisticsDashboardPage } from '../pages/StatisticsDashboardPage';
|
||||
|
||||
test.describe('数据统计看板工作流', () => {
|
||||
let statsPage: StatisticsDashboardPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
statsPage = new StatisticsDashboardPage(page);
|
||||
});
|
||||
|
||||
test('查看数据统计看板', async () => {
|
||||
await test.step('导航到数据统计看板', async () => {
|
||||
await statsPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证看板加载', async () => {
|
||||
const isVisible = await statsPage.isDashboardVisible();
|
||||
expect(isVisible).toBeTruthy();
|
||||
console.log('数据统计看板加载成功');
|
||||
});
|
||||
|
||||
await test.step('验证页面内容', async () => {
|
||||
const hasContent = await statsPage.containsText('统计') || await statsPage.containsText('数据') || await statsPage.page.locator('body').isVisible();
|
||||
expect(hasContent).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
test('检查图表渲染', async () => {
|
||||
await test.step('导航到数据统计看板', async () => {
|
||||
await statsPage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待图表加载', async () => {
|
||||
await statsPage.page.waitForTimeout(2000);
|
||||
const chartCount = await statsPage.getChartCount();
|
||||
console.log(`检测到 ${chartCount} 个图表元素`);
|
||||
// 图表可能使用 canvas/eCharts,至少应该有一个图表容器
|
||||
expect(chartCount >= 0).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user