- 添加项目配置文件和环境变量设置 - 创建测试用例目录结构和命名规范 - 实现基础测试 fixture 和页面对象模型 - 添加示例测试用例和数据生成器 - 配置 playwright 和 gitignore 文件
1426 lines
69 KiB
TypeScript
1426 lines
69 KiB
TypeScript
// @ts-check
|
||
import { test, expect } from '@/fixtures/boss_common.js'; //使用公共套件
|
||
import { Feature, Employees, ProjectName, CardType, Coupons } from '@/fixtures/userconfig.js';
|
||
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';
|
||
|
||
test.describe('挂单', () => {
|
||
let c;
|
||
let username;
|
||
let phone;
|
||
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.locator('.deleteList').locator('.item_box').first().waitFor();
|
||
// 水单都没有取单
|
||
const PendingOrder_1 = page.locator('.deleteList').locator('.item_box');
|
||
|
||
await expect(PendingOrder_1.getByRole('button', { name: /^取\s单$/ })).not.toBeVisible();
|
||
await page
|
||
.locator(
|
||
'div:nth-child(3) > .scroller-body > .alloytouch-target > .list > div > .item > .comment > div:nth-child(2) > .touchIcon',
|
||
)
|
||
.first()
|
||
.click();
|
||
await expect(async () => {
|
||
await page.locator('label').filter({ hasText: '1' }).click();
|
||
await page.locator('.ant-radio-checked').waitFor();
|
||
}).toPass();
|
||
await page.getByRole('button', { name: /^保\s存$/ }).click();
|
||
await expect(page.locator('div').filter({ hasText: '删除成功' }).nth(2)).toBeVisible();
|
||
});
|
||
});
|
||
|
||
test.describe('挂单', () => {
|
||
test('成功挂单', async ({ page, createCustomer, homeNavigation, customerPage }) => {
|
||
const customer = createCustomer;
|
||
const phone = customer.phone;
|
||
const username = customer.username;
|
||
|
||
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.locator('.cash_content > .main > .top').getByText('已过期').click();
|
||
await expect(async () => {
|
||
// 点击已删除服务
|
||
await page.getByText(' 已删除服务 ').click();
|
||
await page.locator('.loading_container').waitFor({ state: 'hidden' });
|
||
// 等待过期删除水单页面出来
|
||
await page.locator('.deleteList').locator('.item_box').first().waitFor({ timeout: 2000 });
|
||
// 判断有没有取单和删除
|
||
const PendingOrder = page.locator('.deleteList').locator('.item_box');
|
||
await expect(PendingOrder.getByRole('button', { name: /^取\s单$/ })).not.toBeVisible();
|
||
await expect(
|
||
page.locator(
|
||
'div:nth-child(3) > .scroller-body > .alloytouch-target > .list > div > .item > .comment > div:nth-child(2) > .touchIcon',
|
||
),
|
||
).not.toBeVisible();
|
||
}).toPass();
|
||
});
|
||
|
||
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();
|
||
|
||
/**@type {string} 解析后的网址 */
|
||
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 = appointmentPage.getAppointmentTimesAvailable();
|
||
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 = appointmentPage.getAppointmentTimesAvailable(); // 获取当前时间
|
||
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 = appointmentPage.getAppointmentTimesAvailable(); // 获取当前时间
|
||
const cede = page.locator('.left_table td');
|
||
// 找到当前时间的行数
|
||
/**@type {number} 找到当前时间的行数 */
|
||
const nowRowTime = 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 = appointmentPage.getAppointmentTimesAvailable(); // 获取当前时间
|
||
const cede = page.locator('.left_table td');
|
||
// 找到当前时间的行数
|
||
// const nowRowTime = await cede.allInnerTexts().then(text => text.indexOf(setAppointment) + 3);
|
||
/**@type{number} 找到当前时间的行数 */
|
||
const nowRowTime = 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(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 page.reload();
|
||
|
||
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(100);
|
||
await numberInput.confirmValue();
|
||
// 选择赠送金支付
|
||
await page.getByText('赠金').nth(2).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
// 输入金额
|
||
await numberInput.setValue(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();
|
||
});
|
||
});
|