1243 lines
60 KiB
TypeScript
1243 lines
60 KiB
TypeScript
// @ts-check
|
||
import { test, expect } from '@/fixtures/boss_common.js';
|
||
import { faker } from '@faker-js/faker/locale/zh_CN';
|
||
import { Customer } from '@/utils/customer';
|
||
import { KeepOnlyNumbers } from '@/utils/utils.js';
|
||
import fs from 'fs';
|
||
import path from 'path';
|
||
import { Employees, ProjectName } from '@/fixtures/userconfig.js';
|
||
import { staffData } from '@/fixtures/staff.js';
|
||
|
||
test.describe('营业记录', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
await page.addLocatorHandler(page.getByRole('button', { name: '我知道了' }), async () => {
|
||
await page.getByRole('button', { name: '我知道了' }).click();
|
||
await expect(page.getByRole('button', { name: '我知道了' })).not.toBeVisible();
|
||
await page.reload();
|
||
});
|
||
|
||
await page.addLocatorHandler(page.locator('.ant-notification', { hasText: '反结算成功' }), async () => {
|
||
await page.locator('.ant-notification', { hasText: '反结算成功' }).locator('a').click();
|
||
await expect(page.locator('.ant-notification', { hasText: '反结算成功' })).not.toBeVisible();
|
||
});
|
||
});
|
||
|
||
test('根据条件搜索营业记录', async ({ page, homeNavigation, customerPage, createCustomCustomer }) => {
|
||
const customer = new Customer(2, 1);
|
||
const project = { num: '100012', name: '雪肌晶纯护理', Price: 300 };
|
||
let billNo = '';
|
||
|
||
await test.step('创建顾客', async () => {
|
||
await createCustomCustomer(customer);
|
||
});
|
||
|
||
await test.step('开单结算拿取单号', async () => {
|
||
// 进入顾客详情页面
|
||
await homeNavigation.gotoModule('顾客');
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.username);
|
||
await customerPage.openCustomerDetail(customer.username, customer.phone);
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
await expect(page.locator('div').filter({ hasText: /^结\s算$/ })).toBeVisible();
|
||
// 选择项目1
|
||
await page.getByText(project.num).click();
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
await page.locator('.paymentInfoItem').filter({ hasText: '现金' }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
// 结算
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS';
|
||
}),
|
||
page.getByRole('button', { name: /^结\s算$/ }).click(),
|
||
]);
|
||
const responseBody = await response.json();
|
||
billNo = responseBody?.content?.billNo;
|
||
});
|
||
expect(billNo).not.toBeNull();
|
||
|
||
const $bill = page.getByRole('cell', { name: billNo }).nth(1);
|
||
|
||
await test.step('条件搜索', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
await expect(page.getByText('营业记录').first()).toBeVisible();
|
||
await page.getByRole('combobox').first().click();
|
||
await page.getByRole('option', { name: '购买项目/卖品' }).click();
|
||
await page.getByRole('combobox').nth(1).click();
|
||
await page.getByRole('option', { name: '已结算' }).click();
|
||
await page.getByRole('combobox').nth(2).click();
|
||
await page.getByRole('option', { name: '未对单' }).click();
|
||
|
||
await expect($bill).toBeVisible();
|
||
});
|
||
|
||
await test.step('搜索水单号', async () => {
|
||
await page.getByRole('button').click();
|
||
await page.getByPlaceholder('输入流水单号搜索').fill(billNo);
|
||
await page.locator('.search_btn > svg').click();
|
||
|
||
await expect($bill).toBeVisible();
|
||
});
|
||
|
||
await test.step('进入水单详情和顾客详情', async () => {
|
||
await $bill.click();
|
||
await expect(page.locator('li').getByText(billNo)).toBeVisible();
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^单据明细$/ })
|
||
.locator('use')
|
||
.click();
|
||
await page.locator('.main-table-body_tr').getByText(customer.username).first().click();
|
||
await expect(page.getByRole('tabpanel').getByText(customer.username)).toBeVisible();
|
||
});
|
||
});
|
||
|
||
test.describe('单据明细', () => {
|
||
test.beforeAll(async () => {
|
||
const currentFileName = path.basename(__filename);
|
||
// 构造快照目录
|
||
const snapshotDir = path.resolve('tests/imgs/__screenshots__/touch', currentFileName);
|
||
|
||
// 如果目录不存在,则创建它
|
||
if (!fs.existsSync(snapshotDir)) {
|
||
fs.mkdirSync(snapshotDir, { recursive: true });
|
||
}
|
||
});
|
||
|
||
test('反结算', async ({ page, homeNavigation, customerPage, createCustomer, numberInput }) => {
|
||
// 定义随机单号
|
||
let ReceiptNum = faker.helpers.fromRegExp(/1[3-9][0-9]{8}/);
|
||
const project_1 = ProjectName.Projects.Projects_2; // 项目
|
||
const employee_1 = Employees.FirstShop.Employee_6; // 员工
|
||
const project_2 = ProjectName.Projects.Projects_3; // 项目
|
||
const employee_2 = Employees.FirstShop.Employee_4; // 员工
|
||
// 创建顾客A随机姓名 手机
|
||
const customer = createCustomer;
|
||
|
||
await test.step('开单结算拿取单号', async () => {
|
||
// 进入顾客详情页面
|
||
await homeNavigation.gotoModule('顾客');
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.username);
|
||
await customerPage.openCustomerDetail(customer.username, customer.phone);
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
// 选择项目1
|
||
await page.getByText(project_1.num).click();
|
||
// 点击添加员工
|
||
await page.locator('#buyList').getByRole('button').nth(1).click();
|
||
// 选择员工1
|
||
await page.locator('.hand_txt .name_txt').getByText(employee_1.name).click();
|
||
await page.getByRole('button', { name: /^确\s认$/ }).click();
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
// 点击修改单号
|
||
await page.locator('.input165').click();
|
||
await page.getByPlaceholder('请输入内容').fill(ReceiptNum);
|
||
await page.locator('.tools_icon').last().click();
|
||
// 点击现金
|
||
await page.locator('.paymentInfoItem').filter({ hasText: '现金' }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
await page.getByRole('button', { name: /^结\s算$/ }).click();
|
||
await expect(page.locator('.ant-message')).toContainText('结算成功');
|
||
});
|
||
|
||
await test.step('进入流水模块,进行反结算', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
// 点击指定单号
|
||
await page
|
||
.locator('.m-table__fixed-left .m-table-cell .bill .m-dropdown-link ', {
|
||
hasText: ReceiptNum,
|
||
})
|
||
.click();
|
||
// 点击反结算
|
||
await page.locator('.oversized', { hasText: '反结算' }).click();
|
||
await page.locator('.custom_content').waitFor();
|
||
// 删除单据内的项目
|
||
await page.locator('.buy_item .buy_name .del_btn').last().click();
|
||
// 选择项目C
|
||
await page.getByText(project_2.num).click();
|
||
await page.locator('#buyList').getByText(project_2.name).click();
|
||
// 点击添加员工
|
||
await page.locator('#buyList').getByRole('button').nth(1).click();
|
||
await page.getByText(employee_2.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();
|
||
// 结算
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
// 使用银联支付
|
||
await page.locator('.paymentInfoItem', { hasText: '银联' }).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 page.addLocatorHandler(page.getByRole('button', { name: '我知道了' }), async () => {
|
||
await page.getByRole('button', { name: '我知道了' }).click();
|
||
await expect(page.getByRole('button', { name: '我知道了' })).not.toBeVisible();
|
||
await page.reload();
|
||
await page
|
||
.locator('.m-table__fixed-left .m-table-cell .bill .m-dropdown-link ', {
|
||
hasText: ReceiptNum,
|
||
})
|
||
.click();
|
||
});
|
||
});
|
||
|
||
await test.step('进入单据明细,查看反结算内容', async () => {
|
||
await page.locator('.m-receiptDetail_tip', { hasText: '单据明细' }).waitFor();
|
||
// 对比第一个项目
|
||
await expect.soft(page.locator('.items_name .name_txt').first()).toContainText(project_2.name);
|
||
// 对比员工
|
||
await expect
|
||
.soft(
|
||
page
|
||
.locator(
|
||
'.m-detailComponent_report .main-table-body_tr:nth-child(1) .billUser_item .userName',
|
||
)
|
||
.first(),
|
||
)
|
||
.toContainText(employee_2.name);
|
||
// 对比数量
|
||
await expect.soft(page.locator('.m-detailComponent-cell .num').last()).toContainText('2');
|
||
// 对比总金额
|
||
const project1ResultCollect = Number(ProjectName.Projects.Projects_3.Price) * 2 + '';
|
||
await expect(page.locator('.m-detailComponent_consume_title .amount')).toContainText(
|
||
project1ResultCollect,
|
||
);
|
||
});
|
||
});
|
||
|
||
test('撤单', async ({ page, homeNavigation, customerPage, createCustomer }) => {
|
||
const ReceiptNum = faker.helpers.fromRegExp(/1[3-9][0-9]{8}/); // 随机单号
|
||
let OddNumber = page.locator('.m-table__fixed-left .m-table-cell .bill .m-dropdown-link ', {
|
||
hasText: ReceiptNum,
|
||
});
|
||
const project = ProjectName.Projects.Projects_3;
|
||
|
||
const customer = createCustomer;
|
||
|
||
await test.step('开单获取单号', async () => {
|
||
// 进入顾客详情页面
|
||
await homeNavigation.gotoModule('顾客');
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.username);
|
||
await customerPage.openCustomerDetail(customer.username, customer.phone);
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
// 选择项目1
|
||
await page.getByText(project.num).click();
|
||
// 结算
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
// 点击修改单号
|
||
await page.locator('.input165').click();
|
||
// 输入随机单号
|
||
await page.getByPlaceholder('请输入内容').fill(ReceiptNum);
|
||
// 确认
|
||
await page.locator('.tools_icon').last().click();
|
||
await page.locator('.paymentInfoItem', { hasText: '现金' }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
await page.getByRole('button', { name: /^结\s算$/ }).click();
|
||
await expect(page.locator('.ant-message')).toContainText('结算成功');
|
||
});
|
||
|
||
await test.step('根据单号进行撤单,判断撤单成功', async () => {
|
||
// 点击流水
|
||
await page.reload();
|
||
await homeNavigation.gotoModule('流水');
|
||
// 点击下拉框
|
||
await page.locator('.ant-dropdown-link > .anticon > svg').first().click();
|
||
// 选择营业记录
|
||
await page.getByRole('menuitem', { name: '营业记录' }).click();
|
||
// 点击指定单号
|
||
await page
|
||
.locator('.m-table__fixed-left .m-table-cell .bill .m-dropdown-link ', {
|
||
hasText: ReceiptNum,
|
||
})
|
||
.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: '确 认' }).click();
|
||
|
||
// 点击下拉框
|
||
await page.locator('.ant-dropdown-link > .anticon > svg').first().click();
|
||
// 选择营业记录
|
||
await page.getByRole('menuitem', { name: '营业记录' }).click();
|
||
// 点击撤单查看
|
||
await page.locator('.search_select').first().click();
|
||
await page.locator('.ant-select-dropdown-menu-item', { hasText: '已撤单' }).click();
|
||
// 判断撤的单子是否还在
|
||
await expect(OddNumber).toBeVisible();
|
||
});
|
||
});
|
||
|
||
test('补签', async ({ page, homeNavigation, customerPage, createCustomer }) => {
|
||
const customer = createCustomer;
|
||
const project = { num: '100012', name: '雪肌晶纯护理', Price: 300 };
|
||
|
||
let billNo = '';
|
||
|
||
await test.step('开单结算,不勾选签字,拿取单号', async () => {
|
||
// 进入顾客详情页面
|
||
await homeNavigation.gotoModule('顾客');
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.username);
|
||
await customerPage.openCustomerDetail(customer.username, customer.phone);
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
// 选择项目1
|
||
await page.getByText(project.num).click();
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
await page.locator('.paymentInfoItem').filter({ hasText: '现金' }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
// 结算
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS';
|
||
}),
|
||
page.getByRole('button', { name: /^结\s算$/ }).click(),
|
||
]);
|
||
const responseBody = await response.json();
|
||
billNo = responseBody?.content?.billNo;
|
||
expect(billNo).not.toBeNull();
|
||
});
|
||
|
||
const $bill = page.getByRole('cell', { name: billNo }).nth(1);
|
||
|
||
await test.step('进入水单详情进行补签', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
await expect(page.getByText('营业记录').first()).toBeVisible();
|
||
await $bill.click();
|
||
await expect(page.locator('li').getByText(billNo)).toBeVisible();
|
||
await page.getByText('补签').click();
|
||
await expect(page.getByText('请签字确认消费')).toBeVisible();
|
||
const $canvas = page.locator('canvas').first();
|
||
const canvasBoundingBox = await $canvas.boundingBox();
|
||
if (canvasBoundingBox) {
|
||
const { x, y, width, height } = canvasBoundingBox;
|
||
|
||
// 模拟鼠标按下操作
|
||
await page.mouse.move(x + width / 4, y + height / 2);
|
||
await page.mouse.down();
|
||
|
||
// 模拟签字路径(可以自定义路径)
|
||
await page.mouse.move(x + width / 2, y + height / 2);
|
||
await page.mouse.move(x + width / 1.5, y + height / 3);
|
||
await page.mouse.move(x + width / 1.2, y + height / 1.8);
|
||
|
||
// 释放鼠标
|
||
await page.mouse.up();
|
||
} else {
|
||
throw new Error('无法找到签字区域');
|
||
}
|
||
|
||
await page.getByRole('button', { name: '签好了' }).click();
|
||
await expect(page.locator('li').getByText(billNo)).toBeVisible();
|
||
await page.waitForLoadState('load');
|
||
|
||
const $img = page.locator('.slider_list_item', { has: page.getByText('签名') }).locator('img');
|
||
await expect($img).toHaveScreenshot({
|
||
threshold: 0.25, // 相似度阈值(0.1 表示 10% 以内的差异可以接受)
|
||
animations: 'disabled', // 处理有动画的元素
|
||
});
|
||
});
|
||
});
|
||
|
||
test('查看配方', async ({ page, homeNavigation, customerPage, createCustomer }) => {
|
||
const project = { num: '100012', name: '雪肌晶纯护理', Price: 300 };
|
||
const customer = createCustomer;
|
||
|
||
let billNo = '';
|
||
let useProductName = '';
|
||
await test.step('开单,购买项目并消耗,消耗时选择项目配方', async () => {
|
||
// 进入顾客详情页面
|
||
await homeNavigation.gotoModule('顾客');
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.username);
|
||
await customerPage.openCustomerDetail(customer.username, customer.phone);
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
// 选择项目1
|
||
await page.getByText(project.num).click();
|
||
await page.locator('.commodity_item').first().click();
|
||
// 打开使用区-项目配方
|
||
await page.locator('.staff_setting').first().click();
|
||
await page.getByLabel('项目配方').check();
|
||
await page.getByRole('button', { name: /确\s认/ }).click();
|
||
// 选择项目配方
|
||
await page.locator('.formula_noData').click();
|
||
await expect(async () => {
|
||
await page.locator('.list_box').getByRole('checkbox').first().check();
|
||
await expect(page.locator('.menu-item-dot').first()).toBeVisible();
|
||
}).toPass({ timeout: 30_000 });
|
||
useProductName = (await page.locator('.list_box .label').first().innerText()).trim();
|
||
|
||
await page.getByRole('button', { name: '确定选择' }).click();
|
||
await page.locator('input[type="tel"]').fill('1');
|
||
await page.getByRole('button', { name: /保\s存/ }).click();
|
||
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
await page.locator('.paymentInfoItem').filter({ hasText: '现金' }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
// 结算
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS';
|
||
}),
|
||
page.getByRole('button', { name: /^结\s算$/ }).click(),
|
||
]);
|
||
const responseBody = await response.json();
|
||
billNo = responseBody?.content?.billNo;
|
||
});
|
||
expect(billNo).not.toBeNull();
|
||
expect(useProductName).not.toBeNull();
|
||
|
||
await test.step('查看单据明细的配方消耗', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
await page.locator('.m-table-fixed-body').getByText(billNo).first().click();
|
||
const $$listItem = page.locator('.slider_list_item');
|
||
const $openConsumptionRecord = $$listItem
|
||
.filter({
|
||
has: page.getByText('开用记录'),
|
||
})
|
||
.getByText('查看详情');
|
||
|
||
await $openConsumptionRecord.click();
|
||
const $popup = page.locator('.popup_content');
|
||
await expect($popup.getByText(useProductName)).toBeVisible();
|
||
const useProductNumber = (
|
||
await $popup.locator('.main-table-body_tr').first().locator('td').nth(1).innerText()
|
||
).trim();
|
||
expect(useProductNumber).toBe('1');
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|
||
test.describe('业绩流水', () => {
|
||
test('根据条件搜索业绩流水', async ({
|
||
page,
|
||
customerPage,
|
||
homeNavigation,
|
||
createCustomer,
|
||
wasteBookBusinessRecordPage,
|
||
}) => {
|
||
const customer = createCustomer;
|
||
|
||
let billNo = '';
|
||
const firstProject = { num: '', name: '' };
|
||
const firstGoods = { num: '', name: '' };
|
||
await test.step('开单,购买项目、卖品并消耗,消耗购买项目', async () => {
|
||
// 进入顾客详情页面
|
||
await homeNavigation.gotoModule('顾客');
|
||
await customerPage.searchCustomer(customer.phone);
|
||
await customerPage.selectSearchCustomer(customer.username);
|
||
await customerPage.openCustomerDetail(customer.username, customer.phone);
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
await expect(page.locator('div').filter({ hasText: /^结\s算$/ })).toBeVisible();
|
||
|
||
// 选择项目1
|
||
const $firstProject = page.locator('.list_box .project_list').first();
|
||
await $firstProject.click();
|
||
firstProject.num = await $firstProject.locator('.number').innerText();
|
||
firstProject.name = await $firstProject.locator('.title').innerText();
|
||
await page.locator('.commodity_item').first().click();
|
||
|
||
// 选择卖品
|
||
await page.getByText('卖品', { exact: true }).click();
|
||
await $firstProject.click();
|
||
firstGoods.num = await $firstProject.locator('.number').innerText();
|
||
firstGoods.name = await $firstProject.locator('.title').innerText();
|
||
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结\s算$/ })
|
||
.click();
|
||
await page.locator('.paymentInfoItem').filter({ hasText: '现金' }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS';
|
||
}),
|
||
page.getByRole('button', { name: /^结\s算$/ }).click(),
|
||
]);
|
||
await page.getByRole('button', { name: '不寄存' }).click();
|
||
const responseBody = await response.json();
|
||
billNo = responseBody?.content?.billNo;
|
||
});
|
||
expect(billNo).not.toBeNull();
|
||
expect(firstProject.num).not.toBe('');
|
||
expect(firstProject.name).not.toBe('');
|
||
expect(firstGoods.num).not.toBe('');
|
||
expect(firstGoods.name).not.toBe('');
|
||
|
||
await test.step('根据筛选条件进行搜索水单', async () => {
|
||
await Promise.all([homeNavigation.gotoModule('流水'), page.waitForLoadState()]);
|
||
await wasteBookBusinessRecordPage.gotoSubPage('业绩流水');
|
||
|
||
// 流水单
|
||
const $flowChart = page.getByRole('row', { name: billNo, exact: true }).first();
|
||
const $projectViewSelect = page
|
||
.locator('.com_picker')
|
||
.filter({ hasText: '选择' })
|
||
.locator('.menu-item-dot')
|
||
.first();
|
||
const $goodsViewSelect = page
|
||
.locator('.com_picker')
|
||
.filter({ hasText: '选择卖品' })
|
||
.locator('.menu-item-dot')
|
||
.first();
|
||
|
||
await page.getByTitle('全部水单类型').click();
|
||
await page.getByRole('option', { name: '购买项目/卖品' }).click();
|
||
// 选择项目
|
||
await page.locator('span').filter({ hasText: '选择项目' }).getByRole('list').click();
|
||
await page.getByRole('textbox', { name: '请输入首字母或关键字检索' }).fill(firstProject.num);
|
||
await page.getByRole('button', { name: /搜\s索/ }).click();
|
||
await expect(async () => {
|
||
await page.getByLabel(firstProject.name).uncheck();
|
||
await page.getByLabel(firstProject.name).check();
|
||
await expect($projectViewSelect).toBeVisible({ timeout: 2000 });
|
||
}).toPass({ timeout: 30_000 });
|
||
await page.getByRole('button', { name: '确定选择' }).click();
|
||
|
||
// 选择卖品
|
||
await page.getByTitle('购买项目/卖品').click();
|
||
await page.getByRole('option', { name: '全部水单类型' }).click();
|
||
await page.getByTitle('全部水单类型').click();
|
||
await page.getByRole('option', { name: '购买项目/卖品' }).click();
|
||
await page.locator('span').filter({ hasText: '选择卖品' }).getByRole('list').click();
|
||
await page.getByRole('textbox').nth(2).fill(firstGoods.num);
|
||
await page.getByRole('button', { name: /搜\s索/ }).click();
|
||
await expect(async () => {
|
||
await page.getByLabel(firstGoods.name).uncheck();
|
||
await page.getByLabel(firstGoods.name).check();
|
||
await expect($goodsViewSelect).toBeVisible({ timeout: 2000 });
|
||
}).toPass({ timeout: 30_000 });
|
||
await page.getByRole('button', { name: '确定选择' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('购买项目/卖品').click();
|
||
await page.getByRole('option', { name: '消耗项目' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('消耗项目').click();
|
||
await page.getByRole('option', { name: '开卡' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('开卡').click();
|
||
await page.getByRole('option', { name: '充值' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('充值').click();
|
||
await page.getByRole('option', { name: '还款' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('还款').click();
|
||
await page.getByRole('option', { name: '换项目/产品' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('换项目/产品').click();
|
||
await page.getByRole('option', { name: '抹欠款' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('抹欠款').click();
|
||
await page.getByRole('option', { name: '补录' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('补录').click();
|
||
await page.getByRole('option', { name: '跨店帮忙' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('跨店帮忙').click();
|
||
await page.getByRole('option', { name: '会员卡退卡' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.reload();
|
||
await page.getByRole('button').click();
|
||
await page.getByPlaceholder('输入流水单号搜索').fill(billNo);
|
||
await page.locator('.search_btn > svg').click();
|
||
await expect($flowChart).toBeVisible();
|
||
});
|
||
});
|
||
|
||
test('查询业绩流水列表明细', async ({ page, homeNavigation, createCustomer, wasteBookBusinessRecordPage }) => {
|
||
// 创建顾客A随机姓名 手机
|
||
const ca = createCustomer;
|
||
const usernameA = ca.username;
|
||
const phoneA = ca.phone;
|
||
|
||
await test.step('开单购买会员卡', async () => {
|
||
await homeNavigation.gotoModule('收银');
|
||
await page.getByRole('button', { name: /^开\s单$/ }).click();
|
||
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(phoneA);
|
||
await page
|
||
.locator('.search_text')
|
||
.filter({ hasText: /^搜\s索$/ })
|
||
.click();
|
||
// 选择会员
|
||
await page.locator('.custom_content').getByText(usernameA).click();
|
||
await page.locator('.loading_container').waitFor({ state: 'hidden' });
|
||
await page.locator('.custom_content').waitFor();
|
||
// 点击开卡
|
||
const ActivateCards = page.getByRole('button', { name: /^开\s卡$/ });
|
||
if (await ActivateCards.isVisible()) {
|
||
await page.getByRole('button', { name: /^开\s卡$/ }).click();
|
||
} else {
|
||
await page.locator('.more').first().click();
|
||
await page.getByText('去开卡').click();
|
||
}
|
||
// 选择会员卡A
|
||
await page
|
||
.locator('.memberCard_box > .needsclick')
|
||
.getByText(/^会员卡$/)
|
||
.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();
|
||
// 会员协议签署确认(需判断 常报错)
|
||
try {
|
||
await page.locator('.modal_title', { hasText: '会员协议签署确认' }).waitFor();
|
||
await page.getByRole('button', { name: /跳\s过/ }).click();
|
||
} catch {
|
||
console.log('无会员协议签署');
|
||
}
|
||
await expect(page.locator('.ant-message')).toContainText('结算成功');
|
||
});
|
||
|
||
await test.step('进入顾客详情', async () => {
|
||
await page.reload();
|
||
await homeNavigation.gotoModule('顾客');
|
||
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(phoneA);
|
||
await page.getByText('搜索', { exact: true }).click();
|
||
await page.getByText(usernameA).click();
|
||
// 点击进入详情
|
||
await page.locator('.user_info_head .user_name', { hasText: usernameA }).last().click();
|
||
});
|
||
|
||
// 定义随机单号
|
||
const ReceiptNum = faker.helpers.fromRegExp(/1[3-9][0-9]{8}/);
|
||
const Cash = '30';
|
||
const CardAmount = '10';
|
||
const FreeAmount = '20';
|
||
const Arrears = '20';
|
||
// 选择员工A
|
||
const employee1 = Employees.FirstShop.Employee_6.name;
|
||
await test.step('开单消耗项目,选择员工,混合支付,随机单号', async () => {
|
||
await page.locator('span').filter({ hasText: '去开单' }).first().click();
|
||
await page.getByText(ProjectName.Projects.Projects_17.num).click();
|
||
// 点击添加员工
|
||
await page.locator('#buyList').getByRole('button').nth(1).click();
|
||
await page.locator('.hand_txt .name_txt').getByText(employee1).click();
|
||
// 确认
|
||
await page.getByRole('button', { name: /^确\s认$/ }).click();
|
||
// 消耗该项目1次
|
||
await page.locator('.commodity_item').last().click();
|
||
// 点击添加员工
|
||
await page.locator('.use_item .staff_btn').click();
|
||
// 选择员工A
|
||
await page.locator('.hand_txt .name_txt').getByText(employee1).click();
|
||
// 确认
|
||
await page.getByRole('button', { name: /^确\s认$/ }).click();
|
||
await page
|
||
.locator('div')
|
||
.filter({ hasText: /^结 算$/ })
|
||
.click();
|
||
// 点击修改单号
|
||
await page.locator('.input165').click();
|
||
// 输入随机单号
|
||
await page.getByPlaceholder('请输入内容').fill(ReceiptNum);
|
||
// 确认
|
||
await page.locator('.tools_icon').last().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(CardAmount);
|
||
//确认金额
|
||
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(FreeAmount);
|
||
//确认金额
|
||
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(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 page.getByLabel('推送消费提醒').uncheck();
|
||
//取消结算签字
|
||
await page.getByLabel('结算签字').uncheck();
|
||
//结算
|
||
await page.getByRole('button', { name: /^结\s算$/ }).click();
|
||
});
|
||
|
||
await test.step('进入水单详情页,查看数据', async () => {
|
||
// 进入业绩流水
|
||
await homeNavigation.gotoModule('流水');
|
||
await wasteBookBusinessRecordPage.gotoSubPage('业绩流水');
|
||
// 点击搜索水单
|
||
await expect(async () => {
|
||
await page.getByRole('button').click();
|
||
await page.locator('.searchButton .search_input .ant-input').waitFor({ timeout: 2000 });
|
||
}).toPass();
|
||
await page.locator('.searchButton .search_input .ant-input').fill(ReceiptNum);
|
||
await page.locator('.searchButton .search_input .search_btn').click();
|
||
await page.locator('.loading_container').waitFor({ state: 'hidden' });
|
||
await expect(page.locator('.m-table__fixed-left .m-dropdown-link').first()).toContainText(ReceiptNum);
|
||
|
||
// 现金业绩
|
||
const CashPerformance = KeepOnlyNumbers(
|
||
await page
|
||
.locator('.m-table__body-wrapper .main-table-body_tr')
|
||
.nth(1)
|
||
.locator('.is-right')
|
||
.first()
|
||
.innerText(),
|
||
);
|
||
const Cashs = Number(Cash) * 0.8 + '';
|
||
console.log('现金业绩' + CashPerformance);
|
||
|
||
// 划卡业绩
|
||
const CardPerformance = KeepOnlyNumbers(
|
||
await page
|
||
.locator('.m-table__body-wrapper .main-table-body_tr')
|
||
.nth(1)
|
||
.locator('.is-right')
|
||
.nth(1)
|
||
.innerText(),
|
||
);
|
||
console.log('划卡业绩' + CardPerformance);
|
||
|
||
// 划赠金业绩
|
||
const FreePerformance = KeepOnlyNumbers(
|
||
await page
|
||
.locator('.m-table__body-wrapper .main-table-body_tr')
|
||
.nth(1)
|
||
.locator('.is-right')
|
||
.nth(2)
|
||
.innerText(),
|
||
);
|
||
console.log('赠金业绩' + FreePerformance);
|
||
|
||
// 消耗业绩
|
||
const ExpendPerformance = KeepOnlyNumbers(
|
||
await page
|
||
.locator('.m-table__body-wrapper .main-table-body_tr')
|
||
.nth(0)
|
||
.locator('.is-right')
|
||
.nth(4)
|
||
.innerText(),
|
||
);
|
||
const ProjectPrice = ProjectName.Projects.Projects_17.Price; // 项目价格
|
||
const ProjectPrices = Number(ProjectPrice) * 0.8 + ''; // 会员卡打8折
|
||
console.log('消耗业绩' + ExpendPerformance);
|
||
|
||
// 消耗 员工
|
||
const ExpendEmployee = await page
|
||
.locator('.m-table__body-wrapper .main-table-body_tr')
|
||
.nth(0)
|
||
.locator('.billUser span')
|
||
.last()
|
||
.innerText();
|
||
console.log('消耗 员工' + ExpendEmployee);
|
||
|
||
// 购买 员工
|
||
const BuyEmployee = await page
|
||
.locator('.m-table__body-wrapper .main-table-body_tr')
|
||
.nth(1)
|
||
.locator('.billUser span')
|
||
.last()
|
||
.innerText();
|
||
console.log('购买 员工' + BuyEmployee);
|
||
|
||
expect(CashPerformance).toBe(Cashs); // 现金业绩
|
||
expect(CardPerformance).toBe(CardAmount); // 划卡业绩
|
||
expect(FreePerformance).toBe(FreeAmount); // 划赠金业绩
|
||
expect(ExpendPerformance).toBe(ProjectPrices); // 消耗业绩
|
||
expect(ExpendEmployee).toBe(employee1); // 消耗 员工
|
||
expect(BuyEmployee).toBe(employee1); // 购买 员工
|
||
});
|
||
});
|
||
});
|
||
|
||
test.describe('对账流水', () => {
|
||
test('根据条件搜索对账流水', async ({ page, homeNavigation, createCustomer, wasteBookBusinessRecordPage }) => {
|
||
const customer = createCustomer;
|
||
const project = { no: '100018', name: '苹果精萃护理', shortName: '精萃护理', price: '980' };
|
||
let billNo: string;
|
||
await test.step('选择顾客开单,结算使用银联、支付宝、微信、欠款、现金', async () => {
|
||
await homeNavigation.gotoModule('收银');
|
||
await page.getByRole('button', { name: /开\s单/ }).click();
|
||
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone);
|
||
await page.locator('.ant-input-suffix', { hasText: '搜索' }).click();
|
||
await page.locator('.member_list .phone', { hasText: customer.phone }).click();
|
||
await page.locator('.project_list .number', { hasText: project.no }).click();
|
||
await page.locator('.pay_btn', { hasText: /^结\s算$/ }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
|
||
const rightPaymentInfoItem = page.locator('.right .paymentmain .paymentInfoItem');
|
||
const leftPaymentInfoItem = page.locator('.left .paymentmain .paymentInfoItem');
|
||
page.locator('.left .paymentmain .paymentInfoItem').filter({
|
||
hasText: '混合支付',
|
||
});
|
||
await leftPaymentInfoItem.filter({ hasText: '混合支付' }).click();
|
||
// 银联
|
||
await rightPaymentInfoItem.filter({ hasText: '银联' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 支付宝
|
||
await rightPaymentInfoItem.filter({ hasText: '支付宝' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 微信
|
||
await rightPaymentInfoItem.filter({ hasText: '微信' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 欠款
|
||
await rightPaymentInfoItem.filter({ hasText: '欠款' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 现金
|
||
await rightPaymentInfoItem.filter({ hasText: '现金' }).first().click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
|
||
// 等待 /bill 请求完成并获取流水单号
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && res.status() === 200;
|
||
}),
|
||
page.getByRole('button', { name: /结\s算/ }).click(),
|
||
]);
|
||
|
||
const responseBody = await response.json();
|
||
billNo = responseBody?.content?.billNo;
|
||
expect(billNo).not.toBeNull();
|
||
});
|
||
|
||
await test.step('根据筛选条件进行搜索水单', async () => {
|
||
await Promise.all([homeNavigation.gotoModule('流水'), page.waitForLoadState()]);
|
||
await wasteBookBusinessRecordPage.gotoSubPage('对账流水');
|
||
|
||
// 流水单
|
||
const $flowChart = page.getByRole('cell', { name: billNo, exact: true }).first();
|
||
|
||
await page.getByTitle('全部水单类型').click();
|
||
await page.getByTitle('全部记账流水').click();
|
||
await page.getByRole('option', { name: '有记账无收款流水' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('全部水单类型').click();
|
||
await page.getByRole('option', { name: '购买项目/卖品' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('购买项目/卖品').click();
|
||
await page.getByRole('option', { name: '开卡' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('开卡').click();
|
||
await page.getByRole('option', { name: '充值' }).click();
|
||
await expect($flowChart).not.toBeVisible();
|
||
|
||
await page.getByTitle('充值').click();
|
||
await page.getByRole('option', { name: '全部水单类型' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('全部支付方式').click();
|
||
await page.getByRole('option', { name: '现金' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('现金').click();
|
||
await page.getByRole('option', { name: '银联' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('银联').click();
|
||
await page.getByRole('option', { name: '微信' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.getByTitle('微信').click();
|
||
await page.getByRole('option', { name: '支付宝' }).click();
|
||
await expect($flowChart).toBeVisible();
|
||
|
||
await page.reload();
|
||
await page.getByRole('button').click();
|
||
await page.getByPlaceholder('输入流水单号搜索').fill(billNo);
|
||
await page.locator('.search_btn > svg').click();
|
||
await expect($flowChart).toBeVisible();
|
||
});
|
||
});
|
||
test('对账流水只展示现金、支付宝、银联、微信', async ({ page, homeNavigation, createCustomer }) => {
|
||
const project = { no: '100018', name: '苹果精萃护理', shortName: '精萃护理', price: '980' };
|
||
|
||
const customer = createCustomer;
|
||
|
||
let billNo:string;
|
||
|
||
await test.step('选择顾客开单,结算使用银联、支付宝、微信、欠款、现金', async () => {
|
||
await homeNavigation.gotoModule('收银');
|
||
await page.getByRole('button', { name: /开\s单/ }).click();
|
||
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone);
|
||
await page.locator('.ant-input-suffix', { hasText: '搜索' }).click();
|
||
await page.locator('.member_list .phone', { hasText: customer.phone }).click();
|
||
await page.locator('.project_list .number', { hasText: project.no }).click();
|
||
await page.locator('.pay_btn', { hasText: /^结\s算$/ }).click();
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
|
||
const rightPaymentInfoItem = page.locator('.right .paymentmain .paymentInfoItem');
|
||
const leftPaymentInfoItem = page.locator('.left .paymentmain .paymentInfoItem');
|
||
page.locator('.left .paymentmain .paymentInfoItem').filter({
|
||
hasText: '混合支付',
|
||
});
|
||
await leftPaymentInfoItem.filter({ hasText: '混合支付' }).click();
|
||
// 银联
|
||
await rightPaymentInfoItem.filter({ hasText: '银联' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 支付宝
|
||
await rightPaymentInfoItem.filter({ hasText: '支付宝' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 微信
|
||
await rightPaymentInfoItem.filter({ hasText: '微信' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 欠款
|
||
await rightPaymentInfoItem.filter({ hasText: '欠款' }).click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.popup_content input').fill('1');
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
// 现金
|
||
await rightPaymentInfoItem.filter({ hasText: '现金' }).first().click();
|
||
await page.getByRole('button', { name: '增加收款' }).click();
|
||
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
|
||
|
||
// 等待 /bill 请求完成并获取流水单号
|
||
const [response] = await Promise.all([
|
||
page.waitForResponse(async res => {
|
||
return res.url().includes('/bill') && res.status() === 200;
|
||
}),
|
||
page.getByRole('button', { name: /结\s算/ }).click(),
|
||
]);
|
||
|
||
const responseBody = await response.json();
|
||
billNo = responseBody?.content?.billNo;
|
||
expect(billNo).not.toBeNull();
|
||
});
|
||
|
||
await test.step('进入流水-对账流水', async () => {
|
||
// 进入流水模块
|
||
await homeNavigation.gotoModule('流水');
|
||
await page.locator('.ant-dropdown-link', { hasText: '营业记录' }).click();
|
||
await Promise.all([
|
||
await page.getByRole('menuitem', { name: '对账流水' }).click(),
|
||
await page.waitForResponse(
|
||
response => response.url().includes('/payment_flow') && response.status() === 200,
|
||
),
|
||
]);
|
||
|
||
// 拿取现金列的列数
|
||
let index: number;
|
||
const thLocator = page.locator('.m-table__header tr').last().locator('th');
|
||
const headers = await thLocator.allInnerTexts();
|
||
index = headers.findIndex(headerText => headerText.includes('支付方式'));
|
||
if (index !== -1) {
|
||
console.log(`"支付方式" 列是第 ${index + 1} 列`);
|
||
} else {
|
||
throw new Error('没有找到支付方式列');
|
||
}
|
||
|
||
const paymentArray = (
|
||
await page
|
||
.locator('.main-table-body_tr ', { hasText: billNo })
|
||
.locator(`td:nth-child(${index + 1})`)
|
||
.allInnerTexts()
|
||
).map(i => i.trim());
|
||
console.log(paymentArray);
|
||
|
||
expect.soft(paymentArray).toContain('银联');
|
||
expect.soft(paymentArray).toContain('现金');
|
||
expect.soft(paymentArray).toContain('支付宝');
|
||
expect.soft(paymentArray).toContain('微信');
|
||
expect.soft(paymentArray).toContain('微信');
|
||
expect(paymentArray).not.toContain('欠款');
|
||
});
|
||
});
|
||
});
|
||
|
||
test.describe('日结单', () => {
|
||
/**
|
||
* 获取员工列的各项数据
|
||
* @param {import('@playwright/test').Page} page
|
||
* @param {number} index 员工列
|
||
* @param {{ 'name': string, 'lastPrice': number, 'price': number }[]} data 员工数据
|
||
*/
|
||
async function getColumnPrice(page, index, data) {
|
||
const columnName = ['现金', '消耗', '划卡', '客数', '客次', '拓客', '留客', '项目数', '卖品', '总耗业绩'];
|
||
for (const name of columnName) {
|
||
const price = await page
|
||
.locator('.m-table__body-wrapper tr', { hasText: name })
|
||
.locator('td')
|
||
.nth(index)
|
||
.locator('.hlknum')
|
||
.innerText();
|
||
console.log(`${name} -- ${price}`);
|
||
|
||
const item = data.find(item => item.name === name);
|
||
if (!item) {
|
||
throw new Error(`没有找到 ${name} 数据`);
|
||
}
|
||
item.lastPrice = item.price;
|
||
item.price = price.trim() === '--' ? 0 : Number(price);
|
||
}
|
||
}
|
||
|
||
test('根据条件搜索日结单', async ({ page, homeNavigation }) => {
|
||
const employee_1 = staffData.firstStore.firstSector.employee_2;
|
||
const employee_2 = staffData.firstStore.secondSector.employee_2;
|
||
const firstSectorName = staffData.firstStore.firstSector.name;
|
||
const secondSectorName = staffData.firstStore.secondSector.name;
|
||
|
||
await test.step('进入日结单模块', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
await page.getByText('日结单').first().click();
|
||
await expect(page.getByText('查看更多汇总数据')).toBeVisible();
|
||
|
||
await expect(page.getByRole('cell', { name: employee_1.name })).toBeVisible();
|
||
await expect(page.getByRole('cell', { name: employee_2.name })).toBeVisible();
|
||
});
|
||
|
||
await test.step('切换到一部门查看员工A', async () => {
|
||
await page.locator('.shop-picker-store > .icon > svg').click();
|
||
await page.getByLabel(firstSectorName).check();
|
||
await page.getByRole('button', { name: /保\s存/ }).click();
|
||
await expect(page.getByRole('cell', { name: employee_1.name })).toBeVisible();
|
||
await expect(page.getByRole('cell', { name: employee_2.name })).not.toBeVisible();
|
||
});
|
||
|
||
await test.step('切换到二部门查看员工B', async () => {
|
||
await page.locator('.shop-picker-store > .icon > svg').click();
|
||
await page.getByLabel(secondSectorName).check();
|
||
await page.getByRole('button', { name: /保\s存/ }).click();
|
||
await expect(page.getByRole('cell', { name: employee_1.name })).not.toBeVisible();
|
||
await expect(page.getByRole('cell', { name: employee_2.name })).toBeVisible();
|
||
});
|
||
});
|
||
|
||
test('查询日结单明细', async ({ page, homeNavigation, createCustomer }) => {
|
||
// 使用的员工
|
||
const employee = staffData.firstStore.firstSector.employee_1;
|
||
const project = { no: '100018', name: '苹果精萃护理', shortName: '精萃护理', price: 980 };
|
||
|
||
// 当前员工的日结单数据初始值
|
||
const employeeData = [
|
||
{ name: '现金', price: 0, lastPrice: 0 },
|
||
{
|
||
name: '消耗',
|
||
price: 0,
|
||
lastPrice: 0,
|
||
},
|
||
{ name: '划卡', price: 0, lastPrice: 0 },
|
||
{
|
||
name: '客数',
|
||
price: 0,
|
||
lastPrice: 0,
|
||
},
|
||
{ name: '客次', price: 0, lastPrice: 0 },
|
||
{
|
||
name: '拓客',
|
||
price: 0,
|
||
lastPrice: 0,
|
||
},
|
||
{ name: '留客', price: 0, lastPrice: 0 },
|
||
{
|
||
name: '项目数',
|
||
price: 0,
|
||
lastPrice: 0,
|
||
},
|
||
{ name: '卖品', price: 0, lastPrice: 0 },
|
||
{ name: '总耗业绩', price: 0, lastPrice: 0 },
|
||
];
|
||
|
||
const customer = createCustomer;
|
||
|
||
// 拿取员工列的列数
|
||
let index;
|
||
await test.step('进入流水-日结单,获取员工数据', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
await page.locator('.top_tab').getByText('日结单').first().click();
|
||
await page
|
||
.getByRole('row', {
|
||
name: '现金',
|
||
exact: true,
|
||
})
|
||
.locator('div')
|
||
.nth(1)
|
||
.waitFor();
|
||
|
||
const thLocator = page.locator('.m-table__header-wrapper tr').last().locator('th');
|
||
await thLocator.last().waitFor();
|
||
const headers = await thLocator.allInnerTexts();
|
||
index = headers.findIndex(headerText => {
|
||
return headerText.includes(employee.name) && headerText.includes(String(employee.id));
|
||
});
|
||
if (index !== -1) {
|
||
console.log(`"${employee.name}" 列是第 ${index + 1} 列`);
|
||
} else {
|
||
throw new Error(`没有找到${employee.name}, ${employee.id}列`);
|
||
}
|
||
|
||
// 获取员工各个行的值
|
||
await getColumnPrice(page, index, employeeData);
|
||
});
|
||
|
||
await test.step('开单结算,选择员工', async () => {
|
||
await homeNavigation.gotoModule('收银');
|
||
await page.getByRole('button', { name: /开\s单/ }).click();
|
||
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone);
|
||
await page.locator('.ant-input-suffix', { hasText: '搜索' }).click();
|
||
await page.locator('.member_list .phone', { hasText: customer.phone }).click();
|
||
// 购买并消费项目A
|
||
await page.locator('.project_list .number', { hasText: project.no }).click();
|
||
await page.locator('#shoppingCart .commodity_list li').first().click();
|
||
|
||
// 购买项目选择员工A
|
||
await page.locator('.buy_item').first().locator('.buy_staff').getByRole('button').click();
|
||
await page
|
||
.locator('.check_row', {
|
||
hasText: employee.name,
|
||
})
|
||
.getByRole('checkbox')
|
||
.check();
|
||
await page.getByRole('button', { name: /确\s认/ }).click();
|
||
|
||
// 消耗项目选择员工A
|
||
await page.locator('.use_item').first().locator('.use_staff').getByRole('button').click();
|
||
await page
|
||
.locator('.check_row', {
|
||
hasText: employee.name,
|
||
})
|
||
.getByRole('checkbox')
|
||
.check();
|
||
await page.getByRole('button', { name: /确\s认/ }).click();
|
||
await page.locator('.pay_btn', { hasText: /^结\s算$/ }).click();
|
||
|
||
// 去使用现金结算
|
||
await page.getByLabel('推送消费提醒').uncheck();
|
||
await page.getByLabel('结算签字').uncheck();
|
||
await page.locator('.left .paymentInfoItem', { hasText: '现金' }).click();
|
||
await page.getByRole('button', { name: /结\s算/ }).click();
|
||
});
|
||
|
||
await test.step('进入流水-日结单,比较员工数据变化', async () => {
|
||
await homeNavigation.gotoModule('流水');
|
||
await page.locator('.top_tab').getByText('日结单').first().click();
|
||
await page
|
||
.getByRole('row', {
|
||
name: '现金',
|
||
exact: true,
|
||
})
|
||
.locator('div')
|
||
.nth(1)
|
||
.waitFor();
|
||
|
||
await getColumnPrice(page, index, employeeData);
|
||
|
||
// 购买0.5
|
||
const checks = [
|
||
{ name: '现金', expected: project.price * 0.5 },
|
||
{
|
||
name: '消耗',
|
||
expected: project.price * 0.6,
|
||
},
|
||
{ name: '客数', expected: 1 },
|
||
{ name: '客次', expected: 1 },
|
||
{
|
||
name: '拓客',
|
||
expected: 1,
|
||
},
|
||
{ name: '留客', expected: 0 },
|
||
{ name: '项目数', expected: 1 },
|
||
{
|
||
name: '卖品',
|
||
expected: 0,
|
||
},
|
||
{ name: '总耗业绩', expected: project.price * 0.6 },
|
||
];
|
||
|
||
checks.forEach((check, index) => {
|
||
const item = employeeData.find(i => i.name === check.name);
|
||
if (!item) {
|
||
throw new Error(`没有找到 ${check.name} 数据`);
|
||
}
|
||
if (index < checks.length - 1) {
|
||
expect.soft(parseFloat((item.price - item.lastPrice).toFixed(2))).toBe(check.expected);
|
||
} else {
|
||
expect(parseFloat((item.price - item.lastPrice).toFixed(2))).toBe(check.expected);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
});
|