// @ts-check import { faker } from '@faker-js/faker/locale/zh_CN'; import { test, expect } from '@/fixtures/boss_common.js'; import path from 'path'; import { decodeQR } from '@/utils/utils.js'; import { Customer } from '@/utils/customer'; import { staffData } from '@/fixtures/staff.js'; import { HomeNavigation } from '@/pages/homeNavigationPage.js'; import fs from 'fs'; import { Page } from '@playwright/test'; test.describe('商城', () => { test.describe('上架好物', () => { test('售卖中商品操作', async ({ page, homeNavigation, createCustomer, customerPage }) => { const code = page.locator('.m-table__body-wrapper .main-table-body_tr'); const $goods_f = code.filter({ has: page.locator('td .title', { hasText: '商品F' }) }); const customer = createCustomer; await test.step('给顾客开会员卡', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); await page.locator('.number_service').waitFor(); await page.getByRole('button', { name: /^开\s卡$/ }).click(); // 选择会员卡A await page .locator('.memberCard_box > .needsclick') .getByText(/^会员卡$/) .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 page.locator('use').first().click(); }); await test.step('进入H5商城购买商品商品F', async () => { await page.goto(process.env.STOREH5_URL ?? ''); await page.locator('.bar_item', { hasText: '我的' }).click(); await page.getByText('登录', { exact: true }).click(); // 登录顾客手机 await page.locator('.uni-radio-input').click(); //点击同意协议 await page.locator('.uni-radio-input-checked').waitFor(); await page .locator('.login-box_input') .filter({ has: page.locator('.input-placeholder', { hasText: '请输入手机号码' }), }) .locator('.uni-input-input') .fill(customer.phone); await page .locator('.login-box_input') .filter({ has: page.locator('.input-placeholder', { hasText: '请输入验证码' }), }) .locator('.uni-input-input') .fill('1660'); await expect(async () => { await page.locator('.login-box_btn', { hasText: /^登录$/ }).click(); await page.locator('.bar_item', { hasText: '商城' }).waitFor({ timeout: 2000 }); }).toPass(); // 进入商城 await page.locator('.bar_item', { hasText: '商城' }).click(); // 全部 await page.locator('.li', { hasText: '全部' }).click(); await expect(page.locator('.mescroll-wxs-content .pname', { hasText: '商品F' }).first()).toBeVisible(); // 点击进入商品 await page.locator('.mescroll-wxs-content .pname', { hasText: '商品F' }).first().click(); // 购买商品 await page.locator('.button_hover', { hasText: '立即购买' }).click(); // 选择门店 await page.locator('.scroll-view-item').first().waitFor(); await page.locator('.scroll-view-item', { hasText: 'AT测试一店' }).click(); await page .locator('.pickstore-body') .filter({ has: page.locator('.scroll-view-item', { hasText: 'AT测试一店' }) }) .locator('.public_color') .waitFor(); // 确认 await page.locator('.mgj-picker-btn-ok', { hasText: /^确认$/ }).click(); await page.locator('.box-header_content .title', { hasText: '订单支付' }).waitFor(); // 选择会员卡支付 await page.locator('.yellow_row', { hasText: '会员卡' }).click(); await page.locator('.uni-radio-input-checked').waitFor(); // 确认支付 await page.locator('.okbtn', { hasText: '确认支付' }).click(); await expect(page.locator('.okText', { hasText: '支付成功' })).toBeVisible(); }); await test.step('返回上架好物验证', async () => { await page.goto(process.env.BASE_URL ?? ''); // 进入营销模块 await homeNavigation.gotoModule('营销'); await page.locator('.listBox .name', { hasText: '上架好物' }).click(); await page.locator('.batch').waitFor(); // 进入订单列表 await $goods_f.locator('.ant-btn', { hasText: '订单列表' }).click(); await page.locator('.popup_content .title', { hasText: '订单列表' }).waitFor(); // 验证订单列表中有顾客购买的商品F await expect( page.locator('.popup_content .main-table-body_tr').first().locator('td').nth(2), ).toContainText(customer.phone); // 关闭订单列表 await page.locator('.popup_content .close_icon').last().click(); // 下架商品 await $goods_f.locator('.ant-btn', { hasText: '下架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '下架成功' })).toBeVisible(); // 判断商品下架后不可见 await expect( page.locator('.m-table__body-wrapper .main-table-body_tr', { hasText: '商品F' }), ).not.toBeVisible(); // 点击未上架 await page.locator('.tab_item', { hasText: '未上架' }).click(); await expect(page.getByText('查询中')).not.toBeVisible(); // 判断商品As可见 await expect( page.locator('.m-table__body-wrapper .main-table-body_tr', { hasText: '商品F' }), ).toBeVisible(); await $goods_f.locator('.ant-btn', { hasText: '上架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '上架成功' })).toBeVisible(); }); }); test('查询商品', async ({ page, homeNavigation }) => { await test.step('进入营销上架好物', async () => { // 进入营销-上架好物 await homeNavigation.gotoModule('营销'); await page.locator('.listBox .name', { hasText: '上架好物' }).click(); await page.locator('.batch').waitFor(); }); await test.step('通过商品分类查询', async () => { // 点击分类查询健康养生 await page.locator('.ant-select-selection__rendered', { hasText: '全部分类' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '健康养生' }).click(); await page.locator('.main-table-body_tr').first().waitFor(); // 校验健康养生的商品AsI艾经络 const Health = page.locator('.main-table-body_tr .title', { hasText: 'AI艾经络' }); await expect(Health).toBeVisible(); await page.locator('.ant-radio-button-wrapper', { hasText: '卖品类' }).click(); await page.locator('.ant-radio-button-wrapper', { hasText: '服务类' }).click(); await page.locator('.ant-select-selection__rendered', { hasText: '全部商品类别' }).waitFor(); }); await test.step('通过商品类别查询', async () => { // 点击商品类别卖品 await page.locator('.ant-select-selection__rendered', { hasText: '全部商品类别' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '卖品' }).click(); await page.locator('.main-table-body_tr').first().waitFor(); // 校验卖品中精油是否存在 const EssentialOil = page.locator('.main-table-body_tr .title', { hasText: '精油' }); await expect(EssentialOil).toBeVisible(); await page.locator('.ant-radio-button-wrapper', { hasText: '卖品类' }).click(); await page.locator('.ant-radio-button-wrapper', { hasText: '服务类' }).click(); await page.locator('.ant-select-selection__rendered', { hasText: '全部商品类别' }).waitFor(); }); await test.step('通过营销方案查询', async () => { // 点击营销方案 await page.locator('.ant-select-selection__rendered', { hasText: '全部营销方案' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '团购' }).click(); await page.locator('.main-table-body_tr').first().waitFor(); // 校验团购商品Cs存在 const productC = page.locator('.main-table-body_tr .title', { hasText: '团购商品C' }); await expect(productC).toBeVisible(); await page.locator('.ant-radio-button-wrapper', { hasText: '卖品类' }).click(); await page.locator('.ant-radio-button-wrapper', { hasText: '服务类' }).click(); await page.locator('.ant-select-selection__rendered', { hasText: '全部商品类别' }).waitFor(); }); await test.step('通过关键字查询', async () => { // 通过关键字搜索 await page.getByPlaceholder('关键字搜索').fill('肌底清洁'); await page.locator('.ant-input-prefix').first().click(); await page.locator('.main-table-body_tr').first().waitFor(); const keyword = page.locator('.main-table-body_tr .title', { hasText: '肌底清洁' }); await expect(keyword).toBeVisible(); }); }); test('商品系列', async ({ page, homeNavigation }) => { const code = page.locator('.main-table-body_tr').first(); await test.step('进入营销上架好物', async () => { // 进入营销-上架好物 await homeNavigation.gotoModule('营销'); await page.locator('.listBox .name', { hasText: '上架好物' }).click(); await page.locator('.batch').waitFor(); // 点击商品系列 await page.locator('.ant-radio-button-wrapper', { hasText: '商品系列' }).click(); await page.locator('.ant-btn-lg').first().waitFor(); // 点击新增 await page.locator('.ant-btn-lg', { hasText: /^新\s增$/ }).click(); await page.locator('.header', { hasText: '新增商品系列' }).waitFor(); // 关闭 这里的关闭是因为不进行一些操作 后面的内容不加载 强行点了一下新增并关掉 await page.locator('.box .top .anticon').click(); // 循环把商品系列都删了 const del = page.locator('.main-table-body_tr'); const dels = await del.count(); if (await del.first().isVisible()) { console.log('有' + dels + '个待删除'); for (let i = 0; i < dels; i++) { await page .locator('.main-table-body_tr') .nth(i) .locator('.ant-btn-link', { hasText: '删除' }) .click(); await page.locator('.content', { hasText: '确认删除该商品系列吗?' }).waitFor(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message', { hasText: '删除成功' }).waitFor(); } await expect(del).not.toBeVisible(); } }); await test.step('新增', async () => { // 点击新增 await page.locator('.ant-btn-lg', { hasText: /^新\s增$/ }).click(); await page.locator('.header', { hasText: '新增商品系列' }).waitFor(); // 输入系列名称 // await page.locator('.ant-form-item-children .ant-input').fill('测试商品A') await page.getByPlaceholder('长度不大于10个字符').fill('测试商品A'); // 点击添加商品 await page.locator('.addBtn').click(); await page.locator('.popup_content .title', { hasText: '选择商品' }).waitFor(); // 选择商品 await page.locator('.customWith').first().click(); const productA = await page.locator('.customWith').first().innerText(); await page.locator('.customWith').nth(1).click(); const productB = await page.locator('.customWith').nth(1).innerText(); // 确认选择 await page.locator('.comfirm_btn', { hasText: '确认选择' }).click(); await page.locator('.ant-radio-wrapper').last().click(); // 确认添加 await page.locator('.submit_btn', { hasText: '确认添加' }).click(); await page.locator('.ant-message').waitFor(); await expect(page.locator('.header', { hasText: '新增商品系列' })).not.toBeVisible(); // 校验新增数据准确性 const NameA = await code.locator('td').first().innerText(); const productName = await code.locator('td').nth(2).innerText(); const productBName = await code.locator('td').nth(3).innerText(); expect(NameA).toBe('测试商品A'); const regex = new RegExp(`^(${productB}、${productA}|${productA}、${productB})$`); expect(productName).toMatch(regex); expect(productBName).toBe(productB); }); await test.step('编辑', async () => { // 点击编辑 await page.locator('.main-table-body_tr').first().locator('.ant-btn-link', { hasText: '编辑' }).click(); await page.locator('.header', { hasText: '编辑商品系列' }).waitFor(); // 修改系列名称 await page.getByPlaceholder('长度不大于10个字符').fill('测试商品B'); // 确认保存 await page.locator('.submit_btn', { hasText: '确认保存' }).click(); await page.locator('.ant-message').waitFor(); await expect(page.locator('.header', { hasText: '编辑商品系列' })).not.toBeVisible(); const NameB = await code.locator('td').first().innerText(); expect(NameB).toBe('测试商品B'); }); await test.step('删除', async () => { await page.locator('.main-table-body_tr').first().locator('.ant-btn-link', { hasText: '删除' }).click(); await page.locator('.content', { hasText: '确认删除该商品系列吗?' }).waitFor(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '删除成功' })).toBeVisible(); await expect(code.locator('td').first()).not.toBeVisible(); }); }); test('商品属性', async ({ page, homeNavigation }) => { const code = page.locator('.main-table-body_tr').first(); await test.step('进入营销上架好物', async () => { // 进入营销-上架好物 await homeNavigation.gotoModule('营销'); await page.locator('.listBox .name', { hasText: '上架好物' }).click(); await page.locator('.batch').waitFor(); // 点击商品系列 await page.locator('.ant-radio-button-wrapper', { hasText: '商品属性' }).click(); await page.locator('.ant-btn-lg').first().waitFor(); // 点击新增 await page.locator('.ant-btn-lg', { hasText: /^新\s增$/ }).click(); await page.locator('.header', { hasText: '新增商品属性' }).waitFor(); // 关闭 await page.locator('.box .top .anticon').click(); // 循环把商品属性删了 const del = page.locator('.main-table-body_tr'); const dels = await del.count(); if (await del.first().isVisible()) { console.log('有' + dels + '个待删除'); for (let i = 0; i < dels; i++) { await page .locator('.main-table-body_tr') .nth(i) .locator('.ant-btn-link', { hasText: '删除' }) .click(); await page.locator('.content', { hasText: '确认删除该商品属性吗?' }).waitFor(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '删除成功' })).toBeVisible(); } await expect(del).not.toBeVisible(); } }); await test.step('新增', async () => { // 点击新增 await page.locator('.ant-btn-lg', { hasText: /^新\s增$/ }).click(); await page.locator('.header', { hasText: '新增商品属性' }).waitFor(); // 输入系列名称 await page.getByPlaceholder('长度不大于10个字符').first().fill('测试商品属性'); // 点击添加商品属性 await page.locator('.ant-btn', { hasText: '添加属性' }).click(); const quantity = await page.locator('.del_icon').count(); expect(quantity).toBe(2); // 点击添加商品属性 await page.locator('.ant-btn', { hasText: '添加属性' }).click(); const quantitys = await page.locator('.del_icon').count(); expect(quantitys).toBe(3); await page.getByPlaceholder('长度不大于10个字符').nth(1).fill('商品属性A'); await page.getByPlaceholder('长度不大于10个字符').nth(2).fill('商品属性B'); await page.getByPlaceholder('长度不大于10个字符').nth(3).fill('商品属性C'); await page.locator('.submit_btn', { hasText: /^添\s加$/ }).click(); await page.locator('.ant-message').waitFor(); await expect(page.locator('.header', { hasText: '新增商品属性' })).not.toBeVisible(); // 校验新增数据准确性 const NameA = await code.locator('td').first().innerText(); const productName = await code.locator('td').nth(1).innerText(); expect(NameA).toBe('测试商品属性'); expect(productName).toBe('商品属性A、 商品属性B、 商品属性C'); }); await test.step('编辑', async () => { // 点击编辑 await page.locator('.main-table-body_tr').first().locator('.ant-btn-link', { hasText: '编辑' }).click(); await page.locator('.header', { hasText: '编辑商品属性' }).waitFor(); // 删除两个商品属性 await page.locator('.del_icon').last().click(); const quantitys = await page.locator('.del_icon').count(); expect(quantitys).toBe(2); await page.locator('.del_icon').last().click(); const quantity = await page.locator('.del_icon').count(); expect(quantity).toBe(0); // 确认保存 await page.locator('.submit_btn', { hasText: /^保\s存$/ }).click(); await page.locator('.ant-message').waitFor(); await expect(page.locator('.header', { hasText: '编辑商品属性' })).not.toBeVisible(); const productNameB = await code.locator('td').nth(1).innerText(); expect(productNameB).toBe('商品属性A'); }); await test.step('删除', async () => { await page.locator('.main-table-body_tr').first().locator('.ant-btn-link', { hasText: '删除' }).click(); await page.locator('.content', { hasText: '确认删除该商品属性吗?' }).waitFor(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '删除成功' })).toBeVisible(); await expect(code.locator('td').first()).not.toBeVisible(); }); }); }); test.describe('上架好物', () => { test.beforeEach(async ({ page, homeNavigation }) => { // 下架所有测试商品 await homeNavigation.gotoModule('营销'); await page.locator('.listBox .name', { hasText: '上架好物' }).click(); await page.locator('.batch').waitFor(); await expect(page.locator('.no_data')).not.toBeVisible(); // 商品列表定位器 const code = page.locator('.m-table__body-wrapper .main-table-body_tr'); const goodsList = ['商品As', '商品B', '商品D', '商品Cs', '商品H', '商品M']; for (const goods of goodsList) { const commodity = code.filter({ has: page.locator('td .title', { hasText: goods }) }).first(); if (await commodity.isVisible()) { await commodity.locator('.ant-btn', { hasText: '下架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '下架成功' })).toBeVisible(); } } }); test('未上架商品操作', async ({ page, homeNavigation }) => { // 商品列表定位器 const code = page.locator('.m-table__body-wrapper .main-table-body_tr'); // 各商品显示路径 const commodityA = code.filter({ has: page.locator('td .title', { hasText: '商品As' }) }); const commodityB = code.filter({ has: page.locator('td .title', { hasText: '商品B' }) }); const commodityD = code.filter({ has: page.locator('td .title', { hasText: '商品D' }) }); const commodityCS = code.filter({ has: page.locator('td .title', { hasText: '商品Cs' }) }); const commodityH = code.filter({ has: page.locator('td .title', { hasText: '商品H' }) }); const commodityM = code.filter({ has: page.locator('td .title', { hasText: '商品M' }) }); await test.step('返回上架好物验证', async () => { // 跳转查询中消失 const noData = page.locator('.no_data'); const Element = page.locator('.ant-btn-primary', { hasText: /^新\s增$/ }); // 进入营销模块 await page.goto(process.env.BASE_URL ?? ''); await homeNavigation.gotoModule('营销'); await page.locator('.listBox .name', { hasText: '上架好物' }).click(); await page.locator('.batch').waitFor(); // 上架商品As上架 await page.locator('.tab_item', { hasText: '未上架' }).click(); await expect(Element).toBeVisible(); await expect(noData).not.toBeVisible(); await commodityA.locator('.ant-btn', { hasText: '上架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '上架成功' })).toBeVisible(); // 下架商品As await page.locator('.tab_item', { hasText: '售卖中' }).click(); await expect(noData).not.toBeVisible(); await expect(commodityA).toBeVisible(); await commodityA.locator('.ant-btn', { hasText: '下架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '下架成功' })).toBeVisible(); // 进入未上架 await page.locator('.tab_item', { hasText: '未上架' }).click(); await expect.soft(noData).not.toBeVisible(); await expect(Element).toBeVisible(); await expect.soft(commodityB).toBeVisible(); await expect(commodityCS).toBeVisible(); // 获取商品B 商品Cs行数 const cede = page.locator('.m-table__body-wrapper .main-table-body_tr'); const productBLine = await cede .locator('td .title') .allInnerTexts() .then(text => { return text.findIndex(item => item.includes('商品B')); }); const productCLine = await cede .locator('td .title') .allInnerTexts() .then(text => { return text.findIndex(item => item.includes('商品Cs')); }); if (productBLine === -1 || productCLine === -1) { throw new Error('商品B或商品Cs不存在未上架商品中'); } // 批量操作上架商品B 商品Cs const check = page.locator('.m-table-fixed-body tbody tr'); await check.nth(productBLine).locator('td').nth(0).click(); await check.nth(productBLine).locator('.ant-checkbox-wrapper-checked').waitFor(); await check.nth(productCLine).locator('td').nth(0).click(); await check.nth(productCLine).locator('.ant-checkbox-wrapper-checked').waitFor(); await page.locator('.batch_span', { hasText: '批量操作' }).click(); await page.locator('.ant-dropdown-menu-item', { hasText: '上架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '上架成功' })).toBeVisible(); // 售卖中存在商品B 商品Cs await page.locator('.tab_item', { hasText: '售卖中' }).click(); await expect(noData).not.toBeVisible(); await expect(commodityB).toBeVisible(); await expect(commodityCS).toBeVisible(); // 下架商品B await commodityB.locator('.ant-btn', { hasText: '下架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '下架成功' })).toBeVisible(); // 下架商品Cs await commodityCS.locator('.ant-btn', { hasText: '下架' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '下架成功' })).toBeVisible(); // 进入未上架 await page.locator('.tab_item', { hasText: '未上架' }).click(); await expect.soft(Element).toBeVisible(); await expect(noData).not.toBeVisible(); // 复制商品D,并且改名为商品H await commodityD.locator('.ant-btn', { hasText: '复制' }).click(); const service = page.locator('.header', { hasText: '新增服务' }); await expect(service).toBeVisible(); await page.getByPlaceholder('长度不大于40个字符').fill('商品H'); await page.locator('.ant-btn-primary', { hasText: /^保\s存$/ }).click(); await expect(page.locator('.ant-message', { hasText: '保存成功' })).toBeVisible(); await expect(commodityH).toBeVisible(); // 删除商品H await commodityH.locator('.ant-btn', { hasText: '删除' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message', { hasText: '删除成功' }).waitFor(); //新增商品M await page.locator('.input', { hasText: /^新\s增$/ }).click(); await expect.soft(service).toBeVisible(); await page.getByPlaceholder('长度不大于40个字符').fill('商品M'); // 选择商品分类 await page .locator('.ant-row') .filter({ has: page.locator('.ant-form-item-required', { hasText: '商品分类' }) }) .locator('.ant-col-19 .ant-select-enabled') .last() .click(); await page.locator('.ant-select-dropdown-menu-item').first().click(); await page .locator('.ant-row') .filter({ has: page.locator('.ant-form-item-required', { hasText: '商品售价' }) }) .getByPlaceholder('保留两位小数') .fill('99'); await page .locator('.ant-row') .filter({ has: page.locator('.ant-form-item-required', { hasText: '门店原价' }) }) .getByPlaceholder('保留两位小数') .fill('19'); await page .locator('.ant-row') .filter({ has: page.locator('.ant-form-item-required', { hasText: '最大可售卖数' }) }) .locator('.ant-input') .fill('999'); // 添加全部门店 await page.locator('.addShopBtn', { hasText: '添加可销售门店' }).click(); await expect(page.locator('.comSelect_title', { hasText: /^选择$/ })).toBeVisible(); await page.getByRole('button', { name: /全\s选/ }).click(); await page.getByRole('button', { name: '确定选择' }).first().click(); await page.locator('.ant-btn-primary', { hasText: '下一步' }).click(); // 允许使用会员卡金支付 await page.getByLabel('允许使用会员卡金支付').check(); await page.getByLabel('所有').check(); await page.locator('.ant-btn-primary', { hasText: '下一步' }).click(); await page.locator('.ant-row .upload_icon').last().click(); // 上传图片 const path1 = './tests/imgs/商品M.jpg'; await page .locator('span') .filter({ hasText: '我已阅读并同意 《慧来客图片上传协议》' }) .getByRole('textbox') .setInputFiles(path1); await page.locator('.ant-btn', { hasText: '开始上传' }).click(); await expect(page.locator('.ant-message', { hasText: '上传成功' })).toBeVisible(); await page.locator('.ant-upload-list-item-list-type-picture-card').waitFor(); await page.locator('.ant-btn-primary', { hasText: /^保\s存$/ }).click(); await expect(page.locator('.ant-message', { hasText: '保存成功' })).toBeVisible(); // 校验商品M await expect(commodityM).toBeVisible(); // 删除商品M await commodityM.locator('.ant-btn', { hasText: '删除' }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message', { hasText: '删除成功' }).waitFor(); await page.locator('.close_btn > .icon > svg').click(); await expect(page.locator('.close_btn > .icon > svg')).not.toBeVisible(); }); }); }); test.describe('商城订单', () => { test('查询订单', async ({ page, homeNavigation, createCustomer, customerPage }) => { const customer = createCustomer; await test.step('给顾客进行购买会员卡', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /开\s单/ }).click(); // 选择会员 await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); await page.locator('.number_service').waitFor(); // 点击开卡 await page.getByRole('button', { name: /^开\s卡$/ }).click(); // 选择会员卡A await page .locator('.memberCard_box > .needsclick') .getByText(/^会员卡$/) .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('进入H5商城购买商品', async () => { await page.goto(process.env.STOREH5_URL ?? ''); await page.locator('.bar_item', { hasText: '我的' }).click(); await page.getByText('登录', { exact: true }).click(); // 登录顾客手机 // 点击同意协议 await page.locator('.uni-radio-input').click(); await page.locator('.uni-radio-input-checked').waitFor(); await page .locator('.login-box_input') .filter({ has: page.locator('.input-placeholder', { hasText: '请输入手机号码' }), }) .locator('.uni-input-input') .fill(customer.phone); await page .locator('.login-box_input') .filter({ has: page.locator('.input-placeholder', { hasText: '请输入验证码' }), }) .locator('.uni-input-input') .fill('1660'); await expect(async () => { await page.locator('.login-box_btn', { hasText: /^登录$/ }).click(); await page.locator('.bar_item', { hasText: '商城' }).waitFor(); }).toPass(); // 进入商城 await page.locator('.bar_item', { hasText: '商城' }).click(); // 全部 await page.locator('.li', { hasText: '全部' }).click(); // 点击进入商品 await page.locator('.mescroll-wxs-content .pname', { hasText: '商品F' }).first().click(); // 购买商品 await page.locator('.button_hover', { hasText: '立即购买' }).click(); // 选择门店 await page.locator('.scroll-view-item').first().waitFor(); await page.locator('.scroll-view-item', { hasText: 'AT测试一店' }).click(); await page .locator('.pickstore-body') .filter({ has: page.locator('.scroll-view-item', { hasText: 'AT测试一店' }) }) .locator('.public_color') .waitFor(); // 确认 await page.locator('.mgj-picker-btn-ok', { hasText: /^确认$/ }).click(); await page.locator('.box-header_content .title', { hasText: '订单支付' }).waitFor(); // 选择会员卡支付 await page.locator('.yellow_row', { hasText: '会员卡' }).click(); await page.locator('.uni-radio-input-checked').waitFor(); // 确认支付 await page.locator('.okbtn', { hasText: '确认支付' }).click(); await expect(page.locator('.okText', { hasText: '支付成功' })).toBeVisible(); // 返回 await page.locator('.back').click(); // 购买商品 await page.locator('.button_hover', { hasText: '立即购买' }).click(); // 选择门店 await page.locator('.scroll-view-item').first().waitFor(); await page.locator('.scroll-view-item', { hasText: 'AT测试一店' }).click(); await page .locator('.pickstore-body') .filter({ has: page.locator('.scroll-view-item', { hasText: 'AT测试一店' }) }) .locator('.public_color') .waitFor(); // 确认 await page.locator('.mgj-picker-btn-ok', { hasText: /^确认$/ }).click(); await page.locator('.box-header_content .title', { hasText: '订单支付' }).waitFor(); // 选择微信支付 await page.locator('.form_row .wechat').click(); await page.locator('.uni-radio-input-checked').waitFor(); // 确认支付 await page.locator('.okbtn', { hasText: '确认支付' }).click(); await expect(async () => { const Yes = page.locator('.uni-modal__btn_primary', { hasText: '是' }); if (await Yes.isVisible()) { await page.locator('.uni-modal__btn_primary', { hasText: '是' }).click(); await page.locator('.okbtn', { hasText: '确认支付' }).click(); } await expect(Yes).not.toBeVisible(); // 购买一个套餐F 自动核销为已使用 await page.locator('.jump_btn', { hasText: '回到商家' }).last().waitFor({ timeout: 5000 }); //不限制会等30秒 await page.locator('.jump_btn', { hasText: '回到商家' }).last().click(); }).toPass(); // 进入商城 await page.locator('.bar_item', { hasText: '商城' }).click(); // 全部 await page.locator('.li', { hasText: '全部' }).click(); // 点击进入商品 await page.locator('.mescroll-wxs-content .pname', { hasText: '套餐F' }).first().click(); // 购买商品 await page.locator('.button_hover', { hasText: '立即购买' }).click(); // 选择门店 await page.locator('.scroll-view-item').first().waitFor(); await page.locator('.scroll-view-item', { hasText: 'AT测试一店' }).click(); await page .locator('.pickstore-body') .filter({ has: page.locator('.scroll-view-item', { hasText: 'AT测试一店' }) }) .locator('.public_color') .waitFor(); // 确认 await page.locator('.mgj-picker-btn-ok', { hasText: /^确认$/ }).click(); await page.locator('.box-header_content .title', { hasText: '订单支付' }).waitFor(); // 选择会员卡支付 await page.locator('.yellow_row', { hasText: '会员卡' }).click(); await page.locator('.uni-radio-input-checked').waitFor(); // 确认支付 await page.locator('.okbtn', { hasText: '确认支付' }).click(); await expect.soft(page.locator('.okText', { hasText: '支付成功' })).toBeVisible(); }); await test.step('回商城订单根据状态校验', async () => { await page.goto(process.env.BASE_URL ?? ''); // 进入营销 await homeNavigation.gotoModule('营销'); // 点击商城订单 await page.locator('.listBox .name', { hasText: '商城订单' }).click(); await page.locator('.top .title', { hasText: '商城' }).waitFor(); // 勾选已使用 await expect(async () => { await page.locator('.ant-checkbox-wrapper', { hasText: '未使用' }).click(); const SelectA = page.locator('.ant-checkbox-wrapper-checked', { hasText: '未使用' }); await expect(SelectA).not.toBeVisible({ timeout: 2000 }); }).toPass(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 判断刚创的会员有已使用套餐 const code = page.locator('.scroller .list .detail'); const HaveBeenUsed = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '套餐F' }) }) .filter({ has: page.locator('.status_text', { hasText: '已使用' }) }); await expect(HaveBeenUsed).toBeVisible(); // 勾选未使用 await expect(async () => { await page.locator('.ant-checkbox-wrapper', { hasText: '未使用' }).click(); const SelectA = page.locator('.ant-checkbox-wrapper-checked', { hasText: '未使用' }); await expect(SelectA).toBeVisible({ timeout: 2000 }); await page.locator('.ant-checkbox-wrapper', { hasText: '已使用' }).click(); const SelectC = page.locator('.ant-checkbox-wrapper-checked', { hasText: '已使用' }); await expect(SelectC).not.toBeVisible({ timeout: 2000 }); }).toPass(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 判断刚创的会员有未使用商品 const NotInUse = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '商品F' }) }) .filter({ has: page.locator('.status_text', { hasText: '未使用' }) }); await expect(NotInUse).toBeVisible(); // 勾选未支付 await expect(async () => { await page.locator('.ant-checkbox-wrapper', { hasText: '未支付' }).click(); const SelectB = page.locator('.ant-checkbox-wrapper-checked', { hasText: '未支付' }); await expect(SelectB).toBeVisible({ timeout: 2000 }); await page.locator('.ant-checkbox-wrapper', { hasText: '未使用' }).click(); const SelectC = page.locator('.ant-checkbox-wrapper-checked', { hasText: '未使用' }); await expect(SelectC).not.toBeVisible({ timeout: 2000 }); }).toPass(); // 判断刚创的会员有待支付 const NonPayment = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '商品F' }) }) .filter({ has: page.locator('.status_text', { hasText: '待支付' }) }); await expect(NonPayment).toBeVisible(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 除了退款全勾上 await expect(async () => { await page.locator('.ant-checkbox-wrapper', { hasText: '未支付' }).click(); const SelectB = page.locator('.ant-checkbox-wrapper-checked', { hasText: '未支付' }); await expect(SelectB).toBeVisible({ timeout: 2000 }); await page.locator('.ant-checkbox-wrapper', { hasText: '未使用' }).click(); const SelectA = page.locator('.ant-checkbox-wrapper-checked', { hasText: '未使用' }); await expect(SelectA).toBeVisible({ timeout: 2000 }); await page.locator('.ant-checkbox-wrapper', { hasText: '已使用' }).click(); const SelectC = page.locator('.ant-checkbox-wrapper-checked', { hasText: '已使用' }); await expect(SelectC).toBeVisible({ timeout: 2000 }); }).toPass(); }); await test.step('根据类型校验', async () => { await page.locator('.ant-select-selection__rendered', { hasText: '选择商品类型' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '服务类' }).click(); const ServiceClass = page.locator('.ant-select-selection-selected-value', { hasText: '服务类' }); await ServiceClass.waitFor(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 判断刚创的会员有已使用套餐 const code = page.locator('.scroller .list .detail'); const HaveBeenUsed = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '套餐F' }) }) .filter({ has: page.locator('.status_text', { hasText: '已使用' }) }); await expect(HaveBeenUsed).toBeVisible(); // 去掉筛选条件 await page.locator('.anticon-close-circle').click(); await expect(ServiceClass).not.toBeVisible(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await page.locator('.ant-select-selection__rendered', { hasText: '选择商品分类' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '美容养颜' }).click(); const CommodityType = page.locator('.ant-select-selection-selected-value', { hasText: '美容养颜' }); await expect(CommodityType).toBeVisible(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 判断刚创的会员有已使用套餐 await expect(HaveBeenUsed).toBeVisible(); // 去掉筛选条件 await page.locator('.anticon-close-circle').click(); await expect(CommodityType).not.toBeVisible(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); await page.locator('.ant-select-selection--multiple', { hasText: '选择使用门店' }).click(); await page.locator('.comSelect_title', { hasText: '选择使用门店' }).click(); // 选择一店 await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); await page.locator('.loading_container').waitFor({ state: 'hidden' }); // 判断刚创的会员有已使用套餐 await expect(HaveBeenUsed).toBeVisible(); await page.locator('.ant-select-selection__choice__remove').click(); }); await test.step('根据搜索校验', async () => { // 点击搜索 await page.locator('.searchButton').click(); await page.getByPlaceholder('搜索关键字').fill('套餐F'); await page.locator('.ant-input-affix-wrapper-input-with-clear-btn .search_btn').click(); // 判断刚创的会员有已使用套餐 const code = page.locator('.scroller .list .detail'); const HaveBeenUsed = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '套餐F' }) }) .filter({ has: page.locator('.status_text', { hasText: '已使用' }) }); await expect(HaveBeenUsed).toBeVisible(); }); }); test('订单详情', async ({ page, homeNavigation, createCustomer, customerPage }) => { const code = page.locator('.scroller .list .detail'); const customer = createCustomer; await test.step('开会员卡用于消费商品', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /^开\s单$/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); await page.locator('.number_service').waitFor(); await page.getByRole('button', { name: /^开\s卡$/ }).click(); // 选择会员卡A await page .locator('.memberCard_box > .needsclick') .getByText(/^会员卡$/) .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('进入H5商城购买商品', async () => { await page.goto(process.env.STOREH5_URL ?? ''); await page.locator('.bar_item', { hasText: '我的' }).click(); await page.getByText('登录', { exact: true }).click(); // 登录顾客手机 await page.locator('.uni-radio-input').click(); //点击同意协议 await page.locator('.uni-radio-input-checked').waitFor(); await page .locator('.login-box_input') .filter({ has: page.locator('.input-placeholder', { hasText: '请输入手机号码' }), }) .locator('.uni-input-input') .fill(customer.phone); await page .locator('.login-box_input') .filter({ has: page.locator('.input-placeholder', { hasText: '请输入验证码' }), }) .locator('.uni-input-input') .fill('1660'); await expect(async () => { await page.locator('.login-box_btn', { hasText: /^登录$/ }).click(); await page.locator('.bar_item', { hasText: '商城' }).waitFor(); }).toPass({ timeout: 60000 }); // 进入商城 await page.locator('.bar_item', { hasText: '商城' }).click(); // 全部 await page.locator('.li', { hasText: '全部' }).click(); // 点击进入商品 await page.locator('.mescroll-wxs-content .pname', { hasText: '商品E' }).first().click(); // 购买商品 await page.locator('.button_hover', { hasText: '立即购买' }).click(); // 选择门店 await page.locator('.scroll-view-item').first().waitFor(); await page.locator('.scroll-view-item', { hasText: 'AT测试一店' }).click(); await page .locator('.pickstore-body') .filter({ has: page.locator('.scroll-view-item', { hasText: 'AT测试一店' }) }) .locator('.public_color') .waitFor(); // 确认 await page.locator('.mgj-picker-btn-ok', { hasText: /^确认$/ }).click(); await page.locator('.box-header_content .title', { hasText: '订单支付' }).waitFor(); // 选择会员卡支付 await page.locator('.yellow_row', { hasText: '会员卡' }).click(); await page.locator('.uni-radio-input-checked').waitFor(); // 确认支付 await page.locator('.okbtn', { hasText: '确认支付' }).click(); await expect(page.locator('.okText', { hasText: '支付成功' })).toBeVisible(); }); await test.step('搜索商品E验证', async () => { await page.goto(process.env.BASE_URL ?? ''); // 进入营销 await homeNavigation.gotoModule('营销'); // 点击商城订单 await page.locator('.listBox .name', { hasText: '商城订单' }).click(); await page.locator('.top .title', { hasText: '商城' }).waitFor(); // 点击搜索 await page.locator('.searchButton').click(); await page.getByPlaceholder('搜索关键字').fill('商品E'); await page.locator('.ant-input-affix-wrapper-input-with-clear-btn .search_btn').click(); // 判断会员买的商品E 数量1 实付金额100元,状态未使用 const Member = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '商品E' }) }) .filter({ has: page.locator('.status_text', { hasText: '未使用' }) }) .filter({ has: page.locator('.num', { hasText: '1' }) }) .filter({ has: page.locator('.amount', { hasText: '¥100' }) }); await expect(Member).toBeVisible(); }); await test.step('点击顾客名称进入顾客详情', async () => { // 点击顾客名称 await page.locator('.scroller .list .detail .user', { hasText: customer.username }).click(); await page.locator('.consume_data').waitFor(); // 对比该顾客是不是刚创建的 await expect.soft(page.locator('.user_name')).toContainText(customer.username); // await expect(page.getByText(customer.phone)).toBeVisible(); await expect(page.locator('.member_info_box .phone')).toContainText(customer.phone); // 关闭顾客详情 await page.locator('.close_icons').click(); const BasicData = page.locator('.ant-tabs-tab-active', { hasText: '基本资料' }); await expect(BasicData).not.toBeVisible(); }); await test.step('点击备注,输入备注并保存', async () => { const remark = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '商品E' }) }) .filter({ has: page.locator('.status_text', { hasText: '未使用' }) }) .filter({ has: page.locator('.num', { hasText: '1' }) }) .filter({ has: page.locator('.amount', { hasText: '¥100' }) }); await expect(remark).toBeVisible(); // 点击备注 并输入备注 await remark.locator('.comment .anticon').click(); await page.locator('.title', { hasText: '编辑备注' }).waitFor(); await page.getByPlaceholder('请输入1-100个字符备注内容').click(); // 点击输入框触发保存 await page.getByPlaceholder('请输入1-100个字符备注内容').fill('测试'); await page.locator('.comfirm_btn', { hasText: /^保\s存$/ }).click(); // 判断刚输入的备注是否成功 await expect(remark.locator('.comment')).toContainText('测试'); }); await test.step('点击详情,查看商品购买详情', async () => { const Details = code .filter({ has: page.locator('.head', { hasText: customer.username }) }) .filter({ has: page.locator('div .name', { hasText: '商品E' }) }) .filter({ has: page.locator('.status_text', { hasText: '未使用' }) }) .filter({ has: page.locator('.num', { hasText: '1' }) }) .filter({ has: page.locator('.amount', { hasText: '¥100' }) }); // 点击详情 await Details.locator('.ant-btn-link', { hasText: '详情' }).click(); await expect(page.locator('.header', { hasText: '订单详情' })).toBeVisible(); // 判断会员手机、订单状态、支付方式、实付金额 await expect.soft(page.locator('.info_warp .phone')).toContainText(customer.phone); await expect.soft(page.locator('.box').getByText('未使用')).toBeVisible(); await expect.soft(page.locator('.alloytouch-target .item').locator('div').nth(9)).toContainText('卡金'); await expect(page.locator('.alloytouch-target .item').locator('div').nth(19)).toContainText('100'); }); }); test.skip('导出', async ({ page, homeNavigation }) => { // 进入营销 await homeNavigation.gotoModule('营销'); // 点击商城订单 await page.locator('.listBox .name', { hasText: '商城订单' }).click(); await page.locator('.top .title', { hasText: '商城' }).waitFor(); const downloadPromise = page.waitForEvent('download'); // 点击更多 await page.locator('.more .batch_span').click(); // 点击导出 await page.locator('.ant-dropdown-menu-item', { hasText: '导出' }).click(); const download = await downloadPromise; // 获取下载的文件名 const fileName = download.suggestedFilename(); // 指定保存下载文件的路径 const downloadPath = path.join(__dirname, `@/imgs/${fileName}`); // 保存下载的文件 await download.saveAs(downloadPath); // 验证文件是否成功保存 const fileExists = fs.existsSync(downloadPath); expect(fileExists).toBeTruthy(); }); }); test('抢购', async ({ page, homeNavigation }) => { // 进入营销-抢购 await homeNavigation.gotoModule('营销'); await page.locator('.category_1_itemStyle .category_1_itemStyle_content_name', { hasText: /^抢购$/ }).click(); await page.locator('.main-table-body_tr').first().waitFor(); const GroupBuying = await page.locator('.ant-select-selection-selected-value').innerText(); expect(GroupBuying).toBe('抢购'); }); test('团购', async ({ page, homeNavigation }) => { // 进入营销-团购 await homeNavigation.gotoModule('营销'); await page.locator('.category_1_itemStyle .category_1_itemStyle_content_name', { hasText: /^团购$/ }).click(); await page.locator('.main-table-body_tr').first().waitFor(); const GroupBuying = await page.locator('.ant-select-selection-selected-value').innerText(); expect(GroupBuying).toBe('团购'); }); }); test.describe('品牌', () => { test.describe('门店信息', () => { test('品牌信息配置', async ({ page, homeNavigation }) => { await homeNavigation.gotoModule('营销'); await page.getByText('个性装扮').click(); // 随机门店名称 const marketingName = 'AT测试' + faker.string.alpha(3); // 上传图片路径 const uploadImgFile = path.join(__dirname, '@/imgs/upload.jpg'); const $marketingNameInput = page .locator('div') .filter({ has: page.getByText('品牌名称') }) .locator('input[type="text"]'); const $uploadBtn = page.locator('input[type="file"]'); const $uploadImg = page .locator('div') .filter({ has: page.getByText('品牌logo') }) .locator('.upload_img img'); await $marketingNameInput.fill(marketingName); await page.getByLabel('icon: delete').locator('svg').click(); await $uploadImg.focus(); await expect($uploadBtn).toBeVisible(); await $uploadBtn.setInputFiles(uploadImgFile); const [res] = await Promise.all([ page.waitForResponse(res => res.url().includes('/base64Upload') && res.status() === 200), page.getByRole('button', { name: '开始上传' }).click(), ]); const resBody = await res.json(); const getImgPath = resBody?.content?.filePath; expect(getImgPath).not.toBeNull(); await page.getByRole('button', { name: /保\s存/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); await page.locator('label').filter({ hasText: '门店信息' }).click(); await page.locator('label').filter({ hasText: '品牌信息' }).click(); await expect($marketingNameInput).toHaveValue(marketingName); await expect($uploadImg.filter({ hasText: getImgPath })).toBeVisible(); }); test.skip('门店信息配置,预览修改配置', async ({ page, homeNavigation }) => { const storeName = 'AT测试一店' + faker.string.alpha(3); const storeTag = '一店' + faker.string.alpha(3); const storePhone = faker.helpers.fromRegExp(/1[3-9][0-1]{9}/); const $firstStoreTr = page.locator('.main-table-body_tr').first(); const $popupIframe = page.locator('.popup_content iframe').contentFrame(); await test.step('进入门店信息', async () => { await homeNavigation.gotoModule('营销'); await page.getByText('个性装扮').click(); await page.locator('span').filter({ hasText: '门店信息' }).click(); await expect(page.getByText('门店排序')).toBeVisible(); }); await test.step('门店信息配置', async () => { const $storeName = page.locator('.item', { hasText: '门店名称' }).locator('.ant-input'); const $storeTag = page.locator('.item', { hasText: '区域标签' }).locator('.ant-input'); const $storePhone = page.locator('.item', { hasText: '电话' }).locator('.ant-input'); await $firstStoreTr.getByText('编辑').first().click(); await $storeName.fill(storeName); await $storeTag.fill(storeTag); await $storePhone.fill(storePhone); await page.locator('.tangram-suggestion tr > td').first().click(); await page.getByRole('button', { name: /保\s存/ }).click(); await expect(page.getByRole('cell', { name: storeName })).toBeVisible(); await expect(page.getByRole('cell', { name: storeTag })).toBeVisible(); await expect(page.getByRole('cell', { name: storePhone })).toBeVisible(); }); await test.step('预览修改配置', async () => { await $firstStoreTr.getByText('扫码预览').first().click(); await $popupIframe.locator('.bar_item', { hasText: '预约' }).click(); await $popupIframe.getByText('切换门店').click(); await expect($popupIframe.getByText(storeName)).toBeVisible(); }); }); test('门店排序', async ({ page, homeNavigation }) => { let firstTrStoreName: string; let secondTrStoreName: string; await test.step('进入门店信息', async () => { await homeNavigation.gotoModule('营销'); await page.getByText('个性装扮').click(); await page.locator('span').filter({ hasText: '门店信息' }).click(); await expect(page.getByText('门店排序')).toBeVisible(); }); await test.step('门店排序,查看门店排序', async () => { await page.getByText('门店排序').click(); const $popup = page.locator('.popup_content'); const $firstTr = $popup.locator('.sort_tbody .tr').nth(0); const $secondTr = $popup.locator('.sort_tbody .tr').nth(1); firstTrStoreName = await $firstTr.locator('.item').first().innerText(); secondTrStoreName = await $secondTr.locator('.item').first().innerText(); // await page.pause(); await $secondTr.locator('.item').nth(1).dragTo($firstTr.locator('.item').nth(1)); await expect($firstTr.locator('.item').first()).toContainText(secondTrStoreName); await page.getByRole('button', { name: /保\s存/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); const $$storeTr = page.locator('.main-table-body_tr'); await expect($$storeTr.nth(0).getByRole('cell').nth(1)).toContainText(secondTrStoreName); await expect($$storeTr.nth(1).getByRole('cell').nth(1)).toContainText(firstTrStoreName); }); }); }); test.describe('个性化', () => { test('模块', async ({ page, homeNavigation }) => { let createModuleName = '新增模块名称' + faker.helpers.fromRegExp(/[0-9]{2}/); let editModuleName = '修改模块名称' + faker.helpers.fromRegExp(/[0-9]{2}/); const sideIframe = page.frameLocator('.side iframe'); const popupIframe = page.locator('.popup_content iframe').contentFrame(); let tableTr = page.locator('.tr'); let lastTableTr = tableTr.last(); await test.step('新增模块', async () => { await homeNavigation.gotoModule('营销'); await page.getByText('个性装扮').click(); await page.getByText('个性化').click(); await page.getByRole('button', { name: '新增模块' }).click(); // 输入模块信息 await page.getByPlaceholder('输入名称').fill(createModuleName); await page.getByText('选择图标').click(); await page .locator('div') .filter({ hasText: /^分析$/ }) .first() .click(); await lastTableTr .locator('div') .filter({ hasText: /^选择页面$/ }) .click(); await page.locator('tr', { hasText: '商城' }).getByLabel('', { exact: true }).check(); await page.getByRole('button', { name: /确\s认/ }).click(); await page.locator('.pre-table-body').getByText('确认').click(); await page.getByRole('button', { name: /保\s存/ }).click(); await expect(async () => { await sideIframe.locator('.bar_item', { hasText: createModuleName }).click(); await expect(sideIframe.locator('uni-view.title', { hasText: createModuleName })).toBeVisible({ timeout: 2000, }); }).toPass(); }); await test.step('修改模块名称,隐藏模块', async () => { await page .locator('div') .filter({ hasText: new RegExp(`^${createModuleName}$`) }) .locator('svg') .click(); await page.getByPlaceholder('输入名称').fill(editModuleName); await page.getByRole('button', { name: /保\s存/ }).click(); // 查看修改后的模块名称 await expect(sideIframe.locator('.bar_item', { hasText: editModuleName })).toBeVisible(); // 模块隐藏和展示成功 await page.locator('.tr', { hasText: editModuleName }).getByRole('switch', { name: '是' }).click(); await page.getByRole('button', { name: /保\s存/ }).click(); await page.locator('.ant-message-notice', { hasText: '操作成功' }).waitFor(); await expect(sideIframe.locator('.bar_item', { hasText: editModuleName })).not.toBeVisible(); await page.locator('.tr', { hasText: editModuleName }).getByRole('switch', { name: '否' }).click(); await page.getByRole('button', { name: /保\s存/ }).click(); await page.locator('.ant-message-notice', { hasText: '操作成功' }).waitFor(); await expect(sideIframe.locator('.bar_item', { hasText: editModuleName })).toBeVisible(); }); await test.step('模块排序,删除模块', async () => { const editTableTr = tableTr.filter({ hasText: editModuleName }); // 模块排序 await page .locator('div') .filter({ hasText: /^模块排序$/ }) .nth(1) .click(); await editTableTr.locator('.td.td-opt').dragTo(tableTr.nth(1).locator('.td.td-opt')); await page.getByText('结束排序').click(); await page.locator('.ant-message', { hasText: '排序成功' }).waitFor(); await page.getByRole('button', { name: /保\s存/ }).click(); // await page.pause(); const barItemText = await sideIframe.locator('.bar_item').allInnerTexts(); expect(barItemText[0]).toContain(editModuleName); // 模块删除 await editTableTr.getByText('删除').click(); await page.getByRole('button', { name: /确\s认/ }).click(); await page.locator('.ant-message', { hasText: '删除模块成功' }).waitFor(); await expect(sideIframe.locator('.bar_item', { hasText: editModuleName })).not.toBeVisible(); await expect(editTableTr).not.toBeVisible(); // 判断预览 await page.getByRole('button', { name: '保存并预览' }).click(); await expect(popupIframe.locator('.bar_item').last()).toBeVisible(); // 二维码能够解析出url const dirPath = path.resolve(__dirname, '@/tests/imgs'); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } const filePath = path.resolve(dirPath, 'previewWindow.jpg'); await page.locator('.qrcode .hqrcode').screenshot({ path: filePath }); const urlContent = decodeQR(filePath); expect(urlContent).not.toBeNull(); }); }); test('个性化配置', async ({ page, homeNavigation }) => { const $setAppointment = page.locator('.tr').filter({ has: page.getByText('预约').first(), }); await test.step('进入门店信息', async () => { await homeNavigation.gotoModule('营销'); await page.getByText('个性装扮').click(); await page.getByText('个性化').click(); await expect(page.getByRole('button', { name: '新增模块' })).toBeVisible(); await $setAppointment.getByText('个性化').click(); await expect(page.getByText('个性化设置')).toBeVisible(); await page.getByLabel('员工优先模式选择员工>选择项目>选择时间>确认预约').check(); const $box = page.locator('.box'); await $box.getByRole('button', { name: /保\s存/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); await expect(page.getByText('个性化设置')).not.toBeVisible(); }); await test.step('查看配置生效', async () => { const $sideIframe = page.locator('.side iframe').contentFrame(); await $sideIframe.getByText('预约', { exact: true }).click(); await expect($sideIframe.getByText('不指定人预约')).toBeVisible(); }); }); let initPage: Page; test.beforeAll(async ({ browser, baseURL }) => { initPage = await browser.newPage(); const homeNavigation = new HomeNavigation(initPage); await initPage.goto(baseURL ?? ''); await homeNavigation.gotoModule('营销'); // 恢复个性化配置 await initPage.getByText('个性装扮').click(); await initPage.getByText('个性化').click(); await test.step('重置预约个性化配置', async () => { const $setAppointment = initPage.locator('.tr').filter({ has: initPage.getByText('预约').first(), }); await expect($setAppointment).toBeVisible(); await $setAppointment.getByText('个性化').click(); await expect(initPage.getByText('个性化设置')).toBeVisible(); await initPage.getByLabel('项目优先模式选择项目>选择时间>选择员工>确认预约').check(); const $box = initPage.locator('.box'); await $box.getByRole('button', { name: /保\s存/ }).click(); }); }); test.afterAll(async ({ baseURL }) => { const homeNavigation = new HomeNavigation(initPage); await initPage.goto(baseURL ?? ''); await homeNavigation.gotoModule('营销'); // 删除所有新增模块 await initPage.getByText('个性装扮').click(); await initPage.getByText('个性化').click(); await initPage .locator('div') .filter({ hasText: /^我的$/ }) .last() .waitFor(); const deleteCount = async () => await initPage.locator('.td', { hasText: '删除' }).count(); const maxRetry = 10; let retry = 0; while ((await deleteCount()) > 0 && retry < maxRetry) { await initPage.locator('.td').getByText('删除').first().click(); await initPage.getByRole('button', { name: /确\s认/ }).click(); await initPage.waitForLoadState('domcontentloaded'); retry++; } }); }); test.describe('个性化', () => { test('配色', async ({ page, homeNavigation }) => { let colorArray: string[]; await test.step('进入个性化装扮', async () => { await homeNavigation.gotoModule('营销'); await page.getByText('个性装扮').click(); await page.getByText('个性化').click(); await page.locator('.main-head span').filter({ hasText: '配色' }).click(); }); await test.step('获取所有主题色', async () => { const colorItems = await page.locator('.color-item a:first-child').all(); colorArray = await Promise.all( colorItems.map(async item => { return await item.evaluate(el => getComputedStyle(el).backgroundColor); }), ); expect(colorArray.length).not.toBe(0); }); await test.step('设置主题色,并且查看预览色', async () => { const randomColor = faker.number.int({ min: 0, max: colorArray.length - 1 }); const $$colorItem = page.locator('.color-item'); await $$colorItem.nth(randomColor).click(); await page.getByRole('button', { name: '保存并预览' }).click(); const $popupIframe = page.locator('.popup_content iframe').contentFrame(); const $logo = $popupIframe.locator('.bar_item', { hasText: '我的' }).locator('.logo'); await $logo.waitFor(); await page.waitForTimeout(2000); const logoColor = await $logo.evaluate(e => getComputedStyle(e).color); expect(logoColor).toBe(colorArray[randomColor]); }); }); test('页面', async ({ page, homeNavigation }) => { const pageName = '测试页面' + faker.string.alpha(3); const pageContent = '测试页面'; const copyPageName = pageName + '复制'; const $tableTr = page.locator('.main-table-body_tr'); const $newPageTr = $tableTr.filter({ has: page.locator('td:first-child').filter({ hasText: new RegExp(`^${pageName}$`) }), }); const $copyPageTr = $tableTr.filter({ has: page.locator('td:first-child').filter({ hasText: new RegExp(`^${copyPageName}$`) }), }); const $storePageTr = $tableTr.filter({ has: page.locator('td:first-child').filter({ hasText: '商城' }), }); await homeNavigation.gotoModule('营销'); await test.step('进入品牌-个性化-页面', async () => { await page.getByText('个性装扮').click(); await page.getByText('个性化').click(); await page.locator('.main-head span').filter({ hasText: '页面' }).click(); }); await test.step('创建页面', async () => { await page.getByRole('button', { name: '创建页面' }).click(); await page.getByText('选择模板').click(); const $$viewList = page.locator('.temp-view'); await $$viewList.first().focus(); await expect($$viewList.first().getByText('复制此模板')).toBeVisible(); await $$viewList.first().getByText('复制此模板').click(); await page.locator('.add-btn').first().click(); await page.getByText('公告栏').click(); await page.getByPlaceholder('请输入公告内容').fill(pageContent); await page.getByPlaceholder('自定义页面名称').fill(pageName); await page.getByRole('button', { name: /保\s存/ }).click(); await expect.soft($newPageTr).toBeVisible(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); }); await test.step('应用新建页面到商城模块', async () => { await $newPageTr.locator('td').nth(2).locator('svg').click(); const $popup = page.locator('.popup_content'); const index = await page .locator('.popup_content .main-table-body_tr') .allInnerTexts() .then(text => { return text.findIndex(el => el.includes('商城')); }); const $popupTr = $popup.locator('.m-table__fixed-left').locator('tr').nth(index); await $popupTr.getByRole('checkbox').check(); await expect($popupTr.getByRole('checkbox')).toBeChecked(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect(page.getByRole('button', { name: /确\s认/ })).not.toBeVisible(); }); await test.step('保存并预览页面', async () => { await page.getByText('模块', { exact: true }).click(); await page.getByRole('button', { name: '保存并预览' }).click(); const $popupIframe = page.locator('.popup_content iframe').contentFrame(); await $popupIframe.locator('.bar_item', { hasText: '商城' }).click(); await expect.soft($popupIframe.getByText(pageContent).first()).toBeVisible(); await page.locator('.close-btn > svg').click(); }); await test.step('复制新建页面', async () => { await page.locator('.main-head span').filter({ hasText: '页面' }).click(); await $newPageTr.getByText('复制').click(); await page.getByPlaceholder('自定义页面名称').fill(copyPageName); await page.getByRole('button', { name: /保\s存/ }).click(); await expect.soft($copyPageTr).toBeVisible(); }); await test.step('重置页面应用,并且删除页面', async () => { await $storePageTr.locator('td').nth(2).locator('svg').click(); const $popup = page.locator('.popup_content'); const index = await page .locator('.popup_content .main-table-body_tr') .allInnerTexts() .then(text => { return text.findIndex(el => el.includes('商城')); }); const $popupTr = $popup.locator('.m-table__fixed-left').locator('tr').nth(index); await $popupTr.getByRole('checkbox').check(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect(page.getByRole('button', { name: /确\s认/ })).not.toBeVisible(); await $newPageTr.getByText('删除').click(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect.soft($newPageTr).not.toBeVisible(); await $copyPageTr.getByText('删除').click(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect.soft($copyPageTr).not.toBeVisible(); }); }); }); }); test.describe('邀客系统', () => { test('礼品设置', async ({ page, homeNavigation, marketingPage, marketingInviteGuestsPage }) => { const giftName = '新增礼品' + faker.string.alpha(3); const editGiftName = giftName + '编辑'; const copyGiftName = giftName + '复制'; const $$pickerItem = page.locator('.com_picker').locator('div > label'); const $bodyTable = page.locator('.m-table__body-wrapper'); const $fixedLeftTable = page.locator('.m-table__fixed-left'); const $giftTr = $bodyTable .locator('.main-table-body_tr') .filter({ has: page.getByRole('cell', { name: giftName, exact: true }) }); const $editGiftTr = $bodyTable .locator('.main-table-body_tr') .filter({ has: page.getByRole('cell', { name: editGiftName, exact: true }) }); const $copyGiftTr = $bodyTable .locator('.main-table-body_tr') .filter({ has: page.getByRole('cell', { name: copyGiftName, exact: true }) }); await test.step('礼品设置', async () => { await homeNavigation.gotoModule('营销'); await marketingPage.gotoStrategySubPage('邀客系统'); await marketingInviteGuestsPage.gotoSubPage('设置'); await marketingInviteGuestsPage.gotoSettingSubPage('礼品设置'); }); await test.step('新增礼品', async () => { await page.getByRole('button', { name: '新增礼品' }).click(); await page.getByPlaceholder('长度不大于20个字符').fill(giftName); await page.getByRole('button', { name: '添加项目' }).click(); await expect(async () => { await $$pickerItem.first().getByRole('checkbox').uncheck(); await $$pickerItem.first().getByRole('checkbox').check(); await expect(page.locator('span').filter({ hasText: '全部' }).locator('span')).toBeVisible({ timeout: 2000, }); }).toPass(); await page.getByRole('button', { name: '确定选择' }).click(); const $$serviceItem = page.locator('.item', { hasText: '体验项目' }).locator('.drag-item'); // 输入选择的体验项目有效期 await $$serviceItem.first().getByRole('textbox').nth(1).fill('3'); await page.getByRole('button', { name: '确认保存' }).click(); await expect($giftTr).toBeVisible(); }); await test.step('编辑礼品', async () => { await $giftTr.getByText('编辑').click(); await page.getByPlaceholder('长度不大于20个字符').fill(editGiftName); await page.getByRole('button', { name: '添加项目' }).click(); await expect(async () => { await $$pickerItem.nth(2).getByRole('checkbox').uncheck(); await $$pickerItem.nth(2).getByRole('checkbox').check(); await expect(page.locator('span').filter({ hasText: '全部' }).locator('span')).toBeVisible({ timeout: 2000, }); }).toPass(); await page.getByRole('button', { name: '确定选择' }).click(); const $$serviceItem = page.locator('.item', { hasText: '体验项目' }).locator('.drag-item'); // 输入选择的体验项目有效期 await $$serviceItem.nth(1).getByRole('textbox').nth(1).fill('3'); await page.getByRole('button', { name: '确认保存' }).click(); await expect($editGiftTr).toBeVisible(); }); await test.step('复制礼品', async () => { await $editGiftTr.getByText('复制').click(); await page.getByPlaceholder('长度不大于20个字符').fill(copyGiftName); await page.getByRole('button', { name: '确认保存' }).click(); await expect($copyGiftTr).toBeVisible(); }); await test.step('批量删除礼品', async () => { const $$selectGift = $fixedLeftTable.locator('tbody td[colspan="1"]'); const allGiftName = await page.locator('.main-table-body_tr td:nth-child(2)').allInnerTexts(); const editGiftIndex = allGiftName.findIndex(e => e === editGiftName); const copyGiftIndex = allGiftName.findIndex(e => e === copyGiftName); await $$selectGift.nth(editGiftIndex).locator('input').check(); await $$selectGift.nth(copyGiftIndex).locator('input').check(); await page.getByText('批量操作').click(); await page.getByRole('menuitem', { name: '批量删除' }).click(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect($editGiftTr).not.toBeVisible(); await expect($copyGiftTr).not.toBeVisible(); }); }); test('礼品分配', async ({ page, homeNavigation, marketingPage, marketingInviteGuestsPage }) => { const firstStoreEmployee = staffData.firstStore.firstSector.employee_1; page.locator('.m-table__header-wrapper'); const $bodyTable = page.locator('.m-table__body-wrapper'); page.locator('.m-table__fixed-left'); const $firstStoreEmployeeTr = $bodyTable .locator('.main-table-body_tr') .filter({ has: page.getByRole('cell', { name: firstStoreEmployee.name }) }) .filter({ has: page.getByText('顾问') }); const $margin = $firstStoreEmployeeTr.locator('td').nth(4); await test.step('进入礼品分配页面', async () => { await homeNavigation.gotoModule('营销'); await marketingPage.gotoStrategySubPage('邀客系统'); await marketingInviteGuestsPage.gotoSubPage('设置'); await marketingInviteGuestsPage.gotoSettingSubPage('礼品分配'); }); await test.step('选择一店员工进行分配礼品', async () => { await expect(async () => { await page.locator('.store_box a').click(); await expect(page.locator('.com_picker').getByLabel('AT测试一店')).toBeVisible({ timeout: 2000 }); }).toPass(); await page.getByLabel('AT测试一店').check(); const lastValue = Number(await $margin.innerText()); await $firstStoreEmployeeTr.getByText('分配').click(); await page.locator('.gift_item').first().getByRole('checkbox').check(); await page.getByRole('button', { name: '保存' }).click(); await page.getByRole('button', { name: '确认添加' }).click(); await page.locator('.ant-message', { hasText: '操作成功' }).waitFor(); await expect(page.getByRole('button', { name: '确认添加' })).not.toBeVisible(); const value = Number(await $margin.innerText()); expect(value - lastValue).toBe(1); }); }); test('返利方案配置', async ({ page, homeNavigation, createCustomer, marketingPage, marketingInviteGuestsPage }) => { const customer = createCustomer; const rebateSchemeName = '新建返利方案' + faker.string.alpha(3); page.locator('.m-table__header-wrapper'); const $bodyTable = page.locator('.m-table__body-wrapper'); page.locator('.m-table__fixed-left'); const $$inputBalance = page.locator('.public_list').filter({ hasText: '返余额' }).locator('input'); const $$inputIntegral = page.locator('.public_list').filter({ hasText: '返积分' }).locator('input'); // 项目选择 const $$pickerItem = page.locator('.com_picker').locator('div > label'); await test.step('进入管理,将该顾客设置为邀客', async () => { await homeNavigation.gotoModule('营销'); await marketingPage.gotoStrategySubPage('邀客系统'); await marketingInviteGuestsPage.gotoSubPage('邀客管理'); await page.getByRole('button', { name: '添加邀客' }).click(); await page.getByRole('button', { name: '手动添加邀客' }).click(); await page .locator('.popup_content') .getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索') .fill(customer.phone); await page.locator('.popup_content').getByText('搜索').click(); await page.getByRole('row', { name: customer.phone }).getByLabel('').check(); await page.getByRole('button', { name: '确认选择' }).click(); await page.getByRole('button', { name: '确认添加' }).click(); await expect(page.getByText('导入成功')).toBeVisible(); await page.getByRole('button', { name: /确\s认/ }).click(); }); await test.step('新建返利方案', async () => { await marketingInviteGuestsPage.gotoSubPage('返利方案'); await page.getByRole('button', { name: '创建方案' }).click(); await page.getByPlaceholder('长度不大于20个字符').fill(rebateSchemeName); await page.getByRole('checkbox', { name: '通用返利' }).check(); await $$inputBalance.nth(0).fill('10'); await $$inputBalance.nth(1).fill('5'); await $$inputIntegral.nth(0).fill('10'); await $$inputIntegral.nth(1).fill('5'); await page.getByRole('checkbox', { name: '指定项目' }).check(); await page.getByRole('button', { name: '新增' }).click(); await expect(async () => { await $$pickerItem.nth(2).getByRole('checkbox').uncheck(); await $$pickerItem.nth(2).getByRole('checkbox').check(); await expect(page.locator('span').filter({ hasText: '全部' }).locator('span')).toBeVisible({ timeout: 2000, }); }).toPass(); await page.getByRole('button', { name: '确定选择' }).click(); await page.getByText('卖品', { exact: true }).first().click(); await page.getByRole('checkbox', { name: '通用返利' }).check(); await $$inputBalance.nth(0).fill('10'); await $$inputBalance.nth(1).fill('5'); await $$inputIntegral.nth(0).fill('10'); await $$inputIntegral.nth(1).fill('5'); await page.getByRole('button', { name: /保\s存/ }).click(); await expect(page.getByRole('cell', { name: rebateSchemeName })).toBeVisible(); }); await test.step('为新建返利方案配置邀客', async () => { await page.getByRole('row', { name: rebateSchemeName }).locator('svg').first().click(); await page.getByRole('button', { name: '添加邀客' }).click(); await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone); await expect(async () => { await page.getByText('搜索', { exact: true }).click(); await expect(page.getByRole('row', { name: customer.phone })).toBeVisible({ timeout: 2000 }); }).toPass(); await page.getByRole('row', { name: customer.phone }).getByLabel('').check(); await page.getByRole('button', { name: '确认选择' }).click(); await page.getByRole('button', { name: /保\s存/ }).click(); const $rebateScheme = $bodyTable.locator('.main-table-body_tr').filter({ hasText: rebateSchemeName }); await expect($rebateScheme).toContainText('1'); await page.getByRole('row', { name: rebateSchemeName }).locator('svg').first().click(); await page.getByText('移除').first().click(); await page.getByRole('button', { name: /保\s存/ }).click(); await page.getByRole('row', { name: rebateSchemeName }).getByText('删除').click(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); // 关闭邀客管理页面 await page.locator('.top').filter({ hasText: '邀客系统' }).locator('.close_btn').click(); await expect(page.locator('.top').filter({ hasText: '邀客系统' })).not.toBeVisible(); }); }); test('邀客管理', async ({ page, homeNavigation, tablePage, customerPage, createCustomers, marketingPage }) => { let customers: Customer[] = []; await test.step('创建顾客', async () => { customers = await createCustomers(2); }); await test.step('进入邀客管理页面,添加邀客', async () => { await homeNavigation.gotoModule('营销'); await marketingPage.gotoStrategySubPage('邀客系统'); await page.getByRole('button', { name: '添加邀客' }).click(); await page.getByRole('button', { name: '手动添加邀客' }).click(); const $selectCustomerView = page.locator('.popup_content'); // 批量手动添加邀客 for (const customer of customers) { await $selectCustomerView.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customer.phone); await $selectCustomerView.getByText('搜索', { exact: true }).click(); await $selectCustomerView.getByRole('row', { name: customer.phone }).getByLabel('').check(); } await page.getByRole('button', { name: '确认选择' }).click(); await page.getByRole('button', { name: '确认添加' }).click(); await expect(page.getByText('导入成功')).toBeVisible(); await page.getByRole('button', { name: /确\s认/ }).click(); }); const $$bodyTrTable = tablePage.bodyTrTable; const $firstCustomerTr = $$bodyTrTable.filter({ hasText: customers[0].phone }); const $secondCustomerTr = $$bodyTrTable.filter({ hasText: customers[1].phone }); await test.step('搜索邀客B,将邀客A设置为邀客B的上级', async () => { await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customers[1].phone); await page.getByText('搜索', { exact: true }).click(); await $secondCustomerTr.getByText('详情').click(); // 设置上级 const $settingLastCustomer = page.locator('.left_box .list_', { hasText: '上级' }); await $settingLastCustomer.locator('svg').click(); const $selectCustomerView = page.locator('.popup_content'); await $selectCustomerView.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customers[0].phone); await $selectCustomerView.getByText('搜索', { exact: true }).click(); await $selectCustomerView.getByRole('row', { name: customers[0].phone }).getByLabel('').click(); await expect($settingLastCustomer).toContainText(customers[0].username); // 关闭详情页 await page.locator('.top').filter({ hasText: '邀客详情' }).locator('.close_btn').click(); // 关闭邀客管理页面 await page.locator('.top').filter({ hasText: '邀客系统' }).locator('.close_btn').click(); }); const project = { num: '100020', name: '青春雅致套', price: 1980 }; await test.step('邀客B购买项目', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /开\s单/ }).click(); await customerPage.searchCustomer(customers[1].phone); await customerPage.selectSearchCustomer(customers[1].phone); await page.locator('.project_list .number', { hasText: project.num }).click(); await page.locator('.pay_btn', { hasText: /结\s算/ }).click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); const leftPaymentInfoItem = page.locator('.left .paymentmain .paymentInfoItem'); await leftPaymentInfoItem.filter({ hasText: '现金' }).click(); await page.getByRole('button', { name: /结\s算/ }).click(); await expect(page.getByRole('button', { name: /开\s单/ })).toBeVisible(); }); await test.step('搜索邀客A,查看邀客A的下级,进入邀客A详情查看好友数、收益', async () => { await homeNavigation.gotoModule('营销'); await marketingPage.gotoStrategySubPage('邀客系统'); // 搜索邀客A await page.getByPlaceholder('姓名(拼音首字)、手机号、档案号搜索').fill(customers[0].phone); await page.getByText('搜索', { exact: true }).click(); // 展开邀客A await $firstCustomerTr.locator('td').nth(0).click(); await expect.soft($firstCustomerTr).toBeVisible(); await expect.soft($secondCustomerTr).toBeVisible(); // 邀客A详情 await $firstCustomerTr.getByText('详情').click(); const $friendsNum = page.locator('.left_box .list', { hasText: 'TA的好友' }); await expect.soft($friendsNum).toContainText('1'); // 邀客A收益 const $income = page.locator('.left_box .list', { hasText: '收益' }); await expect.soft($income).toContainText(`${project.price * 0.1}`); // 关闭详情页 await page.locator('.top').filter({ hasText: '邀客详情' }).locator('.close_btn').click(); // 关闭邀客管理页面 await page.locator('.top').filter({ hasText: '邀客系统' }).locator('.close_btn').click(); await expect(page.locator('.exit_btn')).toBeVisible(); }); }); });