331 lines
15 KiB
TypeScript
331 lines
15 KiB
TypeScript
// @ts-check
|
||
import { faker } from '@faker-js/faker/locale/zh_CN';
|
||
import { test, expect } from '@/fixtures/boss_common.js';
|
||
import { staffData } from '@/common/staff';
|
||
import { AppointmentOperation } from '@/pages/appointmentPage';
|
||
import { getNextAppointmentTime } from '@/utils/timeUtils';
|
||
|
||
test('使用预约单元格', async ({ page, homeNavigation, createCustomer, appointmentPage, customerPage }) => {
|
||
const employee = staffData.firstStore.firstSector.employee_1;
|
||
const appointmentTime = getNextAppointmentTime();
|
||
const customer = createCustomer;
|
||
|
||
/** 当前可预约时间定位器 */
|
||
const $time = page.locator('.times_table td').filter({ hasText: appointmentTime });
|
||
/** 顾客预约定位器 */
|
||
const $customerAppointment = page.locator('.a_userInfo').filter({ hasText: customer.phone }).filter({ hasText: customer.username });
|
||
|
||
await test.step('进行未指定预约', async () => {
|
||
await homeNavigation.gotoModule('预约');
|
||
|
||
// 将时间盒子滚动到当前窗口可见
|
||
await page.locator('.timeLine_Start').scrollIntoViewIfNeeded();
|
||
await $time.scrollIntoViewIfNeeded();
|
||
|
||
// 打开未指定预约单元格
|
||
await appointmentPage.openAppointmentCell('未指定');
|
||
// 新建预约
|
||
await appointmentPage.operationAppointment(AppointmentOperation.ADD_APPOINT);
|
||
// 选择顾客A
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.phone);
|
||
// 确认新建预约
|
||
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 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 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);
|
||
await customerPage.searchCustomer(customer.phone);
|
||
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 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 page.getByRole('button', { name: '取消预约' }).click();
|
||
await page.getByRole('button', { name: /确\s认/ }).click();
|
||
await expect($customerAppointment).not.toBeVisible();
|
||
});
|
||
});
|
||
|
||
test('占用预约单元格', async ({ page, homeNavigation, createCustomer, appointmentPage, customerPage }) => {
|
||
// 获取当前可预约时间
|
||
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 });
|
||
// 员工定位器
|
||
const $employee = page.locator('.room_table .tr .name_th').filter({ hasText: employee.name });
|
||
// 顾客预约定位器
|
||
const $customerAppointment = page
|
||
.locator('.a_userInfo')
|
||
.filter({ hasText: customer.phone })
|
||
.filter({ hasText: customer.username });
|
||
|
||
await test.step('占用单元格', async () => {
|
||
// 进入预约模块
|
||
await homeNavigation.gotoModule('预约');
|
||
// 窗口滚动到员工、预约时间可见
|
||
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 expect(page.locator('.ant-message', { hasText: '占用成功' })).toBeVisible();
|
||
});
|
||
|
||
await test.step('备注占用单元格', async () => {
|
||
// 特殊等待,页面内容已变化,但是去操作时,变为上一个状态,只能等待再去操作
|
||
await page.waitForTimeout(2000);
|
||
// 打开占用操作窗口
|
||
await page.locator('.a_userInfo .occupy', { 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 expect(page.locator('.a_userInfo .occupy', { hasText: remark })).toBeVisible();
|
||
});
|
||
|
||
await test.step('取消占用单元格', async () => {
|
||
// 打开占用操作窗口
|
||
await page.locator('.a_userInfo .occupy', { 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 test.step('取消占用后,能够进行预约', async () => {
|
||
// 重新选择员工王芳,进行预约单元格
|
||
await $employee.scrollIntoViewIfNeeded();
|
||
await $time.scrollIntoViewIfNeeded();
|
||
|
||
// 打开预约单元格
|
||
await appointmentPage.openAppointmentCell(employee.name);
|
||
|
||
// 选择顾客去创建预约
|
||
await expect(async () => {
|
||
await appointmentPage.operationAppointment(AppointmentOperation.ADD_APPOINT);
|
||
await page.getByText('选择会员').waitFor({ timeout: 2000 });
|
||
}).toPass();
|
||
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 page.getByRole('button', { name: '确认新建' }).click();
|
||
await expect($customerAppointment).toBeVisible();
|
||
});
|
||
});
|
||
|
||
test.describe('预约状态', () => {
|
||
test('预约-挂单-结算', async ({ page, homeNavigation, createCustomer, appointmentPage, customerPage, billSet }) => {
|
||
const employee = staffData.firstStore.firstSector.employee_4;
|
||
const project = { no: '100018', name: '苹果精萃护理', shortName: '精萃护理', price: 980 };
|
||
const appointmentTime = getNextAppointmentTime();
|
||
const customer = createCustomer;
|
||
|
||
// 当前可预约时间定位器
|
||
const $time = page.locator('.times_table td').filter({ hasText: appointmentTime });
|
||
// 员工定位器
|
||
const $employee = page.locator('.room_table .tr .name_th').filter({ hasText: employee.name });
|
||
|
||
// 获取设置的预约状态
|
||
let appointmentStatusSetting;
|
||
await test.step('获取预约状态', async () => {
|
||
await homeNavigation.gotoModule('预约');
|
||
appointmentStatusSetting = await appointmentPage.getAppointmentStatusSetting();
|
||
});
|
||
|
||
await test.step('进行创建预约', async () => {
|
||
await $time.scrollIntoViewIfNeeded();
|
||
await $employee.scrollIntoViewIfNeeded();
|
||
// 打开预约单元格,进行预约
|
||
await appointmentPage.openAppointmentCell(employee.name, undefined, 10);
|
||
await appointmentPage.operationAppointment(AppointmentOperation.ADD_APPOINT);
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.phone);
|
||
await expect.soft(page.locator('.newAppointmentContent .header_title')).toContainText('新建预约');
|
||
await expect(page.locator('.newAppointmentContent .content .phone')).toContainText(customer.phone);
|
||
await page.getByRole('button', { name: '确认新建' }).click();
|
||
await expect(page.locator('.ant-message', { hasText: '预约成功' })).toBeVisible();
|
||
});
|
||
|
||
await test.step('判断预约,状态为未到店', async () => {
|
||
const { customerColor, customerStatus } = await appointmentPage.getCustomerAppointmentStatus(customer);
|
||
// 进入未到店状态
|
||
expect.soft(customerColor).toEqual(appointmentStatusSetting.NORMAL.color);
|
||
expect(customerStatus).toEqual(appointmentStatusSetting.NORMAL.name);
|
||
});
|
||
|
||
await test.step('进行挂单,状态为已开单', async () => {
|
||
await page
|
||
.locator('.a_userInfo', { hasText: customer.username })
|
||
.first()
|
||
.locator('.user_name_info')
|
||
.click();
|
||
// 预约进行挂单
|
||
await page.getByRole('button', { name: '到店开单' }).click();
|
||
await page
|
||
.locator('.project_list')
|
||
.filter({ hasText: project.name })
|
||
.filter({ hasText: project.no })
|
||
.click();
|
||
await page.locator('.hold_bill', { hasText: '挂单' }).click();
|
||
await expect(page.locator('.ant-message', { hasText: '挂单成功' })).toBeVisible();
|
||
|
||
await homeNavigation.gotoModule('预约');
|
||
|
||
// 获取当前预约的状态
|
||
const { customerColor, customerStatus } = await appointmentPage.getCustomerAppointmentStatus(customer);
|
||
// 进入未到店状态
|
||
expect.soft(customerColor).toEqual(appointmentStatusSetting.BILL.color);
|
||
expect(customerStatus).toEqual(appointmentStatusSetting.BILL.name);
|
||
});
|
||
|
||
await test.step('进行结算,状态为已结算', async () => {
|
||
await page
|
||
.locator('.a_userInfo', { hasText: customer.username })
|
||
.first()
|
||
.locator('.user_name_info')
|
||
.click();
|
||
await page.getByRole('button', { name: /取\s单/ }).click();
|
||
await page.locator('.pay_btn', { hasText: /结\s算/ }).click();
|
||
// 取消推送消费提醒和结算签字
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click();
|
||
// 结算
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS';
|
||
}),
|
||
page.getByRole('button', { name: /结\s算/ }).click(),
|
||
]);
|
||
const responseBody = await response.json();
|
||
const billNo = responseBody?.content?.billNo;
|
||
expect(billNo).not.toBeNull();
|
||
billSet.add(billNo);
|
||
|
||
// 处理结算后的弹窗
|
||
await page.addLocatorHandler(page.getByRole('button', { name: '我知道了' }), async () => {
|
||
await page.getByRole('button', { name: '我知道了' }).click();
|
||
await expect(page.getByRole('button', { name: '我知道了' })).not.toBeVisible();
|
||
await page.reload();
|
||
await homeNavigation.gotoModule('预约');
|
||
});
|
||
|
||
// 进入预约模块
|
||
await homeNavigation.gotoModule('预约');
|
||
// 获取当前创建预约的状态
|
||
const { customerColor, customerStatus } = await appointmentPage.getCustomerAppointmentStatus(customer);
|
||
// 进入未到店状态
|
||
expect.soft(customerColor).toEqual(appointmentStatusSetting.SETTLED.color);
|
||
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();
|
||
}
|
||
|
||
}); |