refactor(test): 重构预约测试逻辑

- 优化了预约详情页面的打开和关闭方法
- 改进了预约操作的处理流程
- 添加了 PopupContent 组件以简化弹窗操作
-调整了测试用例的结构,提高了可读性和可维护性
This commit is contained in:
LingandRX 2025-01-02 22:24:12 +08:00
parent 345e68a1b4
commit e2647263a3
5 changed files with 83 additions and 101 deletions

View File

@ -1,8 +1,9 @@
import { test as base } from '@playwright/test';
import { NumberInput } from '@/pages/components';
import { NumberInput, PopupContent } from '@/pages/components';
type MyFixture = {
numberInput: NumberInput;
popupContent: PopupContent;
};
export const test = base.extend<MyFixture>({
@ -10,4 +11,9 @@ export const test = base.extend<MyFixture>({
const numberInput = new NumberInput(page);
await use(numberInput);
},
popupContent: async ({ page }, use) => {
const popupContent = new PopupContent(page);
await use(popupContent);
},
});

View File

@ -205,14 +205,14 @@ export class AppointmentPage {
*/
openAppointmentDetail = async (text: string) => {
await this.page.locator('.a_userInfo', { hasText: text }).first().locator('.user_name_info').click();
await this.page.getByText('预约详情').waitFor();
await this.page.locator('div.m_sliding_menu div.title').waitFor();
};
/**
*
*/
closeAppointmentDetail = async () => {
await this.page.locator('.close > svg > use').first().click();
await this.page.locator('div.m_sliding_menu i.close.anticon').click();
};
/**
@ -292,12 +292,12 @@ export class AppointmentPage {
* - CANCEL_OCCUPY
*/
operationAppointment = async (operation: AppointmentOperation) => {
// 预约操作窗口
const $popup = this.page.locator('.popup_content .content');
// 操作按钮
const $operation = this.page.locator('div.popup_content div.content').getByText(operation);
// 点击操作
await expect(async () => {
await $popup.getByText(operation).click();
await expect($popup.getByText(operation)).not.toBeInViewport({ timeout: 3000 });
await $operation.click();
await expect($operation).not.toBeInViewport({ timeout: 1500 });
}).toPass();
};
}

View File

@ -1,3 +1,4 @@
import { NumberInput } from './numberInput';
import { NumberInput } from '@/pages/components/numberInput';
import { PopupContent } from '@/pages/components/popupContent';
export { NumberInput };
export { NumberInput, PopupContent };

View File

@ -0,0 +1,23 @@
import { Locator, Page } from '@playwright/test';
export class PopupContent {
private readonly page: Page;
private readonly popupLocator: Locator;
private readonly confirmButtonLocator: Locator;
private readonly cancelButtonLocator: Locator;
async confirm(): Promise<void> {
await this.confirmButtonLocator.click();
}
async cancel(): Promise<void> {
await this.cancelButtonLocator.click();
}
constructor(page: Page) {
this.page = page;
this.popupLocator = this.page.locator('div.popup_content');
this.confirmButtonLocator = this.popupLocator.getByRole('button', { name: /确\s认/ });
this.cancelButtonLocator = this.popupLocator.getByRole('button', { name: /取\s消/ });
}
}

View File

@ -5,7 +5,14 @@ import { staffData } from '@/common/staff';
import { AppointmentOperation } from '@/pages/appointmentPage';
import { getNextAppointmentTime } from '@/utils/timeUtils';
test('使用预约单元格', async ({ page, homeNavigation, createCustomer, appointmentPage, customerPage }) => {
test('使用预约单元格', async ({
page,
homeNavigation,
createCustomer,
appointmentPage,
customerPage,
popupContent,
}) => {
const employee = staffData.firstStore.firstSector.employee_1;
const appointmentTime = getNextAppointmentTime();
const customer = createCustomer;
@ -19,7 +26,7 @@ test('使用预约单元格', async ({ page, homeNavigation, createCustomer, app
await homeNavigation.gotoModule('预约');
// 将时间盒子滚动到当前窗口可见
await page.locator('.timeLine_Start').scrollIntoViewIfNeeded();
await page.getByRole('button', { name: /设\s置/ }).waitFor();
await $time.scrollIntoViewIfNeeded();
// 打开未指定预约单元格
@ -29,10 +36,10 @@ test('使用预约单元格', async ({ page, homeNavigation, createCustomer, app
// 选择顾客A
await customerPage.searchCustomer(customer.phone);
await customerPage.selectSearchCustomer(customer.phone);
// 确认新建预约
await page.getByRole('button', { name: '确认新建' }).click();
// 判断新建预约成功
await expect($customerAppointment).toBeVisible();
await $customerAppointment.waitFor();
await appointmentPage.openAppointmentDetail(customer.phone);
await expect(page.getByText('未到店', { exact: true })).toBeVisible();
await appointmentPage.closeAppointmentDetail();
@ -42,23 +49,13 @@ test('使用预约单元格', async ({ page, homeNavigation, createCustomer, app
// 打开未指定预约单元格
await appointmentPage.openAppointmentDetail(customer.phone);
await page.getByRole('button', { name: '取消预约' }).click();
// 确认取消预约
await Promise.all([
page.getByRole('button', { name: /确\s认/ }).click(),
page.waitForResponse(response => response.url().includes('/reservation_num') && response.status() === 200),
]);
// 判断取消预约成功
await popupContent.confirm();
await expect($customerAppointment).not.toBeVisible();
});
await test.step('指定员工进行预约', async () => {
await $time.scrollIntoViewIfNeeded();
// 打开预约选择窗口
await expect(async () => {
await appointmentPage.openAppointmentCell(employee.name);
await expect(page.locator('.popup_content', { hasText: '选择操作' })).toBeVisible({ timeout: 2000 });
}).toPass();
// 新建预约
await appointmentPage.operationAppointment(AppointmentOperation.ADD_APPOINT);
@ -66,40 +63,36 @@ test('使用预约单元格', async ({ page, homeNavigation, createCustomer, app
await customerPage.selectSearchCustomer(customer.phone);
// 在预约窗口确认顾客信息
await expect(page.locator('.newAppointmentContent .content .phone')).toContainText(customer.phone);
await expect(
page.locator('.content .right .right_ul_li', {
hasText: employee.name,
}),
).toBeVisible();
await expect(page.locator('div.name_box div.phone')).toContainText(customer.phone);
await expect(page.locator('div.user_box')).toContainText(employee.name);
// 判断新建预约成功
await page.getByRole('button', { name: '确认新建' }).click();
await expect($customerAppointment).toBeVisible();
await appointmentPage.openAppointmentDetail(customer.phone);
await expect(page.getByText('未到店', { exact: true })).toBeVisible();
await appointmentPage.closeAppointmentDetail();
});
await test.step('取消预约', async () => {
await page.locator('.a_userInfo', { hasText: customer.username }).first().locator('.user_name_info').click();
await expect(page.locator('div.state')).toContainText('未到店');
await page.getByRole('button', { name: '取消预约' }).click();
await page.getByRole('button', { name: /确\s认/ }).click();
await popupContent.confirm();
await expect($customerAppointment).not.toBeVisible();
});
});
test('占用预约单元格', async ({ page, homeNavigation, createCustomer, appointmentPage, customerPage }) => {
test('占用预约单元格', async ({
page,
homeNavigation,
createCustomer,
appointmentPage,
customerPage,
popupContent,
}) => {
// 获取当前可预约时间
let appointmentTime = getNextAppointmentTime();
// 创建顾客
const customer = createCustomer;
// 员工王芳
const employee = staffData.firstStore.firstSector.employee_3;
// 占用单元格备注
const remark = '占用预约单元格' + faker.string.alpha(2);
// 当前可预约时间定位器
const $time = page.locator('.times_table td').filter({ hasText: appointmentTime });
// 员工定位器
@ -109,6 +102,7 @@ test('占用预约单元格', async ({ page, homeNavigation, createCustomer, app
.locator('.a_userInfo')
.filter({ hasText: customer.phone })
.filter({ hasText: customer.username });
const $$occupy = page.locator('.occupy');
await test.step('占用单元格', async () => {
// 进入预约模块
@ -116,52 +110,39 @@ test('占用预约单元格', async ({ page, homeNavigation, createCustomer, app
// 窗口滚动到员工、预约时间可见
await $time.scrollIntoViewIfNeeded();
await $employee.scrollIntoViewIfNeeded();
// 长按目标位置
await appointmentPage.openAppointmentCell(employee.name);
// 进行占用单元格
await Promise.all([
appointmentPage.operationAppointment(AppointmentOperation.ADD_OCCUPY),
page.waitForResponse(response => response.url().includes('/reservation') && response.status() === 200),
]);
await appointmentPage.operationAppointment(AppointmentOperation.ADD_OCCUPY);
// 占用成功
await expect(page.locator('.ant-message', { hasText: '占用成功' })).toBeVisible();
await expect(page.locator('div.ant-message', { hasText: '占用成功' })).toBeVisible();
await expect($$occupy.filter({ hasText: '占用' }).last()).toBeVisible();
});
await test.step('备注占用单元格', async () => {
// 特殊等待,页面内容已变化,但是去操作时,变为上一个状态,只能等待再去操作
await page.waitForTimeout(2000);
// 打开占用操作窗口
await page.locator('.a_userInfo .occupy', { hasText: '占用' }).last().click();
await $$occupy.filter({ hasText: '占用' }).last().click();
// 进入添加备注
await appointmentPage.operationAppointment(AppointmentOperation.ADD_REMARK);
// 进行添加备注,确认添加备注成功
await page.getByPlaceholder('请输入备注').fill(remark);
await Promise.all([
page
.locator('.popup_content')
.getByRole('button', { name: /确\s认/ })
.click(),
page.waitForResponse(response => response.url().includes('/reservation_num') && response.status() === 200),
]);
await popupContent.confirm();
// 判断备注后的单元格存在
await expect(page.locator('.a_userInfo .occupy', { hasText: remark })).toBeVisible();
await expect($$occupy.filter({ hasText: remark })).toBeVisible();
});
await test.step('取消占用单元格', async () => {
// 打开占用操作窗口
await page.locator('.a_userInfo .occupy', { hasText: remark }).click();
await $$occupy.filter({ hasText: remark }).click();
// 取消占用
await appointmentPage.operationAppointment(AppointmentOperation.CANCEL_OCCUPY);
await expect(async () => {
const confirm = page.locator('.popup_content').getByRole('button', { name: /确\s认/ });
await confirm.click();
await expect(confirm).not.toBeVisible();
}).toPass();
// 判断取消占用成功
await expect(page.locator('.ant-message', { hasText: '取消占用成功' })).toBeVisible();
await expect(page.locator('.a_userInfo .occupy', { hasText: remark })).not.toBeVisible();
await expect(async () => {
await popupContent.confirm();
await expect($$occupy.filter({ hasText: remark })).not.toBeVisible({ timeout: 1500 });
}).toPass();
});
await test.step('取消占用后,能够进行预约', async () => {
@ -180,18 +161,16 @@ test('占用预约单元格', async ({ page, homeNavigation, createCustomer, app
await customerPage.searchCustomer(customer.phone);
await customerPage.selectSearchCustomer(customer.phone);
// 确认进入新建预约页面
await expect(
page.locator('.content .right .right_ul_li', {
hasText: employee.name,
}),
).toBeVisible();
await expect(page.locator('.newAppointmentContent .header_title')).toContainText('新建预约');
await expect(page.locator('.newAppointmentContent .content .phone')).toContainText(customer.phone);
// 在预约窗口确认顾客信息
await expect(page.locator('div.name_box div.phone')).toContainText(customer.phone);
await expect(page.locator('div.user_box')).toContainText(employee.name);
// 新建后,确认新建成功
await page.getByRole('button', { name: '确认新建' }).click();
await expect($customerAppointment).toBeVisible();
await appointmentPage.openAppointmentDetail(customer.phone);
await page.getByRole('button', { name: '取消预约' }).click();
await popupContent.confirm();
await expect($customerAppointment).not.toBeVisible();
});
});
@ -302,30 +281,3 @@ test.describe('预约状态', () => {
});
});
});
test('测试预约操作', async ({ page, homeNavigation }) => {
await homeNavigation.gotoModule('预约');
await page.getByRole('button', { name: /设\s置/ }).waitFor();
await page.waitForTimeout(3000);
// await page.mouse.wheel(0, 500);
const $table = page.locator('.content_table');
const tableBox = await $table.boundingBox();
if (tableBox) {
const startX = tableBox.x + tableBox.width / 2; // 元素中心点 X 坐标
const startY = tableBox.y + tableBox.height / 2; // 元素中心点 Y 坐标
// 移动鼠标到起始位置
await page.mouse.move(startX, startY);
// 按下鼠标左键
await page.mouse.down();
// 向左拖动 (X 坐标减小Y 坐标保持不变)
await page.mouse.move(startX - 400, startY, { steps: 10 });
// 松开鼠标左键
await page.mouse.up();
}
});