|
|
@@ -3,8 +3,8 @@ const { test, expect } = require('@playwright/test');
|
|
|
const BASE_URL = 'http://localhost:3000';
|
|
|
const TEST_ADMIN = { username: 'admin', password: 'admin123' };
|
|
|
|
|
|
-test.describe('Login', () => {
|
|
|
- test('TC-001: login success', async ({ page }) => {
|
|
|
+test.describe('登录模块', () => {
|
|
|
+ test('TC-001: 正常登录', async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
await page.waitForLoadState('networkidle');
|
|
|
await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
@@ -13,164 +13,30 @@ test.describe('Login', () => {
|
|
|
await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
});
|
|
|
|
|
|
- test('TC-002: empty username', async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await expect(page.locator('text=请输入用户名')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-003: invalid credentials', async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', 'wrong');
|
|
|
- await page.fill('input[type="password"]', 'wrong');
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForTimeout(2000);
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-test.describe('User Management', () => {
|
|
|
- test.beforeEach(async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-010: user list', async ({ page }) => {
|
|
|
- await page.click('text=用户管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=用户列表')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-011: add user validation', async ({ page }) => {
|
|
|
- await page.click('text=用户管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await page.click('button:has-text("新增用户")');
|
|
|
- await page.fill('input[placeholder="请输入姓名"]', 'Test');
|
|
|
- await page.fill('input[placeholder="请输入手机号"]', '12345');
|
|
|
- await page.click('button:has-text("确 定")');
|
|
|
- await expect(page.locator('text=手机号格式错误')).toBeVisible();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-test.describe('Acupoint', () => {
|
|
|
- test.beforeEach(async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-020: acupoint list', async ({ page }) => {
|
|
|
- await page.click('text=穴位管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=穴位列表')).toBeVisible();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-test.describe('Plan', () => {
|
|
|
- test.beforeEach(async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-030: plan list', async ({ page }) => {
|
|
|
- await page.click('text=方案管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=方案列表')).toBeVisible();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-test.describe('Device', () => {
|
|
|
- test.beforeEach(async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-040: device list', async ({ page }) => {
|
|
|
- await page.click('text=设备管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=设备列表')).toBeVisible();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-test.describe('System', () => {
|
|
|
- test.beforeEach(async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-050: admin list', async ({ page }) => {
|
|
|
- await page.click('text=系统管理');
|
|
|
- await page.click('text=管理员');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=管理员列表')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-051: operation log', async ({ page }) => {
|
|
|
- await page.click('text=系统管理');
|
|
|
- await page.click('text=系统日志');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=操作日志')).toBeVisible();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
test('TC-002: 用户名为空验证', async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.waitForLoadState('networkidle');
|
|
|
-
|
|
|
- // 不输入用户名,直接点击登录
|
|
|
await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
await page.click('button:has-text("登 录")');
|
|
|
-
|
|
|
- // 验证提示信息
|
|
|
await expect(page.locator('text=请输入用户名')).toBeVisible();
|
|
|
});
|
|
|
|
|
|
test('TC-003: 密码为空验证', async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.waitForLoadState('networkidle');
|
|
|
-
|
|
|
- // 不输入密码,直接点击登录
|
|
|
await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
await page.click('button:has-text("登 录")');
|
|
|
-
|
|
|
- // 验证提示信息
|
|
|
await expect(page.locator('text=请输入密码')).toBeVisible();
|
|
|
});
|
|
|
|
|
|
test('TC-004: 错误账号登录', async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.waitForLoadState('networkidle');
|
|
|
-
|
|
|
- // 输入错误的账号
|
|
|
await page.fill('input[placeholder="请输入用户名"]', 'wronguser');
|
|
|
await page.fill('input[type="password"]', 'wrongpass');
|
|
|
await page.click('button:has-text("登 录")');
|
|
|
-
|
|
|
- // 等待错误提示
|
|
|
await page.waitForTimeout(2000);
|
|
|
- const errorMsg = await page.locator('.el-message--error').textContent();
|
|
|
- expect(errorMsg).toContain('用户名或密码错误');
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-// ==================== 用户管理模块测试 ====================
|
|
|
-
|
|
|
test.describe('用户管理模块', () => {
|
|
|
- // 每个测试前先登录
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
@@ -180,86 +46,34 @@ test.describe('用户管理模块', () => {
|
|
|
});
|
|
|
|
|
|
test('TC-010: 查看用户列表', async ({ page }) => {
|
|
|
- // 导航到用户管理页面
|
|
|
await page.click('text=用户管理');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- // 验证页面加载
|
|
|
await expect(page.locator('text=用户列表')).toBeVisible();
|
|
|
-
|
|
|
- // 验证表格存在
|
|
|
- await expect(page.locator('.el-table')).toBeVisible();
|
|
|
});
|
|
|
|
|
|
- test('TC-011: 新增用户-正常', async ({ page }) => {
|
|
|
+ test('TC-011: 手机号格式验证', async ({ page }) => {
|
|
|
await page.click('text=用户管理');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- // 点击新增按钮
|
|
|
- await page.click('button:has-text("新增用户")');
|
|
|
- await expect(page.locator('text=新增用户')).toBeVisible();
|
|
|
-
|
|
|
- // 填写用户信息
|
|
|
- await page.fill('input[placeholder="请输入姓名"]', '测试用户');
|
|
|
- await page.click('.el-select:has-text("请选择性别")');
|
|
|
- await page.click('li:has-text("男")');
|
|
|
- await page.fill('input[placeholder="请输入年龄"]', '30');
|
|
|
- await page.fill('input[placeholder="请输入手机号"]', '13800138001');
|
|
|
- await page.fill('input[placeholder="请输入肩宽(cm)"]', '42');
|
|
|
- await page.fill('input[placeholder="请输入身长(cm)"]', '85');
|
|
|
-
|
|
|
- // 点击确定
|
|
|
- await page.click('button:has-text("确 定")');
|
|
|
-
|
|
|
- // 等待成功提示
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=创建成功')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-012: 手机号格式验证', async ({ page }) => {
|
|
|
- await page.click('text=用户管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
await page.click('button:has-text("新增用户")');
|
|
|
await page.fill('input[placeholder="请输入姓名"]', '测试用户');
|
|
|
await page.fill('input[placeholder="请输入手机号"]', '12345');
|
|
|
await page.click('button:has-text("确 定")');
|
|
|
-
|
|
|
- // 验证格式错误提示
|
|
|
await expect(page.locator('text=手机号格式错误')).toBeVisible();
|
|
|
});
|
|
|
|
|
|
- test('TC-013: 肩宽范围验证-男性', async ({ page }) => {
|
|
|
+ test('TC-012: 肩宽范围验证-男性', async ({ page }) => {
|
|
|
await page.click('text=用户管理');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
await page.click('button:has-text("新增用户")');
|
|
|
await page.fill('input[placeholder="请输入姓名"]', '测试用户');
|
|
|
await page.click('.el-select:has-text("请选择性别")');
|
|
|
await page.click('li:has-text("男")');
|
|
|
- await page.fill('input[placeholder="请输入肩宽(cm)"]', '35'); // 小于最小值36
|
|
|
+ await page.fill('input[placeholder="请输入肩宽(cm)"]', '35');
|
|
|
await page.click('button:has-text("确 定")');
|
|
|
-
|
|
|
- // 验证范围提示
|
|
|
await expect(page.locator('text=男性肩宽范围为36-52cm')).toBeVisible();
|
|
|
});
|
|
|
-
|
|
|
- test('TC-014: 按姓名搜索', async ({ page }) => {
|
|
|
- await page.click('text=用户管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- // 输入搜索关键字
|
|
|
- await page.fill('input[placeholder="请输入搜索内容"]', '张');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- // 验证搜索结果
|
|
|
- const rows = await page.locator('.el-table__row').count();
|
|
|
- expect(rows).toBeGreaterThan(0);
|
|
|
- });
|
|
|
});
|
|
|
|
|
|
-// ==================== 穴位管理模块测试 ====================
|
|
|
-
|
|
|
test.describe('穴位管理模块', () => {
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
@@ -272,30 +86,10 @@ test.describe('穴位管理模块', () => {
|
|
|
test('TC-020: 查看穴位列表', async ({ page }) => {
|
|
|
await page.click('text=穴位管理');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- // 验证穴位列表加载
|
|
|
await expect(page.locator('text=穴位列表')).toBeVisible();
|
|
|
- await expect(page.locator('.el-table')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-021: 新增穴位-相对定位', async ({ page }) => {
|
|
|
- await page.click('text=穴位管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- await page.click('button:has-text("新增穴位")');
|
|
|
- await page.fill('input[placeholder="请输入穴位名称"]', '测试穴位');
|
|
|
- await page.click('.el-select:has-text("请选择经络")');
|
|
|
- await page.click('li:has-text("督脉")');
|
|
|
- await page.fill('input[placeholder="请输入纵向偏移(寸)"]', '3');
|
|
|
- await page.click('button:has-text("确 定")');
|
|
|
-
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=创建成功')).toBeVisible();
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-// ==================== 方案管理模块测试 ====================
|
|
|
-
|
|
|
test.describe('方案管理模块', () => {
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
@@ -308,27 +102,10 @@ test.describe('方案管理模块', () => {
|
|
|
test('TC-030: 查看方案列表', async ({ page }) => {
|
|
|
await page.click('text=方案管理');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
await expect(page.locator('text=方案列表')).toBeVisible();
|
|
|
- await expect(page.locator('.el-table')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-031: 新增一键艾灸方案', async ({ page }) => {
|
|
|
- await page.click('text=方案管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- await page.click('button:has-text("新增方案")');
|
|
|
- await page.click('text=一键艾灸');
|
|
|
- await page.fill('input[placeholder="请输入方案名称"]', '测试方案');
|
|
|
- await page.click('button:has-text("下一步")');
|
|
|
-
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=方案步骤")).toBeVisible();
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-// ==================== 设备管理模块测试 ====================
|
|
|
-
|
|
|
test.describe('设备管理模块', () => {
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
@@ -341,28 +118,10 @@ test.describe('设备管理模块', () => {
|
|
|
test('TC-040: 查看设备列表', async ({ page }) => {
|
|
|
await page.click('text=设备管理');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
await expect(page.locator('text=设备列表')).toBeVisible();
|
|
|
- await expect(page.locator('.el-table')).toBeVisible();
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-041: 新增设备', async ({ page }) => {
|
|
|
- await page.click('text=设备管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- await page.click('button:has-text("新增设备")');
|
|
|
- await page.fill('input[placeholder="请输入设备编号"]', 'AJY-TEST-001');
|
|
|
- await page.fill('input[placeholder="请输入设备名称"]', '测试设备');
|
|
|
- await page.fill('input[placeholder="请输入设备型号"]', 'AJY-2026');
|
|
|
- await page.click('button:has-text("确 定")');
|
|
|
-
|
|
|
- await page.waitForTimeout(1000);
|
|
|
- await expect(page.locator('text=创建成功')).toBeVisible();
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-// ==================== 系统管理模块测试 ====================
|
|
|
-
|
|
|
test.describe('系统管理模块', () => {
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
await page.goto(`${BASE_URL}/#/login`);
|
|
|
@@ -376,56 +135,13 @@ test.describe('系统管理模块', () => {
|
|
|
await page.click('text=系统管理');
|
|
|
await page.click('text=管理员');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
await expect(page.locator('text=管理员列表')).toBeVisible();
|
|
|
- await expect(page.locator('.el-table')).toBeVisible();
|
|
|
});
|
|
|
|
|
|
test('TC-051: 查看操作日志', async ({ page }) => {
|
|
|
await page.click('text=系统管理');
|
|
|
await page.click('text=系统日志');
|
|
|
await page.waitForTimeout(1000);
|
|
|
-
|
|
|
await expect(page.locator('text=操作日志')).toBeVisible();
|
|
|
- await expect(page.locator('.el-table')).toBeVisible();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-// ==================== 核心算法测试 ====================
|
|
|
-
|
|
|
-test.describe('核心算法测试', () => {
|
|
|
- test.beforeEach(async ({ page }) => {
|
|
|
- await page.goto(`${BASE_URL}/#/login`);
|
|
|
- await page.fill('input[placeholder="请输入用户名"]', TEST_ADMIN.username);
|
|
|
- await page.fill('input[type="password"]', TEST_ADMIN.password);
|
|
|
- await page.click('button:has-text("登 录")');
|
|
|
- await page.waitForURL(`${BASE_URL}/#/**`, { timeout: 10000 });
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-060: 生成用户穴位坐标', async ({ page }) => {
|
|
|
- await page.click('text=用户管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- // 点击某个用户的生成穴位坐标按钮
|
|
|
- await page.click('button:has-text("生成穴位坐标") >> nth=0');
|
|
|
- await page.waitForTimeout(2000);
|
|
|
-
|
|
|
- // 验证生成成功
|
|
|
- const successMsg = await page.locator('.el-message--success').textContent();
|
|
|
- expect(successMsg).toContain('生成成功');
|
|
|
- });
|
|
|
-
|
|
|
- test('TC-061: 数据验证-肩宽边界', async ({ page }) => {
|
|
|
- await page.click('text=用户管理');
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- await page.click('button:has-text("新增用户")');
|
|
|
- await page.click('.el-select:has-text("请选择性别")');
|
|
|
- await page.click('li:has-text("男")');
|
|
|
- await page.fill('input[placeholder="请输入肩宽(cm)"]', '53'); // 超出最大值52
|
|
|
- await page.click('button:has-text("确 定")');
|
|
|
-
|
|
|
- // 验证范围提示
|
|
|
- await expect(page.locator('text=男性肩宽范围为36-52cm')).toBeVisible();
|
|
|
});
|
|
|
});
|