This repository has been archived on 2025-04-22. You can view files and clone it, but cannot push or open issues or pull requests.
hlk_autotest/tests/touch/boss_report.spec.ts
LingandRX 6517e4192c feat: 初始化慧来客自动化测试项目
- 添加项目配置文件和环境变量设置
- 创建测试用例目录结构和命名规范
- 实现基础测试 fixture 和页面对象模型
- 添加示例测试用例和数据生成器
- 配置 playwright 和 gitignore 文件
2024-12-22 19:18:27 +08:00

1658 lines
79 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @ts-check
import { expect, test } from '@/fixtures/merchantFixture.js';
// import { test, expect } from '@/fixtures/boss_common.js';
import { faker } from '@faker-js/faker/locale/zh_CN';
import { Customer } from '@/utils/customer';
import { KeepOnlyNumbers, waitSpecifyApiLoad } from '@/utils/utils.js';
import { CardType, Employees, ProjectName } from '@/fixtures/userconfig.js';
test.describe('业绩明细表', () => {
test('数据校验', async ({ page, createCustomer, homeNavigation, reportPage, customerPage }) => {
// 项目名称
const projectA = ProjectName.Projects.Projects_17.name;
const projectB = ProjectName.Projects.Projects_18.name;
const projectC = ProjectName.Projects.Projects_1.name;
// 套餐
const SetMeal = ProjectName.SetMeal.SetMeal_5.name;
// 卖品
const Product = ProjectName.Product.Product_4.name;
// 充值卡
const cardname = CardType.CardTypeList.CardType_5.name;
let ca;
const randomNumA = faker.helpers.fromRegExp(/1[0-9]{10}/);
const randomNumB = faker.helpers.fromRegExp(/1[0-9]{10}/);
// 创建顾客
ca = createCustomer;
// 获取姓名、手机号、档案号
const usernameA = ca.username;
const phoneA = ca.phone;
// 员工
const employee1 = Employees.FirstShop.Employee_6.name;
await test.step('购买会员卡B', async () => {
await homeNavigation.gotoModule('收银');
await page.getByRole('button', { name: /^开\s单$/ }).click();
await customerPage.searchCustomer(phoneA);
await customerPage.selectSearchCustomer(usernameA);
await page.locator('.number_service').waitFor();
// 点击开卡选择会员卡B
await page.getByRole('button', { name: /^开\s卡$/ }).click();
await page.getByText('会员卡B', { exact: true }).click();
// 结算,选择现金支付
await page.getByRole('button', { name: '去结算' }).click();
await page.getByText('现金', { exact: true }).click();
await page.getByLabel('推送消费提醒').uncheck();
await page.getByLabel('结算签字').uncheck();
await page.getByRole('button', { name: /结\s算/ }).click();
await page.getByRole('button', { name: /跳\s过/ }).click();
await expect(page.locator('.ant-message', { hasText: '结算成功' })).toBeVisible();
});
await test.step('购买并且消耗一次项目,然后购买一个套餐', async () => {
await page.reload();
// 点击顾客
await homeNavigation.gotoModule('顾客');
// 输入信息
await customerPage.searchCustomer(phoneA);
await customerPage.selectSearchCustomer(usernameA);
// 点击进入详情
await page.locator('.user_info_head .user_name', { hasText: usernameA }).last().click();
await page.locator('span').filter({ hasText: '去开单' }).first().click();
// 购买项目A
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('.float_tab')
.filter({ hasText: /套\s餐/ })
.click();
// 选择第一个套餐
await page.locator('.project_one > .item').filter({ hasText: ProjectName.SetMeal.SetMeal_5.name }).click();
// 结算
await page
.locator('div')
.filter({ hasText: /^结\s算$/ })
.click();
// 点击修改单号
await page.locator('.input165').click();
// 输入随机单号
await page.getByPlaceholder('请输入内容').fill(randomNumA);
// 确认
await page.locator('.tools_icon').last().click();
// 结算,选择现金支付
await page.getByText('现金', { exact: true }).click();
await page.getByLabel('推送消费提醒').uncheck();
await page.getByLabel('结算签字').uncheck();
await page.getByRole('button', { name: /结\s算/ }).click();
await page.getByRole('button', { name: /跳\s过/ }).click();
await expect(page.locator('.ant-message', { hasText: '结算成功' })).toBeVisible();
});
await test.step('充值1000元卡金', async () => {
// 输入金额
const TopUp = '1000';
// 点击顾客
await page.reload();
await homeNavigation.gotoModule('顾客');
// 输入信息
await customerPage.searchCustomer(phoneA);
await customerPage.selectSearchCustomer(usernameA);
// 点击进入详情
await page.locator('.user_info_head .user_name', { hasText: usernameA }).last().click();
await page.locator('span').filter({ hasText: '去开单' }).first().click();
// 点击充值
await page.getByRole('button', { name: /^充\s值$/ }).click();
// 点击充值总额
await page.locator('span > .touchIcon').first().click();
await page.getByPlaceholder('请输入内容').fill(TopUp);
// 确认金额(勾勾)
await page.locator('.tools_icon').last().click();
// 点击修改单号
await page.locator('.input165').click();
// 输入随机单号
await page.getByPlaceholder('请输入内容').fill(randomNumB);
// 确认
await page.locator('.tools_icon').last().click();
// 结算,选择现金支付
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 page.locator('use').first().click();
});
await test.step('进入业绩明细表进行校验数据', async () => {
// 项目套餐卖品价格
const projectPriceA = Number(ProjectName.Projects.Projects_17.Price);
const projectPriceB = Number(ProjectName.Projects.Projects_18.Price);
const projectPriceC = Number(ProjectName.Projects.Projects_1.Price);
const SetMealPriceTC = Number(ProjectName.SetMeal.SetMeal_5.Price);
const ProductPrice = Number(ProjectName.Product.Product_4.Price);
const cardPrice = Number(CardType.CardTypeList.CardType_5.Price);
// 进入业绩明细表
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('业绩明细表');
// 项目销售记录遍历公用定位
const cede1 = page.locator('.popup_content .m-table__body-wrapper tbody .main-table-body_tr');
// 打开项目销售记录窗口
await page.locator('.m-table-footer .handleNumber').first().click();
await page.locator('.popup_content .title', { hasText: '项目销售记录' }).waitFor();
// 项目A项目名称、单号、员工定位器
const $project_a = cede1
.filter({ hasText: projectA })
.filter({ hasText: randomNumA })
.filter({ has: page.getByText(employee1) });
// 数量、金额、现金业绩
await expect.soft($project_a.locator('.m-table-cell').nth(6)).toContainText('1');
await expect.soft($project_a.locator('.m-table-cell').nth(7)).toContainText(`${projectPriceA}`);
await expect($project_a.locator('.m-table-cell').nth(8)).toContainText(`${projectPriceA * 0.8}`);
// 项目B项目名称、单号、员工定位器
const $project_b = cede1.filter({ hasText: projectB }).filter({ hasText: randomNumA });
// 数量、金额、现金业绩
await expect.soft($project_b.locator('.m-table-cell').nth(6)).toContainText('1');
await expect.soft($project_b.locator('.m-table-cell').nth(7)).toContainText(`${projectPriceB}`);
await expect($project_b.locator('.m-table-cell').nth(8)).toContainText(`${projectPriceB * 0.8}`);
// 项目C项目名称、单号、员工定位器
const $project_c = cede1.filter({ hasText: projectC }).filter({ hasText: randomNumA });
// 数量、金额、现金业绩
await expect.soft($project_c.locator('.m-table-cell').nth(6)).toContainText('1');
await expect.soft($project_c.locator('.m-table-cell').nth(7)).toContainText(`${projectPriceC}`);
await expect($project_c.locator('.m-table-cell').nth(8)).toContainText(`${projectPriceC * 0.8}`);
// 关闭窗口
await page.locator('.popup_content .close_icon').click();
// 打开项目消耗记录窗口
await page.locator('.m-table-footer').nth(1).locator('.handleNumber').first().click();
await page.locator('.popup_content .title', { hasText: '项目消耗记录' }).waitFor();
// 项目A项目名称、单号定位器
const $project_a_consume = cede1.filter({ hasText: projectA }).filter({ hasText: randomNumA });
// 数量、消耗业绩
await expect.soft($project_a_consume.locator('.m-table-cell').nth(6)).toContainText('1');
await expect($project_a_consume.locator('.m-table-cell').nth(8)).toContainText(`${projectPriceA}`);
// 关闭窗口
await page.locator('.popup_content .close_icon').click();
// 打开套餐包销售记录窗口
await page.locator('.m-table-footer').nth(2).locator('.handleNumber').first().click();
await page.locator('.popup_content .title', { hasText: '套餐包销售记录' }).waitFor();
const $project_c_setmeal = cede1.filter({ hasText: SetMeal }).filter({ hasText: randomNumA });
// 数量、金额、现金业绩
await expect.soft($project_c_setmeal.locator('.m-table-cell').nth(4)).toContainText('1');
await expect.soft($project_c_setmeal.locator('.m-table-cell').nth(5)).toContainText(`${SetMealPriceTC}`);
await expect($project_c_setmeal.locator('.m-table-cell').nth(6)).toContainText(`${SetMealPriceTC * 0.8}`);
// 关闭窗口
await page.locator('.popup_content .close_icon').click();
// 打开卖品销售记录窗口
await page.locator('.m-table-footer').nth(3).locator('.handleNumber').first().click();
await page.locator('.popup_content .title', { hasText: '卖品销售记录' }).waitFor();
const $project_d_product = cede1.filter({ hasText: Product }).filter({ hasText: randomNumA });
// 数量、金额、现金业绩
await expect.soft($project_d_product.locator('.m-table-cell').nth(5)).toContainText('1');
await expect.soft($project_d_product.locator('.m-table-cell').nth(6)).toContainText(`${ProductPrice}`);
await expect($project_d_product.locator('.m-table-cell').nth(7)).toContainText(`${ProductPrice * 0.8}`);
// 关闭窗口
await page.locator('.popup_content .close_icon').click();
// 打开会员卡销售记录窗口
await page.locator('.m-table-footer').nth(4).locator('.handleNumber').first().click();
await page.locator('.popup_content .title', { hasText: '会员卡销售记录' }).waitFor();
const $project_e_card = cede1.filter({ hasText: cardname }).filter({ hasText: usernameA });
// 数量、金额、现金业绩
await expect.soft($project_e_card.locator('.m-table-cell').nth(4)).toContainText(`${cardPrice}`);
await expect($project_e_card.locator('.m-table-cell').nth(5)).toContainText(`${cardPrice * 0.8}`);
});
});
test('自定义表格', async ({ page, homeNavigation, reportPage, performanceDetailReportPage }) => {
await test.step('打开业绩明细表保存报表数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('业绩明细表');
await performanceDetailReportPage.updateReportDataIndex();
await performanceDetailReportPage.updateReportDataForTableTotal();
await reportPage.closeRecommendReportPage();
});
const randomReportName = '自定义业绩明细表' + faker.string.alpha(3);
await test.step('新建一个业绩明细表,保存报表数据', async () => {
await reportPage.openCustomReportPage('业绩明细表');
await page.getByRole('button', { name: '保存并查询' }).click();
await page.getByPlaceholder('请输入最多15个字').fill(randomReportName);
await Promise.all([
await page.getByRole('button', { name: /保\s存/ }).click(),
await waitSpecifyApiLoad(page, ['/api/report']),
]);
await expect(page.getByRole('button', { name: /保\s存/ })).not.toBeVisible();
await page.getByText('自定义报表').waitFor();
await performanceDetailReportPage.updateReportDataForTableTotal();
});
await test.step('对比报表数据', async () => {
const reportData = performanceDetailReportPage.reportData;
reportPage.toBeReportDataAsExpected('项目销售', '数量', reportData, 0);
reportPage.toBeReportDataAsExpected('项目销售', '金额', reportData, 0);
reportPage.toBeReportDataAsExpected('项目销售', '现金业绩', reportData, 0);
await reportPage.closeCustomReportPage();
});
await test.step('编辑自定义报表', async () => {
await page
.locator('.m-report_custorm .item')
.filter({ has: page.getByText(randomReportName) })
.locator('.arrow')
.click(); // 点击箭头
await page.getByRole('menuitem', { name: '编辑' }).click(); // 点击删除
await page.getByLabel('项目销售', { exact: true }).uncheck();
await page.getByRole('button', { name: '保存并查询' }).click();
await expect(page.locator('.m-table__header-wrapper tr').first().locator('th').nth(1)).not.toContainText(
'项目销售',
);
await reportPage.closeCustomReportPage();
});
await reportPage.deleteCustomReportPage(randomReportName);
});
});
test.describe('项目销耗存表', () => {
test('数据校验', async ({ page, createCustomers, homeNavigation, reportPage, customerPage, numberInput }) => {
/** @type {Customer[]} */
let customers = [];
await test.step('创建两个顾客', async () => {
customers = await createCustomers(2);
});
if (!customers || customers.length < 2) {
throw new Error('创建顾客失败');
}
const ca = customers[0];
const cb = customers[1];
// 获取姓名、手机号、档案号
const usernameA = ca.username;
const phoneA = ca.phone;
const usernameB = cb.username;
const phoneB = cb.phone;
// 项目A
const projectA = ProjectName.Projects.Projects_8;
// 项目B
const projectB = ProjectName.Projects.Projects_12;
// 项目C
const projectC = ProjectName.Projects.Projects_11;
const $tr = page.locator('.m-table__body-wrapper').locator('.m-table__body tbody tr');
const $project_a = $tr.filter({ hasText: projectA.name });
const $project_b = $tr.filter({ hasText: projectB.name });
const $project_c = $tr.filter({ hasText: projectC.name });
// 定义初始数据
let SalesAmountVerify;
let SalesQuantityVerify;
let BuyersNumVerify;
let ConsumedAmountVerify;
let ConsumedQuantityVerify;
let ConsumedNumVerify;
let AdjustmentAmountBVerify;
let SwapoutQuantityVerify;
let AdjustmentAmountCVerify;
let SwapinQuantityVerify;
let TransfertoAmountVerify;
let TransfertoQuantityVerify;
let rolloutAmountVerify;
let rolloutQuantityVerify;
await test.step('进入项目销耗存表,获取初始数据', async () => {
await homeNavigation.gotoModule('报表');
await page.getByText('推荐报表').waitFor();
await reportPage.gotoSubPage('项目销耗存表');
await page.locator('.m-table__body-wrapper').waitFor();
await expect(page.locator('.m-table__icon__warp')).toBeHidden();
// 获取项目A的初始数据不存在则为0
try {
// 判断A项目是否存在
await expect($project_a).toBeVisible({ timeout: 10_000 });
// A初始销售金额
await $project_a
.locator('.m-table-cell')
.nth(4)
.innerText()
.then(text => {
if (text === '--') {
SalesAmountVerify = 0;
} else {
SalesAmountVerify = Number(KeepOnlyNumbers(text));
}
});
// A初始销售数量
await $project_a
.locator('.m-table-cell')
.nth(5)
.innerText()
.then(text => {
if (text === '--') {
SalesQuantityVerify = 0;
} else {
SalesQuantityVerify = Number(KeepOnlyNumbers(text));
}
});
// A初始购买人数
await $project_a
.locator('.m-table-cell')
.nth(7)
.innerText()
.then(text => {
if (text === '--') {
BuyersNumVerify = 0;
} else {
BuyersNumVerify = Number(KeepOnlyNumbers(text));
}
});
// A初始消耗金额
await $project_a
.locator('.m-table-cell')
.nth(10)
.innerText()
.then(text => {
if (text === '--') {
ConsumedAmountVerify = 0;
} else {
ConsumedAmountVerify = Number(KeepOnlyNumbers(text));
}
});
// A初始消耗数量
await $project_a
.locator('.m-table-cell')
.nth(11)
.innerText()
.then(text => {
if (text === '--') {
ConsumedQuantityVerify = 0;
} else {
ConsumedQuantityVerify = Number(KeepOnlyNumbers(text));
}
});
// A初始消耗人数
await $project_a
.locator('.m-table-cell')
.nth(13)
.innerText()
.then(text => {
if (text === '--') {
ConsumedNumVerify = 0;
} else {
ConsumedNumVerify = Number(KeepOnlyNumbers(text));
}
});
} catch (error) {
SalesAmountVerify = 0;
SalesQuantityVerify = 0;
BuyersNumVerify = 0;
ConsumedAmountVerify = 0;
ConsumedQuantityVerify = 0;
ConsumedNumVerify = 0;
console.log(`${projectA.name}不存在`);
}
// 获取项目B的初始数据不存在则为0
try {
// 判断B项目是否存在
await expect($project_b).toBeVisible({ timeout: 10_000 });
// B初始调整金额
await $project_b
.locator('.m-table-cell')
.nth(15)
.innerText()
.then(text => {
if (text === '--') {
AdjustmentAmountBVerify = 0;
} else {
AdjustmentAmountBVerify = Number(KeepOnlyNumbers(text));
}
});
// B初始换出数量
await $project_b
.locator('.m-table-cell')
.nth(16)
.innerText()
.then(text => {
if (text === '--') {
SwapoutQuantityVerify = 0;
} else {
SwapoutQuantityVerify = Number(KeepOnlyNumbers(text));
}
});
} catch (error) {
AdjustmentAmountBVerify = 0;
SwapoutQuantityVerify = 0;
AdjustmentAmountCVerify = 0;
console.log(`${projectB.name}不存在`);
}
// 获取项目C的初始数据不存在则为0
try {
// 判断C项目是否存在
await expect($project_c).toBeVisible({ timeout: 10_000 });
// C初始调整金额
await $project_c
.locator('.m-table-cell')
.nth(15)
.innerText()
.then(text => {
if (text === '--') {
AdjustmentAmountCVerify = 0;
} else {
AdjustmentAmountCVerify = Number(KeepOnlyNumbers(text));
}
});
// C初始换入数量
await $project_c
.locator('.m-table-cell')
.nth(17)
.innerText()
.then(text => {
if (text === '--') {
SwapinQuantityVerify = 0;
} else {
SwapinQuantityVerify = Number(KeepOnlyNumbers(text));
}
});
// C初始转入金额
await $project_c
.locator('.m-table-cell')
.nth(20)
.innerText()
.then(text => {
if (text === '--') {
TransfertoAmountVerify = 0;
} else {
TransfertoAmountVerify = Number(KeepOnlyNumbers(text));
}
});
// C初始转入数量
await $project_c
.locator('.m-table-cell')
.nth(22)
.innerText()
.then(text => {
if (text === '--') {
TransfertoQuantityVerify = 0;
} else {
TransfertoQuantityVerify = Number(KeepOnlyNumbers(text));
}
});
// C初始转出金额
await $project_c
.locator('.m-table-cell')
.nth(23)
.innerText()
.then(text => {
if (text === '--') {
rolloutAmountVerify = 0;
} else {
rolloutAmountVerify = Number(KeepOnlyNumbers(text));
}
});
// C初始转出数量
await $project_c
.locator('.m-table-cell')
.nth(25)
.innerText()
.then(text => {
if (text === '--') {
rolloutQuantityVerify = 0;
} else {
rolloutQuantityVerify = Number(KeepOnlyNumbers(text));
}
});
} catch (error) {
AdjustmentAmountCVerify = 0;
SwapinQuantityVerify = 0;
TransfertoAmountVerify = 0;
TransfertoQuantityVerify = 0;
rolloutAmountVerify = 0;
rolloutQuantityVerify = 0;
console.log(`${projectC.name}不存在`);
}
});
await test.step('顾客A购买A项目并消耗掉', async () => {
const employee1 = Employees.FirstShop.Employee_6.name;
// 点击顾客
await page.reload();
// 点击顾客
await homeNavigation.gotoModule('顾客');
// 输入信息
await customerPage.searchCustomer(phoneA);
await customerPage.selectSearchCustomer(usernameA);
// 点击进入详情
await page.locator('.user_info_head .user_name', { hasText: usernameA }).last().click();
await page.locator('span').filter({ hasText: '去开单' }).first().click();
// 购买项目A
await page.getByText(projectA.num).click();
// 点击添加员工
await page.locator('#buyList').getByRole('button').nth(1).click();
// 选择员工A
await page.locator('.hand_txt .name_txt').getByText(employee1).click();
// 确认
await page.getByRole('button', { name: /^确\s认$/ }).click();
// 点击体验换成普通
await page.locator('.type_btn').first().click();
await page.locator('.type_item', { hasText: '普通' }).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.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 test.step('顾客B购买项目B', async () => {
const employee2 = Employees.FirstShop.Employee_5.name;
// 点击顾客
await page.reload();
// 点击顾客
await homeNavigation.gotoModule('顾客');
// 输入信息
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(phoneB);
await page.getByText('搜索', { exact: true }).click();
await page.getByText(usernameB).click();
// 点击进入详情
await page.locator('.user_info_head .user_name', { hasText: usernameB }).last().click();
await page.locator('span').filter({ hasText: '去开单' }).first().click();
// 购买项目B
await page.getByText(projectB.num).click();
// 点击添加员工
await page.locator('#buyList').getByRole('button').nth(1).click();
// 选择员工B
await page.locator('.hand_txt .name_txt').getByText(employee2).click();
// 确认
await page.getByRole('button', { name: /^确\s认$/ }).click();
// 点击体验换成普通
await page.locator('.type_btn').first().click();
await page.locator('.type_item', { hasText: '普通' }).click();
// 结算
await page
.locator('div')
.filter({ hasText: /^结 算$/ })
.click();
// 结算,选择现金支付
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();
});
// 换入金额
const exchangeAmount = 16900;
await test.step('顾客B将项目B置换为项目C', async () => {
await page.reload();
// 进入顾客详情页面
await homeNavigation.gotoModule('顾客');
await customerPage.searchCustomer(phoneB);
await customerPage.selectSearchCustomer(usernameB);
await page.locator('.user_info_head .user_name', { hasText: usernameB }).last().click();
await page.locator('.treat_card').first().waitFor();
// 点击项目右下角更多三点
await page.locator('.treat_card .more').first().click();
await page.locator('.ant-dropdown-menu-item', { hasText: '换项目' }).click();
// 点击更换项目
await page.locator('.add_btns .add_btn').click();
// 输入项目C的编号
await page.locator('.comSelect_content_body .ant-input').fill(projectC.num);
// 搜索
await page.locator('.comSelect_content_body .ant-btn', { hasText: /^搜\s索$/ }).click();
await expect(async () => {
// 选择项目
await page.locator('.comSelect_content_body .ant-checkbox').click();
await page.locator('.menu-item-dot').first().waitFor({ timeout: 2000 });
await page.getByRole('button', { name: '确定选择' }).last().click();
const verify = page.locator('.comSelect_title', { hasText: '选择项目' }).last();
await expect(verify).not.toBeVisible({ timeout: 2000 });
}).toPass({ timeout: 60000 });
// 输入次数
await page.locator('.num_input').first().click();
await numberInput.setValue(1);
await numberInput.confirmValue();
await page.locator('.num_input').nth(1).click();
// 输入金额
await numberInput.setValue(exchangeAmount);
await numberInput.confirmValue();
await page.getByRole('button', { name: /确\s认/ }).click();
// 结算,选择现金支付
await page.getByText('现金', { exact: true }).click();
await page.getByLabel('结算签字').uncheck();
await page.getByRole('button', { name: /^结\s算$/ }).click();
await expect(page.locator('.ant-message', { hasText: '结算成功' })).toBeVisible();
});
await test.step('进入项目消耗存,校验数据变化', async () => {
// 进入报表
await page.reload();
// 点击顾客
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('项目销耗存表');
await page.locator('.m-table__body-wrapper').waitFor();
await expect(page.locator('.m-table__icon__warp')).toBeHidden();
// 项目A价格
const projectAmountA = Number(projectA.Price);
// 项目B价格
const projectAmountB = Number(projectB.Price);
// 判断A项目是否存在
await expect($project_a).toBeVisible();
// A销售金额
await expect
.soft($project_a.locator('.m-table-cell').nth(4))
.toContainText(`${SalesAmountVerify + projectAmountA}`);
// A销售数量
await expect.soft($project_a.locator('.m-table-cell').nth(5)).toContainText(`${SalesQuantityVerify + 1}`);
// A购买人数
await expect.soft($project_a.locator('.m-table-cell').nth(7)).toContainText(`${BuyersNumVerify + 1}`);
// A消耗金额
await expect
.soft($project_a.locator('.m-table-cell').nth(10))
.toContainText(`${ConsumedAmountVerify + projectAmountA}`);
// A消耗数量
await expect
.soft($project_a.locator('.m-table-cell').nth(11))
.toContainText(`${ConsumedQuantityVerify + 1}`);
// A消耗人数
await expect($project_a.locator('.m-table-cell').nth(13)).toContainText(`${ConsumedNumVerify + 1}`);
// 判断B项目是否存在
await expect($project_b).toBeVisible();
// B调整金额
await expect
.soft($project_b.locator('.m-table-cell').nth(15))
.toContainText(`${AdjustmentAmountBVerify + projectAmountB}`);
// B换出数量
await expect($project_b.locator('.m-table-cell').nth(16)).toContainText(`${SwapoutQuantityVerify + 1}`);
// 判断C项目是否存在
await expect($project_c).toBeVisible();
// C调整金额
await expect
.soft($project_c.locator('.m-table-cell').nth(15))
.toContainText(`${AdjustmentAmountCVerify + exchangeAmount}`);
// C换入数量
await expect($project_c.locator('.m-table-cell').nth(17)).toContainText(`${SwapinQuantityVerify + 1}`);
});
});
test('自定义报表', async ({ page, homeNavigation, reportPage, itemSalesConsumptionAccessReportPage }) => {
const item = { name: '', reportData: [] };
await test.step('打开项目销耗存表保存报表数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('项目销耗存表');
await itemSalesConsumptionAccessReportPage.updateReportDataIndex();
item.name = (await page.locator('.m-table-fixed-body tr').first().locator('td').nth(0).innerText()).trim();
await itemSalesConsumptionAccessReportPage.getSpecifyItemReportData(item.name, item.reportData);
await reportPage.closeRecommendReportPage();
});
const randomReportName = '自定义项目销耗存表' + faker.string.alpha(3);
await test.step('新建一个项目销耗存表,保存报表数据', async () => {
await reportPage.openCustomReportPage('项目销耗存表');
await page.getByRole('button', { name: '保存并查询' }).click();
await page.getByPlaceholder('请输入最多15个字').fill(randomReportName);
await Promise.all([
await page.getByRole('button', { name: /保\s存/ }).click(),
await waitSpecifyApiLoad(page, ['/api/report']),
]);
await expect(page.getByRole('button', { name: /保\s存/ })).not.toBeVisible();
await expect(page.getByText('自定义报表')).toBeVisible();
});
await test.step('对比报表数据', async () => {
await itemSalesConsumptionAccessReportPage.getSpecifyItemReportData(item.name, item.reportData);
const reportData = item.reportData;
reportPage.toBeReportDataAsExpected('期初', '期初金额', reportData, 0);
reportPage.toBeReportDataAsExpected('期初', '期初数量', reportData, 0);
reportPage.toBeReportDataAsExpected('期初', '期初赠送数量', reportData, 0);
reportPage.toBeReportDataAsExpected('销售', '销售金额', reportData, 0);
reportPage.toBeReportDataAsExpected('销售', '销售数量', reportData, 0);
reportPage.toBeReportDataAsExpected('消耗', '消耗金额', reportData, 0);
await reportPage.closeCustomReportPage();
});
await test.step('编辑自定义报表', async () => {
await page
.locator('.m-report_custorm .item')
.filter({ has: page.getByText(randomReportName) })
.locator('.arrow')
.click(); // 点击箭头
await page.getByRole('menuitem', { name: '编辑' }).click(); // 点击删除
await page.getByLabel('期初', { exact: true }).uncheck();
await page.getByRole('button', { name: '保存并查询' }).click();
await expect(page.locator('.m-table__header-wrapper tr').first().locator('th').nth(1)).not.toContainText(
'期初',
);
await reportPage.closeCustomReportPage();
});
await reportPage.deleteCustomReportPage(randomReportName);
});
});
test.describe('销售消耗汇总表', () => {
test('数据校验', async ({ page, homeNavigation, reportPage, createCustomer }) => {
const ca = createCustomer;
// 获取姓名、手机号、档案号
const usernameA = ca.username;
const phoneA = ca.phone;
let Cash;
let Expend;
await test.step('进入销售消耗汇总表,获取初始数据', async () => {
// 点击报表
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('销售消耗汇总表');
// 获取初始现金业绩
Cash = await page.locator('.m-table__body-wrapper .main-table-body_tr .m-table-cell').nth(1).innerText();
// 获取初始消耗业绩
Expend = await page.locator('.m-table__body-wrapper .main-table-body_tr .m-table-cell').nth(3).innerText();
});
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();
await page.locator('span').filter({ hasText: '去开单' }).first().click();
// 购买项目A
await page.getByText(ProjectName.Projects.Projects_4.num).click();
// 点击添加员工
await page.locator('#buyList').getByRole('button').nth(1).click();
// 选择员工A
const employee1 = Employees.FirstShop.Employee_6.name;
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('.treat_card_content').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.getByText('现金').click();
// 取消推送消息提醒
await page.getByLabel('推送消费提醒').uncheck();
// 取消结算签字
await page.getByLabel('结算签字').uncheck();
// 点击结算
await page.getByRole('button', { name: /^结\s算$/ }).click();
});
await test.step('进入销售消耗汇总表,校验数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('销售消耗汇总表');
// 获取现金业绩
const CashPerformance = await page
.locator('.m-table__body-wrapper .main-table-body_tr .m-table-cell')
.nth(1)
.innerText();
// 获取消耗业绩
const ExpendPerformance = await page
.locator('.m-table__body-wrapper .main-table-body_tr .m-table-cell')
.nth(3)
.innerText();
// 获取项目价格
const ProjectCash = Number(Number(ProjectName.Projects.Projects_4.Price) * 0.8) + Number(Cash) + '';
const ProjectPrice = Number(ProjectName.Projects.Projects_4.Price) + Number(Expend) + '';
// 对比现金业绩
expect(CashPerformance).toBe(ProjectCash);
// 对比消耗业绩
expect(ExpendPerformance).toBe(ProjectPrice);
});
});
test('自定义报表', async ({ page, homeNavigation, reportPage, salesCostSummaryReportPage }) => {
await test.step('打开销售消耗汇总表保存报表数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('销售消耗汇总表');
await salesCostSummaryReportPage.updateReportDataIndex();
await salesCostSummaryReportPage.updateReportData(1);
await reportPage.closeRecommendReportPage();
});
const randomReportName = '自定义销售消耗汇总表' + faker.string.alpha(3);
await test.step('新建一个销售消耗汇总表,保存报表数据', async () => {
await reportPage.openCustomReportPage('销售消耗汇总表');
await page.getByRole('button', { name: '保存并查询' }).click();
await page.getByPlaceholder('请输入最多15个字').fill(randomReportName);
await Promise.all([
await page.getByRole('button', { name: /保\s存/ }).click(),
await waitSpecifyApiLoad(page, ['/api/report']),
]);
await expect(page.getByRole('button', { name: /保\s存/ })).not.toBeVisible();
await expect(page.getByText('自定义报表')).toBeVisible();
await salesCostSummaryReportPage.updateReportData(1);
});
await test.step('对比报表数据', async () => {
const reportData = salesCostSummaryReportPage.reportData;
reportPage.toBeReportDataAsExpected('护理', '现金业绩', reportData, 0);
reportPage.toBeReportDataAsExpected('面部', '现金业绩', reportData, 0);
reportPage.toBeReportDataAsExpected('身体', '现金业绩', reportData, 0);
reportPage.toBeReportDataAsExpected('组合项目', '现金业绩', reportData, 0);
await reportPage.closeCustomReportPage();
});
await test.step('编辑自定义报表', async () => {
await page
.locator('.m-report_custorm .item')
.filter({ has: page.getByText(randomReportName) })
.locator('.arrow')
.click(); // 点击箭头
await page.getByRole('menuitem', { name: '编辑' }).click(); // 点击删除
await page.getByLabel('护理', { exact: true }).check();
await page.getByLabel('护理', { exact: true }).uncheck();
await page.getByRole('button', { name: '保存并查询' }).click();
await expect(page.locator('.m-table__header-wrapper tr').first().locator('th').nth(1)).not.toContainText(
'护理',
);
await reportPage.closeCustomReportPage();
});
await reportPage.deleteCustomReportPage(randomReportName);
});
});
test.describe('业绩汇总表', () => {
test('数据校验', async ({
page,
homeNavigation,
createCustomer,
reportPage,
performanceSummaryReportPage,
customerPage,
numberInput,
}) => {
// 项目
const project = { no: '100019', name: '青春焕活套', price: 880, count: 1 };
// 卖品
const goods = { no: 'aa100045', name: '马郁兰精油', price: 800 };
// 套餐
const setMeal = {
name: '套餐包TCBB004',
price: 900,
projects: [
{ no: '', name: '净颜水润美肌套', price: 200, number: 1 },
{ no: '', name: '雪肌晶纯护理', price: 300, number: 1 },
],
goods: [{ no: '', name: '青春护理套', price: 400, number: 1 }],
};
// 卡金
let cardGold = 5000;
// 门店现金支付业绩比例
let storeSalesRatio = 0.8;
// 充值会员卡金额
let rechargeAmount = 1000;
// 其他--支出金额
let spendingAmount = 1000;
const customer = createCustomer;
await test.step('拿取业绩汇总表的各个列的索引,和初始数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('业绩汇总表');
await performanceSummaryReportPage.updateReportDataIndex();
await performanceSummaryReportPage.updateReportDataFromTotal();
await reportPage.closeRecommendReportPage();
});
await test.step('开原价卡5000元赠金3000元使用现金结算', async () => {
// 打开顾客详情页面
await homeNavigation.gotoModule('顾客');
await customerPage.searchCustomer(customer.phone);
await customerPage.selectSearchCustomer(customer.username);
await page.locator('.m-table__fixed-left').getByText(customer.username).click();
// 去开卡
await page
.locator('.info_package')
.getByRole('button', { name: /开\s卡/ })
.click();
await page.locator('.openCard_box', { hasText: '会员卡购买' }).waitFor();
await page.locator('.openCard_box .memberCard_box', { hasText: '原价卡' }).click();
await page.getByRole('button', { name: '去结算' }).click();
// 使用现金进行结算
await page.getByLabel('推送消费提醒').uncheck();
await page.getByLabel('结算签字').uncheck();
await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click();
await page.getByRole('button', { name: /结\s算/ }).click();
await page.locator('.popup_content', { hasText: '会员协议签署确认' }).waitFor();
await page.getByRole('button', { name: /跳\s过/ }).click();
// 给会员卡充值1000
await page
.getByRole('button', { name: /^充\s值$/ })
.first()
.click();
await page
.locator('.left .row', { hasText: /充值\s总额/ })
.locator('.touchIcon')
.first()
.click();
await numberInput.setValue(rechargeAmount);
await numberInput.confirmValue();
await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click();
await page.getByRole('button', { name: /结\s算/ }).click();
});
await test.step('购买套餐和项目进行混合支付结算', async () => {
// 去购买项目、套餐、卖品
await page.locator('.right_util .goto_pay_cash', { hasText: '去开单' }).click();
// 购买项目project并消耗价格880
await page
.locator('.project_list .number', {
hasText: project.no,
})
.click();
await page.locator('#shoppingCart .commodity_list li').first().click();
// 购买套餐价格1000
await page.locator('.float_tab .item', { hasText: '套餐' }).click();
await page.locator('.item', { hasText: setMeal.name }).click();
// 购买卖品价格800
await page.locator('.float_tab .item', { hasText: '卖品' }).click();
const goodsLocator = page.locator('.project_list .number').filter({ hasText: goods.no });
// 获取获取滚动窗口高度每次滚动一个卖品div高度去判断需要的卖品存在
await page.locator('.project_box .scroller-body').waitFor();
const scrollHeight = await page.evaluate(() => {
const scrollContainer = document.querySelector('.project_box .scroller-body');
return scrollContainer ? scrollContainer.scrollHeight : 0;
});
const moveHeight = await page
.locator('.list_box .project_list')
.first()
.boundingBox()
.then(box => {
if (box) {
return box.height;
} else {
return 0;
}
});
let startScroll = 0;
let endScroll = scrollHeight;
let findStatus = false;
while (startScroll < endScroll) {
startScroll += moveHeight;
console.log(startScroll);
// 每次移动一个高度的卖品盒子
await page.evaluate(moveHeight => {
const scrollContainer = document.querySelector('.project_box .scroller-body');
if (scrollContainer) {
scrollContainer.scrollBy(0, moveHeight);
}
}, moveHeight);
// 发现goodsLocator就退出
findStatus = await goodsLocator.isVisible();
console.log(findStatus);
if (findStatus) {
break;
}
}
console.log(findStatus);
await goodsLocator.scrollIntoViewIfNeeded();
await goodsLocator.click();
await page.locator('.pay_btn', { hasText: /结\s算/ }).click();
// 混合支付
// 左右两侧的支付方式定位器
const rightPaymentInfoItem = page.locator('.right .paymentmain .paymentInfoItem');
const leftPaymentInfoItem = page.locator('.left .paymentmain .paymentInfoItem');
const payListLocator = page.locator('.service_area .itemlist_radio_group .ant-radio-wrapper');
await leftPaymentInfoItem.filter({ hasText: '混合支付' }).click();
// 指定项目使用卡金支付全部金额880
await rightPaymentInfoItem.filter({ hasText: '卡金' }).click();
await payListLocator.filter({ hasText: project.name }).first().getByRole('radio').check();
await page.getByRole('button', { name: '增加收款' }).click();
await page.getByPlaceholder('请输入内容@.').fill(String(project.price));
await page.locator('.number_tr').nth(2).getByRole('button').nth(3).click();
// 指定套餐里的一个项目,使用赠金支付全部金额,雪肌晶纯护理 300
await rightPaymentInfoItem.filter({ hasText: '赠金' }).click();
await payListLocator
.filter({ hasText: setMeal.projects[setMeal.projects.length - 1].name })
.first()
.getByRole('radio')
.check();
await page.getByRole('button', { name: '增加收款' }).click();
await page
.locator('.popup_content input')
.fill(String(setMeal.projects[setMeal.projects.length - 1].price));
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();
// 结算
await page.getByLabel('推送消费提醒').uncheck();
await page.getByLabel('结算签字').uncheck();
await page.getByRole('button', { name: /^结\s算$/ }).click();
await page.locator('.popup_content', { hasText: '会员协议签署确认' }).waitFor();
await page.getByRole('button', { name: /跳\s过/ }).click();
await page.getByRole('button', { name: '不寄存' }).click();
});
await test.step('进入其他对一店开支1000元', async () => {
await homeNavigation.gotoModule('其他');
await page.locator('#frame_detail .top_tab .tab_item', { hasText: '开支' }).click();
await page.locator('.shopname').click();
await page.locator('.shopSelect_shop_content').click();
// 门店选择器,选择一店
await page.locator('.list_box .label').nth(1).click();
await page.getByRole('button', { name: /保\s存/ }).click();
await page.getByRole('button', { name: '新增支出' }).click();
const selectInput = page.locator('.container .ant-form .item');
await selectInput.filter({ hasText: '开支类型' }).locator('div').nth(1).click();
await page.getByLabel('顾客餐').click();
await page
.locator('.popup_content')
.getByRole('button', { name: /^确\s认$/ })
.click();
await selectInput.filter({ hasText: '开支金额' }).locator('div').nth(1).click();
// 支出金额1000
await numberInput.setValue(spendingAmount);
await numberInput.confirmValue();
await Promise.all([
await page.getByRole('button', { name: /^确\s认$/ }).click(),
await page.waitForResponse(async res => {
return res.url().includes('/expense') && res.request().method() === 'POST';
}),
]);
});
await test.step('进入业绩汇总表查询并且对比数据', async () => {
// 进入业绩汇总表
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('业绩汇总表');
await page.getByRole('cell', { name: '营收明细' }).waitFor();
// 拿取业绩汇总表相关数据
await performanceSummaryReportPage.updateReportDataFromTotal();
const reportData = performanceSummaryReportPage.reportData;
console.log(JSON.stringify(reportData));
reportPage.toBeReportDataAsExpected(
'营收明细',
'现金类总额',
reportData,
cardGold +
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price,
);
// 卡金 + 充值卡金 + 套餐现金支付 + 卖品现金支付
reportPage.toBeReportDataAsExpected(
'营收明细',
'现金',
reportData,
cardGold +
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price,
);
// 项目一
reportPage.toBeReportDataAsExpected('营收明细', '划卡', reportData, project.price);
// 套餐内的项目四
reportPage.toBeReportDataAsExpected(
'营收明细',
'划赠金',
reportData,
setMeal.projects[setMeal.projects.length - 1].price,
);
// 2. 开支明细--支出总额 + 1000
reportPage.toBeReportDataAsExpected('开支明细', '支出总额', reportData, spendingAmount);
// 3. 现金业绩
reportPage.toBeReportDataAsExpected(
'现金业绩',
'项目合计',
reportData,
(setMeal.price - setMeal.projects[setMeal.projects.length - 1].price - setMeal.goods[0].price) *
storeSalesRatio,
);
reportPage.toBeReportDataAsExpected(
'现金业绩',
'卖品业绩',
reportData,
(setMeal.goods[0].price + goods.price) * storeSalesRatio,
);
reportPage.toBeReportDataAsExpected(
'现金业绩',
'开充卡业绩',
reportData,
(cardGold + 1000) * storeSalesRatio,
);
reportPage.toBeReportDataAsExpected('现金业绩', '开卡业绩', reportData, cardGold * storeSalesRatio);
reportPage.toBeReportDataAsExpected('现金业绩', '充值业绩', reportData, 1000 * storeSalesRatio);
// (卡金 + 充值卡金 + 套餐现金支付 + 卖品现金支付) * 门店现金支付业绩比例
reportPage.toBeReportDataAsExpected(
'现金业绩',
'总现金业绩',
reportData,
(cardGold +
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price) *
storeSalesRatio,
);
// 4. 划卡业绩--指定项目880
reportPage.toBeReportDataAsExpected('划卡业绩', '项目合计', reportData, project.price);
// 5. 消耗业绩
reportPage.toBeReportDataAsExpected('消耗业绩', '总消耗业绩', reportData, project.price);
reportPage.toBeReportDataAsExpected('消耗业绩', '项目总数', reportData, project.count);
// 6. 客流
reportPage.toBeReportDataAsExpected('客流', '客数', reportData, 1);
reportPage.toBeReportDataAsExpected('客流', '客次', reportData, 1);
// 7. 套餐销售
reportPage.toBeReportDataAsExpected('套餐销售', '总数量', reportData, 1);
reportPage.toBeReportDataAsExpected('套餐销售', '普通数量', reportData, 1);
reportPage.toBeReportDataAsExpected('套餐销售', '总金额', reportData, setMeal.price);
// 现金支付700 * 0.8 + 赠金支付300
reportPage.toBeReportDataAsExpected(
'套餐销售',
'总业绩',
reportData,
(setMeal.price - setMeal.projects[setMeal.projects.length - 1].price) * storeSalesRatio +
setMeal.projects[setMeal.projects.length - 1].price,
);
// 8. 卖品销售
reportPage.toBeReportDataAsExpected('卖品销售', '总数量', reportData, 2);
reportPage.toBeReportDataAsExpected('卖品销售', '普通数量', reportData, 2);
reportPage.toBeReportDataAsExpected('卖品销售', '总金额', reportData, goods.price + setMeal.goods[0].price);
reportPage.toBeReportDataAsExpected(
'卖品销售',
'总业绩',
reportData,
(goods.price + setMeal.goods[0].price) * storeSalesRatio,
);
});
});
test('自定义报表', async ({ page, homeNavigation, reportPage, performanceSummaryReportPage }) => {
await test.step('打开业绩汇总表保存报表数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('业绩汇总表');
await performanceSummaryReportPage.updateReportDataIndex();
await performanceSummaryReportPage.updateReportDataFromTotal();
await reportPage.closeRecommendReportPage();
});
const randomReportName = '自定义业绩汇总表' + faker.string.alpha(3);
await test.step('新建一个业绩汇总表,保存报表数据', async () => {
await reportPage.openCustomReportPage('业绩汇总表');
await page.getByRole('button', { name: '保存并查询' }).click();
await page.getByPlaceholder('请输入最多15个字').fill(randomReportName);
await Promise.all([
await page.getByRole('button', { name: /保\s存/ }).click(),
await waitSpecifyApiLoad(page, ['/api/report']),
]);
await expect(page.getByRole('button', { name: /保\s存/ })).not.toBeVisible();
await expect(page.getByText('自定义报表')).toBeVisible();
await performanceSummaryReportPage.updateReportDataFromTotal();
});
await test.step('对比报表数据', async () => {
const reportData = performanceSummaryReportPage.reportData;
reportPage.toBeReportDataAsExpected('营收明细', '现金', reportData, 0);
reportPage.toBeReportDataAsExpected('营收明细', '划卡', reportData, 0);
reportPage.toBeReportDataAsExpected('营收明细', '划赠金', reportData, 0);
reportPage.toBeReportDataAsExpected('开支明细', '支出总额', reportData, 0);
await reportPage.closeCustomReportPage();
});
await test.step('编辑自定义报表', async () => {
await page
.locator('.m-report_custorm .item')
.filter({ has: page.getByText(randomReportName) })
.locator('.arrow')
.click(); // 点击箭头
await page.getByRole('menuitem', { name: '编辑' }).click(); // 点击删除
await page.getByLabel('营收明细', { exact: true }).check();
await page.getByLabel('营收明细', { exact: true }).uncheck();
await page.getByRole('button', { name: '保存并查询' }).click();
await expect(page.locator('.m-table__header-wrapper tr').first().locator('th').nth(1)).not.toContainText(
'营收明细',
);
await reportPage.closeCustomReportPage();
});
await reportPage.deleteCustomReportPage(randomReportName);
});
});
test.describe('储值卡卡金变动表', () => {
test('数据校验', async ({
page,
homeNavigation,
reportPage,
cardBalanceChangeReportPage,
createCustomer,
customerPage,
numberInput,
}) => {
const customer = createCustomer;
const card_a = {
cardNo: '',
name: '原价卡',
cardGold: 5000,
cardBonus: 3000,
remark: '卡A',
reportData: [],
};
await test.step('进入储值卡卡金变动表获取报表索引、卡A数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('储值卡卡金变动表');
// 更新报表索引
await cardBalanceChangeReportPage.updateReportDataIndex();
// 获取卡A的报表数据
await cardBalanceChangeReportPage.getSpecifyCardReportData(card_a.name, card_a.reportData);
// 关闭推荐报表
await reportPage.closeRecommendReportPage();
});
// 开卡窗口的各个开的定位器
const openCardBox = page.locator('.openCard_box .memberCard_box');
await test.step('给顾客A进行开卡', async () => {
// 进入顾客详情页面
await homeNavigation.gotoModule('顾客');
await customerPage.searchCustomer(customer.phone);
await customerPage.selectSearchCustomer(customer.username);
await page.locator('.m-table__fixed-left').getByText(customer.username).click();
await page.getByRole('button', { name: /开\s卡/ }).click();
await page.locator('.openCard_box', { hasText: '会员卡购买' }).waitFor();
// 选择卡A备注以后进行结算
await openCardBox
.filter({
has: page.locator('.card_name', { hasText: new RegExp(`^${card_a.name}$`) }),
})
.click();
await page.locator('.remark', { hasText: '可输入卡备注' }).click();
await page.getByPlaceholder('请输入1-100个字符备注内容').fill(card_a.remark);
await page.getByRole('button', { name: /确\s认/ }).click();
await page.getByRole('button', { name: '去结算' }).click();
// 使用现金进行结算
await page.getByLabel('推送消费提醒').uncheck();
await page.getByLabel('结算签字').uncheck();
await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click();
await page.getByRole('button', { name: /结\s算/ }).click();
await page.locator('.popup_content', { hasText: '会员协议签署确认' }).waitFor();
await page.getByRole('button', { name: /跳\s过/ }).click();
});
await test.step('卡A充1000赠200修改卡金+1000', async () => {
// 充值金额
const rechargeAmount = 1000;
// 赠送金额
const bonusAmount = 200;
// 修改卡金金额
const modifyCardGold = 1000;
// 给会员卡充值1000赠送200
await page
.getByRole('button', { name: /^充\s值$/ })
.first()
.click();
await page
.locator('.left .row', { hasText: /充值\s总额/ })
.locator('.touchIcon')
.first()
.click();
await numberInput.setValue(rechargeAmount);
await numberInput.confirmValue();
await page.locator('.left .row', { hasText: '赠送金' }).locator('.anticon').last().click();
await numberInput.setValue(bonusAmount);
await numberInput.confirmValue();
await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click();
await page.getByRole('button', { name: /结\s算/ }).click();
await page.locator('.membercard_box', { hasText: '卡A' }).locator('.card_control_btn > .more').click();
await page.getByRole('menuitem', { name: '修改卡金' }).click();
await numberInput.setValue(card_a.cardGold + rechargeAmount + modifyCardGold);
await numberInput.confirmValue();
await page.getByPlaceholder('请输入1-100个字符备注内容').fill('修改卡金+1000');
await page.getByRole('button', { name: /确\s认/ }).click();
await expect(
page.getByText(`¥${card_a.cardGold + rechargeAmount + modifyCardGold}`, {
exact: true,
}),
).toBeVisible();
await page.locator('.close_icons').click();
});
await test.step('进入储值卡卡金变动表,进行比较卡金变动', async () => {
// 进入储值卡卡金变动表
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('储值卡卡金变动表');
// 获取卡A的报表数据
await cardBalanceChangeReportPage.getSpecifyCardReportData(card_a.name, card_a.reportData);
// 查看会员卡A的变动
reportPage.toBeReportDataAsExpected('开充卡', '开充卡金', card_a.reportData, card_a.cardGold + 1000);
reportPage.toBeReportDataAsExpected('开充卡', '开充赠金', card_a.reportData, card_a.cardBonus + 200);
reportPage.toBeReportDataAsExpected('调整', '修改卡金', card_a.reportData, 1000);
reportPage.toBeReportDataAsExpected('结余', '结余卡金', card_a.reportData, card_a.cardGold + 2000);
reportPage.toBeReportDataAsExpected('结余', '结余赠金', card_a.reportData, card_a.cardBonus + 200);
reportPage.toBeReportDataAsExpected('变动', '卡金变动', card_a.reportData, card_a.cardGold + 2000);
reportPage.toBeReportDataAsExpected('变动', '赠金变动', card_a.reportData, card_a.cardBonus + 200);
});
});
test('自定义报表', async ({ page, homeNavigation, reportPage, cardBalanceChangeReportPage }) => {
const card = {
cardNo: '',
name: '原价卡',
cardGold: 5000,
cardBonus: 3000,
remark: '卡A',
reportData: [],
};
await test.step('打开储值卡卡金变动表保存报表数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('储值卡卡金变动表');
await cardBalanceChangeReportPage.updateReportDataIndex();
await cardBalanceChangeReportPage.getSpecifyCardReportData(card.name, card.reportData);
await reportPage.closeRecommendReportPage();
});
const randomReportName = '自定义储值卡卡金变动表' + faker.string.alpha(3);
await test.step('新建一个储值卡卡金变动表,保存报表数据', async () => {
await reportPage.openCustomReportPage('储值卡卡金变动表');
await page.getByRole('button', { name: '保存并查询' }).click();
await page.getByPlaceholder('请输入最多15个字').fill(randomReportName);
await Promise.all([
await page.getByRole('button', { name: /保\s存/ }).click(),
await waitSpecifyApiLoad(page, ['/api/report']),
]);
await expect(page.getByRole('button', { name: /保\s存/ })).not.toBeVisible();
await expect(page.getByText('自定义报表')).toBeVisible();
});
await test.step('对比报表数据', async () => {
await cardBalanceChangeReportPage.getSpecifyCardReportData(card.name, card.reportData);
const reportData = card.reportData;
reportPage.toBeReportDataAsExpected('期初', '期初卡金', reportData, 0);
reportPage.toBeReportDataAsExpected('期初', '期初赠金', reportData, 0);
reportPage.toBeReportDataAsExpected('消费', '消费卡金', reportData, 0);
reportPage.toBeReportDataAsExpected('消费', '消费赠金', reportData, 0);
reportPage.toBeReportDataAsExpected('开充卡', '开充卡金', reportData, 0);
reportPage.toBeReportDataAsExpected('开充卡', '开充赠金', reportData, 0);
await reportPage.closeCustomReportPage();
});
await test.step('编辑自定义报表', async () => {
await page
.locator('.m-report_custorm .item')
.filter({ has: page.getByText(randomReportName) })
.locator('.arrow')
.click(); // 点击箭头
await page.getByRole('menuitem', { name: '编辑' }).click(); // 点击删除
await page.getByLabel('期初', { exact: true }).check();
await page.getByLabel('期初', { exact: true }).uncheck();
await page.getByRole('button', { name: '保存并查询' }).click();
await expect(page.locator('.m-table__header-wrapper tr').first().locator('th').nth(1)).not.toContainText(
'期初',
);
await reportPage.closeCustomReportPage();
});
await reportPage.deleteCustomReportPage(randomReportName);
});
});
test.describe('开支汇总表', () => {
test('数据校验', async ({ page, homeNavigation, reportPage, spendingSummaryReportPage, numberInput }) => {
// 进入开支汇总表
await test.step('进入开支汇总表,获取数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('开支汇总表');
await spendingSummaryReportPage.updateReportDataIndex();
await spendingSummaryReportPage.updateReportData(1);
await reportPage.closeRecommendReportPage();
});
await test.step('新增门店一的开支', async () => {
await homeNavigation.gotoModule('其他');
await page.locator('#frame_detail .top_tab .tab_item', { hasText: '开支' }).click();
await page.locator('.shopname').click();
await page.locator('.shopSelect_shop_content').click();
// 门店选择器,选择一店
await page.locator('.list_box .label').nth(1).click();
await page.getByRole('button', { name: /保\s存/ }).click();
await page.getByRole('button', { name: '新增支出' }).click();
const selectInput = page.locator('.container .ant-form .item');
await selectInput.filter({ hasText: '开支类型' }).locator('div').nth(1).click();
await page.getByLabel('顾客餐').click();
await page
.locator('.popup_content')
.getByRole('button', { name: /^确\s认$/ })
.click();
await selectInput.filter({ hasText: '开支金额' }).locator('div').nth(1).click();
// 支出金额1000
await numberInput.setValue(1000);
await numberInput.confirmValue();
await page.getByRole('button', { name: /^确\s认$/ }).click();
});
await test.step('进入开支汇总表,获取数据进行比较', async () => {
// 进入开支汇总表
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('开支汇总表');
await page.getByRole('cell', { name: '门店', exact: true }).waitFor();
await spendingSummaryReportPage.updateReportData(1);
await reportPage.closeRecommendReportPage();
const reportData = spendingSummaryReportPage.reportData;
reportPage.toBeReportDataAsExpected('支出汇总', '累计支出', reportData, 1000);
reportPage.toBeReportDataAsExpected('支出汇总', '营业收入支出', reportData, 1000);
reportPage.toBeReportDataAsExpected('日常开支', '顾客餐', reportData, 1000);
});
});
});
test.describe('顾客消费分析表', () => {
test('数据校验', async ({
page,
homeNavigation,
createCustomer,
reportPage,
customerPage,
customerConsumptionAnalysisReportPage,
}) => {
const customer = createCustomer;
// 购买并消耗项目
const project = {
no: '100018',
name: '苹果精萃护理',
shortName: '精萃护理',
price: 980,
};
await test.step('进入顾客消费分析表,获取数据', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('顾客消费分析表');
await page.getByRole('cell', { name: '顾客' }).waitFor();
await page.getByRole('button').nth(2).click();
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone);
await Promise.all([
page
.locator('.shopSelect_box')
.getByRole('button', { name: /查\s询/ })
.click(),
page.waitForResponse('**/GKXFFX/**'),
]);
await customerConsumptionAnalysisReportPage.updateReportDataIndex();
await customerConsumptionAnalysisReportPage.updateReportData(customer);
await reportPage.closeRecommendReportPage();
});
await test.step('购买项目并消耗,获取数据进行比较', async () => {
await homeNavigation.gotoModule('收银');
await page.getByRole('button', { name: /开\s单/ }).click();
await customerPage.searchCustomer(customer.phone);
await customerPage.selectSearchCustomer(customer.username);
// 购买项目并消耗价格980
await page
.locator('.project_list .number', {
hasText: project.no,
})
.click();
await page.locator('#shoppingCart .commodity_list li').first().click();
// 结算
await page.getByText(/结\s算/).click();
await page.getByLabel('推送消费提醒').uncheck();
await page.getByLabel('结算签字').uncheck();
await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click();
await page.getByRole('button', { name: /结\s算/ }).click();
await expect(page.getByRole('button', { name: /开\s单/ })).toBeVisible();
});
await test.step('进入顾客消费分析表,获取数据进行比较', async () => {
await homeNavigation.gotoModule('报表');
await reportPage.gotoSubPage('顾客消费分析表');
await page.getByRole('cell', { name: '顾客' }).waitFor();
await page.getByRole('button').nth(2).click();
await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone);
await Promise.all([
page
.locator('.shopSelect_box')
.getByRole('button', { name: /查\s询/ })
.click(),
page.waitForResponse('**/GKXFFX/**'),
]);
await customerConsumptionAnalysisReportPage.updateReportData(customer);
const reportData = customerConsumptionAnalysisReportPage.reportData;
console.log(reportData);
reportPage.toBeReportDataAsExpected('到店次数', '', reportData, 1);
reportPage.toBeReportDataAsExpected('消费次数', '', reportData, 1);
reportPage.toBeReportDataAsExpected('消费金额', '', reportData, project.price);
// reportPage.toBeReportDataAsExpected('护理(购买)', '现金', reportData, project.price);
// reportPage.toBeReportDataAsExpected('护理(购买)', '划卡金', reportData, 0);
});
});
});