|
@@ -0,0 +1,538 @@
|
|
|
|
|
+import { test, expect } from '../../utils/test-setup';
|
|
|
|
|
+import { readFileSync } from 'fs';
|
|
|
|
|
+import { join, dirname } from 'path';
|
|
|
|
|
+import { fileURLToPath } from 'url';
|
|
|
|
|
+
|
|
|
|
|
+const __filename = fileURLToPath(import.meta.url);
|
|
|
|
|
+const __dirname = dirname(__filename);
|
|
|
|
|
+const testUsers = JSON.parse(readFileSync(join(__dirname, '../../fixtures/test-users.json'), 'utf-8'));
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 生成唯一区域名称
|
|
|
|
|
+ * @param prefix - 名称前缀
|
|
|
|
|
+ * @returns 唯一的区域名称
|
|
|
|
|
+ */
|
|
|
|
|
+function generateUniqueRegionName(prefix: string = '测试区域'): string {
|
|
|
|
|
+ const timestamp = Date.now();
|
|
|
|
|
+ const random = Math.floor(Math.random() * 1000);
|
|
|
|
|
+ return `${prefix}_${timestamp}_${random}`;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 生成唯一区域代码
|
|
|
|
|
+ * @param level - 区域层级
|
|
|
|
|
+ * @returns 唯一的区域代码
|
|
|
|
|
+ */
|
|
|
|
|
+function generateUniqueRegionCode(level: string): string {
|
|
|
|
|
+ const timestamp = Date.now();
|
|
|
|
|
+ return `${level.toUpperCase()}_${timestamp}`;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+test.describe.serial('编辑区域测试', () => {
|
|
|
|
|
+ // 用于跟踪测试创建的区域,以便清理
|
|
|
|
|
+ const createdProvinces: string[] = [];
|
|
|
|
|
+
|
|
|
|
|
+ test.beforeEach(async ({ adminLoginPage, regionManagementPage }) => {
|
|
|
|
|
+ // 以管理员身份登录后台
|
|
|
|
|
+ await adminLoginPage.goto();
|
|
|
|
|
+ await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
|
|
|
|
|
+ await adminLoginPage.expectLoginSuccess();
|
|
|
|
|
+ await regionManagementPage.goto();
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.afterEach(async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ // 清理测试创建的数据
|
|
|
|
|
+ let cleanupSuccessCount = 0;
|
|
|
|
|
+ let cleanupFailCount = 0;
|
|
|
|
|
+
|
|
|
|
|
+ for (const provinceName of createdProvinces) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 尝试刷新页面并删除
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await page.waitForLoadState('domcontentloaded', { timeout: 10000 });
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ const exists = await regionManagementPage.regionExists(provinceName);
|
|
|
|
|
+ if (exists) {
|
|
|
|
|
+ const deleteSuccess = await regionManagementPage.deleteRegion(provinceName);
|
|
|
|
|
+ if (deleteSuccess) {
|
|
|
|
|
+ cleanupSuccessCount++;
|
|
|
|
|
+ console.debug(`✅ 已清理测试数据: ${provinceName}`);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ cleanupFailCount++;
|
|
|
|
|
+ console.debug(`⚠️ 删除失败(无成功提示): ${provinceName}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.debug(`ℹ️ 区域不存在,跳过删除: ${provinceName}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ cleanupFailCount++;
|
|
|
|
|
+ console.debug(`❌ 清理异常: ${provinceName}`, error);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 记录清理结果摘要
|
|
|
|
|
+ console.debug(`🧹 测试数据清理: 成功 ${cleanupSuccessCount}, 失败 ${cleanupFailCount}`);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有清理失败,记录警告但不阻塞测试
|
|
|
|
|
+ if (cleanupFailCount > 0) {
|
|
|
|
|
+ console.debug(`⚠️ 有 ${cleanupFailCount} 个区域清理失败,可能产生脏数据`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 清空跟踪列表
|
|
|
|
|
+ createdProvinces.length = 0;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.describe('编辑区域名称', () => {
|
|
|
|
|
+ test('应该成功编辑区域名称', async ({ regionManagementPage }) => {
|
|
|
|
|
+ // 首先创建一个测试省份
|
|
|
|
|
+ const originalName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: originalName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(originalName);
|
|
|
|
|
+
|
|
|
|
|
+ // 等待树形结构刷新
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑区域名称
|
|
|
|
|
+ const newName = generateUniqueRegionName('编辑后的省');
|
|
|
|
|
+ const result = await regionManagementPage.editRegion(originalName, {
|
|
|
|
|
+ name: newName,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 验证编辑成功
|
|
|
|
|
+ expect(result.success).toBe(true);
|
|
|
|
|
+ expect(result.hasError).toBe(false);
|
|
|
|
|
+
|
|
|
|
|
+ // 等待树形结构刷新
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证列表中显示新名称
|
|
|
|
|
+ const exists = await regionManagementPage.regionExists(newName);
|
|
|
|
|
+ expect(exists).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新清理列表中的名称
|
|
|
|
|
+ const index = createdProvinces.indexOf(originalName);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ createdProvinces[index] = newName;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('编辑后原名称不应存在', async ({ regionManagementPage }) => {
|
|
|
|
|
+ const originalName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: originalName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(originalName);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ const newName = generateUniqueRegionName('编辑后的省');
|
|
|
|
|
+ const result = await regionManagementPage.editRegion(originalName, { name: newName });
|
|
|
|
|
+
|
|
|
|
|
+ expect(result.success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证原名称不存在
|
|
|
|
|
+ const originalExists = await regionManagementPage.regionExists(originalName);
|
|
|
|
|
+ expect(originalExists).toBe(false);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证新名称存在
|
|
|
|
|
+ const newExists = await regionManagementPage.regionExists(newName);
|
|
|
|
|
+ expect(newExists).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新清理列表
|
|
|
|
|
+ const index = createdProvinces.indexOf(originalName);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ createdProvinces[index] = newName;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.describe('修改区域代码', () => {
|
|
|
|
|
+ test('应该成功修改行政区划代码', async ({ regionManagementPage }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: 'OLD_CODE',
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 修改代码
|
|
|
|
|
+ const newCode = generateUniqueRegionCode('NEW');
|
|
|
|
|
+ const result = await regionManagementPage.editRegion(provinceName, {
|
|
|
|
|
+ code: newCode,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ expect(result.success).toBe(true);
|
|
|
|
|
+ expect(result.hasError).toBe(false);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('应该能同时修改名称和代码', async ({ regionManagementPage }) => {
|
|
|
|
|
+ const originalName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: originalName,
|
|
|
|
|
+ code: 'OLD_CODE',
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(originalName);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ const newName = generateUniqueRegionName('新省名');
|
|
|
|
|
+ const newCode = generateUniqueRegionCode('NEW');
|
|
|
|
|
+ const result = await regionManagementPage.editRegion(originalName, {
|
|
|
|
|
+ name: newName,
|
|
|
|
|
+ code: newCode,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ expect(result.success).toBe(true);
|
|
|
|
|
+ expect(result.hasError).toBe(false);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+ expect(await regionManagementPage.regionExists(newName)).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新清理列表
|
|
|
|
|
+ const index = createdProvinces.indexOf(originalName);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ createdProvinces[index] = newName;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.describe('区域状态切换', () => {
|
|
|
|
|
+ test('应该成功禁用已启用的区域', async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ console.debug(`创建省份: ${provinceName}`);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ // 刷新页面以确保获取最新状态
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 等待新创建的区域在树中可见
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+ const exists = await regionManagementPage.regionExists(provinceName);
|
|
|
|
|
+ console.debug(`区域 "${provinceName}" 在树中存在: ${exists}`);
|
|
|
|
|
+ if (!exists) {
|
|
|
|
|
+ // 尝试滚动页面查找
|
|
|
|
|
+ await page.mouse.wheel(0, 500);
|
|
|
|
|
+ await page.waitForTimeout(500);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取初始状态
|
|
|
|
|
+ const initialStatus = await regionManagementPage.getRegionStatus(provinceName);
|
|
|
|
|
+ console.debug(`区域 "${provinceName}" 初始状态: ${initialStatus}`);
|
|
|
|
|
+ expect(initialStatus).toBe('启用');
|
|
|
|
|
+
|
|
|
|
|
+ // 禁用区域
|
|
|
|
|
+ const success = await regionManagementPage.toggleRegionStatus(provinceName);
|
|
|
|
|
+ console.debug(`禁用操作返回: ${success}`);
|
|
|
|
|
+ expect(success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 再次刷新页面以确保看到更新后的状态
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 等待新创建的区域在树中可见
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证状态已更新
|
|
|
|
|
+ const newStatus = await regionManagementPage.getRegionStatus(provinceName);
|
|
|
|
|
+ console.debug(`区域 "${provinceName}" 新状态: ${newStatus}`);
|
|
|
|
|
+ expect(newStatus).toBe('禁用');
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('应该成功启用已禁用的区域', async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ // 先禁用
|
|
|
|
|
+ await regionManagementPage.toggleRegionStatus(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证已禁用
|
|
|
|
|
+ const disabledStatus = await regionManagementPage.getRegionStatus(provinceName);
|
|
|
|
|
+ expect(disabledStatus).toBe('禁用');
|
|
|
|
|
+
|
|
|
|
|
+ // 再启用
|
|
|
|
|
+ const success = await regionManagementPage.toggleRegionStatus(provinceName);
|
|
|
|
|
+ expect(success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证状态已恢复为启用
|
|
|
|
|
+ const status = await regionManagementPage.getRegionStatus(provinceName);
|
|
|
|
|
+ expect(status).toBe('启用');
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('取消状态切换应保持原状态', async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ const initialStatus = await regionManagementPage.getRegionStatus(provinceName);
|
|
|
|
|
+ expect(initialStatus).toBe('启用');
|
|
|
|
|
+
|
|
|
|
|
+ // 打开状态切换对话框但取消
|
|
|
|
|
+ await regionManagementPage.openToggleStatusDialog(provinceName);
|
|
|
|
|
+ await regionManagementPage.cancelToggleStatus();
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证状态未改变
|
|
|
|
|
+ const currentStatus = await regionManagementPage.getRegionStatus(provinceName);
|
|
|
|
|
+ expect(currentStatus).toBe(initialStatus);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.describe.skip('编辑子区域 - TODO: 需要修复 createChildRegion 功能', () => {
|
|
|
|
|
+ test('应该成功编辑市级区域名称', async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ const originalCityName = generateUniqueRegionName('测试市');
|
|
|
|
|
+
|
|
|
|
|
+ // 创建省和市
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 创建市后,先展开省节点验证市已创建
|
|
|
|
|
+ const cityResult = await regionManagementPage.createChildRegion(provinceName, '市', {
|
|
|
|
|
+ name: originalCityName,
|
|
|
|
|
+ code: generateUniqueRegionCode('CITY'),
|
|
|
|
|
+ level: 2,
|
|
|
|
|
+ });
|
|
|
|
|
+ expect(cityResult.success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 直接展开新创建的省节点(滚动到可见区域)
|
|
|
|
|
+ await regionManagementPage.expandNode(provinceName);
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证市级区域可见
|
|
|
|
|
+ const cityVisible = await regionManagementPage.regionExists(originalCityName);
|
|
|
|
|
+ console.debug(`市级区域 "${originalCityName}" 可见: ${cityVisible}`);
|
|
|
|
|
+ expect(cityVisible).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑城市名称
|
|
|
|
|
+ const newCityName = generateUniqueRegionName('编辑后的市');
|
|
|
|
|
+ const result = await regionManagementPage.editRegion(originalCityName, {
|
|
|
|
|
+ name: newCityName,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ expect(result.success).toBe(true);
|
|
|
|
|
+ expect(result.hasError).toBe(false);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('应该成功编辑区级区域状态', async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ const cityName = generateUniqueRegionName('测试市');
|
|
|
|
|
+ const districtName = generateUniqueRegionName('测试区');
|
|
|
|
|
+
|
|
|
|
|
+ // 创建省市区三级结构
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ const cityResult = await regionManagementPage.createChildRegion(provinceName, '市', {
|
|
|
|
|
+ name: cityName,
|
|
|
|
|
+ code: generateUniqueRegionCode('CITY'),
|
|
|
|
|
+ level: 2,
|
|
|
|
|
+ });
|
|
|
|
|
+ expect(cityResult.success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ const districtResult = await regionManagementPage.createChildRegion(provinceName, '市', {
|
|
|
|
|
+ name: districtName,
|
|
|
|
|
+ code: generateUniqueRegionCode('DISTRICT'),
|
|
|
|
|
+ level: 3,
|
|
|
|
|
+ });
|
|
|
|
|
+ expect(districtResult.success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 展开省节点
|
|
|
|
|
+ await regionManagementPage.expandNode(provinceName);
|
|
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
|
|
+
|
|
|
|
|
+ // 切换区的状态
|
|
|
|
|
+ const success = await regionManagementPage.toggleRegionStatus(districtName);
|
|
|
|
|
+ expect(success).toBe(true);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.describe('表单验证', () => {
|
|
|
|
|
+ test('清空名称时应显示错误提示', async ({ regionManagementPage }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 打开编辑对话框并清空名称
|
|
|
|
|
+ await regionManagementPage.openEditDialog(provinceName);
|
|
|
|
|
+ await regionManagementPage.page.getByLabel('区域名称').fill('');
|
|
|
|
|
+
|
|
|
|
|
+ // 提交表单
|
|
|
|
|
+ const submitButton = regionManagementPage.page.getByRole('button', { name: '更新' });
|
|
|
|
|
+ await submitButton.click();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证错误提示 - 可能是内联错误或 toast
|
|
|
|
|
+ await regionManagementPage.page.waitForTimeout(500);
|
|
|
|
|
+
|
|
|
|
|
+ // 检查内联错误
|
|
|
|
|
+ const nameError = regionManagementPage.page.getByText('区域名称不能为空');
|
|
|
|
|
+ const hasInlineError = await nameError.count() > 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 检查 toast 错误
|
|
|
|
|
+ const errorToast = regionManagementPage.page.locator('[data-sonner-toast][data-type="error"]');
|
|
|
|
|
+ const hasToastError = await errorToast.count() > 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 至少应该有一种错误提示
|
|
|
|
|
+ expect(hasInlineError || hasToastError).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 取消对话框
|
|
|
|
|
+ await regionManagementPage.cancelDialog();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('应该支持取消编辑操作', async ({ regionManagementPage }) => {
|
|
|
|
|
+ const provinceName = generateUniqueRegionName('测试省');
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: provinceName,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 打开编辑对话框
|
|
|
|
|
+ await regionManagementPage.openEditDialog(provinceName);
|
|
|
|
|
+
|
|
|
|
|
+ // 修改名称
|
|
|
|
|
+ const newName = generateUniqueRegionName('修改后的省');
|
|
|
|
|
+ await regionManagementPage.page.getByLabel('区域名称').fill(newName);
|
|
|
|
|
+
|
|
|
|
|
+ // 点击取消按钮
|
|
|
|
|
+ await regionManagementPage.cancelDialog();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证对话框已关闭
|
|
|
|
|
+ const dialog = regionManagementPage.page.locator('[role="dialog"]');
|
|
|
|
|
+ await expect(dialog).not.toBeVisible();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证数据未修改 - 原名称仍存在
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+ const originalExists = await regionManagementPage.regionExists(provinceName);
|
|
|
|
|
+ expect(originalExists).toBe(true);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test.describe('连续编辑操作', () => {
|
|
|
|
|
+ test('应该能连续编辑多个区域', async ({ regionManagementPage, page }) => {
|
|
|
|
|
+ // 创建多个省份
|
|
|
|
|
+ const province1 = generateUniqueRegionName('测试省1');
|
|
|
|
|
+ const province2 = generateUniqueRegionName('测试省2');
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: province1,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV1'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(province1);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ await regionManagementPage.createProvince({
|
|
|
|
|
+ name: province2,
|
|
|
|
|
+ code: generateUniqueRegionCode('PROV2'),
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ });
|
|
|
|
|
+ createdProvinces.push(province2);
|
|
|
|
|
+
|
|
|
|
|
+ await page.goto('/admin/areas');
|
|
|
|
|
+ await regionManagementPage.waitForTreeLoaded();
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑第一个省份
|
|
|
|
|
+ const newProvince1Name = generateUniqueRegionName('编辑后的省1');
|
|
|
|
|
+ const result1 = await regionManagementPage.editRegion(province1, { name: newProvince1Name });
|
|
|
|
|
+ expect(result1.success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新清理列表
|
|
|
|
|
+ const index1 = createdProvinces.indexOf(province1);
|
|
|
|
|
+ if (index1 > -1) {
|
|
|
|
|
+ createdProvinces[index1] = newProvince1Name;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑第二个省份
|
|
|
|
|
+ const newProvince2Name = generateUniqueRegionName('编辑后的省2');
|
|
|
|
|
+ const result2 = await regionManagementPage.editRegion(province2, { name: newProvince2Name });
|
|
|
|
|
+ expect(result2.success).toBe(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新清理列表
|
|
|
|
|
+ const index2 = createdProvinces.indexOf(province2);
|
|
|
|
|
+ if (index2 > -1) {
|
|
|
|
|
+ createdProvinces[index2] = newProvince2Name;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+});
|