|
|
@@ -13,50 +13,6 @@
|
|
|
import { test, expect, Page } from '../../utils/test-setup';
|
|
|
import { ORDER_STATUS, type OrderStatus, ORDER_STATUS_LABELS } from '../../pages/admin/order-management.page';
|
|
|
|
|
|
-/**
|
|
|
- * 辅助函数:获取订单列表中第一个订单的名称
|
|
|
- *
|
|
|
- * @param page - Playwright Page 对象
|
|
|
- * @returns 第一个订单的名称,如果没有则返回 null
|
|
|
- */
|
|
|
-async function getFirstOrderName(page: Page): Promise<string | null> {
|
|
|
- const table = page.locator('table tbody tr');
|
|
|
-
|
|
|
- // 等待表格数据加载完成(跳过"加载中"等占位符文本)
|
|
|
- await page.waitForTimeout(1000);
|
|
|
-
|
|
|
- const count = await table.count();
|
|
|
-
|
|
|
- if (count === 0) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- // 需要跳过的占位符文本列表
|
|
|
- const placeholderTexts = [
|
|
|
- '加载中...',
|
|
|
- '暂无数据',
|
|
|
- '暂无订单数据',
|
|
|
- '无数据',
|
|
|
- '没有数据'
|
|
|
- ];
|
|
|
-
|
|
|
- // 查找第一个有效的订单行(排除占位符)
|
|
|
- for (let i = 0; i < count; i++) {
|
|
|
- const row = table.nth(i);
|
|
|
- const nameCell = row.locator('td').first();
|
|
|
- const name = await nameCell.textContent();
|
|
|
- const trimmedName = name?.trim() || '';
|
|
|
-
|
|
|
- // 跳过占位符文本
|
|
|
- const isPlaceholder = placeholderTexts.some(placeholder => trimmedName.includes(placeholder));
|
|
|
-
|
|
|
- if (trimmedName && !isPlaceholder && !trimmedName.includes('加载')) {
|
|
|
- return trimmedName;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
-}
|
|
|
|
|
|
/**
|
|
|
* 辅助函数:在创建订单对话框中选择残疾人
|
|
|
@@ -94,7 +50,9 @@ async function selectDisabledPersonForOrder(page: Page): Promise<boolean> {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- await page.waitForTimeout(500);
|
|
|
+ // 等待对话框关闭
|
|
|
+ await page.waitForSelector('[role="dialog"]', { state: 'hidden', timeout: 3000 })
|
|
|
+ .catch(() => console.debug('对话框已关闭或不存在'));
|
|
|
return hasData;
|
|
|
}
|
|
|
|
|
|
@@ -136,10 +94,12 @@ async function createTestOrder(page: Page, orderName: string, status?: OrderStat
|
|
|
console.debug('networkidle 超时,继续检查 Toast 消息');
|
|
|
}
|
|
|
|
|
|
- await page.waitForTimeout(2000);
|
|
|
-
|
|
|
- // 检查成功消息
|
|
|
+ // 等待 Toast 消息出现(成功或错误)
|
|
|
const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ await successToast.waitFor({ state: 'visible', timeout: 3000 })
|
|
|
+ .catch(() => console.debug('未检测到成功 Toast,继续检查'));
|
|
|
+
|
|
|
+ // 检查是否有成功消息
|
|
|
const hasSuccess = await successToast.count() > 0;
|
|
|
|
|
|
// 等待对话框关闭
|
|
|
@@ -206,8 +166,8 @@ test.describe('订单状态流转测试', () => {
|
|
|
const message = await successToast.textContent();
|
|
|
expect(message).toBeDefined();
|
|
|
expect(message?.length).toBeGreaterThan(0);
|
|
|
- // 验证消息包含激活相关的关键词
|
|
|
- expect(message).toMatch(/激活|成功|已激活/);
|
|
|
+ // 验证消息包含激活相关的关键词(更精确的正则)
|
|
|
+ expect(message).toMatch(/激活.*成功|已激活/);
|
|
|
});
|
|
|
|
|
|
test('激活确认对话框应该正确显示', async ({ orderManagementPage, page }) => {
|
|
|
@@ -293,8 +253,8 @@ test.describe('订单状态流转测试', () => {
|
|
|
const message = await successToast.textContent();
|
|
|
expect(message).toBeDefined();
|
|
|
expect(message?.length).toBeGreaterThan(0);
|
|
|
- // 验证消息包含关闭相关的关键词
|
|
|
- expect(message).toMatch(/关闭|完成|成功|已关闭|已完成/);
|
|
|
+ // 验证消息包含关闭相关的关键词(更精确的正则)
|
|
|
+ expect(message).toMatch(/关闭.*成功|已完成/);
|
|
|
});
|
|
|
|
|
|
test('关闭确认对话框应该正确显示', async ({ orderManagementPage, page }) => {
|
|
|
@@ -320,117 +280,128 @@ test.describe('订单状态流转测试', () => {
|
|
|
});
|
|
|
|
|
|
test.describe('状态限制验证', () => {
|
|
|
- let testOrderName: string;
|
|
|
- let currentStatus: OrderStatus;
|
|
|
let shouldSkipTests = false;
|
|
|
|
|
|
- test.beforeEach(async ({ adminLoginPage, orderManagementPage, testUsers }) => {
|
|
|
- // 以管理员身份登录后台
|
|
|
- await adminLoginPage.goto();
|
|
|
- await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
|
|
|
- await adminLoginPage.expectLoginSuccess();
|
|
|
- await orderManagementPage.goto();
|
|
|
+ // 创建测试订单的辅助函数
|
|
|
+ async function setupTestOrder(page: Page, orderName: string): Promise<boolean> {
|
|
|
+ const created = await createTestOrder(page, orderName);
|
|
|
+ if (!created) {
|
|
|
+ shouldSkipTests = true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- // 尝试使用现有订单
|
|
|
- const existingOrder = await getFirstOrderName(orderManagementPage.page);
|
|
|
-
|
|
|
- if (existingOrder) {
|
|
|
- testOrderName = existingOrder;
|
|
|
- currentStatus = (await orderManagementPage.getOrderStatus(testOrderName)) || ORDER_STATUS.DRAFT;
|
|
|
- console.debug(`✓ 使用现有订单: ${testOrderName}, 状态: ${ORDER_STATUS_LABELS[currentStatus]}`);
|
|
|
- } else {
|
|
|
- // 如果没有现有订单,创建一个
|
|
|
- const timestamp = Date.now();
|
|
|
- testOrderName = `状态限制测试_${timestamp}`;
|
|
|
-
|
|
|
- const created = await createTestOrder(orderManagementPage.page, testOrderName);
|
|
|
-
|
|
|
- if (!created) {
|
|
|
- shouldSkipTests = true;
|
|
|
- test.skip(true, '没有残疾人数据,无法创建测试订单');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 验证订单出现在列表中
|
|
|
- await expect(async () => {
|
|
|
- const exists = await orderManagementPage.orderExists(testOrderName);
|
|
|
- expect(exists).toBe(true);
|
|
|
- }).toPass({ timeout: 5000 });
|
|
|
-
|
|
|
- currentStatus = ORDER_STATUS.DRAFT;
|
|
|
+ // 等待订单出现在列表中(使用条件等待而非硬编码超时)
|
|
|
+ try {
|
|
|
+ await page.waitForFunction(
|
|
|
+ (name) => {
|
|
|
+ const table = document.querySelector('table tbody tr');
|
|
|
+ if (!table) return false;
|
|
|
+ const rows = Array.from(document.querySelectorAll('table tbody tr'));
|
|
|
+ return rows.some(row => row.textContent?.includes(name));
|
|
|
+ },
|
|
|
+ orderName,
|
|
|
+ { timeout: 5000 }
|
|
|
+ );
|
|
|
+ } catch {
|
|
|
+ console.debug(`订单 ${orderName} 未在列表中找到`);
|
|
|
}
|
|
|
- });
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- test('不能激活非草稿状态的订单', async ({ orderManagementPage }) => {
|
|
|
+ test('不能激活非草稿状态的订单', async ({ adminLoginPage, orderManagementPage, testUsers }) => {
|
|
|
if (shouldSkipTests) {
|
|
|
test.skip(true, '测试数据不可用');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 如果当前是草稿状态,先激活为进行中
|
|
|
- if (currentStatus === ORDER_STATUS.DRAFT) {
|
|
|
- await orderManagementPage.activateOrder(testOrderName);
|
|
|
- currentStatus = ORDER_STATUS.IN_PROGRESS;
|
|
|
- console.debug(`✓ 已激活订单用于测试`);
|
|
|
+ await adminLoginPage.goto();
|
|
|
+ await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
|
|
|
+ await adminLoginPage.expectLoginSuccess();
|
|
|
+ await orderManagementPage.goto();
|
|
|
+
|
|
|
+ // 测试 IN_PROGRESS 状态不能激活
|
|
|
+ const inProgressOrderName = `限制测试_进行中_${Date.now()}`;
|
|
|
+ if (await setupTestOrder(orderManagementPage.page, inProgressOrderName)) {
|
|
|
+ await orderManagementPage.activateOrder(inProgressOrderName);
|
|
|
+
|
|
|
+ const isActivateEnabled = await orderManagementPage.checkActivateButtonEnabled(inProgressOrderName);
|
|
|
+ expect(isActivateEnabled).toBe(false);
|
|
|
+ console.debug(`✓ IN_PROGRESS 状态的订单不能激活`);
|
|
|
}
|
|
|
|
|
|
- // 对于非草稿状态的订单,激活按钮应该被禁用或不可见
|
|
|
- const isActivatedEnabled = await orderManagementPage.isActivateButtonEnabled(testOrderName);
|
|
|
+ // 测试 COMPLETED 状态不能激活
|
|
|
+ const completedOrderName = `限制测试_已完成_${Date.now()}`;
|
|
|
+ if (await setupTestOrder(orderManagementPage.page, completedOrderName)) {
|
|
|
+ await orderManagementPage.activateOrder(completedOrderName);
|
|
|
+ await orderManagementPage.closeOrder(completedOrderName);
|
|
|
|
|
|
- // 根据当前状态验证
|
|
|
- if (currentStatus === ORDER_STATUS.IN_PROGRESS ||
|
|
|
- currentStatus === ORDER_STATUS.COMPLETED ||
|
|
|
- currentStatus === ORDER_STATUS.CONFIRMED) {
|
|
|
- // 非草稿状态不应该能激活
|
|
|
- expect(isActivatedEnabled).toBe(false);
|
|
|
- console.debug(`✓ 状态 ${ORDER_STATUS_LABELS[currentStatus]} 的订单不能激活`);
|
|
|
+ const isActivateEnabled = await orderManagementPage.checkActivateButtonEnabled(completedOrderName);
|
|
|
+ expect(isActivateEnabled).toBe(false);
|
|
|
+ console.debug(`✓ COMPLETED 状态的订单不能激活`);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- test('不能关闭非进行中状态的订单', async ({ orderManagementPage }) => {
|
|
|
+ test('不能关闭非进行中状态的订单', async ({ adminLoginPage, orderManagementPage, testUsers }) => {
|
|
|
if (shouldSkipTests) {
|
|
|
test.skip(true, '测试数据不可用');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 对于非进行中状态的订单,关闭按钮应该被禁用或不可见
|
|
|
- const isCloseEnabled = await orderManagementPage.isCloseButtonEnabled(testOrderName);
|
|
|
+ await adminLoginPage.goto();
|
|
|
+ await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
|
|
|
+ await adminLoginPage.expectLoginSuccess();
|
|
|
+ await orderManagementPage.goto();
|
|
|
|
|
|
- // 根据当前状态验证
|
|
|
- if (currentStatus === ORDER_STATUS.DRAFT ||
|
|
|
- currentStatus === ORDER_STATUS.COMPLETED ||
|
|
|
- currentStatus === ORDER_STATUS.CONFIRMED) {
|
|
|
- // 非进行中状态不应该能关闭
|
|
|
+ // 测试 DRAFT 状态不能关闭
|
|
|
+ const draftOrderName = `限制测试_草稿_${Date.now()}`;
|
|
|
+ if (await setupTestOrder(orderManagementPage.page, draftOrderName)) {
|
|
|
+ const isCloseEnabled = await orderManagementPage.checkCloseButtonEnabled(draftOrderName);
|
|
|
expect(isCloseEnabled).toBe(false);
|
|
|
- console.debug(`✓ 状态 ${ORDER_STATUS_LABELS[currentStatus]} 的订单不能关闭`);
|
|
|
+ console.debug(`✓ DRAFT 状态的订单不能关闭`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试 COMPLETED 状态不能关闭
|
|
|
+ const completedOrderName = `限制测试_已完成_2_${Date.now()}`;
|
|
|
+ if (await setupTestOrder(orderManagementPage.page, completedOrderName)) {
|
|
|
+ await orderManagementPage.activateOrder(completedOrderName);
|
|
|
+ await orderManagementPage.closeOrder(completedOrderName);
|
|
|
+
|
|
|
+ const isCloseEnabled = await orderManagementPage.checkCloseButtonEnabled(completedOrderName);
|
|
|
+ expect(isCloseEnabled).toBe(false);
|
|
|
+ console.debug(`✓ COMPLETED 状态的订单不能关闭`);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- test('已完成状态不能再次操作', async ({ orderManagementPage }) => {
|
|
|
+ test('已完成状态不能再次操作', async ({ adminLoginPage, orderManagementPage, testUsers }) => {
|
|
|
if (shouldSkipTests) {
|
|
|
test.skip(true, '测试数据不可用');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 如果当前不是已完成状态,先操作到已完成
|
|
|
- if (currentStatus === ORDER_STATUS.DRAFT) {
|
|
|
- await orderManagementPage.activateOrder(testOrderName);
|
|
|
- await orderManagementPage.closeOrder(testOrderName);
|
|
|
- console.debug(`✓ 已将订单操作到已完成状态`);
|
|
|
- } else if (currentStatus === ORDER_STATUS.IN_PROGRESS) {
|
|
|
- await orderManagementPage.closeOrder(testOrderName);
|
|
|
- console.debug(`✓ 已关闭订单`);
|
|
|
+ await adminLoginPage.goto();
|
|
|
+ await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
|
|
|
+ await adminLoginPage.expectLoginSuccess();
|
|
|
+ await orderManagementPage.goto();
|
|
|
+
|
|
|
+ const orderName = `限制测试_已完成操作_${Date.now()}`;
|
|
|
+ if (!await setupTestOrder(orderManagementPage.page, orderName)) {
|
|
|
+ test.skip(true, '测试数据不可用');
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
+ // 操作到已完成状态
|
|
|
+ await orderManagementPage.activateOrder(orderName);
|
|
|
+ await orderManagementPage.closeOrder(orderName);
|
|
|
+
|
|
|
// 验证订单状态为已完成
|
|
|
await expect(async () => {
|
|
|
- const status = await orderManagementPage.getOrderStatus(testOrderName);
|
|
|
+ const status = await orderManagementPage.getOrderStatus(orderName);
|
|
|
expect(status).toBe(ORDER_STATUS.COMPLETED);
|
|
|
}).toPass({ timeout: 5000 });
|
|
|
|
|
|
// 已完成状态的订单不能激活也不能关闭
|
|
|
- const isActivateEnabled = await orderManagementPage.isActivateButtonEnabled(testOrderName);
|
|
|
- const isCloseEnabled = await orderManagementPage.isCloseButtonEnabled(testOrderName);
|
|
|
+ const isActivateEnabled = await orderManagementPage.checkActivateButtonEnabled(orderName);
|
|
|
+ const isCloseEnabled = await orderManagementPage.checkCloseButtonEnabled(orderName);
|
|
|
|
|
|
expect(isActivateEnabled).toBe(false);
|
|
|
expect(isCloseEnabled).toBe(false);
|