ci(gitlab): 添加 GitLab CI 配置并更新测试相关代码
- 新增 .gitlab-ci.yml 文件,配置 GitLab CI/CD 管道 - 移除 AuthAccount 类中未使用的 indexedDBFile 属性 - 简化 baseFixture 中的测试初始化流程 - 更新 CustomerPage 中的顾客创建逻辑 - 调整 boss_cashier.spec.ts 中的二维码解码和输入值设置 - 新增 boss_test.spec.ts 文件,添加创建顾客的测试用例
This commit is contained in:
parent
649efd4f78
commit
3547f32493
29
.gitlab-ci.yml
Normal file
29
.gitlab-ci.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
stages:
|
||||||
|
- test
|
||||||
|
- report
|
||||||
|
|
||||||
|
playwright_tests:
|
||||||
|
stage: test
|
||||||
|
image: mcr.microsoft.com/playwright:focal
|
||||||
|
script:
|
||||||
|
- npm install
|
||||||
|
- npx playwright install
|
||||||
|
- npx playwright test
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- test-results/
|
||||||
|
expire_in: 1 week
|
||||||
|
|
||||||
|
send_report:
|
||||||
|
stage: report
|
||||||
|
image: alpine:latest
|
||||||
|
script:
|
||||||
|
- apk add --no-cache curl
|
||||||
|
- |
|
||||||
|
if [ -d test-results ]; then
|
||||||
|
echo "Test Successful."
|
||||||
|
else
|
||||||
|
echo "No test results found."
|
||||||
|
fi
|
||||||
|
only:
|
||||||
|
- main
|
||||||
@ -10,27 +10,11 @@ class AuthAccount {
|
|||||||
account: string;
|
account: string;
|
||||||
password: string;
|
password: string;
|
||||||
authFile: string;
|
authFile: string;
|
||||||
indexedDBFile: string;
|
|
||||||
|
|
||||||
constructor(account: string, password: string, authFile: string, indexedDBFile: string) {
|
constructor(account: string, password: string, authFile: string) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.authFile = authFile;
|
this.authFile = authFile;
|
||||||
this.indexedDBFile = indexedDBFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadIndexedDBFile(account: string, accountArray: AuthAccount[]) {
|
|
||||||
try {
|
|
||||||
for (const item of accountArray) {
|
|
||||||
if (item.account === account) {
|
|
||||||
return JSON.parse(readFileSync(item.indexedDBFile, 'utf-8'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('indexedDB文件读取失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('未找到该账户');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,14 +22,12 @@ const firstAccount = new AuthAccount(
|
|||||||
getEnvVar('boss_account'),
|
getEnvVar('boss_account'),
|
||||||
getEnvVar('boss_password'),
|
getEnvVar('boss_password'),
|
||||||
`${authConfig.authFilePath}${getEnvVar('boss_account')}.json`,
|
`${authConfig.authFilePath}${getEnvVar('boss_account')}.json`,
|
||||||
`${authConfig.indexedDBFilePath}${getEnvVar('boss_account')}_indexedDB.json`,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const secondAccount = new AuthAccount(
|
const secondAccount = new AuthAccount(
|
||||||
getEnvVar('boss_account_2'),
|
getEnvVar('boss_account_2'),
|
||||||
getEnvVar('boss_password_2'),
|
getEnvVar('boss_password_2'),
|
||||||
`${authConfig.authFilePath}${getEnvVar('boss_account_2')}.json`,
|
`${authConfig.authFilePath}${getEnvVar('boss_account_2')}.json`,
|
||||||
`${authConfig.indexedDBFilePath}${getEnvVar('boss_account_2')}_indexedDB.json`,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
15
tests/fixtures/baseFixture.ts
vendored
15
tests/fixtures/baseFixture.ts
vendored
@ -16,19 +16,14 @@ export const test = base.extend<MyFixture>({
|
|||||||
|
|
||||||
if (!baseURL) throw new Error('baseURL is required');
|
if (!baseURL) throw new Error('baseURL is required');
|
||||||
await page.goto(baseURL);
|
await page.goto(baseURL);
|
||||||
|
// await page.getByRole('button', { name: /开\s单/ }).waitFor();
|
||||||
const mobileObject = await page.evaluate(() => {
|
await expect(page.getByRole('button', { name: /开\s单/ })).toBeEnabled();
|
||||||
return window.localStorage.getItem('hlk_touch_mobile');
|
|
||||||
});
|
|
||||||
if (!mobileObject && mobileObject !== 'null') {
|
|
||||||
throw new Error('localStorage does not contain boss_account or boss_account2');
|
|
||||||
}
|
|
||||||
const mobileString = JSON.parse(mobileObject);
|
|
||||||
const data = AuthAccount.loadIndexedDBFile(mobileString.val, [firstAccount, secondAccount]);
|
|
||||||
|
|
||||||
await page.reload();
|
await page.reload();
|
||||||
|
|
||||||
await page.getByRole('button', { name: /开\s单/ }).waitFor();
|
await page.getByRole('button', { name: /开\s单/ }).click();
|
||||||
|
// await page.getByRole('button', { name: /开\s单/ }).waitFor();
|
||||||
|
await expect(page.getByRole('button', { name: '创建会员' })).toBeEnabled();
|
||||||
|
|
||||||
await use(page);
|
await use(page);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export class CustomerPage {
|
|||||||
private readonly secondStore = {
|
private readonly secondStore = {
|
||||||
firstDepartment: { no: 1, name: '美容部' },
|
firstDepartment: { no: 1, name: '美容部' },
|
||||||
};
|
};
|
||||||
private readonly source: string[] = [
|
private readonly sourceChannel: string[] = [
|
||||||
'邀客',
|
'邀客',
|
||||||
'员工带客',
|
'员工带客',
|
||||||
'美团',
|
'美团',
|
||||||
@ -156,6 +156,7 @@ export class CustomerPage {
|
|||||||
createCustomer = async (customer: Customer) => {
|
createCustomer = async (customer: Customer) => {
|
||||||
const customerPage = '/#/member/member-schame';
|
const customerPage = '/#/member/member-schame';
|
||||||
await this.page.goto(customerPage);
|
await this.page.goto(customerPage);
|
||||||
|
await expect(this.page.getByRole('button', { name: '新增顾客' })).toBeEnabled();
|
||||||
await this.selectStore(customer.store);
|
await this.selectStore(customer.store);
|
||||||
await this.fillCustomerDetails(customer);
|
await this.fillCustomerDetails(customer);
|
||||||
await this.selectDepartment(customer);
|
await this.selectDepartment(customer);
|
||||||
@ -321,7 +322,7 @@ export class CustomerPage {
|
|||||||
* @param {number} source 来源
|
* @param {number} source 来源
|
||||||
*/
|
*/
|
||||||
private readonly selectSource = async (source: number) => {
|
private readonly selectSource = async (source: number) => {
|
||||||
await this.$register.getByLabel(this.source[source]).click();
|
await this.$register.getByLabel(this.sourceChannel[source]).click();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -339,25 +340,27 @@ export class CustomerPage {
|
|||||||
*/
|
*/
|
||||||
private readonly confirmCreation = async (phone: string) => {
|
private readonly confirmCreation = async (phone: string) => {
|
||||||
const [response] = await Promise.all([
|
const [response] = await Promise.all([
|
||||||
this.page.waitForResponse(
|
this.page.waitForResponse(async res => res.url().includes('/invalid_check') && (await res.json()).code === 'SUCCESS'),
|
||||||
async res => res.url().includes('/invalid_check') && (await res.json()).code === 'SUCCESS',
|
|
||||||
),
|
|
||||||
this.page.getByRole('button', { name: '确认创建' }).click(),
|
this.page.getByRole('button', { name: '确认创建' }).click(),
|
||||||
]);
|
]);
|
||||||
const responseBody = await response.json();
|
const responseBody = await response.json();
|
||||||
|
|
||||||
const phoneStatus = responseBody?.content?.status;
|
const phoneStatus = responseBody?.content?.status;
|
||||||
if (phoneStatus === undefined || phoneStatus === null) {
|
if (phoneStatus === undefined || phoneStatus === null) {
|
||||||
|
// 创建顾客成功
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.page.getByText('系统查询到当前手机号被建档后转为无效客,是否要恢复无效客?').waitFor();
|
await this.page.getByText('系统查询到当前手机号被建档后转为无效客,是否要恢复无效客?').waitFor();
|
||||||
await this.page.getByRole('button', { name: '重新建档' }).click();
|
await this.page.getByRole('button', { name: '重新建档' }).click();
|
||||||
const popupWindow = this.page.locator('.ant-message');
|
const popupWindow = this.page.locator('.ant-message');
|
||||||
await popupWindow.waitFor();
|
|
||||||
const popupContent = (await popupWindow.innerText()).trim();
|
await expect(popupWindow).not.toContainText('该手机号码已经被使用');
|
||||||
if (popupContent.includes('该手机号码已经被使用')) {
|
|
||||||
throw new Error(`手机号码 ${phone} 已被使用,无法创建新顾客`);
|
// await popupWindow.waitFor();
|
||||||
}
|
// const popupContent = (await popupWindow.innerText()).trim();
|
||||||
|
// if (popupContent.includes('该手机号码已经被使用')) {
|
||||||
|
// throw new Error(`手机号码 ${phone} 已被使用,无法创建新顾客`);
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -306,6 +306,8 @@ test.describe('挂单', () => {
|
|||||||
const phone = customer.phone;
|
const phone = customer.phone;
|
||||||
const username = customer.username;
|
const username = customer.username;
|
||||||
|
|
||||||
|
await page.pause();
|
||||||
|
|
||||||
await homeNavigation.gotoModule('收银');
|
await homeNavigation.gotoModule('收银');
|
||||||
await page.getByRole('button', { name: /^开\s单$/ }).click();
|
await page.getByRole('button', { name: /^开\s单$/ }).click();
|
||||||
await customerPage.searchCustomer(phone);
|
await customerPage.searchCustomer(phone);
|
||||||
@ -417,7 +419,7 @@ test.describe('挂单', () => {
|
|||||||
await page.locator('.qrcode').screenshot({ path: filePath });
|
await page.locator('.qrcode').screenshot({ path: filePath });
|
||||||
}).toPass();
|
}).toPass();
|
||||||
|
|
||||||
let result: string = await decodeQR(filePath);
|
let result = await decodeQR(filePath);
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
||||||
let url_1 = new URL(result);
|
let url_1 = new URL(result);
|
||||||
@ -1111,7 +1113,7 @@ test.describe('收银-开单&结算', () => {
|
|||||||
await page.getByRole('button', { name: /^确\s认$/ }).click();
|
await page.getByRole('button', { name: /^确\s认$/ }).click();
|
||||||
// 修改数量
|
// 修改数量
|
||||||
await page.locator('.edit_txt div:nth-child(2)').first().click();
|
await page.locator('.edit_txt div:nth-child(2)').first().click();
|
||||||
await numberInput.setValue(2);
|
await numberInput.setValue('common', 2);
|
||||||
await numberInput.confirmValue();
|
await numberInput.confirmValue();
|
||||||
const quantity = (await page.locator('.buy_number').last().innerText()).trim();
|
const quantity = (await page.locator('.buy_number').last().innerText()).trim();
|
||||||
// 结算
|
// 结算
|
||||||
@ -1270,7 +1272,7 @@ test.describe('收银-开单&结算', () => {
|
|||||||
await page.getByText('赠金').nth(2).click();
|
await page.getByText('赠金').nth(2).click();
|
||||||
await page.getByRole('button', { name: '增加收款' }).click();
|
await page.getByRole('button', { name: '增加收款' }).click();
|
||||||
// 输入金额
|
// 输入金额
|
||||||
await numberInput.setCommonValue(90);
|
await numberInput.setValue('common', 90);
|
||||||
await numberInput.confirmValue();
|
await numberInput.confirmValue();
|
||||||
// 结算
|
// 结算
|
||||||
await page.getByRole('button', { name: /^结\s算$/ }).click();
|
await page.getByRole('button', { name: /^结\s算$/ }).click();
|
||||||
|
|||||||
8
tests/touch/boss_test.spec.ts
Normal file
8
tests/touch/boss_test.spec.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { test, expect } from '@/fixtures/boss_common.js'; //使用公共套件
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
test(`创建顾客${i}`, async ({ createCustomer }) => {
|
||||||
|
console.log('创建顾客成功');
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user