refactor(tests): 重构测试代码并优化环境变量配置

- 更新环境变量配置方式,使用 dotenv 库
- 重构员工登录和权限相关代码,提高可维护性
- 优化测试数据结构,增加类型注解
- 删除冗余代码,提高代码可读性
This commit is contained in:
LingandRX 2025-01-01 13:02:27 +08:00
parent c9a8014c09
commit 345e68a1b4
14 changed files with 217 additions and 188 deletions

34
.env
View File

@ -1,22 +1,22 @@
QY_WECHAT_ROOTBOT_URL='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=1c7d2bf1-eae9-4ee9-bdfb-b578e747f2dc'
BASE_URL = 'https://hlk.meiguanjia.net/'
boss_account= "17770720220"
boss_password= "a123456"
boss_account_2= "1770720220"
boss_password_2= "a123456"
staff1_account= "17770720221"
staff1_password= "a123456"
staff2_account= "17770720222"
staff2_password= "a123456"
BASE_URL='https://hlk.meiguanjia.net/'
boss_account="17770720220"
boss_password="a123456"
boss_account_2="1770720220"
boss_password_2="a123456"
staff1_account="17770720221"
staff1_password="a123456"
staff2_account="17770720222"
staff2_password="a123456"
STOREH5_URL = 'https://hlk.meiguanjia.net/h5/#/?env=0&mid=14920&tv=qym&query=%257B%2522tab%2522%253A%2522MALL%2522%257D'
STOREH5_URL ='https://hlk.meiguanjia.net/h5/#/?env=0&mid=14920&tv=qym&query=%257B%2522tab%2522%253A%2522MALL%2522%257D'
WEB_AUTH_USERNAME='mgj'
WEB_AUTH_PASSWORD='mgj123456'
DOMAIN_URL = 'https://autotest.meiguanjia.net'
SERVER_PORT = 9901
PROXY_SERVER_PORT = 9900
LDAP_BindURL = 'ldap://ldapadmin.meiguanjia.net:389'
LDAP_bindDN = 'cn=admin,dc=meiguanjia,dc=net'
LDAP_bindUserDN = 'ou=person,dc=meiguanjia,dc=net'
LDAPbindPSW = '!qaz2Wsxyjy0102'
DOMAIN_URL='https://autotest.meiguanjia.net'
SERVER_PORT=9901
PROXY_SERVER_PORT=9900
LDAP_BindURL='ldap://ldapadmin.meiguanjia.net:389'
LDAP_bindDN='cn=admin,dc=meiguanjia,dc=net'
LDAP_bindUserDN='ou=person,dc=meiguanjia,dc=net'
LDAPbindPSW='!qaz2Wsxyjy0102'

View File

@ -1,6 +1,6 @@
// @ts-check
const { defineConfig, devices } = require('@playwright/test');
// import dotenv from "dotenv";
import dotenv from "dotenv";
import path from 'path';
import { firstAccount, secondAccount } from './tests/common/auth';
@ -10,12 +10,12 @@ import { firstAccount, secondAccount } from './tests/common/auth';
*/
require('dotenv').config({ path: path.resolve(__dirname, '.env') });
// dotenv.config({
// path: path.resolve(
// __dirname,
// ".env" + `${process.env.NODE_ENV ? "." + process.env.NODE_ENV : ""}`
// ),
// });
dotenv.config({
path: path.resolve(
__dirname,
".env" + `${process.env.NODE_ENV ? "." + process.env.NODE_ENV : ""}`
),
});
const firstAuthFile = firstAccount.authFile;
const secondAuthFile = secondAccount.authFile;

View File

@ -1,17 +1,5 @@
//@ts-check
// 默认为生产
let nodeEnv = process.env.NODE_ENV || 'production';
nodeEnv = nodeEnv === 'staging' ? 'production' : nodeEnv;
/**
* -
* - staffData.firstStore.firstSector.employee_1.name
* -
* - staffData.firstStore.firstSector.employee_1.phone
* - ID
* - staffData.firstStore.firstSector.employee_1.id
*/
let staffData = {
const staffData = {
firstStore: {
firstSector: {
name: '美容部',
@ -177,38 +165,4 @@ let staffData = {
},
};
/**
*
* @param {Object} staffData
* @param {string} nodeEnv
* @returns
*/
function init(staffData, nodeEnv) {
const updatedData = JSON.parse(JSON.stringify(staffData)); // 深拷贝对象,避免修改原数据
function updateIds(sector) {
Object.keys(sector).forEach(key => {
const employee = sector[key];
if (employee && employee.id && employee.id[nodeEnv] !== undefined) {
employee.id = employee.id[nodeEnv]; // 将 id 替换为 production 或 test 的值
}
});
}
// 遍历 firstStore 和 secondStore 下的各个 sector更新员工的 id
Object.keys(updatedData).forEach(storeKey => {
const store = updatedData[storeKey];
Object.keys(store).forEach(sectorKey => {
const sector = store[sectorKey];
if (typeof sector === 'object' && sector !== null && sector.name) {
updateIds(sector); // 更新每个 sector 的员工 id
}
});
});
return updatedData; // 返回更新后的数据
}
staffData = init(staffData, nodeEnv);
export { staffData };

View File

@ -1,30 +1,3 @@
// 会员信息
export const Member = {
//测试会员
MemName_0: {
name: "测试会员",
PhoneNum: "1112223334",
},
// 陈世美
MemName_1: {
name: "陈世美",
PhoneNum: "15099903112",
},
// 潘金莲
MemName_2: {
name: "潘金莲",
PhoneNum: "15099903111",
},
// 武大郎
MemName_3: {
name: "武大郎",
PhoneNum: "15099903110",
},
MemName_4: {
name: "随机会员",
PhoneNum: "15099903110",
},
};
// 常见字符
export const Feature = {
// 门店

View File

@ -3,9 +3,6 @@ import { HomeNavigation } from '@/pages/homeNavigationPage.js';
import { TransferManagementPage } from '@/pages/inventory';
export const test = base.extend({
/**
* @type { import("@playwright/test").Page }
*/
firstStaffPage: async ({ browser }, use) => {
const context = await browser.newContext({
storageState: '.auth/user_1.json',
@ -15,9 +12,6 @@ export const test = base.extend({
await use(page);
await context.close();
},
/**
* @type { import("@playwright/test").Page }
*/
secondStaffPage: async ({ browser }, use) => {
const context = await browser.newContext({
storageState: '.auth/user_2.json',

View File

@ -13,50 +13,106 @@ export class CardBalanceChangeReportPage {
{
name: '期初',
content: [
{ name: '期初卡金', index: -1 },
{ name: '期初赠金', index: -1 },
{
name: '期初卡金', index: -1,
value: 0,
lastValue: 0,
},
{
name: '期初赠金', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '消费',
content: [
{ name: '消费卡金', index: -1 },
{ name: '消费赠金', index: -1 },
{
name: '消费卡金', index: -1,
value: 0,
lastValue: 0,
},
{
name: '消费赠金', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '开充卡',
content: [
{ name: '开充卡金', index: -1 },
{ name: '开充赠金', index: -1 },
{
name: '开充卡金', index: -1,
value: 0,
lastValue: 0,
},
{
name: '开充赠金', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '调整',
content: [
{ name: '修改卡金', index: -1 },
{ name: '修改赠金', index: -1 },
{
name: '修改卡金', index: -1,
value: 0,
lastValue: 0,
},
{
name: '修改赠金', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '转移',
content: [
{ name: '转移卡金', index: -1 },
{ name: '转移赠金', index: -1 },
{
name: '转移卡金', index: -1,
value: 0,
lastValue: 0,
},
{
name: '转移赠金', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '结余',
content: [
{ name: '结余卡金', index: -1 },
{ name: '结余赠金', index: -1 },
{
name: '结余卡金', index: -1,
value: 0,
lastValue: 0,
},
{
name: '结余赠金', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '变动',
content: [
{ name: '卡金变动', index: -1 },
{ name: '赠金变动', index: -1 },
{
name: '卡金变动', index: -1,
value: 0,
lastValue: 0,
},
{
name: '赠金变动', index: -1,
value: 0,
lastValue: 0,
},
],
},
];

View File

@ -4,7 +4,7 @@ import { Customer } from '@/utils/customer';
export class CustomerConsumptionAnalysisReportPage {
readonly page: Page;
private _reportData: reportData[];
private readonly _reportData: reportData[];
/**
*
*/

View File

@ -13,33 +13,81 @@ export class SalesCostSummaryReportPage {
{
name: '护理',
content: [
{ name: '现金业绩', index: -1 },
{ name: '划卡业绩', index: -1 },
{ name: '消耗业绩', index: -1 },
{
name: '现金业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '划卡业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '消耗业绩', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '面部',
content: [
{ name: '现金业绩', index: -1 },
{ name: '划卡业绩', index: -1 },
{ name: '消耗业绩', index: -1 },
{
name: '现金业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '划卡业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '消耗业绩', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '身体',
content: [
{ name: '现金业绩', index: -1 },
{ name: '划卡业绩', index: -1 },
{ name: '消耗业绩', index: -1 },
{
name: '现金业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '划卡业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '消耗业绩', index: -1,
value: 0,
lastValue: 0,
},
],
},
{
name: '组合项目',
content: [
{ name: '现金业绩', index: -1 },
{ name: '划卡业绩', index: -1 },
{ name: '消耗业绩', index: -1 },
{
name: '现金业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '划卡业绩', index: -1,
value: 0,
lastValue: 0,
},
{
name: '消耗业绩', index: -1,
value: 0,
lastValue: 0,
},
],
},
];

View File

@ -107,6 +107,7 @@ export class TablePage {
* -1
* @param text
* @param index getLeftTableHeaderIndex
* @param options
* @returns
*/
getLeftTableBodyIndex = async (text: string, index: number, options?: { repeat: number }) => {

View File

@ -1,33 +1,37 @@
import { test as setup, expect } from '@playwright/test';
import { getEnvVar } from '@/utils/envUtils';
const authFileArray = ['.auth/user_1.json', '.auth/user_2.json'];
const employee = [
{
phone: process.env.staff1_account,
password: process.env.staff1_password,
authFile: '.auth/user_1.json',
},
{
phone: process.env.staff2_account,
password: process.env.staff2_password,
authFile: '.auth/user_2.json',
},
];
setup.describe('员工登录', () => {
for (let i = 0; i < 2; i++) {
setup(`门店员工登录_${i}`, async ({ page }) => {
for (const e of employee) {
setup(`门店员工登录_${e.phone}`, async ({ page }) => {
const phone = e.phone || '';
const password = e.password || '';
const baseUrl = getEnvVar('BASE_URL');
const $phone = page.getByRole('textbox', { name: '请输入您的手机号码' });
const $password = page.getByRole('textbox', { name: '请输入登录密码' });
const $login = page.getByRole('button', { name: /登\s录/ });
await page.goto(baseUrl);
await $phone.fill(employee[i].phone);
await $phone.fill(phone);
const checkPhone = page.locator('.ant-row', { has: $phone }).locator('.pass_svg');
await expect(checkPhone).toBeVisible();
await $password.fill(employee[i].password);
await $password.fill(password);
await page.getByLabel('请同意慧来客隐私政策和用户协议').check();
await $login.click();
await expect(page.getByRole('button', { name: /开\s单/ })).toBeEnabled();
await page.context().storageState({ path: authFileArray[i] });
await page.context().storageState({ path: e.authFile });
});
}
});

View File

@ -6,6 +6,7 @@ import { faker } from '@faker-js/faker/locale/zh_CN';
import path from 'path';
import { AppointmentOperation } from '@/pages/appointmentPage.js';
import { Customer } from '@/utils/customer';
import { getNextAppointmentTime } from '@/utils/timeUtils';
test.describe('挂单', () => {
let c: Customer;
@ -460,7 +461,7 @@ test.describe('收银-房态', () => {
test('预约选床位', async ({ page, homeNavigation, createCustomer, cashierRoomPage, appointmentPage }) => {
const customer = createCustomer;
// 获取当前时间
const setAppointment = appointmentPage.getAppointmentTimesAvailable();
const setAppointment = getNextAppointmentTime();
const employee = Employees.FirstShop.Employee_6;
await test.step('进行员工预约,进入预约界面', async () => {
@ -611,7 +612,7 @@ test.describe('收银-房态', () => {
await homeNavigation.gotoModule('收银');
await page.locator('#frame_detail div').filter({ hasText: '房态' }).nth(3).click();
await page.locator('.room_table').first().waitFor();
const setAppointment = appointmentPage.getAppointmentTimesAvailable(); // 获取当前时间
const setAppointment = getNextAppointmentTime(); // 获取当前时间
const cede = page.locator('.left_table td');
// 找到当前时间的行数
@ -757,7 +758,7 @@ test.describe('收银-房态', () => {
const remark2 = faker.helpers.fromRegExp(/1[3-9][0-9]{6}/);
await page.locator('#frame_detail div').filter({ hasText: '房态' }).nth(3).click();
await page.locator('.room_table').first().waitFor();
const setAppointment = appointmentPage.getAppointmentTimesAvailable(); // 获取当前时间
const setAppointment = getNextAppointmentTime(); // 获取当前时间
const cede = page.locator('.left_table td');
// 找到当前时间的行数
const nowRowTime: number = await cede.allInnerTexts().then(text => {
@ -818,7 +819,7 @@ test.describe('收银-房态', () => {
test('修改占用床位', async ({ page, appointmentPage }) => {
await page.locator('#frame_detail div').filter({ hasText: '房态' }).nth(3).click();
await page.locator('.room_table').first().waitFor();
const setAppointment = appointmentPage.getAppointmentTimesAvailable(); // 获取当前时间
const setAppointment = getNextAppointmentTime(); // 获取当前时间
const cede = page.locator('.left_table td');
// 找到当前时间的行数
const nowRowTime: number = await cede.allInnerTexts().then(text => {

View File

@ -2024,7 +2024,7 @@ test.describe('顾客分配', () => {
const index = titleList.findIndex(text => text === '现金总额');
// 拿取前三个顾客的现金总额
let amountArray = [];
let amountArray: number[];
for (let i = 0; i < 3; i++) {
const amountStr = await amountList.nth(i).locator('td').nth(index).innerText();
const amount = convertAmountText(amountStr).amount;
@ -2218,18 +2218,14 @@ test.describe('顾客分配', () => {
test.describe('顾客分析', () => {
test('查看顾客项目分析', async ({ page, homeNavigation, createCustomers, customerPage, numberInput }) => {
/**@type {Customer[]} */
let customers = [];
let customers: Customer[];
await test.step('创建两个顾客', async () => {
// 创建顾客
customers = await createCustomers(2);
});
const ca = customers[0];
const cb = customers[1];
console.log(`顾客A: ${ca.username}${ca.phone}`);
console.log(`顾客B: ${cb.username}${cb.phone}`);
// 获取姓名、手机号、档案号
const usernameA = ca.username;
const phoneA = ca.phone;
@ -3553,7 +3549,7 @@ test.describe('批量操作', () => {
test('群发优惠券', async ({ page, homeNavigation }) => {
// 用于存储会员名称
const useNames = [];
let useNames: string[];
await test.step('勾选会员并记录该会员手机', async () => {
// 进入顾客界面
await homeNavigation.gotoModule('顾客');

View File

@ -280,14 +280,11 @@ test.describe('业绩明细表', () => {
test.describe('项目销耗存表', () => {
test('数据校验', async ({ page, createCustomers, homeNavigation, reportPage, customerPage, numberInput }) => {
/** @type {Customer[]} */
let customers = [];
let customers: Customer[];
await test.step('创建两个顾客', async () => {
customers = await createCustomers(2);
});
if (!customers || customers.length < 2) {
throw new Error('创建顾客失败');
}
const ca = customers[0];
const cb = customers[1];
// 获取姓名、手机号、档案号
@ -935,14 +932,14 @@ test.describe('销售消耗汇总表', () => {
test.describe('业绩汇总表', () => {
test('数据校验', async ({
page,
homeNavigation,
createCustomer,
reportPage,
performanceSummaryReportPage,
customerPage,
numberInput,
}) => {
page,
homeNavigation,
createCustomer,
reportPage,
performanceSummaryReportPage,
customerPage,
numberInput,
}) => {
// 项目
const project = { no: '100019', name: '青春焕活套', price: 880, count: 1 };
// 卖品
@ -1166,10 +1163,10 @@ test.describe('业绩汇总表', () => {
'现金类总额',
reportData,
cardGold +
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price,
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price,
);
// 卡金 + 充值卡金 + 套餐现金支付 + 卖品现金支付
reportPage.toBeReportDataAsExpected(
@ -1177,10 +1174,10 @@ test.describe('业绩汇总表', () => {
'现金',
reportData,
cardGold +
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price,
rechargeAmount +
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price,
);
// 项目一
reportPage.toBeReportDataAsExpected('营收明细', '划卡', reportData, project.price);
@ -1201,7 +1198,7 @@ test.describe('业绩汇总表', () => {
'项目合计',
reportData,
(setMeal.price - setMeal.projects[setMeal.projects.length - 1].price - setMeal.goods[0].price) *
storeSalesRatio,
storeSalesRatio,
);
reportPage.toBeReportDataAsExpected(
'现金业绩',
@ -1227,7 +1224,7 @@ test.describe('业绩汇总表', () => {
setMeal.price -
setMeal.projects[setMeal.projects.length - 1].price +
goods.price) *
storeSalesRatio,
storeSalesRatio,
);
// 4. 划卡业绩--指定项目880
@ -1251,7 +1248,7 @@ test.describe('业绩汇总表', () => {
'总业绩',
reportData,
(setMeal.price - setMeal.projects[setMeal.projects.length - 1].price) * storeSalesRatio +
setMeal.projects[setMeal.projects.length - 1].price,
setMeal.projects[setMeal.projects.length - 1].price,
);
// 8. 卖品销售
@ -1324,14 +1321,14 @@ test.describe('业绩汇总表', () => {
test.describe('储值卡卡金变动表', () => {
test('数据校验', async ({
page,
homeNavigation,
reportPage,
cardBalanceChangeReportPage,
createCustomer,
customerPage,
numberInput,
}) => {
page,
homeNavigation,
reportPage,
cardBalanceChangeReportPage,
createCustomer,
customerPage,
numberInput,
}) => {
const customer = createCustomer;
const card_a = {
@ -1565,13 +1562,13 @@ test.describe('开支汇总表', () => {
test.describe('顾客消费分析表', () => {
test('数据校验', async ({
page,
homeNavigation,
createCustomer,
reportPage,
customerPage,
customerConsumptionAnalysisReportPage,
}) => {
page,
homeNavigation,
createCustomer,
reportPage,
customerPage,
customerConsumptionAnalysisReportPage,
}) => {
const customer = createCustomer;
// 购买并消耗项目

View File

@ -1,5 +1,10 @@
import dotenv from 'dotenv';
dotenv.config();
export function getEnvVar(key: string): string {
const value = process.env[key];
console.log(`${key}: ${value}`);
if (!value) {
throw new Error(`Environment variable ${key} is not set`);
}