08ea5fbe98
添加用户管理视图、API和状态管理文件
399 lines
12 KiB
TypeScript
399 lines
12 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { APIHelper } from '../helpers/api-helper';
|
|
import { FormHelper } from '../helpers/form-helper';
|
|
import { TableHelper } from '../helpers/table-helper';
|
|
import { ScreenshotHelper } from '../helpers/screenshot-helper';
|
|
|
|
test.describe('测试辅助工具使用示例', () => {
|
|
let apiHelper: APIHelper;
|
|
let formHelper: FormHelper;
|
|
let tableHelper: TableHelper;
|
|
let screenshotHelper: ScreenshotHelper;
|
|
|
|
test.beforeEach(async ({ page, apiContext }) => {
|
|
apiHelper = new APIHelper(apiContext, 'https://api.example.com');
|
|
formHelper = new FormHelper(page, 'form#user-form');
|
|
tableHelper = new TableHelper(page, 'table#data-table');
|
|
screenshotHelper = new ScreenshotHelper(page);
|
|
});
|
|
|
|
test('API辅助工具示例', async () => {
|
|
test.info().annotations.push({ type: 'API测试', description: '演示API辅助工具的各种功能' });
|
|
|
|
await test.step('GET请求示例', async () => {
|
|
const response = await apiHelper.get('/users');
|
|
expect(response.success).toBe(true);
|
|
expect(response.data).toBeDefined();
|
|
});
|
|
|
|
await test.step('POST请求示例', async () => {
|
|
const userData = {
|
|
name: '张三',
|
|
email: 'zhangsan@example.com',
|
|
age: 30
|
|
};
|
|
|
|
const response = await apiHelper.post('/users', userData);
|
|
expect(response.success).toBe(true);
|
|
expect(response.data).toMatchObject(userData);
|
|
});
|
|
|
|
await test.step('带认证的请求示例', async () => {
|
|
await apiHelper.login('/auth/login', {
|
|
username: 'admin',
|
|
password: 'password123'
|
|
});
|
|
|
|
const response = await apiHelper.get('/protected/resource');
|
|
expect(response.success).toBe(true);
|
|
});
|
|
|
|
await test.step('文件上传示例', async () => {
|
|
const response = await apiHelper.upload('/upload', '/path/to/file.pdf');
|
|
expect(response.success).toBe(true);
|
|
});
|
|
|
|
await test.step('错误处理示例', async () => {
|
|
const response = await apiHelper.get('/nonexistent');
|
|
expect(response.success).toBe(false);
|
|
expect(response.status).toBe(404);
|
|
});
|
|
});
|
|
|
|
test('表单辅助工具示例', async ({ page }) => {
|
|
test.info().annotations.push({ type: '表单测试', description: '演示表单辅助工具的各种功能' });
|
|
|
|
await page.goto('/user-form');
|
|
|
|
await test.step('配置表单字段', async () => {
|
|
formHelper.setFields([
|
|
{
|
|
name: 'username',
|
|
selector: 'input[name="username"]',
|
|
type: 'text',
|
|
required: true
|
|
},
|
|
{
|
|
name: 'email',
|
|
selector: 'input[name="email"]',
|
|
type: 'email',
|
|
required: true
|
|
},
|
|
{
|
|
name: 'age',
|
|
selector: 'input[name="age"]',
|
|
type: 'number',
|
|
required: false
|
|
},
|
|
{
|
|
name: 'gender',
|
|
selector: 'select[name="gender"]',
|
|
type: 'select',
|
|
required: true
|
|
},
|
|
{
|
|
name: 'agree',
|
|
selector: 'input[name="agree"]',
|
|
type: 'checkbox',
|
|
required: true
|
|
}
|
|
]);
|
|
|
|
await formHelper.waitForFormReady();
|
|
});
|
|
|
|
await test.step('填写表单', async () => {
|
|
await formHelper.fillForm({
|
|
username: '张三',
|
|
email: 'zhangsan@example.com',
|
|
age: '30',
|
|
gender: '男',
|
|
agree: true
|
|
});
|
|
|
|
const formData = await formHelper.getFormData();
|
|
expect(formData.username).toBe('张三');
|
|
expect(formData.email).toBe('zhangsan@example.com');
|
|
});
|
|
|
|
await test.step('验证表单', async () => {
|
|
const validations = await formHelper.validate();
|
|
const allValid = validations.every(v => v.valid);
|
|
expect(allValid).toBe(true);
|
|
});
|
|
|
|
await test.step('提交表单', async () => {
|
|
await screenshotHelper.captureBeforeAction('form-submit');
|
|
await formHelper.submit();
|
|
await page.waitForTimeout(1000);
|
|
await screenshotHelper.captureAfterAction('form-submit');
|
|
});
|
|
|
|
await test.step('清空表单', async () => {
|
|
await formHelper.clearForm();
|
|
const formData = await formHelper.getFormData();
|
|
expect(formData.username).toBe('');
|
|
expect(formData.email).toBe('');
|
|
});
|
|
});
|
|
|
|
test('表格辅助工具示例', async ({ page }) => {
|
|
test.info().annotations.push({ type: '表格测试', description: '演示表格辅助工具的各种功能' });
|
|
|
|
await page.goto('/data-table');
|
|
|
|
await test.step('配置表格列', async () => {
|
|
tableHelper.setColumns([
|
|
{
|
|
name: 'id',
|
|
selector: 'td:nth-child(1)',
|
|
type: 'number',
|
|
sortable: true
|
|
},
|
|
{
|
|
name: 'name',
|
|
selector: 'td:nth-child(2)',
|
|
type: 'text',
|
|
sortable: true,
|
|
filterable: true
|
|
},
|
|
{
|
|
name: 'email',
|
|
selector: 'td:nth-child(3)',
|
|
type: 'text',
|
|
filterable: true
|
|
},
|
|
{
|
|
name: 'status',
|
|
selector: 'td:nth-child(4)',
|
|
type: 'text',
|
|
sortable: true
|
|
},
|
|
{
|
|
name: 'actions',
|
|
selector: 'td:nth-child(5)',
|
|
type: 'action'
|
|
}
|
|
]);
|
|
|
|
await tableHelper.waitForData();
|
|
});
|
|
|
|
await test.step('获取表格数据', async () => {
|
|
const rowCount = await tableHelper.getRowCount();
|
|
expect(rowCount).toBeGreaterThan(0);
|
|
|
|
const rows = await tableHelper.getAllRows();
|
|
expect(rows.length).toBe(rowCount);
|
|
});
|
|
|
|
await test.step('查找行', async () => {
|
|
const row = await tableHelper.findRowByColumn('name', '张三');
|
|
expect(row).toBeDefined();
|
|
expect(row?.data.name).toBe('张三');
|
|
});
|
|
|
|
await test.step('过滤表格', async () => {
|
|
await tableHelper.filterByColumn('name', '张三');
|
|
await page.waitForTimeout(500);
|
|
|
|
const filteredRows = await tableHelper.findRowsByColumn('name', '张三');
|
|
expect(filteredRows.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
await test.step('排序表格', async () => {
|
|
await tableHelper.sortByColumn('name', 'asc');
|
|
await page.waitForTimeout(500);
|
|
|
|
const sortOrder = await tableHelper.getSortOrder('name');
|
|
expect(sortOrder).toBe('asc');
|
|
});
|
|
|
|
await test.step('执行行操作', async () => {
|
|
const row = await tableHelper.findRowByColumn('name', '张三');
|
|
if (row) {
|
|
await tableHelper.viewRow(row.index);
|
|
await page.waitForTimeout(500);
|
|
await page.goBack();
|
|
}
|
|
});
|
|
|
|
await test.step('选择行', async () => {
|
|
await tableHelper.selectRow(0);
|
|
const selectedRows = await tableHelper.getSelectedRows();
|
|
expect(selectedRows.length).toBe(1);
|
|
});
|
|
|
|
await test.step('分页操作', async () => {
|
|
const totalPages = await tableHelper.getTotalPages();
|
|
if (totalPages > 1) {
|
|
await tableHelper.nextPage();
|
|
await page.waitForTimeout(500);
|
|
|
|
const currentPage = await tableHelper.getCurrentPage();
|
|
expect(currentPage).toBe(2);
|
|
}
|
|
});
|
|
});
|
|
|
|
test('截图辅助工具示例', async ({ page }) => {
|
|
test.info().annotations.push({ type: '截图测试', description: '演示截图辅助工具的各种功能' });
|
|
|
|
await page.goto('/dashboard');
|
|
|
|
await test.step('捕获整页截图', async () => {
|
|
const screenshotPath = await screenshotHelper.captureFullPage();
|
|
expect(screenshotPath).toBeDefined();
|
|
});
|
|
|
|
await test.step('捕获视口截图', async () => {
|
|
const screenshotPath = await screenshotHelper.captureViewport();
|
|
expect(screenshotPath).toBeDefined();
|
|
});
|
|
|
|
await test.step('捕获元素截图', async () => {
|
|
const element = page.locator('.dashboard-card');
|
|
const screenshotPath = await screenshotHelper.captureElement(element);
|
|
expect(screenshotPath).toBeDefined();
|
|
});
|
|
|
|
await test.step('带描述的截图', async () => {
|
|
const screenshotPath = await screenshotHelper.captureWithDescription('登录后的仪表盘');
|
|
expect(screenshotPath).toBeDefined();
|
|
});
|
|
|
|
await test.step('操作前后截图', async () => {
|
|
await screenshotHelper.captureBeforeAction('button-click');
|
|
|
|
await page.click('.action-button');
|
|
await page.waitForTimeout(1000);
|
|
|
|
await screenshotHelper.captureAfterAction('button-click');
|
|
});
|
|
|
|
await test.step('步骤截图', async () => {
|
|
await screenshotHelper.captureStep('步骤1: 打开菜单');
|
|
await page.click('.menu-button');
|
|
await page.waitForTimeout(500);
|
|
|
|
await screenshotHelper.captureStep('步骤2: 选择选项');
|
|
await page.click('.menu-item');
|
|
await page.waitForTimeout(500);
|
|
|
|
await screenshotHelper.captureStep('步骤3: 完成操作');
|
|
});
|
|
|
|
await test.step('悬停截图', async () => {
|
|
const element = page.locator('.hover-element');
|
|
const screenshotPath = await screenshotHelper.captureOnHover(element);
|
|
expect(screenshotPath).toBeDefined();
|
|
});
|
|
|
|
await test.step('失败时截图', async () => {
|
|
try {
|
|
await page.click('.nonexistent-button');
|
|
} catch (error) {
|
|
const screenshotPath = await screenshotHelper.captureOnFailure('按钮点击失败', error as Error);
|
|
expect(screenshotPath).toBeDefined();
|
|
}
|
|
});
|
|
|
|
await test.step('生成截图报告', async () => {
|
|
const reportPath = await screenshotHelper.createScreenshotReport();
|
|
expect(reportPath).toBeDefined();
|
|
});
|
|
});
|
|
|
|
test('综合测试示例', async ({ page, apiContext }) => {
|
|
test.info().annotations.push({ type: '综合测试', description: '演示多个辅助工具的综合使用' });
|
|
|
|
await test.step('API登录', async () => {
|
|
const loginResponse = await apiHelper.post('/auth/login', {
|
|
username: 'testuser',
|
|
password: 'testpass'
|
|
});
|
|
|
|
expect(loginResponse.success).toBe(true);
|
|
|
|
const token = loginResponse.data.token;
|
|
apiHelper.setToken(token);
|
|
});
|
|
|
|
await test.step('导航到页面', async () => {
|
|
await page.goto('/user-management');
|
|
await screenshotHelper.captureStep('页面加载完成');
|
|
});
|
|
|
|
await test.step('配置表单', async () => {
|
|
formHelper.setFields([
|
|
{
|
|
name: 'username',
|
|
selector: 'input[name="username"]',
|
|
type: 'text',
|
|
required: true
|
|
},
|
|
{
|
|
name: 'email',
|
|
selector: 'input[name="email"]',
|
|
type: 'email',
|
|
required: true
|
|
}
|
|
]);
|
|
|
|
await formHelper.waitForFormReady();
|
|
});
|
|
|
|
await test.step('填写并提交表单', async () => {
|
|
await formHelper.fillForm({
|
|
username: '新用户',
|
|
email: 'newuser@example.com'
|
|
});
|
|
|
|
await screenshotHelper.captureBeforeAction('表单提交');
|
|
await formHelper.submit();
|
|
await page.waitForTimeout(1000);
|
|
await screenshotHelper.captureAfterAction('表单提交');
|
|
});
|
|
|
|
await test.step('验证数据在表格中', async () => {
|
|
tableHelper.setColumns([
|
|
{
|
|
name: 'username',
|
|
selector: 'td:nth-child(2)',
|
|
type: 'text'
|
|
},
|
|
{
|
|
name: 'email',
|
|
selector: 'td:nth-child(3)',
|
|
type: 'text'
|
|
}
|
|
]);
|
|
|
|
await tableHelper.waitForData();
|
|
|
|
const row = await tableHelper.findRowByColumn('username', '新用户');
|
|
expect(row).toBeDefined();
|
|
expect(row?.data.email).toBe('newuser@example.com');
|
|
});
|
|
|
|
await test.step('通过API验证数据', async () => {
|
|
const response = await apiHelper.get('/users');
|
|
expect(response.success).toBe(true);
|
|
|
|
const user = response.data.find((u: any) => u.username === '新用户');
|
|
expect(user).toBeDefined();
|
|
});
|
|
|
|
await test.step('清理数据', async () => {
|
|
const row = await tableHelper.findRowByColumn('username', '新用户');
|
|
if (row) {
|
|
await tableHelper.deleteRow(row.index);
|
|
await page.waitForTimeout(1000);
|
|
}
|
|
|
|
const deletedRow = await tableHelper.findRowByColumn('username', '新用户');
|
|
expect(deletedRow).toBeUndefined();
|
|
});
|
|
});
|
|
});
|