refactor(test): 重构预约测试逻辑
- 优化了预约详情页面的打开和关闭方法 - 改进了预约操作的处理流程 - 添加了 PopupContent 组件以简化弹窗操作 -调整了测试用例的结构,提高了可读性和可维护性
This commit is contained in:
parent
345e68a1b4
commit
e2647263a3
8
tests/fixtures/componentsFixture.ts
vendored
8
tests/fixtures/componentsFixture.ts
vendored
@ -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);
|
||||
},
|
||||
});
|
||||
|
||||
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
@ -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 };
|
||||
|
||||
23
tests/pages/components/popupContent.ts
Normal file
23
tests/pages/components/popupContent.ts
Normal 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消/ });
|
||||
}
|
||||
}
|
||||
@ -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.openAppointmentCell(employee.name);
|
||||
|
||||
// 新建预约
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
@ -301,31 +280,4 @@ test.describe('预约状态', () => {
|
||||
expect(customerStatus).toEqual(appointmentStatusSetting.SETTLED.name);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user