// @ts-check import { test, expect } from '@/fixtures/boss_common.js'; //使用公共套件 import { Feature, Employees, ProjectName, CardType, Coupons } from '@/common/userconfig'; import { decodeQR, KeepOnlyNumbers } from '@/utils/utils.js'; import { faker } from '@faker-js/faker/locale/zh_CN'; import path from 'path'; import { AppointmentOperation } from '@/pages/appointmentPage.js'; import { Customer } from '@/utils/customer'; import { getNextAppointmentTime } from '@/utils/timeUtils'; test.describe('挂单', () => { let c: Customer; let username: string; let phone: string; test.beforeEach('测试前新建会员', async ({ page, homeNavigation, createCustomer, customerPage }) => { // 创建顾客 c = createCustomer; // 获取姓名、手机号、档案号 username = c.username; phone = c.phone; // 开卡 await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); await page.getByRole('button', { name: /^开\s卡$/ }).click(); await page.getByText('原价卡项目10折,套餐10折,卖品10折卡金:¥5000').click(); await page.getByRole('button', { name: '去结算' }).click(); await page.getByText('现金').click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); await page.getByRole('button', { name: /^结\s算$/ }).click(); await page.getByRole('button', { name: /跳\s过/ }).click(); await page.locator('use').first().click(); }); test('查看员工名下挂单', async ({ page, customerPage }) => { let OrderLQ = 0; let OrderZP = 0; await test.step('记录员工原挂单数量', async () => { // 点击底部员工刘强 const EmployeeLQ = page.locator('.userpanel_item').getByText(Employees.FirstShop.Employee_8.name); if (await EmployeeLQ.isVisible()) { await page.locator('.userpanel_item').filter({ hasText: Employees.FirstShop.Employee_8.name }).click(); await page.locator('.item_box').first().waitFor(); OrderLQ = await page.locator('.item_box').count(); } else { OrderLQ = 0; } // 点击底部员工周萍 const EmployeeZP = page.locator('.userpanel_item', { hasText: Employees.FirstShop.Employee_9.name }); if (await EmployeeZP.isVisible()) { await page.locator('.userpanel_item').filter({ hasText: Employees.FirstShop.Employee_9.name }).click(); await page.locator('.item_box').first().waitFor(); OrderZP = await page.locator('.item_box').count(); } else { OrderZP = 0; } }); await test.step('刘强挂单1', async () => { //员工1开第1单 await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第一个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_1.name }).click(); // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:刘强 await page .locator('.counselor:nth-child(2)') .locator('.check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_8.name }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); }); await test.step('刘强挂单2', async () => { //员工1开第2单 await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第三个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_3.name }).click(); // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:刘强 await page .locator('.counselor:nth-child(2)') .locator('.check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_8.name }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); }); await test.step('刘强挂单3', async () => { //员工1开第3单 await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第二个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_2.name }).click(); // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:刘强 await page .locator('.counselor:nth-child(2)') .locator('.check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_8.name }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); }); await test.step('周萍挂单1', async () => { //员工2开第1单 await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第一个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_1.name }).click(); // 先点击选中第一个项目 // await page.locator('.buy_item').filter({hasText:ProjectName.Projects.Projects_1.name}).first().locator('.buy_staff').click() // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:周萍 await page .locator('.counselor:nth-child(2)') .locator('.check_row:nth-child(2) .check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_9.name }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); }); await test.step('周萍挂单2', async () => { //员工2开第2单 await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第二个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_2.name }).click(); // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:周萍 await page .locator('.counselor:nth-child(2)') .locator('.check_row:nth-child(2) .check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_9.name }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); // 等待挂单成功 await page.locator('.ant-message').waitFor(); // 判断挂单成功弹窗消失后再执行下一步 await expect(page.locator('.ant-message')).not.toBeVisible(); }); await test.step('最后校验挂单数量', async () => { // 点击底部员工刘强 await page.locator('.userpanel_item').filter({ hasText: Employees.FirstShop.Employee_8.name }).click(); await page.locator('.item_box').first().waitFor(); const order = await page.locator('.item_box').all(); expect(order.length).toBe(3 + OrderLQ); // 点击底部员工周萍 await page.locator('.userpanel_item').filter({ hasText: Employees.FirstShop.Employee_9.name }).click(); await page.locator('.item_box').first().waitFor(); const order1 = await page.locator('.item_box').all(); expect(order1.length).toBe(2 + OrderZP); }); }); test('使用挂单支付', async ({ page, customerPage }) => { await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第一个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_1.name }).click(); // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:吴浩 await page .locator('.counselor:nth-child(2)') .locator('.check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_10.name }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); // 稍等水单出现 await page.locator('.item_box').first().waitFor(); // // 点击底部员工吴浩 // 取单 await page.locator('.item_box', { hasText: username }).waitFor(); await page .locator('.item_box') .first() .getByRole('button', { name: /^取\s单$/ }) .click(); //结算 await page .locator('.pay_btn') .filter({ hasText: /^结\s算$/ }) .click(); //点击优惠券折扣 await page.getByText('优惠券抵扣').click(); //点击赠送优惠券 await page.getByText('赠送优惠券').click(); //点击定额10元券 await page .locator('.popup_content') .locator('.alloytouch-target') .filter({ hasText: Coupons.coupon.coupon_1.name }) .click(); //确认 await page .locator('.operation_btn') .first() .getByRole('button', { name: /^确\s定$/ }) .click(); //选择定额10元券 await page.getByLabel(Coupons.coupon.coupon_1.name).first().check(); //确认选择 await page.getByRole('button', { name: '确认选择' }).click(); //点击混合支付 await page.locator('.paytype').first().getByText('混合支付').click(); //点击现金 const rightPaymentInfoItem = page.locator('.right .paymentmain .paymentInfoItem'); await rightPaymentInfoItem.getByText('现金', { exact: true }).click(); //增加收款 await page.getByRole('button', { name: '增加收款' }).click(); //输入金额 await page.locator('.money_discount_input').fill('100'); //确认金额 await page.locator('.sure .tools_icon').click(); //点击欠款 await rightPaymentInfoItem.getByText('欠款', { exact: true }).click(); //增加收款 await page.getByRole('button', { name: '增加收款' }).click(); //输入金额 await page.locator('.money_discount_input').fill('90'); //确认金额 await page.locator('.sure .tools_icon').click(); //点击微信 await rightPaymentInfoItem.getByText('微信', { exact: true }).click(); //增加收款 await page.getByRole('button', { name: '增加收款' }).click(); //输入金额 await page.locator('.money_discount_input').fill('100'); //确认金额 await page.locator('.sure .tools_icon').click(); //取消推送消息提醒 await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); await page.getByRole('button', { name: /^结\s算$/ }).click(); await expect(page.locator('.ant-message', { hasText: '结算成功' })).toBeVisible(); }); test('已过期单据不能取单,只能删除', async ({ page }) => { await page.getByText('已过期 / 删除单据').click(); await page.getByText('警告:已过期服务无法取单结算,请至收银台处理').waitFor(); const $firstOrder = page.locator('.deleteList .m_sliding_menu .item_box').first(); await expect($firstOrder.getByRole('button', { name: /^取\s单$/ })).not.toBeVisible(); await $firstOrder.locator('.comment > div:nth-child(2) > .touchIcon').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill('测试备注'); await Promise.all([ page.getByRole('button', { name: /^保\s存$/ }).click(), expect(page.locator('.ant-message').filter({ hasText: '删除成功' })).toBeVisible(), ]); }); }); test.describe('挂单', () => { test('成功挂单', async ({ page, createCustomer, homeNavigation, customerPage }) => { const customer = createCustomer; const phone = customer.phone; const username = customer.username; // await page.pause(); await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择第一个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_1.name }).click(); // 选择第二个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_2.name }).click(); // 选择第三个项目 await page.locator('.project_list').filter({ hasText: ProjectName.Projects.Projects_3.name }).click(); // 选择套餐 await page.locator('.float_tab').getByText('套餐').click(); // 选择第一个套餐 await page.locator('.project_one > .item').filter({ hasText: ProjectName.SetMeal.SetMeal_1.name }).click(); // 选择第二个套餐 await page.locator('.project_one > .item').filter({ hasText: ProjectName.SetMeal.SetMeal_2.name }).click(); // 点击卖品 await page.locator('.float_tab').getByText('卖品').click(); // 点击第一个卖品 await page .locator('.number_service > .project_list') .filter({ hasText: ProjectName.Product.Product_1.name }) .click(); // 点击第二个卖品 await page .locator('.number_service > .project_list') .filter({ hasText: ProjectName.Product.Product_2.name }) .click(); // 先点击选中第一个项目 await page .locator('.buy_item') .filter({ hasText: ProjectName.Projects.Projects_1.name }) .first() .locator('.buy_staff') .click(); // 选择添加员工 await page.locator('button.staff_btn').click(); // 选择员工:陈刚 await page .locator('.counselor:nth-child(1)') .locator('.check_item:nth-child(1)') .filter({ hasText: Employees.FirstShop.Employee_6.name }) .click(); // 点击选择他店员工 await page.locator('.userAdd').filter({ hasText: '选择他店员工' }).click(); // 选择门店 await page.locator('.label_checkbox').filter({ hasText: Feature.Store.Store_2.name }).click(); // 确定并去选择员工 await page.locator('.comfirm_btn').filter({ hasText: '确定并去选择员工' }).click(); // 选择一个员工 await page.locator('.label_checkbox').filter({ hasText: Employees.SecondShop.Employee_1.name }).click(); // 确认 await page .locator('.comfirm_btn ') .filter({ hasText: /^确\s定$/ }) .click(); // 保存并复制到其他项目 await page.locator('button.save_and_copy').filter({ hasText: '保存并复制到其他项目/卖品' }).click(); // 挂单 await page.locator('#cart_bottom_btn').getByText('挂单').click(); await page .locator('.item_box') .filter({ hasText: ProjectName.Projects.Projects_1.name }) .first() .locator('.open') .click(); //用这里来判断是否挂单成功 const parentLocator = page .locator('.item_box') .filter({ has: page.locator('.text-ellipsis', { hasText: username }) }); await expect.soft(parentLocator).toContainText(ProjectName.Projects.Projects_1.name); await expect.soft(parentLocator).toContainText(ProjectName.Projects.Projects_2.name); await expect.soft(parentLocator).toContainText(ProjectName.Projects.Projects_3.name); await expect.soft(parentLocator).toContainText(ProjectName.Product.Product_1.name); await expect.soft(parentLocator).toContainText(ProjectName.Product.Product_2.name); await expect.soft(parentLocator).toContainText(ProjectName.Projects.Projects_5.name); await expect.soft(parentLocator).toContainText(ProjectName.Projects.Projects_6.name); await expect.soft(parentLocator).toContainText(ProjectName.Projects.Projects_7.name); await expect(parentLocator).toContainText(ProjectName.Projects.Projects_4.name); }); test('已删除单据不能取单,也不能删除', async ({ page }) => { // 找到已过期/删除单据 await page.getByText('已过期 / 删除单据').click(); await expect(page.getByText('已删除服务', { exact: true })).toBeInViewport(); await page.getByText('已删除服务', { exact: true }).click(); await expect(page.getByText('警告:已过期服务无法取单结算,请至收银台处理')).not.toBeInViewport(); const $slidingMenu = page.locator('div.deleteList .m_sliding_menu'); await expect($slidingMenu.locator('div.item_box').first()).toBeVisible(); await expect($slidingMenu.locator('div.comment > i.anticon').first()).not.toBeVisible(); }); test('微信/支付宝收款', async ({ page, homeNavigation, baseURL }) => { // 点击收款 await page .locator('.right_view') .getByRole('button', { name: /^收\s款$/ }) .click(); //输入金额 await page.getByPlaceholder('请输入金额').fill('1'); //点击微信 await page.locator('li').filter({ hasText: '微信' }).click(); const filePath = path.resolve(__dirname, '@/imgs/payqrcode.jpg'); console.log(filePath); await expect(async () => { await page.locator('.qrcode').click(); await page.locator('.qrcode').screenshot({ path: filePath }); }).toPass(); let result = await decodeQR(filePath); console.log(result); let url_1 = new URL(result); // 分割成数组 let pathParts = url_1.pathname.split('/'); // 获取数组的最后一个元素 let lastPart = pathParts[pathParts.length - 1]; console.log(lastPart); //点击支付宝 await page.locator('.top > .icon').click(); await page.locator('li').filter({ hasText: '支付宝' }).click(); await page.locator('.top > .icon').click(); await page.goto(result); await page.locator('.amount').waitFor(); let amount = await page.locator('.amount').textContent(); expect('1.00').toBe(amount); //重新进入慧来客 await page.goto(baseURL ?? ''); await expect(page.getByRole('button', { name: /开\s单/ })).toBeVisible(); await homeNavigation.gotoModule('流水'); await page.locator('.top_tab').getByText('收款记录').click(); await page .locator('.m-table__body-wrapper tbody .m-table-cell', { hasText: '哆啦宝' }) .first() .waitFor({ timeout: 2000 }); }); }); test.describe('收银-房态', () => { test('预约选床位', async ({ page, homeNavigation, createCustomer, cashierRoomPage, appointmentPage }) => { const customer = createCustomer; // 获取当前时间 const setAppointment = getNextAppointmentTime(); const employee = Employees.FirstShop.Employee_6; await test.step('进行员工预约,进入预约界面', async () => { await homeNavigation.gotoModule('预约'); await expect(page.locator('.room_table .tr .name_th', { hasText: employee.name })).toBeVisible(); await page.locator('.room_table .tr .name_th', { hasText: employee.name }).scrollIntoViewIfNeeded(); await page.locator('.times_table td', { hasText: setAppointment }).scrollIntoViewIfNeeded(); // 打开预约选择窗口 await appointmentPage.openAppointmentCell(employee.name); await expect(page.locator('.popup_content', { hasText: '选择操作' })).toBeVisible(); await appointmentPage.operationAppointment(AppointmentOperation.ADD_APPOINT); await expect(page.getByText('选择会员')).toBeVisible(); await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone); await page.locator('.ant-input-suffix', { hasText: '搜索' }).click(); await page.locator('.member_list .member_list_li .phone', { hasText: customer.phone }).click(); await expect(page.locator('.newAppointmentContent .header_title')).toContainText('新建预约'); await expect(page.locator('.newAppointmentContent .content .phone')).toContainText(customer.phone); }); await test.step('进入床位选择,选择床位', async () => { await page.getByText('请选择床位').click(); await page.getByRole('cell', { name: '按摩房' }).waitFor(); await page.locator('.canChoose', { hasText: '选择' }).first().click(); await page.getByRole('button', { name: '确认新建' }).click(); await expect(page.locator('.ant-message', { hasText: '预约成功' })).toBeVisible(); }); await test.step('进入收银-房态,查看顾客房态', async () => { // 进入房态页面 await homeNavigation.gotoModule('收银'); await page.getByText('房态').click(); await page.getByRole('cell', { name: '按摩房' }).waitFor(); // 判断顾客房态状态 await cashierRoomPage.checkStatus(customer, 'wait'); // 打开顾客详情页面 await page.getByText(customer.username).click(); await page.locator('.ant-tabs-tab-active').filter({ hasText: '基本资料' }).waitFor(); await page.locator('.close_icons').click(); // 返回预约板块 await homeNavigation.gotoModule('预约'); await page .locator('.appointment') .filter({ has: page.locator('.user_phone', { hasText: customer.phone }) }) .locator('.user_name_info') .click(); await page.locator('.info_center .title').waitFor(); await page.locator('.btn_box_btnStyle', { hasText: '取消预约' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '取消预约成功' })).toBeVisible(); }); }); test('开单选床位', async ({ page, homeNavigation, createCustomer, customerPage }) => { const customer = createCustomer; await test.step('开卡', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); await page.locator('.number_service').waitFor(); await page.getByRole('button', { name: /^开\s卡$/ }).click(); // 选择会员卡A await page.locator('.memberCard_box > .needsclick').getByText('会员卡A').click(); // 结算 await page.getByRole('button', { name: '去结算' }).click(); // 选择现金支付 await page.getByText('现金').click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); await page.getByRole('button', { name: /^结\s算$/ }).click(); await page.locator('.modal_title', { hasText: '会员协议签署确认' }).waitFor(); await page.getByRole('button', { name: /跳\s过/ }).click(); await page.getByRole('button', { name: '转寄存' }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 关闭收银界面 await page.locator('use').first().click(); }); await test.step('开单选择床位', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); await page.getByRole('button', { name: '关联床位' }).click(); await page.locator('.left', { hasText: '安排床位' }).waitFor(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await expect(async () => { const noRoom = page.locator('.noRoom', { hasText: '门店暂未配置房间/床位信息' }); if (await noRoom.isVisible()) { await page.locator('.top_control .close').click(); await page.getByRole('button', { name: '关联床位' }).click(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await expect(noRoom).not.toBeVisible(); } }).toPass(); // 点击选择床位 const allRoom = page.locator('.room_beds_table .room_table tr'); const count = await allRoom.count(); for (let i = 0; i < count; i++) { const tr = allRoom.nth(i); const userProject = tr.getByRole('button', { name: /^选\s择$/ }); if (await userProject.isVisible()) { await userProject.click(); await page.getByText('30分钟', { exact: true }).click(); await page.locator('#cart_bottom_btn').getByText('挂单').click(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await page.getByText('房态').click(); await expect(page.locator('.room_board')).toBeVisible(); // 判断该会员是否有服务中的床位 await expect.soft(page.locator('.doing', { hasText: customer.username })).toBeVisible(); await page.locator('.tab_item', { hasText: '挂单' }).click(); // await page.reload(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await page .locator('.item_box', { hasText: customer.username }) .first() .getByRole('button', { name: /^取\s单$/ }) .click(); // 点击取消关联床位 await expect(page.locator('.right_control_btn .close_icon')).toBeVisible(); await page.locator('.right_control_btn .close_icon').click(); await page.getByRole('button', { name: '确 认' }).click(); await page.locator('#cart_bottom_btn').getByText('挂单').click(); break; } else { console.log('无房间,测试失败'); } } }); }); test('占用床位', async ({ page, homeNavigation, createCustomer, cashierRoomPage, customerPage, appointmentPage, }) => { const customer = createCustomer; const employee = Employees.FirstShop.Employee_6; await homeNavigation.gotoModule('收银'); await page.locator('#frame_detail div').filter({ hasText: '房态' }).nth(3).click(); await page.locator('.room_table').first().waitFor(); const setAppointment = getNextAppointmentTime(); // 获取当前时间 const cede = page.locator('.left_table td'); // 找到当前时间的行数 const nowRowTime = await cede.allInnerTexts().then(text => text.indexOf(setAppointment)); // 获取第几列没被占用 const nowRowRoom = await page .locator(`.room_board .tr .td:nth-child(${nowRowTime})`) .allInnerTexts() .then(text => text.findIndex(item => !item.includes('占用'))); if (nowRowRoom === -1 || nowRowTime === -1) { throw new Error('未找到可用床位或时间'); } const startElement = page.locator('.room_board .tr').nth(nowRowRoom).locator('.td').nth(nowRowTime); // 确保元素存在 if (!startElement) { console.error('元素未找到'); } // 边界框 const startRect = await startElement.boundingBox(); if (!startRect) { throw new Error('元素边界框未获取到'); } const startX = startRect.x + startRect.width / 2; const startY = startRect.y + startRect.height / 2; await expect(async () => { // 占用床位 await page.mouse.move(startX, startY); await page.mouse.down(); await page.waitForTimeout(2000); await page.mouse.move(startX, startY); await page.mouse.up(); const Occupied = page.locator('.ant-message', { hasText: '该时间段已被占用' }); if (await Occupied.isVisible()) { const startX = startRect.x + startRect.width * 1.5; const startY = startRect.y + startRect.height / 2; // 占用床位 await page.mouse.move(startX, startY); await page.mouse.down(); await page.waitForTimeout(2000); await page.mouse.move(startX, startY); await page.mouse.up(); const startElements = page .locator('.room_board .tr') .nth(nowRowRoom + 1) .locator('.td') .nth(nowRowTime); await expect(startElements.locator('.occupy_text', { hasText: /^占用$/ })).toBeVisible({ timeout: 2000, }); } else { await expect(startElement.locator('.occupy_text', { hasText: /^占用$/ })).toBeVisible({ timeout: 2000, }); } }).toPass(); await test.step('进行员工预约,进入预约界面', async () => { await homeNavigation.gotoModule('预约'); await page.locator('.room_table .tr .name_th', { hasText: employee.name }).waitFor(); await page.locator('.room_table .tr .name_th', { hasText: employee.name }).scrollIntoViewIfNeeded(); await page.locator('.times_table td', { hasText: setAppointment }).scrollIntoViewIfNeeded(); // 打开预约选择窗口 await appointmentPage.openAppointmentCell(employee.name); await page.locator('.popup_content', { hasText: '选择操作' }).waitFor(); await appointmentPage.operationAppointment(AppointmentOperation.ADD_APPOINT); await page.getByText('选择会员').waitFor(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); await expect(page.locator('.newAppointmentContent .header_title')).toContainText('新建预约'); await expect(page.locator('.newAppointmentContent .content .phone')).toContainText(customer.phone); }); await test.step('进入床位选择,选择床位', async () => { await page.getByText('请选择床位').click(); await page.getByRole('cell', { name: '按摩房' }).waitFor(); // 尝试点击被占用,可能点不到 await expect(async () => { await startElement.click(); const time = page.locator('.ant-message', { hasText: '请选择预约的时段!' }); if (!(await time.isVisible())) { const BeOccupied = page.locator('.ant-message', { hasText: '床位已被占用,请重新选择', }); await expect.soft(BeOccupied).toBeVisible({ timeout: 2000 }); } else { await page.locator('.canChoose', { hasText: '选择' }).first().click(); } await page.locator('.canChoose', { hasText: '选择' }).first().click(); }).toPass(); await expect(async () => { await page.getByRole('button', { name: '确认新建' }).click(); await expect(page.locator('.ant-message', { hasText: '预约成功' })).toBeVisible({ timeout: 3000, }); }).toPass(); }); await test.step('进入收银-房态,查看顾客房态', async () => { // 进入房态页面 await homeNavigation.gotoModule('收银'); await page.getByText('房态').click(); await page.getByRole('cell', { name: '按摩房' }).waitFor(); // 判断顾客房态状态 await cashierRoomPage.checkStatus(customer, 'wait'); // 打开顾客详情页面 await page.getByText(customer.username).click(); await expect(page.locator('.ant-tabs-tab-active').filter({ hasText: '基本资料' })).toBeVisible(); await page.locator('.close_icons').click(); // 取消占用 await startElement .locator('.occupy_text', { hasText: /^占用$/ }) .first() .click(); await page.getByText('取消占用').first().click(); await page.getByRole('button', { name: '确 认' }).click(); await expect(page.locator('div').filter({ hasText: '取消占用成功!' }).nth(2)).toBeVisible(); // 返回预约板块 await homeNavigation.gotoModule('预约'); await page .locator('.appointment') .filter({ has: page.locator('.user_phone', { hasText: customer.phone }) }) .locator('.user_name_info') .click(); await page.locator('.info_center .title').waitFor(); await page.locator('.btn_box_btnStyle', { hasText: '取消预约' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message', { hasText: '取消预约成功' }).waitFor(); }); }); test('取消占用床位', async ({ page, appointmentPage }) => { const remark = faker.helpers.fromRegExp(/1[3-9][0-9]{6}/); const remark2 = faker.helpers.fromRegExp(/1[3-9][0-9]{6}/); await page.locator('#frame_detail div').filter({ hasText: '房态' }).nth(3).click(); await page.locator('.room_table').first().waitFor(); const setAppointment = getNextAppointmentTime(); // 获取当前时间 const cede = page.locator('.left_table td'); // 找到当前时间的行数 const nowRowTime: number = await cede.allInnerTexts().then(text => { return text.findIndex(item => item === setAppointment) + 2; }); // 获取第几列没被占用 const nowRowRoom = await page .locator(`.room_board .tr .td:nth-child(${nowRowTime})`) .allInnerTexts() .then(text => text.findIndex(item => !item.includes('占用'))); if (nowRowRoom === -1) { throw new Error('未找到可用床位或时间'); } const startElement = page.locator('.room_board .tr').nth(nowRowRoom).locator('.td').nth(nowRowTime); // 确保元素存在 if (!startElement) { console.error('元素未找到'); } // 边界框 const startRect = await startElement.boundingBox(); if (!startRect) { throw new Error('元素边界框未获取到'); } const startX = startRect.x + startRect.width / 2; const startY = startRect.y + startRect.height / 2; await page.mouse.move(startX, startY); await page.mouse.down(); await page.waitForTimeout(2000); await page.mouse.move(startX, startY); await page.mouse.up(); await startElement .locator('.occupy_text', { hasText: /^占用$/ }) .first() .click(); await page.getByText('添加备注').click(); await page.getByPlaceholder('请输入备注').fill(remark); await page.getByRole('button', { name: '确 认' }).click(); await page.locator('.occupy_remark', { hasText: remark }).click(); await page.getByText('修改备注').first().click(); await page.getByPlaceholder('请输入备注').fill(remark2); await page.getByRole('button', { name: '确 认' }).click(); await page.locator('.occupy_remark', { hasText: remark2 }).click(); await page.getByText('返回').click(); await page.locator('.occupy_remark').click(); await page.getByText('取消占用').first().click(); await page.getByRole('button', { name: '确 认' }).click(); await expect(page.locator('div').filter({ hasText: '取消占用成功' }).nth(2)).toBeVisible(); }); test('修改占用床位', async ({ page, appointmentPage }) => { await page.locator('#frame_detail div').filter({ hasText: '房态' }).nth(3).click(); await page.locator('.room_table').first().waitFor(); const setAppointment = getNextAppointmentTime(); // 获取当前时间 const cede = page.locator('.left_table td'); // 找到当前时间的行数 const nowRowTime: number = await cede.allInnerTexts().then(text => { return text.findIndex(item => item === setAppointment) + 2; }); // 获取第几列没被占用 const nowRowRoom = await page .locator(`.room_board .tr .td:nth-child(${nowRowTime})`) .allInnerTexts() .then(text => text.findIndex(item => !item.includes('占用'))); if (nowRowRoom === -1 || nowRowTime === -1) { throw new Error('未找到可用床位或时间'); } const startElement = page.locator('.room_board .tr').nth(nowRowRoom).locator('.td').nth(nowRowTime); // 确保元素存在 if (!startElement) { console.error('元素未找到'); } // 边界框 const startRect = await startElement.boundingBox(); if (!startRect) { throw new Error('元素边界框未获取到'); } const startX = startRect.x + startRect.width / 2; const startY = startRect.y + startRect.height / 2; const startedX = startRect.x + startRect.width * 1.5; const startedY = startRect.y + startRect.height / 2; await page.mouse.move(startX, startY); await page.mouse.down(); await page.waitForTimeout(2000); await page.mouse.up(); await expect(startElement.locator('.occupy_text', { hasText: /^占用$/ })).toBeVisible(); await page.mouse.move(startX, startY); await page.mouse.down(); await page.waitForTimeout(2000); await page.mouse.move(startedX, startedY); await page.mouse.up(); const startElemented = page .locator('.room_board .tr') .nth(nowRowRoom + 1) .locator('.td') .nth(nowRowTime); // toPass 可能点不出取消占用 await expect(async () => { await startElemented .locator('.occupy_text', { hasText: /^占用$/ }) .first() .click(); await page.getByText('取消占用').first().waitFor({ timeout: 2000 }); }).toPass(); await page.getByText('取消占用').first().click(); await page.getByRole('button', { name: '确 认' }).click(); await expect(page.locator('div').filter({ hasText: '取消占用成功!' }).nth(2)).toBeVisible(); }); }); test.describe('收银-开单&结算', () => { test('开单-反结算-撤单', async ({ page, homeNavigation, createCustomer, customerPage, wasteBookBusinessRecordPage, numberInput, }) => { // 定义一个随机单号 const randomBillNo1 = faker.helpers.fromRegExp(/1[3-9][0-9]{8}/); const randomBillNo2 = faker.helpers.fromRegExp(/1[3-9][0-9]{9}/); const customer = createCustomer; const username = customer.username; const phone = customer.phone; // 单据定位器 const $$billLeft = page.locator('.m-table__fixed-left .m-table-cell .bill .m-dropdown-link'); const $$billBody = page.locator('.m-table__body-wrapper tbody .m-table-cell'); await test.step('创建会员开单', async () => { // 项目1和项目2 const project1 = ProjectName.Projects.Projects_15; const project2 = ProjectName.Projects.Projects_17; // 员工1和员工2 const employee1 = Employees.FirstShop.Employee_6.name; const employee2 = Employees.FirstShop.Employee_7.name; // 现金 const cash = 50; // 欠款 const arrears = 50; // 微信 const weChat = 100; await test.step('开单购买项目,选择员工结算', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择项目1 await page.getByText(project1.num).click(); // 购买项目添加员工1 await expect(async () => { await page.locator('.buy_staff').last().click(); await expect(page.locator('.header', { hasText: '员工业绩' })).toBeVisible({ timeout: 2000 }); }).toPass(); await page.getByLabel(employee1).first().check(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 选择项目2 await page.getByText(project2.num).click(); // 点击添加员工2 await expect(async () => { await page.locator('.buy_staff').last().click(); await expect(page.locator('.header', { hasText: '员工业绩' })).toBeVisible({ timeout: 2000 }); }).toPass(); await page.getByLabel(employee2).first().check(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 结算 await page.getByText(/结\s算/).click(); // 输入随机单号 await page.locator('.input165').click(); await page.getByPlaceholder('请输入内容').fill(randomBillNo1); // 确认 await page.locator('.tools_icon').last().click(); // 点击混合支付 await page.locator('.paytype').getByText('混合支付').click(); // 制定选择项目A await page .locator('.itemlist_radio_group') .getByText(/^星灿明眸奢享套\s/) .click(); // 输入现金金额 const rightPaymentInfoItem = page.locator('.right .paymentmain .paymentInfoItem'); await rightPaymentInfoItem.getByText('现金', { exact: true }).click(); await page.getByRole('button', { name: '增加收款' }).click(); await page.locator('.money_discount_input').fill(`${cash}`); await page.locator('.sure .tools_icon').click(); // 输入欠款金额 await rightPaymentInfoItem.getByText('欠款', { exact: true }).click(); await page.getByRole('button', { name: '增加收款' }).click(); await page.locator('.money_discount_input').fill(`${arrears}`); // 输入微信金额 await page.locator('.sure .tools_icon').click(); await rightPaymentInfoItem.getByText('微信', { exact: true }).click(); await page.getByRole('button', { name: '增加收款' }).click(); await page.locator('.money_discount_input').fill(`${weChat}`); await page.locator('.sure .tools_icon').click(); await page.locator('.additional').filter({ hasText: '关键数据配置' }).getByText('未分配').click(); await page.locator('.popup_content').getByLabel(employee1).check(); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); await page.getByRole('button', { name: /^结\s算$/ }).click(); }); // 获取项目1定位器 const $project1Result = page.locator('.m-detailComponent_report .items_name .name_txt').first(); // 获取项目2定位器 const $project2Result = page.locator( '.m-detailComponent_report .main-table-body_tr:nth-child(2) .items_name .name_txt', ); // 获取员工1定位器 const $Employee1Result = page.locator('.m-detailComponent_report .billUser_item .userName').first(); // 获取员工2定位器 const $Employee2Result = page.locator( '.m-detailComponent_report .main-table-body_tr:nth-child(2) .billUser_item .userName', ); // 获取总金额定位器 const $TotalAmount = page.locator('.m-detailComponent_consume_title .amount'); // 获取现金定位器 const $JudgmentArrears = page.locator('.m-detailComponent_consume_title .overdraft'); await test.step('在营业记录、业绩流水、对账流水查看单据明细', async () => { await homeNavigation.gotoModule('流水'); // 在营业记录中查询 // 等待加载完成 await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 打开单据明细 await $$billLeft.getByText(randomBillNo1).first().click(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await page.locator('.m-receiptDetail_tip', { hasText: '单据明细' }).waitFor(); // 对比第一个输入的项目 await expect.soft($project1Result).toContainText(project1.name); // 对比第二个输入的项目 await expect.soft($project2Result).toContainText(project2.name); // 对比第一个员工为陈刚 await expect.soft($Employee1Result).toContainText(employee1); // 对比第二个员工为张伟 await expect.soft($Employee2Result).toContainText(employee2); // 判断总金额 await expect.soft($TotalAmount).toContainText(`${cash + arrears + weChat}`); // 判断欠款 await expect($JudgmentArrears).toContainText(`${arrears}`); await page.reload(); // 点击流水 await homeNavigation.gotoModule('流水'); // 在业绩流水中查询 await wasteBookBusinessRecordPage.gotoSubPage('业绩流水'); // 打开单据明细 await $$billLeft.getByText(randomBillNo1).first().click(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await page.locator('.m-receiptDetail_tip', { hasText: '单据明细' }).waitFor(); // 对比第一个输入的项目 await expect.soft($project1Result).toContainText(project1.name); // 对比第二个输入的项目 await expect.soft($project2Result).toContainText(project2.name); // 对比第一个员工为陈刚 await expect.soft($Employee1Result).toContainText(employee1); // 对比第二个员工为张伟 await expect.soft($Employee2Result).toContainText(employee2); // 判断总金额 await expect.soft($TotalAmount).toContainText(`${cash + arrears + weChat}`); // 判断欠款 await expect($JudgmentArrears).toContainText(`${arrears}`); await page.reload(); // 点击流水 await homeNavigation.gotoModule('流水'); // 在对账流水中查询 await wasteBookBusinessRecordPage.gotoSubPage('对账流水'); // 打开单据明细 await $$billBody.getByText(randomBillNo1).first().click(); await expect(page.locator('.loading_container')).toBeHidden(); await page.locator('.m-receiptDetail_tip', { hasText: '单据明细' }).waitFor(); // 对比第一个输入的项目 await expect.soft($project1Result).toContainText(project1.name); // 对比第二个输入的项目 await expect.soft($project2Result).toContainText(project2.name); // 对比第一个员工为陈刚 await expect.soft($Employee1Result).toContainText(employee1); // 对比第二个员工为张伟 await expect.soft($Employee2Result).toContainText(employee2); // 判断总金额 await expect.soft($TotalAmount).toContainText(`${cash + arrears + weChat}`); // 判断欠款 await expect($JudgmentArrears).toContainText(`${arrears}`); }); }); await page.reload(); await test.step('反结算', async () => { const project1 = ProjectName.Projects.Projects_15.name; const project2 = ProjectName.Projects.Projects_9.name; const employee1 = Employees.FirstShop.Employee_6.name; await homeNavigation.gotoModule('流水'); await wasteBookBusinessRecordPage.gotoSubPage('营业记录'); // 点击指定单号 await $$billLeft.getByText(randomBillNo1).first().click(); // 点击反结算 await page.locator('.oversized', { hasText: '反结算' }).click(); await page.locator('.custom_content').waitFor(); await page.locator('.buy_item .buy_name .del_btn').last().click(); // 选择项目1 await expect(async () => { await page.getByText(ProjectName.Projects.Projects_9.num).click(); await page.locator('#buyList').getByText('青春雅致套').waitFor(); }).toPass(); await expect(async () => { const employeeLogo = page.locator('#buyList').getByRole('button').nth(1); if (!(await employeeLogo.isVisible())) { await page.locator('.buy_staff').last().click(); // 点击添加员工 await page.locator('#buyList').getByRole('button').nth(1).click(); await page.locator('.header', { hasText: '员工业绩' }).waitFor({ timeout: 2000 }); } else { // 点击添加员工 await page.locator('#buyList').getByRole('button').nth(1).click(); await page.locator('.header', { hasText: '员工业绩' }).waitFor({ timeout: 2000 }); } }).toPass(); // 选择员工1 const employee2 = Employees.FirstShop.Employee_4.name; await page.getByText(Employees.FirstShop.Employee_4.name).first().click(); // 确认 await page.getByRole('button', { name: /^确\s认$/ }).click(); // 修改数量 await page.locator('.edit_txt div:nth-child(2)').first().click(); await numberInput.setValue('common', 2); await numberInput.confirmValue(); const quantity = (await page.locator('.buy_number').last().innerText()).trim(); // 结算 await page .locator('div') .filter({ hasText: /^结\s算$/ }) .click(); // 修改单号 await page.getByPlaceholder('不输入则自动生成订单号').click(); await numberInput.setString(randomBillNo2); await numberInput.confirmValue(); // 使用银联支付 await page.getByText('银联', { exact: true }).click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); // 结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await expect(page.locator('.ant-message', { hasText: '结算成功' })).toBeVisible(); // 对比第一个项目 await expect.soft(page.locator('.items_name .name_txt').first()).toContainText(project1); // 对比第二个项目 await expect.soft(page.locator('.items_name .name_txt').last()).toContainText(project2); // 对比员工 await expect .soft( page .locator('.m-detailComponent_report .main-table-body_tr:nth-child(1) .billUser_item .userName') .first(), ) .toContainText(employee1); await expect .soft( page .locator('.m-detailComponent_report .main-table-body_tr:nth-child(2) .billUser_item .userName') .last(), ) .toContainText(employee2); // 对比数量 await expect.soft(page.locator('.m-detailComponent-cell .num').last()).toContainText(quantity); // 对比总金额 const project1ResultCollect = ProjectName.Projects.Projects_15.Price; const project2ResultCollect = ProjectName.Projects.Projects_9.Price; await expect(page.locator('.m-detailComponent_consume_title .amount')).toContainText( `${Number(project1ResultCollect) + Number(project2ResultCollect) * Number(quantity)}`, ); }); await page.reload(); await test.step('撤单', async () => { // 进入营业记录页面 await homeNavigation.gotoModule('流水'); // 点击指定单号 await $$billLeft.getByText(randomBillNo2).click(); // 点击撤单 await page.locator('.ant-btn', { hasText: '撤单' }).click(); // 点击输入备注 await page.locator('.label_text').last().click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill('撤单'); await page.locator('.saveCheck').waitFor(); await page.getByRole('button', { name: /确\s认/ }).click(); // 点击撤单查看 await page.locator('.search_select').first().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '已撤单' }).click(); // 判断撤的单子是否还在 await expect($$billLeft.getByText(randomBillNo2).first()).toBeVisible(); }); }); test('开卡-使用卡金和赠金-充值卡金', async ({ page, homeNavigation, createCustomer, customerPage, numberInput, }) => { const c = createCustomer; const username = c.username; const phone = c.phone; await test.step('开卡', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); await page.locator('.number_service').waitFor(); // 点击开卡 await page.getByRole('button', { name: /^开\s卡$/ }).click(); const CardTypeA = '会员卡A'; // 选择会员卡A await page.locator('.memberCard_box > .needsclick').getByText(CardTypeA, { exact: true }).click(); // 结算 await page.getByRole('button', { name: '去结算' }).click(); // 选择现金支付 await page.getByText('现金').click(); // 取消推送消费提醒 await page.getByLabel('推送消费提醒').uncheck(); // 取消结算签字 await page.getByLabel('结算签字').uncheck(); // 结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await page.getByRole('button', { name: /跳\s过/ }).click(); // 寄存卖品 await page.getByRole('button', { name: '转寄存' }).click(); // 确认 await page.getByRole('button', { name: /^确\s认$/ }).click(); // 关闭收银界面 await page.locator('use').first().click(); // 点击顾客 await page.locator('.link_item_member').click(); // 输入会员信息 await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); await customerPage.openCustomerDetail(username, phone); // 校验会员卡金 赠送金是否准确 await expect.soft(page.locator('.membercard_box .card_name .name').first()).toContainText(CardTypeA); // 卡金对比 await expect.soft(page.locator('.balance_right').first()).toContainText('1000'); // 赠送金对比 await expect(page.locator('.membercard_box .bonuses').first()).toContainText('100'); }); await test.step('使用卡金和赠金', async () => { //使用卡金和赠金 await page.reload(); await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 选择项目A await page.getByText(ProjectName.Projects.Projects_15.num).click(); // 选择项目B await page.getByText(ProjectName.Projects.Projects_17.num).click(); // 结算 await page.getByText(/^结\s算$/).click(); // 点击优惠券 await page.getByText('张优惠券可用').click(); // 点一张优惠券 await page.locator('.item > .name').first().click(); // 确认选择 await page.getByRole('button', { name: '确认选择' }).click(); // 点击混合支付 await page.getByText('混合支付').click(); // 选择卡金支付 await page.getByText('卡金').nth(4).click(); await page.getByRole('button', { name: '增加收款' }).click(); // 输入金额 await numberInput.setValue('common', 100); await numberInput.confirmValue(); // 选择赠送金支付 await page.getByText('赠金').nth(2).click(); await page.getByRole('button', { name: '增加收款' }).click(); // 输入金额 await numberInput.setValue('common', 90); await numberInput.confirmValue(); // 结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await expect(page.getByRole('button', { name: /^结\s算$/ })).not.toBeVisible(); }); await page.reload(); await test.step('充值卡金', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); await page.locator('.membercard_box .name_row .balance').waitFor(); const CardAmount = KeepOnlyNumbers(await page.locator('.membercard_box .name_row .balance').innerText()); // 点击充值 await page.getByRole('button', { name: /^充\s值$/ }).click(); // 点击充值总额 await page.locator('span > .touchIcon').first().click(); // 输入金额 const TopUp = 1000; await page.getByPlaceholder('请输入内容').fill(`${TopUp}`); // 确认金额(勾勾) await page.locator('.tools_icon').last().click(); // 点击现金 await page.getByText('现金').click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); // 点击结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); // 关闭收银界面 await page.locator('use').first().click(); await homeNavigation.gotoModule('顾客'); // 搜索会员 await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 点击会员卡 await page.locator('.user_name', { hasText: username }).last().click(); // 校验会员卡金是否准确 const BalanceSumTotal = Number(CardAmount) + TopUp; await expect(page.locator('.balance_right').first()).toContainText(`${BalanceSumTotal}`); await page.getByRole('tab', { name: '流水' }).click(); await page.getByText('会员卡记录').click(); await page.locator('.flow_list').waitFor(); // 记录 await expect(page.locator('.flow_section td:nth-child(5)').first()).toContainText(`${TopUp}`); }); }); test('还欠款', async ({ page, homeNavigation, createCustomer, customerPage }) => { // 创建顾客 const c = createCustomer; // 获取姓名、手机号、档案号 const username = c.username; const phone = c.phone; await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 点击开卡 await page.getByRole('button', { name: /^开\s卡$/ }).click(); // 选择会员卡A await page.locator('.memberCard_box > .needsclick').getByText(CardType.CardTypeList.CardType_1.name).click(); // 结算 await page.getByRole('button', { name: '去结算' }).click(); //点击混合支付 await page.locator('.paytype').first().getByText('混合支付').click(); //点击现金 const rightPaymentInfoItem = page.locator('.right .paymentmain .paymentInfoItem'); await rightPaymentInfoItem.getByText('现金', { exact: true }).click(); //增加收款 await page.getByRole('button', { name: '增加收款' }).click(); //输入金额 await page.locator('.money_discount_input').fill('500'); //确认金额 await page.locator('.sure .tools_icon').click(); //点击欠款 await rightPaymentInfoItem.getByText('欠款', { exact: true }).click(); //增加收款 await page.getByRole('button', { name: '增加收款' }).click(); //输入金额 await page.locator('.money_discount_input').fill('100'); //确认金额 await page.locator('.sure .tools_icon').click(); //点击微信 await rightPaymentInfoItem.getByText('微信', { exact: true }).click(); //增加收款 await page.getByRole('button', { name: '增加收款' }).click(); //输入金额 await page.locator('.money_discount_input').fill('400'); //确认金额 await page.locator('.sure .tools_icon').click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); //结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await page.getByRole('button', { name: /^跳\s过$/ }).click(); await page.locator('.ant-message', { hasText: '结算成功' }).waitFor(); await page.getByRole('button', { name: '不寄存' }).click(); await page.locator('.close').first().click(); await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 点击还款 await page.locator('.comment > div:nth-child(2) > button:nth-child(2)').first().click(); // 点击修改金额 await page.locator('.touchIcon').first().waitFor(); await page.locator('.touchIcon').first().click(); // 输入金额 await page.getByPlaceholder('请输入内容').fill('50'); // 确认 await page.locator('.tools_icon').last().click(); // 选择现金支付 await page.getByText('现金').click(); // 结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await page.locator('.ant-message', { hasText: '结算成功' }).waitFor(); // 点击顾客 await homeNavigation.gotoModule('顾客'); // 输入信息 await customerPage.searchCustomer(phone); await customerPage.selectSearchCustomer(username); // 点击进入详情 await page.locator('.user_info_head .user_name', { hasText: username }).last().click(); await page.getByRole('tab', { name: '流水' }).click(); await page.locator('label').filter({ hasText: '欠还款记录' }).click(); // 总欠款100 await expect(page.locator('.total_debt', { hasText: '100' })).toBeVisible(); // 待还款50 await expect(page.locator('.stay_paid', { hasText: '50' })).toBeVisible(); }); });