// @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(); } });