// @ts-check import { faker } from '@faker-js/faker/locale/zh_CN'; import { expect, test } from '@/fixtures/boss_common.js'; import { CleanPunctuation, getListIndexForTargetElement, KeepOnlyNumbers } from '@/utils/utils.js'; import { ProjectName } from '@/fixtures/userconfig.js'; import { Customer } from '@/utils/customer'; test.describe('出入库管理', () => { test.describe('入库单', () => { test('入库', async ({ page, homeNavigation, numberInput }) => { const remark = '入库' + faker.helpers.fromRegExp(/1[0-9]{4}/); const productA = ProjectName.Product.Product_3; /**@type {number} 产品A余量 */ let productASurplus; const quantity1 = 100; const quantity2 = 5; await test.step('获取入库前数据', async () => { // 进入AT测试一店的入库页面 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 获取入库前的库存信息 const $productA = page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productA.name }), }) .filter({ has: page.locator('td', { hasText: productA.num }), }); // 等待加载出指定内容,获取产品A的余量 await expect($productA).toBeVisible(); productASurplus = await $productA.locator('td').nth(4).innerText().then(Number); // 入库产品A,判断点击该产品有两行入库(负数才有) await $productA.click(); const $$productAOrder = page.locator('.bill_report .m-table__body tbody tr'); await $$productAOrder.first().waitFor(); expect(await $$productAOrder.count()).toBe(2); // 点击第一个产品修改数量 100 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(quantity1); await numberInput.confirmValue(); // 点击最后一个入库 修复数量 5 await page.locator('.m-table-cell_warp').last().click(); await numberInput.setValue(quantity2); await numberInput.confirmValue(); // 选择入库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '采购入库' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认入库' }).click(); await expect(page.getByRole('button', { name: '确认入库' })).not.toBeVisible(); }); /**@type {number} 入库单的索引 */ let billEntryIndex; await test.step('校验入库单', async () => { // 根据备注找出入库单在第几行 const codes = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); await expect(codes.first()).toBeInViewport(); billEntryIndex = await codes.allInnerTexts().then(text => { return text.findIndex(item => item.includes(remark)); }); if (billEntryIndex === -1) { throw new Error('未找到入库单'); } // 判断该状态为未审核状态 await expect(codes.nth(billEntryIndex).locator('td').nth(-6)).toContainText('未审核'); // 进入审核页面,确认入库,判断该状态为已审核状态 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(billEntryIndex) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); await expect(codes.nth(billEntryIndex).locator('td').nth(-6)).toContainText('已审核'); await page.getByRole('button', { name: /^入\s库$/ }).click(); }); await test.step('反审入库单', async () => { await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); // 获取入库后的库存余量 const $$productA = page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productA.num }), }) .filter({ has: page.locator('td', { hasText: productA.name }), }) .locator('td'); // 校验入库后的数量 await expect($$productA.nth(4)).toContainText(`${productASurplus + quantity1 + quantity2}`); // 关闭商品入库 await page.locator('.comBill_header .close').click(); // 进行反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(billEntryIndex) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 最后校验反审后恢复原来的数量 await expect($$productA.nth(4)).toContainText(`${productASurplus}`); }); }); test('期初入库', async ({ page, homeNavigation }) => { // 出入库管理代码段 const code = page.locator('.m-table__body-wrapper .main-table-body_tr').first(); // 产品编码代码段 const Productcode = page.locator('.upload_file tbody tr').first().locator('td'); await test.step('进入设置添加产品', async () => { await homeNavigation.gotoModule('设置'); await page.locator('.tab_item', { hasText: '库存' }).click(); await page.locator('.tag_list_box').first().waitFor(); // 点击下拉框 await page.locator('.tab_item', { hasText: '库存' }).click(); await page.locator('.ant-dropdown-open').waitFor(); await page.locator('.ant-dropdown-menu-item', { hasText: '期初数据' }).click(); await page.locator('.thead_tr').first().waitFor(); // 点击产品编码,span await Productcode.nth(1).click(); // 输入编号和初始库存 await Productcode.nth(1).locator('.ant-input').first().fill(ProjectName.Product.Product_5.num); await Productcode.nth(2).locator('.ant-input').last().fill('1'); // 确认添加 await page.locator('.comfirm_add', { hasText: '确认添加' }).click(); await page.locator('.popup_content .title', { hasText: '导入成功' }).waitFor(); await page.locator('.popup_content .operation_btn .comfirm_btn', { hasText: /^确\s认$/ }).click(); }); await test.step('进入库存校验', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.locator('.m-table__fixed-left th .m-table-cell', { hasText: '门店' }).waitFor(); // 点击门店选择器 await page.locator('.shop_select .text-ellipsis').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); // 选择总部 await expect(async () => { await page.locator('.label_item', { hasText: '总部' }).click(); await page.locator('.ant-checkbox-wrapper-checked', { hasText: '总部' }).waitFor({ timeout: 2000 }); }).toPass(); await expect(async () => { await page.locator('.label_item', { hasText: 'AT测试一店' }).click(); await expect( page.locator('.ant-checkbox-wrapper-checked', { hasText: 'AT测试一店' }), ).not.toBeVisible({ timeout: 2000 }); }).toPass(); // 确认选择 await page.locator('.comPicker_btn', { hasText: '确定选择' }).click(); // 选择入库方式 await page.locator('.ant-select-selection__rendered', { hasText: '全部入库方式' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '期初导入' }).click(); await expect(page.locator('.m-table__icon__warp')).toBeHidden(); // 校验 const verify1 = code.locator('.m-table-cell', { hasText: '期初导入' }); await expect(verify1).toBeVisible(); const verify2 = code.locator('.property_item', { hasText: ' 肌因深层x1 ' }); await expect(verify2).toBeVisible(); }); await test.step('冻结', async () => { await page.locator('.m-table__fixed-right .m-table-cell_btn', { hasText: '冻结' }).first().click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); await expect(code.filter({ has: page.locator('.m-table-cell', { hasText: '已冻结' }) })).toBeVisible(); }); await test.step('解冻', async () => { await page.locator('.m-table__fixed-right .m-table-cell_btn', { hasText: '解冻' }).first().click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); await expect( code.filter({ has: page.locator('.m-table-cell', { hasText: '已冻结' }) }), ).not.toBeVisible(); }); }); test('入库明细', async ({ page, homeNavigation, numberInput }) => { // 入库产品 const productA = ProjectName.Product.Product_9.name; const productNumA = ProjectName.Product.Product_9.num; const productB = ProjectName.Product.Product_10.name; const productNumB = ProjectName.Product.Product_10.num; const remark = faker.helpers.fromRegExp(/1[0-9]{10}/); // 余量 let lastSurplus; await test.step('记录一个产品', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: '总部' }).click(); await page.locator('.m-table__header-wrapper thead th', { hasText: '产品名称' }).first().waitFor(); // 点击A产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNumA }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .click(); // 余量 lastSurplus = await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNumA }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(4) .innerText(); }); await test.step('添加备注入库一单', async () => { // 选择库存数量 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(2); await numberInput.confirmValue(); // 选择入库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '采购入库' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认入库' }).click(); await expect( page.locator('.m-table__header-wrapper thead th', { hasText: '产品名称' }).first(), ).not.toBeVisible(); }); await test.step('通过备注找单据明细', async () => { // 根据备注找出入库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 对比产品编号 const productID = await page.locator('.bill_report .m-table-fixed-body .auto_desc').nth(0).innerText(); expect(productID).toBe(productNumA); // 对比产品名称 const product = await page.locator('.bill_report .m-table-fixed-body .auto_desc').nth(1).innerText(); expect(product).toBe(productA); // 对比余量 const surplus = await page.locator('.bill_report .main-table-body_tr td').nth(3).innerText(); expect(surplus).toBe(lastSurplus); // 对比入库数量 const quantity = await page.locator('.bill_report .main-table-body_tr td').nth(4).innerText(); expect(quantity).toBe('2'); }); await test.step('修改入库单', async () => { // 点击三个点 await page.locator('.more_btn').click(); // 修改 await page.locator('.ant-dropdown-menu-item', { hasText: '修改' }).click(); await page.locator('.m-table__header-wrapper thead th', { hasText: '产品名称' }).first().waitFor(); // 选择库存数量 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(4); await numberInput.confirmValue(); // 点击B产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNumB }), }) .filter({ has: page.locator('td', { hasText: productB }), }) .locator('td') .nth(0) .click(); await page.getByRole('button', { name: '确认入库' }).click(); await expect( page.locator('.m-table__header-wrapper thead th', { hasText: '产品名称' }).first(), ).not.toBeVisible(); }); await test.step('通过备注再次找单据明细', async () => { // 根据备注找出入库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); const codes = page.locator('.bill_report .main-table-body_tr'); // 对比A余量 const surplus = await codes .filter({ has: page.locator('td', { hasText: productNumA }) }) .filter({ has: page.locator('td', { hasText: productA }) }) .locator('td') .nth(3) .innerText(); expect(surplus).toBe(lastSurplus); // 对比A入库数量 const quantity = await codes .filter({ has: page.locator('td', { hasText: productNumA }) }) .filter({ has: page.locator('td', { hasText: productA }) }) .locator('td') .nth(4) .innerText(); expect(quantity).toBe('4'); // 对比B入库数量 const quantityB = await codes .filter({ has: page.locator('td', { hasText: productNumB }) }) .filter({ has: page.locator('td', { hasText: productB }) }) .locator('td') .nth(4) .innerText(); expect(quantityB).toBe('1'); }); await test.step('删除', async () => { // 点击三个点 await page.locator('.more_btn').click(); // 删除 await page.locator('.ant-dropdown-menu-item', { hasText: '删除' }).click(); await page.locator('.popup_content .title', { hasText: '删除单据' }).waitFor(); // 确认 await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); }); }); test('查询', async ({ page, homeNavigation, numberInput }) => { // 入库产品 const productA = ProjectName.Product.Product_9.name; const productNumA = ProjectName.Product.Product_9.num; const remark = faker.helpers.fromRegExp(/1[0-9]{10}/); // 余量 let lastSurplus; let nowRowB = 0; await test.step('记录一个产品', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: '总部' }).click(); await page.locator('.m-table__header-wrapper thead th', { hasText: '产品名称' }).first().waitFor(); // 点击A产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNumA }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .click(); // 余量 lastSurplus = await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNumA }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(4) .innerText(); }); await test.step('添加备注入库一单', async () => { // 选择库存数量 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(1); await numberInput.confirmValue(); // 选择入库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '采购入库' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认入库' }).click(); await expect( page.locator('.m-table__header-wrapper thead th', { hasText: '产品名称' }).first(), ).not.toBeVisible(); }); await test.step('通过备注找单据明细', async () => { await page.locator('.ant-select-selection__rendered', { hasText: '审核状态' }).click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '未审核' }).click(); // 根据备注找出入库单在第几行 const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 对比产品编号 const productID = await page.locator('.bill_report .m-table-fixed-body .auto_desc').nth(0).innerText(); expect(productID).toBe(productNumA); // 对比产品名称 const product = await page.locator('.bill_report .m-table-fixed-body .auto_desc').nth(1).innerText(); expect(product).toBe(productA); // 对比余量 const surplus = await page.locator('.bill_report .main-table-body_tr td').nth(3).innerText(); expect(surplus).toBe(lastSurplus); // 对比入库数量 const quantity = await page.locator('.bill_report .main-table-body_tr td').nth(4).innerText(); expect(quantity).toBe('1'); // 关闭窗口 await page.locator('.close_icon').last().click(); }); await test.step('选择门店,状态', async () => { // 点击门店选择器 await page.locator('.shop_select .text-ellipsis').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); // 选择一店 await expect(async () => { await page.locator('.com_picker').last().locator('.label_item', { hasText: 'AT测试一店' }).click(); await expect( page .locator('.com_picker') .last() .locator('.ant-checkbox-wrapper-checked', { hasText: 'AT测试一店' }), ).toBeVisible({ timeout: 2000 }); }).toPass(); await expect(async () => { await page.locator('.com_picker').last().locator('.label_item', { hasText: '总部' }).click(); await expect( page .locator('.com_picker') .last() .locator('.ant-checkbox-wrapper-checked', { hasText: '总部' }), ).not.toBeVisible(); }).toPass(); // 确认选择 await page.locator('.comPicker_btn', { hasText: '确定选择' }).click(); // 判断该单不存在 const bill = page.locator('.m-table__body-wrapper .m-table__body tbody tr td', { hasText: remark }); await expect(bill).not.toBeVisible(); }); await test.step('删除', async () => { // 点击门店选择器 await page.locator('.shop_select .text-ellipsis').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); // 选择总部 await expect(async () => { await page.locator('.com_picker').last().locator('.label_item', { hasText: '总部' }).click(); await expect( page .locator('.com_picker') .last() .locator('.ant-checkbox-wrapper-checked', { hasText: '总部' }), ).toBeVisible(); }).toPass(); await expect(async () => { await page.locator('.com_picker').last().locator('.label_item', { hasText: 'AT测试一店' }).click(); await expect( page .locator('.com_picker') .last() .locator('.ant-checkbox-wrapper-checked', { hasText: 'AT测试一店' }), ).not.toBeVisible({ timeout: 2000 }); }).toPass(); // 确认选择 await page.locator('.comPicker_btn', { hasText: '确定选择' }).click(); // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); // 点击三个点 await page.locator('.more_btn').click(); // 删除 await page.locator('.ant-dropdown-menu-item', { hasText: '删除' }).click(); await page.locator('.popup_content .title', { hasText: '删除单据' }).waitFor(); // 确认 await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); }); }); }); test.describe('出库单', () => { test('出库', async ({ page, homeNavigation, numberInput }) => { const remark = faker.helpers.fromRegExp(/1[0-9]{10}/); const productA = ProjectName.Product.Product_4.name; const productNum = ProjectName.Product.Product_4.num; // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载出指定内容 await page.locator('.panel_report .m-table__header-wrapper').waitFor(); // 获取出库前的库存信息 const productId = CleanPunctuation( await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .innerText(), ); expect(productId).toBe(productNum); const productName = CleanPunctuation( await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(1) .innerText(), ); expect(productName).toBe(productA); const productSurplus = CleanPunctuation( await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(4) .innerText(), ); // 点击该产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .click(); // 点击产品修改数量 await page.locator('.m-table-cell_warp').first().click(); const quantity1 = '10'; await numberInput.setValue(Number(quantity1)); await numberInput.confirmValue(); // 选择出库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '产品销售' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认出库' }).click(); // // 判断该状态为未审核状态 const examineStatus = CleanPunctuation( await page .locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: remark }), }) .locator('td') .nth(7) .innerText(), ); expect(examineStatus).toBe('未审核'); // 根据备注找出库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); // 判断该状态为已审核状态 const examineStatusd = CleanPunctuation( await page .locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: remark }), }) .locator('td') .nth(7) .innerText(), ); expect(examineStatusd).toBe('已审核'); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 获取出库后的库存余量 const productSurplused = CleanPunctuation( await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(4) .innerText(), ); expect(Number(productSurplused)).toBe(Number(productSurplus) + Number(quantity1)); // 重新找到该单在第几行(受其他用例影响) let nowRowC = 0; for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowC = i; break; } } // 关闭商品出库 await page.locator('.comBill_header .close').click(); await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowC) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); const productSurpluseds = CleanPunctuation( await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(4) .innerText(), ); console.log('用例结束剩余' + productSurpluseds); console.log('用例开始剩余' + productSurplus); expect(Number(productSurpluseds)).toBe(Number(productSurplus)); }); }); }); test.describe('库存管理', () => { test.describe('库存余量', () => { test('查询', async ({ page, homeNavigation, tablePage }) => { const goodsFromA = { no: 'aa100016', name: '启动青春套', price: 2380, isSale: true, isConsumable: true, }; const goodsFromB = { no: 'aa100019', name: '舒眠套', price: 0, isSale: false, isConsumable: true, }; const $goodsFromATr = tablePage.bodyTrTable.filter({ hasText: goodsFromA.name, }); const $goodsFromBTr = tablePage.bodyTrTable.filter({ hasText: goodsFromB.name, }); await test.step('根据耗材和非耗材搜索产品A', async () => { await homeNavigation.gotoModule('库存'); await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goodsFromA.no); await page.locator('.search_icon').first().click(); await tablePage.bodyTrTable.first().waitFor(); await page.getByLabel('耗材', { exact: true }).check(); await expect.soft($goodsFromATr).toBeVisible(); await page.getByLabel('非耗材', { exact: true }).check(); await expect.soft($goodsFromATr).not.toBeVisible(); }); await test.step('根据产品和非产品搜索产品B', async () => { await page.getByLabel('卖品', { exact: true }).check(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('耗材', { exact: true }).uncheck(); await page.getByLabel('非耗材', { exact: true }).uncheck(); await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goodsFromB.no); await page.locator('.search_icon').first().click(); await tablePage.bodyTrTable.first().waitFor(); await page.getByLabel('卖品', { exact: true }).uncheck(); await expect.soft($goodsFromBTr).toBeVisible(); await page.getByLabel('卖品', { exact: true }).check(); await page.getByLabel('非卖品', { exact: true }).uncheck(); await expect.soft($goodsFromBTr).not.toBeVisible(); }); await test.step('搜索产品分类', async () => { await page.getByPlaceholder('编码/名称/条码/拼音码').fill(''); await page.getByLabel('卖品', { exact: true }).check(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('耗材', { exact: true }).uncheck(); await page.getByLabel('非耗材', { exact: true }).uncheck(); await tablePage.bodyTrTable.first().waitFor(); await page.getByText('分类查询').click(); await page .locator('.property_item') .filter({ hasText: '产品类别' }) .getByRole('combobox') .filter({ hasText: '请选择内容' }) .click(); await page.getByRole('option', { name: '美容' }).click(); await page.getByRole('button', { name: /搜\s索/ }).click(); await tablePage.bodyTrTable.first().waitFor(); const goodsCategoryIndex = await tablePage.getFirstHeaderTableIndex('产品类别'); await page.getByRole('cell', { name: '产品类别' }).getByText('产品类别').click(); await tablePage.bodyTrTable.first().waitFor(); await expect(tablePage.bodyTrTable.first().locator('td').nth(goodsCategoryIndex)).toContainText('美容'); await page.getByRole('cell', { name: '产品类别' }).getByText('产品类别').click(); await tablePage.bodyTrTable.first().waitFor(); await expect(tablePage.bodyTrTable.first().locator('td').nth(goodsCategoryIndex)).toContainText('美容'); await page.getByRole('cell', { name: '产品类别' }).getByText('产品类别').click(); await tablePage.bodyTrTable.first().waitFor(); await expect(tablePage.bodyTrTable.first().locator('td').nth(goodsCategoryIndex)).toContainText('美容'); }); }); test('流水明细', async ({ page, homeNavigation, numberInput }) => { //出库数量 const quantity1 = 10; const remark = faker.helpers.fromRegExp(/1[0-9]{10}/); const productA = ProjectName.Product.Product_2.name; const productNum = ProjectName.Product.Product_2.num; /**@type {string} 单号*/ let billNo; await test.step('出库', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 点击该产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .click(); // 点击产品修改数量 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(quantity1); await numberInput.confirmValue(); // 选择出库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '产品开用' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认出库' }).click(); // 根据备注找出库单在第几行 const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const nowRowB = await allTrB.allInnerTexts().then(text => { return text.findIndex(item => item.includes(remark)); }); // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); // 判断该状态为已审核状态 await expect( page .locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: remark }), }) .locator('td') .nth(7), ).toContainText('已审核'); const billNo = CleanPunctuation( await page .locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: remark }), }) .locator('td') .nth(1) .innerText(), ); expect(billNo).not.toBe(''); }); await test.step('产品余量', async () => { await page.locator('.tab_item', { hasText: '库存管理' }).click(); // 根据项目编号点击产品余量 await page .locator('.m-table-with-footer .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .locator('.on_click_cell') .first() .click(); await expect(page.locator('.m-table__icon__warp')).toBeHidden(); const code = page.locator('.hideTop .m-table-wrapper .m-table__body-wrapper'); if (await code.isVisible()) { const $$billNoTr = page .locator('.popup_content .m-table-border .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td'); // 根据单号找到刚出库的单子 获取库存变动以及结余 await expect($$billNoTr.nth(4)).toContainText(`${-quantity1}`); const code = page.locator( '.popup_content .m-table-border .m-table__body-wrapper .m-table__body tbody tr', ); const nowRow = await code.allInnerTexts().then(text => { return text.findIndex(item => item.includes(billNo)); }); // 结余 const surplus = Number(await $$billNoTr.nth(5).innerText()); await expect( code .nth(nowRow + 1) .locator('td') .nth(5), ).toContainText(`${surplus + quantity1}`); // 关闭窗口 await page.locator('.noMargin .close_icon').click(); } else { console.log('出库失败,该产品无出库数据'); } }); await test.step('开用余量', async () => { // 根据项目编号点击开用余量 await page .locator('.m-table-with-footer .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .locator('.on_click_cell') .last() .click(); // 获取该产品的容量 const capacity = KeepOnlyNumbers( await page.locator('.hideTop .goodsFlow_session_rt span').nth(4).innerText(), ); const code = page .locator('.hideTop .m-table-wrapper .m-table__body-wrapper .main-table-body_tr') .first(); if (await code.isVisible()) { const $$billNoTr = page .locator('.goodsFlow_table .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td'); // 根据单号找到刚出库的单子 获取库存变动以及结余 await expect($$billNoTr.nth(5)).toContainText(`${quantity1 * capacity}`); const codeA = page.locator('.goodsFlow_table .m-table__body tbody tr'); // 对比结余 let nowRowA = await codeA.allInnerTexts().then(text => { return text.findIndex(item => item.includes(billNo)); }); // 结余 const surplus = await $$billNoTr.nth(6).innerText().then(Number); await expect( codeA .nth(nowRowA + 1) .locator('td') .nth(6), ).toContainText(`${surplus - capacity * quantity1}`); // 关闭窗口 await page.locator('.noMargin .close_icon').click(); } else { console.log('出库失败,该产品无出库数据'); // 关闭窗口 await page.locator('.noMargin .close_icon').click(); } }); await test.step('反审清理数据', async () => { await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.locator('.outInStock_filter .search_select').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '出库单' }).click(); // 根据备注找出库单在第几行 const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const nowRowC = await allTrB.allInnerTexts().then(text => { return text.findIndex(item => item.includes(remark)); }); // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowC) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); }); }); }); test.describe('安全库存差额表', async () => { test('查询', async ({ page, homeNavigation, tablePage, inventoryManagementPage, numberInput }) => { const goodsFromA = { no: 'aa100016', name: '启动青春套', price: 2380, isSale: true, isConsumable: true, }; const goodsFromB = { no: 'aa100019', name: '舒眠套', price: 0, isSale: false, isConsumable: true, }; await test.step('进入安全库存差额表', async () => { await homeNavigation.gotoModule('库存'); await inventoryManagementPage.gotoSubPage('安全库存差额表'); }); const $goodsFromATr = tablePage.bodyTrTable.filter({ hasText: goodsFromA.name, }); const $goodsFromBTr = tablePage.bodyTrTable.filter({ hasText: goodsFromB.name, }); await test.step('查询产品A', async () => { await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goodsFromA.no); await page.locator('.search_icon').first().click(); await page.getByLabel('卖品', { exact: true }).uncheck(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('仅显示差额产品', { exact: true }).uncheck(); await expect.soft($goodsFromATr).not.toBeVisible(); await page.getByLabel('卖品', { exact: true }).check(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('仅显示差额产品', { exact: true }).uncheck(); await expect.soft($goodsFromATr).toBeVisible(); await page.getByLabel('卖品', { exact: true }).uncheck(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('仅显示差额产品', { exact: true }).check(); await expect.soft($goodsFromATr).not.toBeVisible(); }); await test.step('查询产品B', async () => { await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goodsFromB.no); await page.locator('.search_icon').first().click(); await page.getByLabel('卖品', { exact: true }).uncheck(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('仅显示差额产品', { exact: true }).uncheck(); await expect.soft($goodsFromBTr).toBeVisible(); await page.getByLabel('卖品', { exact: true }).uncheck(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('仅显示差额产品', { exact: true }).check(); await expect.soft($goodsFromBTr).not.toBeVisible(); await page.getByLabel('卖品', { exact: true }).check(); await page.getByLabel('非卖品', { exact: true }).check(); await page.getByLabel('仅显示差额产品', { exact: true }).uncheck(); await expect.soft($goodsFromBTr).toBeVisible(); }); await test.step('设置产品A的安全库存差额', async () => { await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goodsFromA.no); await page.locator('.search_icon').first().click(); const $goodsFromA = tablePage.bodyTrTable.filter({ hasText: goodsFromA.name, }); const $goodsMargin = $goodsFromA.locator('td').nth(4); const $safetyStock = $goodsFromA.locator('td').nth(5); const $goodsDiff = $goodsFromA.locator('td').nth(6); const goodsMargin = Number(await $goodsMargin.innerText()); await $safetyStock.click(); const random = faker.number.int({ min: 1, max: 100 }); await numberInput.setValue(random); await numberInput.confirmValue(); await expect($goodsDiff).toContainText(`${Math.abs(goodsMargin - 100)}`); }); }); }); test.describe('寄存余量表', async () => { test('查询', async ({ page, homeNavigation, tablePage, inventoryManagementPage }) => { await test.step('进入寄存余量表', async () => { await homeNavigation.gotoModule('库存'); await inventoryManagementPage.gotoSubPage('寄存余量表'); }); const goods = { no: 'aa100001', name: '家居搭配护理套', }; const $goodsTr = tablePage.bodyTrTable .filter({ hasText: goods.name, }) .filter({ hasText: goods.no, }); await test.step('使用产品编码、产品名称进行搜索', async () => { await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goods.no); await page.locator('.search_icon').first().click(); await expect($goodsTr).toBeVisible(); await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goods.name); await page.locator('.search_icon').first().click(); await expect($goodsTr).toBeVisible(); }); await test.step('查询寄存余量排序', async () => { await page.getByPlaceholder('编码/名称/条码/拼音码').fill(''); await page.locator('.search_icon').first().click(); const $firstTr = tablePage.bodyTrTable.first(); const $secondTr = tablePage.bodyTrTable.nth(1); // 倒序 await page.getByText('寄存余量', { exact: true }).click(); let firstStorageMargin = Number(await $firstTr.locator('td').nth(6).innerText()); let secondStorageMargin = Number(await $secondTr.locator('td').nth(6).innerText()); expect.soft(secondStorageMargin).toBeGreaterThanOrEqual(firstStorageMargin); // 正序 await page.getByText('寄存余量', { exact: true }).click(); firstStorageMargin = Number(await $firstTr.locator('td').nth(6).innerText()); secondStorageMargin = Number(await $secondTr.locator('td').nth(6).innerText()); expect.soft(firstStorageMargin).toBeGreaterThanOrEqual(secondStorageMargin); }); }); test('寄存记录', async ({ page, homeNavigation, createCustomer, customerPage, tablePage, inventoryManagementPage, }) => { const goods = { no: 'aa100022', name: '芳香护理套(身体)', }; const customer = createCustomer; /**@type {string} */ let billNo; await test.step('进行开单购买卖品并寄存', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /开\s单/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.phone); await page.getByText('卖品', { exact: true }).click(); await page.locator('.project_list .number').filter({ hasText: goods.no }).click(); await page.locator('.pay_btn', { hasText: /结\s算/ }).click(); await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); // 结算获取单号 const [response] = await Promise.all([ page.waitForResponse(async res => { return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS'; }), page.getByRole('button', { name: /结\s算/ }).click(), ]); billNo = (await response.json())?.content?.billNo; expect(billNo).not.toBeNull(); // 寄存 await page.getByRole('button', { name: '转寄存' }).click(); await page.getByRole('button', { name: /确\s认/ }).click(); await expect(page.getByRole('button', { name: /开\s单/ })).toBeVisible(); }); await test.step('进入寄存余量表', async () => { await homeNavigation.gotoModule('库存'); await inventoryManagementPage.gotoSubPage('寄存余量表'); }); const $goodsTr = tablePage.bodyTrTable .filter({ hasText: goods.name, }) .filter({ hasText: goods.no, }); await test.step('搜索产品,查询寄存余量、寄存记录', async () => { // 搜索产品 await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goods.no); await page.locator('.search_icon').first().click(); await expect($goodsTr).toBeVisible(); // 点击寄存余量 const $goodsStorageMargin = $goodsTr.locator('td').nth(6); await $goodsStorageMargin.click(); // 查看寄存余量 const $customerTr = page.locator('.main-table-body_tr').filter({ hasText: customer.username }); await expect.soft($customerTr.locator('td').nth(1)).toContainText('1'); // 查看寄存记录 await $customerTr.getByText('寄存记录').click(); await expect.soft(page.getByText(billNo)).toBeVisible(); }); }); }); }); test.describe('统计', async () => { test.describe('入库统计', () => { test('入库流水', async ({ page, homeNavigation, numberInput }) => { const remark = faker.helpers.fromRegExp(/1[0-9]{10}/); const productA = ProjectName.Product.Product_5.name; const productNum = ProjectName.Product.Product_5.num; const quantity1 = 20; //数量 const UnitPrice = 10; //单价 /**@type {string} 单号*/ let billNo; let totality; let GrossAmount; await test.step('获取入库前数据', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择入库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '入库统计' }).click(); // 选择门店 await page.locator('.shop_picker').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); await page.locator('.compicker_part-box .label', { hasText: 'AT测试一店' }).click(); await page.locator('.compicker_part-box .label', { hasText: '总部' }).click(); await page.getByRole('button', { name: '确定选择' }).click(); await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await page.locator('.keyword_search input').fill(productNum); // 点击搜索 await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await page.locator('.ant-input-clear-icon').click(); await page.locator('.keyword_search input').fill(productNum); await expect(async () => { // 点击搜索 await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await expect(page.locator('.m-table__loading')).toBeHidden(); }).toPass({ timeout: 60000 }); const NotFound = page.locator('.m-table__empty', { hasText: '抱歉,未搜索到相关数据' }); if (await NotFound.isVisible()) { totality = 0; GrossAmount = 0; } else { await page .locator('.main-table-body_tr') .last() .locator('td', { hasText: productNum }) .waitFor({ timeout: 2000 }); // 获取总数 totality = KeepOnlyNumbers(await page.locator('.main-table-body_tr td').nth(5).innerText()); console.log('前' + totality); // 获取总额 GrossAmount = KeepOnlyNumbers(await page.locator('.main-table-body_tr td').nth(6).innerText()); console.log('前' + GrossAmount); } }); await test.step('入库', async () => { await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 点击该产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .click(); // 点击设置 await page.locator('.set_icon').click(); // 等待弹窗出来 await page.locator('.popup_content .content').waitFor(); // 点击显示单价和小计 await page.locator('.set_btn .ant-checkbox-input ').check(); // 确认 await page.locator('.ant-btn-lg', { hasText: /^确\s认$/ }).click(); // 选择库存数量 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(quantity1); await numberInput.confirmValue(); // 点击修改单价 await page.locator('.m-table-cell_warp').last().click(); await numberInput.setValue(UnitPrice); await numberInput.confirmValue(); // 选择入库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '采购入库' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认入库' }).click(); // 根据备注找出入库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowB = i; break; } } // 获取单号 const billNo = CleanPunctuation( await page .locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: remark }), }) .locator('td') .nth(1) .innerText(), ); expect(billNo).not.toBeNull(); // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); }); await test.step('校验入库后数据', async () => { await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择入库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '入库统计' }).click(); // 选择产品 await page.locator('.keyword_search input').fill(productNum); await expect(async () => { // 点击搜索 await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await page .locator('.main-table-body_tr') .first() .locator('td', { hasText: productNum }) .waitFor({ timeout: 2000 }); }).toPass({ timeout: 60000 }); // 获取入库后总数 await expect(page.locator('.main-table-body_tr td').nth(5)).toContainText( `${Number(totality) + Number(quantity1)}`, ); // 获取入库后总额 await expect(page.locator('.main-table-body_tr td').nth(6)).toContainText( `${Number(GrossAmount) + Number(quantity1) * Number(UnitPrice)}`, ); // 点击总数进入流水 await page.locator('.main-table-body_tr td').nth(5).click(); // 查看期初数量 const InitialQuantity = Number( KeepOnlyNumbers( await page .locator('.hideTop .table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td') .nth(4) .innerText(), ), ); // 查看库存变动 const alteration = Number( KeepOnlyNumbers( await page .locator('.hideTop .table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td') .nth(5) .innerText(), ), ); // 查看库存变动 const surplus = Number( KeepOnlyNumbers( await page .locator('.hideTop .table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td') .nth(6) .innerText(), ), ); // 结余 = 期初 + 库存变动 expect(surplus).toBe(InitialQuantity + alteration); }); await test.step('反审清理数据', async () => { await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.locator('.outInStock_filter .search_select').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '入库单' }).click(); // 根据备注找入库单在第几行 let nowRowC = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowC = i; break; } } // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowC) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); }); }); test('查询', async ({ page, homeNavigation }) => { const remarkA = faker.helpers.fromRegExp(/1[0-9]{10}/); const remarkB = faker.helpers.fromRegExp(/1[0-9]{10}/); // 定义一个卖品和非卖品 const productNameA = ProjectName.Product.Product_11.name; const productNoA = ProjectName.Product.Product_11.num; const productNameB = ProjectName.Product.Product_12.name; const productNoB = ProjectName.Product.Product_12.num; await test.step('卖品入库一单', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 点击卖品-产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNoA }), }) .filter({ has: page.locator('td', { hasText: productNameA }), }) .locator('td') .nth(0) .click(); // 选择入库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '采购入库' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkA); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认入库' }).click(); // 根据备注找出入库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remarkA)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); }); await test.step('非卖品入库一单', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^入\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 点击非卖品-产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNoB }), }) .filter({ has: page.locator('td', { hasText: productNameB }), }) .locator('td') .nth(0) .click(); // 选择入库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '采购入库' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkB); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认入库' }).click(); // 根据备注找出入库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remarkB)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); }); await test.step('校验', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择入库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '入库统计' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 不勾选非卖品 await expect(async () => { await page.locator('.needsclick', { hasText: /^非卖品$/ }).click(); await expect( page.locator('.ant-checkbox-wrapper-checked', { hasText: /^非卖品$/ }), ).not.toBeVisible({ timeout: 2000 }); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 判断刚入库的卖品存在 非卖品不存在 await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoA })).toBeVisible({ timeout: 2000, }); await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoB })).not.toBeVisible({ timeout: 2000, }); }).toPass(); // 不勾选非卖品 await expect(async () => { await page.locator('.needsclick', { hasText: /^非卖品$/ }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: /^非卖品$/ })).toBeVisible({ timeout: 2000, }); await page.locator('.needsclick', { hasText: /^卖品$/ }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: /^卖品$/ })).not.toBeVisible({ timeout: 2000, }); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 判断刚入库的卖品不存在 卖品不存在 await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoA })).not.toBeVisible({ timeout: 2000, }); await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoB })).toBeVisible({ timeout: 2000, }); }).toPass(); }); await test.step('反审清理数据', async () => { await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.locator('.outInStock_filter .search_select').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '入库单' }).click(); // 根据备注找入库单A在第几行 let nowRowA = 0; const allTrA = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countA = await allTrA.count(); for (let i = 0; i < countA; i++) { const trA = allTrA.nth(i); const productA = await trA.locator('td').nth(-2).innerText(); if (productA.includes(remarkA)) { nowRowA = i; break; } } // 根据备注找入库单B在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remarkB)) { nowRowB = i; break; } } // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowA) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); }); }); }); test.describe('出库统计', () => { test('出库流水', async ({ page, homeNavigation, numberInput }) => { const remark = faker.helpers.fromRegExp(/1[0-9]{10}/); const productA = ProjectName.Product.Product_5.name; const productNum = ProjectName.Product.Product_5.num; const quantity1 = 20; //数量 const UnitPrice = 10; //单价 /**@type {string} 单号*/ let billNo; let totality = 0; await test.step('获取出库前总数', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).waitFor(); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择出库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '出库统计' }).click(); // 选择门店 await page.locator('.shop_picker').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); await page.locator('.compicker_part-box .label', { hasText: 'AT测试一店' }).click(); await page.locator('.compicker_part-box .label', { hasText: '总部' }).click(); await page.getByRole('button', { name: '确定选择' }).click(); await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await page.locator('.keyword_search input').fill(productNum); // 点击搜索 await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await page.locator('.ant-input-clear-icon').click(); await page.locator('.keyword_search input').fill(productNum); await expect(async () => { // 点击搜索 await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); const NotFound = page.locator('.m-table__empty', { hasText: '抱歉,未搜索到相关数据' }); if (await NotFound.isVisible()) { totality = 0; } else { await page .locator('.main-table-body_tr') .first() .locator('td', { hasText: productNum }) .waitFor({ timeout: 2000 }); // 获取总数 totality = KeepOnlyNumbers(await page.locator('.main-table-body_tr td').nth(5).innerText()); console.log('前' + totality); } }).toPass({ timeout: 60000 }); }); await test.step('出库', async () => { await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 点击该产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNum }), }) .filter({ has: page.locator('td', { hasText: productA }), }) .locator('td') .nth(0) .click(); // 点击设置 await page.locator('.set_icon').click(); // 等待弹窗出来 await page.locator('.popup_content .content').waitFor(); // 点击显示单价和小计 await page.locator('.set_btn .ant-checkbox-input ').check(); // 确认 await page.locator('.ant-btn-lg', { hasText: /^确\s认$/ }).click(); // 选择库存数量 await page.locator('.m-table-cell_warp').first().click(); await numberInput.setValue(quantity1); await numberInput.confirmValue(); // 点击修改单价 await page.locator('.m-table-cell_warp').last().click(); await numberInput.setValue(UnitPrice); await numberInput.confirmValue(); // 选择出库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '产品销售' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认出库' }).click(); // 根据备注找出 出库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowB = i; break; } } // 获取单号 const billNo = CleanPunctuation( await page .locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: remark }), }) .locator('td') .nth(1) .innerText(), ); console.log('单号' + billNo); // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await expect(page.locator('.m-table__icon__warp')).toBeHidden(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); }); await test.step('校验出库后数据', async () => { await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择出库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '出库统计' }).click(); // 页面变化但是内容却是上一页的 硬等2秒加载 await page.waitForTimeout(2000); // 选择产品 await page.locator('.keyword_search input').fill(productNum); await expect(async () => { // 点击搜索 await page.locator('.keyword_search .ant-input-suffix .search_icon').click(); await page .locator('.main-table-body_tr') .first() .locator('td', { hasText: productNum }) .waitFor({ timeout: 2000 }); }).toPass({ timeout: 60000 }); // 获取出库后总数 await expect(page.locator('.main-table-body_tr td').nth(5)).toBe(Number(totality) + Number(quantity1)); // 点击总数进入流水 await page.locator('.main-table-body_tr td').nth(5).click(); // 查看期初数量 const InitialQuantity = Number( KeepOnlyNumbers( await page .locator('.hideTop .table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td') .nth(4) .innerText(), ), ); // 查看库存变动 const alteration = Number( KeepOnlyNumbers( await page .locator('.hideTop .table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td') .nth(5) .innerText(), ), ); // 查看结余 const surplus = Number( KeepOnlyNumbers( await page .locator('.hideTop .table-warp .m-table__body-wrapper .m-table__body tbody tr') .filter({ has: page.locator('td', { hasText: billNo }), }) .locator('td') .nth(6) .innerText(), ), ); // 结余 = 期初 + 库存变动(这里拿到正数 所以是减) expect(surplus).toBe(InitialQuantity - alteration); }); await test.step('反审清理数据', async () => { await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.locator('.outInStock_filter .search_select').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '出库单' }).click(); // 根据备注找出库单在第几行 let nowRowC = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remark)) { nowRowC = i; break; } } // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowC) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); }); }); test('查询', async ({ page, homeNavigation }) => { const remarkA = faker.helpers.fromRegExp(/1[0-9]{10}/); const remarkB = faker.helpers.fromRegExp(/1[0-9]{10}/); // 定义一个卖品和非卖品 const productNameA = ProjectName.Product.Product_11.name; const productNoA = ProjectName.Product.Product_11.num; const productNameB = ProjectName.Product.Product_12.name; const productNoB = ProjectName.Product.Product_12.num; await test.step('卖品出库一单', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 点击卖品-产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNoA }), }) .filter({ has: page.locator('td', { hasText: productNameA }), }) .locator('td') .nth(0) .click(); // 选择出库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '产品销售' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkA); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认出库' }).click(); // 根据备注找出 出库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remarkA)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); }); await test.step('非卖品出库一单', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.getByRole('button', { name: /^出\s库$/ }).click(); await page.locator('.customWith', { hasText: 'AT测试一店' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 点击非卖品-产品 await page .locator('.panel_report tbody tr') .filter({ has: page.locator('td', { hasText: productNoB }), }) .filter({ has: page.locator('td', { hasText: productNameB }), }) .locator('td') .nth(0) .click(); // 选择出库方式 await page.locator('.bill_form .ant-select-selection__rendered').click(); await page.getByRole('option', { name: '产品销售' }).click(); // 点击备注 await page.locator('.bill_remark > .icon > svg').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkB); await page.getByRole('button', { name: /^确\s认$/ }).click(); await page.getByRole('button', { name: '确认出库' }).click(); // 根据备注找出 出库单在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remarkB)) { nowRowB = i; break; } } // 点击明细 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '明细' }) .click(); await page.getByRole('button', { name: /^审\s核$/ }).click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 等待弹窗消失 await expect(page.locator('.popup_content')).not.toBeVisible(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); }); await test.step('校验', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择出库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '出库统计' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 不勾选非卖品 await expect(async () => { await page.locator('.needsclick', { hasText: /^非卖品$/ }).click(); await expect( page.locator('.ant-checkbox-wrapper-checked', { hasText: /^非卖品$/ }), ).not.toBeVisible({ timeout: 2000 }); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 判断刚入库的卖品存在 非卖品不存在 await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoA })).toBeVisible({ timeout: 2000, }); await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoB })).not.toBeVisible({ timeout: 2000, }); }).toPass(); // 不勾选非卖品 await expect(async () => { await page.locator('.needsclick', { hasText: /^非卖品$/ }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: /^非卖品$/ })).toBeVisible({ timeout: 2000, }); await page.locator('.needsclick', { hasText: /^卖品$/ }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: /^卖品$/ })).not.toBeVisible({ timeout: 2000, }); // 等待加载完成 await expect(page.locator('.m-table__loading')).toBeHidden(); // 判断刚入库的卖品不存在 卖品不存在 await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoA })).not.toBeVisible({ timeout: 2000, }); await expect(page.locator('.m-table__body-wrapper td', { hasText: productNoB })).toBeVisible({ timeout: 2000, }); }).toPass(); }); await test.step('反审清理数据', async () => { await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); // 点击出入库管理 await page.locator('.tab_item', { hasText: '出入库管理' }).click(); await page.locator('.outInStock_filter .search_select').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '出库单' }).click(); // 根据备注找出库单A在第几行 let nowRowA = 0; const allTrA = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countA = await allTrA.count(); for (let i = 0; i < countA; i++) { const trA = allTrA.nth(i); const productA = await trA.locator('td').nth(-2).innerText(); if (productA.includes(remarkA)) { nowRowA = i; break; } } // 根据备注找出库单B在第几行 let nowRowB = 0; const allTrB = page.locator('.table-warp .m-table__body-wrapper .m-table__body tbody tr'); const countB = await allTrB.count(); for (let i = 0; i < countB; i++) { const trB = allTrB.nth(i); const productB = await trB.locator('td').nth(-2).innerText(); if (productB.includes(remarkB)) { nowRowB = i; break; } } // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowA) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); // 反审 await page .locator('.m-table__fixed-right .m-table__body tbody tr') .nth(nowRowB) .locator('td') .nth(-1) .locator('.m-table-cell_btn', { hasText: '反审' }) .click(); await page.getByRole('button', { name: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '操作成功' })).toBeVisible(); }); }); }); test.describe('产品进销存表', () => { test('查询', async ({ page, homeNavigation, tablePage, customerPage, createCustomer, numberInput }) => { const productA = ProjectName.Product.Product_13.name; const productNum = ProjectName.Product.Product_13.num; // 创建顾客 const customer = createCustomer; // 定义转入数量 let Buy = '5'; let InQuantity = '2'; //转寄存 let expend = '1'; //领出 // 汇总前数据 let FrontInQuantity; //入库 let FrontOutQuantity; //出库 // 明细前数据 let FrontInDeposit; //转入 let FrontOutDeposit; //领出 await test.step('记录汇总初始数据', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).waitFor(); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择出库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '产品进销存' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 点击门店选择器 await page.locator('.shop_picker').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); // 选择一店 await expect(async () => { await page.locator('.compicker_part-box .label', { hasText: 'AT测试一店' }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: 'AT测试一店' })).toBeVisible({ timeout: 2000, }); }).toPass(); // 取消总部 await expect(async () => { await page.locator('.compicker_part-box .label', { hasText: '总部' }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: '总部' })).not.toBeVisible({ timeout: 2000, }); }).toPass(); await page.getByRole('button', { name: '确定选择' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 输入A产品编号查询 await page.getByPlaceholder('编码/名称/条码/拼音码').fill(productNum); await expect(async () => { // 点击搜索 await page .locator('.ant-input-affix-wrapper-input-with-clear-btn .ant-input-suffix .search_icon') .click(); await expect( page .locator('.m-table__body-wrapper .main-table-body_tr .auto_desc', { hasText: productA }) .first(), ).toBeVisible({ timeout: 2000 }); }).toPass(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 入库排序索引 const inToInventory = await tablePage.getFirstHeaderTableIndex('入库'); // 根据条件定位 const goodsIndex = await tablePage.getBodyTableIndex(['男士精油', 'aa100015', 'oil']); FrontInQuantity = await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(inToInventory + 2) .innerText(); // 出库排序索引 const outInventory = await tablePage.getFirstHeaderTableIndex('出库'); // 根据条件定位 FrontOutQuantity = await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(outInventory + 3) .innerText(); console.log('出:' + FrontOutQuantity); }); await test.step('记录明细数据', async () => { // 点击明细 await page.locator('.ant-switch').first().click(); await expect(page.locator('.ant-switch-checked')).toBeVisible(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); await expect(async () => { // 点击搜索强制刷新下面的数据(可能不出来) await page .locator('.ant-input-affix-wrapper-input-with-clear-btn .ant-input-suffix .search_icon') .click(); await expect(page.getByText('产品销售').first()).toBeVisible({ timeout: 2000 }); }).toPass(); // 寄存转入排序索引 const inToInventory = await tablePage.getFirstHeaderTableIndex('寄存转入'); // 根据条件定位 const goodsIndex = await tablePage.getBodyTableIndex(['男士精油', 'aa100015', 'oil']); await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(inToInventory + 12) .click(); FrontInDeposit = await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(inToInventory + 12) .innerText(); console.log('转入:' + FrontInDeposit); // 寄存领出排序索引 const outInventory = await tablePage.getFirstHeaderTableIndex('寄存领出'); // 根据条件定位 await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(outInventory + 13) .click(); FrontOutDeposit = await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(outInventory + 13) .innerText(); console.log('领出:' + FrontOutDeposit); }); await test.step('顾客购买寄存', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /开\s单/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.phone); await page.getByText('卖品', { exact: true }).click(); await page.locator('.project_list .number').filter({ hasText: productNum }).click(); // 点击选择数量 await page.locator('.edit_txt div:nth-child(2)').first().click(); await numberInput.setValue(Number(Buy)); await numberInput.confirmValue(); await page.locator('.pay_btn', { hasText: /结\s算/ }).click(); await page.locator('.paytype .paymentInfoItem', { hasText: '现金' }).click(); await page.getByLabel('推送消费提醒').uncheck(); await page.getByLabel('结算签字').uncheck(); // 结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); // 寄存 await page.getByRole('button', { name: '转寄存' }).click(); await page .locator('.popup_content') .filter({ has: page.locator('.title', { hasText: '产品寄存' }) }) .locator('.num') .click(); await numberInput.setValue(Number(InQuantity)); await numberInput.confirmValue(); // 确认 await page.getByRole('button', { name: /^确\s认$/ }).click(); await expect(page.locator('.ant-message', { hasText: '寄存成功' })).toBeVisible(); }); await test.step('领出一次寄存品', async () => { await page.getByRole('button', { name: /开\s单/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.phone); // 收银-点击领出寄存品 await page.locator('.treat_card_inner').click(); await page.locator('.name_text', { hasText: productA }).waitFor(); // 收银结算 await page.locator('.pay_btn', { hasText: /结\s算/ }).click(); // 支付结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await expect(page.locator('.ant-message', { hasText: '结算成功' })).toBeVisible(); }); await test.step('汇总核对数据', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).waitFor(); await page.locator('.tab_item', { hasText: '统计' }).click(); // 点击统计下拉框选择出库统计 await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '产品进销存' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 点击门店选择器 await page.locator('.shop_picker').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor(); // 选择一店 await expect(async () => { await page.locator('.compicker_part-box .label', { hasText: 'AT测试一店' }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: 'AT测试一店' })).toBeVisible({ timeout: 2000, }); }).toPass(); // 取消总部 await expect(async () => { await page.locator('.compicker_part-box .label', { hasText: '总部' }).click(); await expect(page.locator('.ant-checkbox-wrapper-checked', { hasText: '总部' })).not.toBeVisible({ timeout: 2000, }); }).toPass(); await page.getByRole('button', { name: '确定选择' }).click(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 输入A产品编号查询 await page.getByPlaceholder('编码/名称/条码/拼音码').fill(productNum); await expect(async () => { // 点击搜索 await page .locator('.ant-input-affix-wrapper-input-with-clear-btn .ant-input-suffix .search_icon') .click(); await expect( page .locator('.m-table__body-wrapper .main-table-body_tr .auto_desc', { hasText: productA }) .first(), ).toBeVisible({ timeout: 2000 }); }).toPass(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); // 入库排序索引 const inToInventory = await tablePage.getFirstHeaderTableIndex('入库'); // 根据条件定位 const goodsIndex = await tablePage.getBodyTableIndex(['男士精油', 'aa100015', 'oil']); // 校验 await expect .soft( tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(inToInventory + 2), ) .toContainText(`${Number(FrontInQuantity) + Number(InQuantity)}`); // 出库排序索引 const outInventory = await tablePage.getFirstHeaderTableIndex('出库'); // 校验 await expect( tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(outInventory + 3), ).toContainText(`${Number(FrontOutQuantity) + Number(Buy) + Number(expend)}`); }); await test.step('明细核对数据', async () => { // 点击明细 await page.locator('.ant-switch').first().click(); await expect(page.locator('.ant-switch-checked')).toBeVisible(); // 等待加载完成 await expect(page.locator('.m-table__loading').first()).toBeHidden(); await expect(async () => { // 点击搜索强制刷新下面的数据(可能不出来) await page .locator('.ant-input-affix-wrapper-input-with-clear-btn .ant-input-suffix .search_icon') .click(); await expect(page.getByText('产品销售').first()).toBeVisible({ timeout: 2000 }); }).toPass(); // 寄存转入排序索引 const inToInventory = await tablePage.getFirstHeaderTableIndex('寄存转入'); // 根据条件定位 const goodsIndex = await tablePage.getBodyTableIndex(['男士精油', 'aa100015', 'oil']); await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(inToInventory + 12) .click(); // 校验 await expect( tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(inToInventory + 12), ).toContainText(`${Number(FrontInDeposit) + Number(InQuantity)}`); // 寄存领出排序索引 const outInventory = await tablePage.getFirstHeaderTableIndex('寄存领出'); // 根据条件定位 await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(outInventory + 13) .click(); // 校验 await expect( tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(outInventory + 13), ).toContainText(`${Number(FrontOutDeposit) + Number(expend)}`); }); }); }); test.describe('开用进销存表', async () => { test('查询', async ({ page, homeNavigation, createCustomer, tablePage, customerPage, numberInput }) => { const customer = createCustomer; // 产品 const goods = { no: 'aa100627', name: '平衡净肤面膜', capacity: 5, unit: '毫升', price: 10, }; let consume; await test.step('查询开用进销存表数据', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '统计' }).click(); await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '开用进销存' }).click(); await page.getByText('汇总').waitFor(); // 搜索产品 await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goods.no); await expect(async () => { await page.locator('.search_icon > svg').first().click(); await expect( tablePage.bodyTrTable .filter({ hasText: goods.name, }) .filter({ hasText: goods.no, }) .first(), ).toBeVisible({ timeout: 2000 }); }).toPass(); // 消耗排序索引 const consumeIndex = await tablePage.getFirstHeaderTableIndex('消耗'); // 产品索引 const goodsIndex = await tablePage.getBodyTableIndex([goods.name, goods.no, goods.unit]); // 获取消耗值 consume = await tablePage.bodyTrTable .nth(goodsIndex) .locator('td') .nth(consumeIndex) .innerText() .then(Number); }); /**@type {string} 单号*/ let billNo; await test.step('顾客开单购买3次项目,并消耗3次项目,选择产品配方3次5ml', async () => { await homeNavigation.gotoModule('收银'); await page.getByRole('button', { name: /开\s单/ }).click(); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.phone); // 购买项目3次 await page .locator('.project_list .number') .nth(faker.number.int({ min: 0, max: 20 })) .click(); await page.locator('#buyList').getByText('1', { exact: true }).click(); await numberInput.setValue(3); await numberInput.confirmValue(); // 打开项目配方设置 await page.locator('.staff_setting').click(); await page.getByLabel('项目配方').check(); await page.getByRole('button', { name: /确\s认/ }).click(); // 消耗项目3次 await page.locator('.commodity_item').first().click(); await page.getByRole('main').getByText('1', { exact: true }).click(); await numberInput.setValue(3); await numberInput.confirmValue(); // 选择产品配方 await page.locator('.formula_noData').click(); await page.getByRole('textbox').fill(goods.no); await page.getByRole('button', { name: /搜\s索/ }).click(); await expect(async () => { await page.getByLabel('平衡净肤面膜').uncheck(); await page.getByLabel('平衡净肤面膜').check(); await expect(page.locator('.menu-item-dot', { hasText: '1' }).first()).toBeVisible({ timeout: 2000, }); }).toPass(); await page.getByRole('button', { name: '确定选择' }).click(); // 单次消耗5ml await page.getByRole('textbox').fill('5'); await page.getByRole('button', { name: /保\s存/ }).click(); // 使用现金支付 await page.getByText(/结\s算/).click(); await page.locator('.pay_img').first().click(); const [response] = await Promise.all([ page.waitForResponse(async res => { return res.url().includes('/bill') && (await res.json()).code === 'SUCCESS'; }), page.getByRole('button', { name: /结\s算/ }).click(), ]); billNo = (await response.json())?.content?.billNo; expect(billNo).not.toBeNull(); await expect(page.getByRole('button', { name: /开\s单/ })).toBeVisible(); }); await test.step('查询开用进销存表数据', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '统计' }).click(); await page.locator('.router_active .ant-dropdown-link').click(); await page.getByRole('menuitem', { name: '开用进销存' }).click(); await page.getByText('汇总').waitFor(); // 搜索产品 await page.getByPlaceholder('编码/名称/条码/拼音码').fill(goods.no); await expect(async () => { await page.locator('.search_icon > svg').first().click(); await expect( tablePage.bodyTrTable .filter({ hasText: goods.name, }) .filter({ hasText: goods.no, }) .first(), ).toBeVisible({ timeout: 2000 }); }).toPass(); // 消耗排序索引 const consumeIndex = await tablePage.getFirstHeaderTableIndex('消耗'); // 产品索引 const goodsIndex = await tablePage.getBodyTableIndex([goods.name, goods.no, goods.unit]); // 获取消耗值 const $lastConsume = tablePage.bodyTrTable.nth(goodsIndex).locator('td').nth(consumeIndex); // 消耗值应该增加 await expect($lastConsume).toContainText(`${consume + 15}`); await tablePage.bodyTrTable.nth(goodsIndex).locator('td').nth(consumeIndex).click(); const $popup = page.locator('.popup_content'); const $popupTr = $popup .locator('.m-table__body-wrapper .m-table__body tbody tr') .filter({ hasText: billNo }); await expect($popupTr).toBeVisible(); await expect($popupTr.locator('td').nth(5)).toHaveText('3'); await expect($popupTr.locator('td').nth(6)).toHaveText('-15'); }); }); }); }); test.describe('调货管理', () => { test.beforeEach(async ({ page }) => { await page.addLocatorHandler(page.getByRole('button', { name: '暂不处理' }), async () => { await page.getByRole('button', { name: '暂不处理' }).click(); await expect(page.getByRole('button', { name: '暂不处理' })).not.toBeVisible(); }); }); test('调货管理', async ({ page, homeNavigation, transferManagementPage }) => { const goods = { a: { no: 'aa100007', name: '肌因能量套', unitPrice: 10, quantity: 5 }, b: { no: 'aa100008', name: '肌因赋活尊享套', unitPrice: 15, quantity: 8 }, }; const remarkA = '调货管理' + faker.helpers.fromRegExp(/[a-d]{2}[0-9]{2}/); const remarkB = '调货管理' + faker.helpers.fromRegExp(/[a-d]{2}[0-9]{2}/); let billA, billB; let quantity = 0; // 数量 let outQuantity = 0; // 调出数量 let unitPrice = 0; // 单价 let outUnitPrice = 0; // 调出单价 let subtotal = 0; // 小计 let outSubtotal = 0; // 调出小计 let totalQuantity = 0; // 总数量 let totalPrice = 0; // 总价 await test.step('进入门店要货', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.top_tab .tab_item').getByText('调货管理').click(); await transferManagementPage.gotoSubPage('门店要货'); }); await test.step('提交要货单A', async () => { // 展示单价和小计 await page.locator('.price_set').click(); await page.locator('.set_btn').getByRole('checkbox').check(); await page.getByRole('button', { name: /确\s认/ }).click(); // 选择产品a,设置产品数量和单价 await page.locator('.panel tr', { hasText: goods.a.no }).click(); let goodsTr = page.locator('.bill_report tr', { hasText: goods.a.name }); await goodsTr.getByRole('spinbutton').first().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.a.quantity)); await page.locator('.number_tr button').nth(11).click(); await goodsTr.getByRole('spinbutton').last().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.a.unitPrice)); await page.locator('.number_tr button').nth(11).click(); // 选择产品b,设置产品数量和单价 await page.locator('.panel tr', { hasText: goods.b.no }).click(); goodsTr = page.locator('.bill_report tr', { hasText: goods.b.name }); await goodsTr.getByRole('spinbutton').first().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.b.quantity)); await page.locator('.number_tr button').nth(11).click(); await goodsTr.getByRole('spinbutton').last().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.b.unitPrice)); await page.locator('.number_tr button').nth(11).click(); // 设置备注 await page.getByText('备注').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkA); await page.getByRole('button', { name: /确\s认/ }).click(); // 提交要货单 await page.getByRole('button', { name: /提\s交/ }).click(); await expect(page.getByRole('cell', { name: '门店要货备注' })).toBeInViewport(); const tableTrList = page.locator('.table_inner .main-table-body_tr'); const billTr = tableTrList.filter({ hasText: remarkA }); await expect(billTr).toBeVisible(); billA = await billTr.locator('td').nth(0).innerText(); expect(billA).not.toBeNull(); }); await test.step('提交要货单B', async () => { await transferManagementPage.gotoSubPage('门店要货'); // 展示单价和小计 await page.locator('.price_set').click(); await page.locator('.set_btn').getByRole('checkbox').check(); await page.getByRole('button', { name: /确\s认/ }).click(); // 选择产品a,设置产品数量和单价 await page.locator('.panel tr', { hasText: goods.a.no }).click(); let goodsTr = page.locator('.bill_report tr', { hasText: goods.a.name }); await goodsTr.getByRole('spinbutton').first().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.a.quantity)); await page.locator('.number_tr button').nth(11).click(); await goodsTr.getByRole('spinbutton').last().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.a.unitPrice)); await page.locator('.number_tr button').nth(11).click(); // 选择产品b,设置产品数量和单价 await page.locator('.panel tr', { hasText: goods.b.no }).click(); goodsTr = page.locator('.bill_report tr', { hasText: goods.b.name }); await goodsTr.getByRole('spinbutton').first().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.b.quantity)); await page.locator('.number_tr button').nth(11).click(); await goodsTr.getByRole('spinbutton').last().click(); await page.getByPlaceholder('请输入内容').fill(String(goods.b.unitPrice)); await page.locator('.number_tr button').nth(11).click(); // 设置备注 await page.getByText('备注').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkB); await page.getByRole('button', { name: /确\s认/ }).click(); // 提交要货单 await page.getByRole('button', { name: /提\s交/ }).click(); await expect(page.getByRole('cell', { name: '门店要货备注' })).toBeInViewport(); const tableTrList = page.locator('.table_inner .main-table-body_tr'); const billTr = tableTrList.filter({ hasText: remarkB }); await expect(billTr).toBeVisible(); billB = await billTr.locator('td').nth(0).innerText(); expect(billB).not.toBeNull(); }); await test.step('标记要货单A为处理中-》生成内部调出单', async () => { // 进入调货管理 await transferManagementPage.gotoSubPage('调货管理'); // 标记为处理中 const tableTrList = page.locator('.table_inner .main-table-body_tr'); const targetTr = tableTrList.filter({ hasText: billA }); const targetIndex = await getListIndexForTargetElement(targetTr, tableTrList); const fixedCell = page.locator('.m-table-fixed-body tr').nth(targetIndex); await fixedCell.getByText('标记为处理中').click(); await page.getByRole('button', { name: '我知道了' }).click(); await fixedCell.getByText('生成内部调出单').click(); await expect(page.locator('.popup_content', { hasText: '要货单-生成内部调出单' })).toBeVisible(); const outBillGoodsList = page.locator('.popup_content .main-table-body_tr'); // 设置产品a的调出单价和数量 let goodsTr = outBillGoodsList.filter({ hasText: goods.a.no }); await goodsTr .locator('td') .nth(7) .locator('input') .fill(`${goods.a.unitPrice + 1}`); await goodsTr .locator('td') .nth(8) .locator('input') .fill(`${goods.a.quantity + 1}`); // 设置产品b的调出单价和数量 goodsTr = outBillGoodsList.filter({ hasText: goods.b.no }); await goodsTr .locator('td') .nth(7) .locator('input') .fill(`${goods.b.unitPrice + 1}`); await goodsTr .locator('td') .nth(8) .locator('input') .fill(`${goods.b.quantity + 1}`); // 生产内部调出单 await page.getByRole('button', { name: /保\s存/ }).click(); await page.getByRole('button', { name: '我知道了' }).click(); }); await test.step('查看内部调货单A', async () => { // 查看内部调货单A const tableTrList = page.locator('.table_inner .main-table-body_tr'); const targetTr = tableTrList.filter({ hasText: billA }); const targetIndex = await getListIndexForTargetElement(targetTr, tableTrList); const fixedCell = page.locator('.m-table-fixed-body tr').nth(targetIndex); await fixedCell.getByText('调货单').click(); // 拿取商品a的数据 let goodsTr = page.locator('.popup_content tr', { hasText: goods.a.name }); quantity = Number(await goodsTr.locator('td').nth(5).innerText()); outQuantity = Number(await goodsTr.locator('td').nth(6).innerText()); unitPrice = Number(await goodsTr.locator('td').nth(7).innerText()); outUnitPrice = Number(await goodsTr.locator('td').nth(8).innerText()); subtotal = Number(await goodsTr.locator('td').nth(9).innerText()); outSubtotal = Number(await goodsTr.locator('td').nth(10).innerText()); totalPrice += quantity * unitPrice; totalQuantity += quantity; // 判断商品a的数据 expect.soft(quantity).toBe(goods.a.quantity); expect.soft(unitPrice).toBe(goods.a.unitPrice); expect.soft(outQuantity).toBe(goods.a.quantity + 1); expect.soft(outUnitPrice).toBe(goods.a.unitPrice + 1); expect.soft(subtotal).toBe(goods.a.quantity * goods.a.unitPrice); expect(outSubtotal).toBe((goods.a.quantity + 1) * (goods.a.unitPrice + 1)); // 拿取商品b的数据 goodsTr = page.locator('.popup_content tr', { hasText: goods.b.name }); quantity = Number(await goodsTr.locator('td').nth(5).innerText()); outQuantity = Number(await goodsTr.locator('td').nth(6).innerText()); unitPrice = Number(await goodsTr.locator('td').nth(7).innerText()); outUnitPrice = Number(await goodsTr.locator('td').nth(8).innerText()); subtotal = Number(await goodsTr.locator('td').nth(9).innerText()); outSubtotal = Number(await goodsTr.locator('td').nth(10).innerText()); totalPrice += quantity * unitPrice; totalQuantity += quantity; // 判断商品b的数据 expect.soft(quantity).toBe(goods.b.quantity); expect.soft(unitPrice).toBe(goods.b.unitPrice); expect.soft(outQuantity).toBe(goods.b.quantity + 1); expect.soft(outUnitPrice).toBe(goods.b.unitPrice + 1); expect.soft(subtotal).toBe(goods.b.quantity * goods.b.unitPrice); expect.soft(outSubtotal).toBe((goods.b.quantity + 1) * (goods.b.unitPrice + 1)); // 判断合计数量、合计金额 expect.soft(totalPrice).toBe(goods.b.quantity * goods.b.unitPrice + goods.a.quantity * goods.a.unitPrice); expect(totalQuantity).toBe(goods.a.quantity + goods.b.quantity); // 关闭弹窗 await page.locator('.title > .close_icon > svg').click(); }); await test.step('驳回要货单B', async () => { // 查看内部调货单B const tableTrList = page.locator('.table_inner .main-table-body_tr'); const targetTr = tableTrList.filter({ hasText: billB }); const targetIndex = await getListIndexForTargetElement(targetTr, tableTrList); const fixedCell = page.locator('.m-table-fixed-body tr').nth(targetIndex); await fixedCell.getByText('驳回').click(); await page.getByRole('button', { name: /确\s认/ }).click(); await transferManagementPage.gotoSubPage('要货单'); const billBTr = page .locator('.m-table__body-wrapper .main-table-body_tr') .filter({ hasText: billB }) .locator('td', { hasText: '被驳回' }); await expect(billBTr).toBeVisible(); }); }); }); test.describe('调货管理', () => { // 此处不需要beforeEach将消息弹窗去除 test('门店要货提醒', async ({ page, homeNavigation, transferManagementPage, tablePage }) => { const goods = { no: 'aa100007', name: '肌因能量套', unitPrice: 10, quantity: 5 }; const remark = '门店要货提醒' + faker.helpers.fromRegExp(/[a-d]{2}[0-9]{2}/); await test.step('进入门店要货', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.top_tab .tab_item').getByText('调货管理').click(); await transferManagementPage.gotoSubPage('门店要货'); }); const $$tableTrList = page.locator('.table_inner .main-table-body_tr'); const $billTr = $$tableTrList.filter({ hasText: remark }); await test.step('保存要货单,查看要货单提醒', async () => { // 选择产品a,设置产品数量和单价 await page.locator('.panel tr', { hasText: goods.no }).click(); // 设置备注 await page.getByText('备注').click(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remark); await page.getByRole('button', { name: /确\s认/ }).click(); // 保存要货单 await page.getByRole('button', { name: /保\s存/ }).click(); await expect(page.getByRole('cell', { name: '门店要货备注' })).toBeInViewport(); await expect($billTr).toBeVisible(); await expect(page.getByText('门店要货', { exact: true })).not.toBeVisible(); await expect(page.getByRole('button', { name: '去处理' })).not.toBeVisible(); }); await test.step('提交要货单,查看要货单提醒', async () => { const billIndex = await tablePage.getBodyTableIndex([remark]); const $$rightTr = tablePage.fixedRightTable.locator('tbody tr'); await $$rightTr.nth(billIndex).getByText('编辑').click(); // 提交要货单 await page.getByRole('button', { name: /提\s交/ }).click(); // await expect(page.getByText('门店要货', { exact: true })).toBeVisible(); const storeName = 'AT测试一店'; await expect(page.getByText(`慧来客提醒您,${storeName}申请调货了~`)).toBeVisible(); await expect(page.getByRole('button', { name: '去处理' })).toBeVisible(); }); }); }); test.describe('过期预警表', () => { test('查询', async ({ page, homeNavigation, customerPage, createCustomer, numberInput }) => { const product = ProjectName.Product.Product_11.name; const productNum = ProjectName.Product.Product_11.num; let code; // 过期预警表代码段 let lastSurplus; // 初始数量 let lastOffSurplus; // 初始关闭数量 const customer = createCustomer; await test.step('记录初始剩余数量', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '库存管理' }).click(); await page.locator('.tab_option', { hasText: '过期预警表' }).click(); await page.locator('.toolbar', { hasText: '寄存' }).waitFor(); await expect(async () => { // 点击门店选择器 await page.locator('.shop_picker').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor({ timeout: 2000 }); }).toPass(); // 选择一店 await page.locator('.com_picker').last().locator('.label_item', { hasText: 'AT测试一店' }).click(); // await expect(page.locator('.com_picker').last().locator('.ant-checkbox-wrapper-checked',{hasText:'AT测试一店'})).toBeVisible({timeout:2000}); await expect(page.locator('.m-table__loading')).toBeHidden(); code = page.locator('.m-table__body-wrapper .m-table__body tr'); // 获取指定产品初始剩余数量 lastSurplus = await code .filter({ has: page.locator('td', { hasText: productNum }) }) .filter({ has: page.locator('td', { hasText: product }) }) .locator('td') .nth(6) .innerText(); // 关闭寄存按钮 await expect(async () => { await page.locator('.ant-switch').click(); await expect(page.locator('.ant-switch-checked')).not.toBeVisible(); }).toPass(); await expect(page.locator('.m-table__loading')).toBeHidden(); // 关闭寄存后产品数量 lastOffSurplus = await code .filter({ has: page.locator('td', { hasText: productNum }) }) .filter({ has: page.locator('td', { hasText: product }) }) .locator('td') .nth(6) .innerText(); }); await test.step('顾客购买指定产品,选择寄存部分', async () => { await homeNavigation.gotoModule('顾客'); await customerPage.searchCustomer(customer.phone); await customerPage.selectSearchCustomer(customer.username); // 点击进入详情 await page.locator('.user_info_head .user_name', { hasText: customer.username }).last().click(); await page.locator('span').filter({ hasText: '去开单' }).first().click(); // 点击卖品 await page.locator('.float_tab').getByText('卖品').click(); // 点击一个卖品 await page.locator('.number_service > .project_list').filter({ hasText: productNum }).click(); // 修改数量 await page.locator('.edit_txt div:nth-child(2)').first().click(); await numberInput.setValue(5); await numberInput.confirmValue(); // 结算 await page .locator('div') .filter({ hasText: /^结\s算$/ }) .click(); // 选择现金支付 await page.getByText('现金').click(); // 取消推送消费提醒 await page.getByLabel('推送消费提醒').uncheck(); // 取消结算签字 await page.getByLabel('结算签字').uncheck(); // 结算 await page.getByRole('button', { name: /^结\s算$/ }).click(); await page.locator('.popup_content .title', { hasText: '产品寄存' }).waitFor(); // 寄存卖品 await page.getByRole('button', { name: '转寄存' }).click(); await page .locator('.popup_content') .filter({ has: page.locator('.title', { hasText: '产品寄存' }) }) .locator('.num') .click(); await numberInput.setValue(3); await numberInput.confirmValue(); // 确认 await page.getByRole('button', { name: /^确\s认$/ }).click(); }); await test.step('查看寄存开启关闭状态的数量', async () => { await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '库存管理' }).click(); await page.locator('.tab_option', { hasText: '过期预警表' }).click(); await page.locator('.toolbar', { hasText: '寄存' }).waitFor(); // 顾客消费寄存后的产品数量 const Surplus = await code .filter({ has: page.locator('td', { hasText: productNum }) }) .filter({ has: page.locator('td', { hasText: product }) }) .locator('td') .nth(6) .innerText(); expect.soft(Surplus * 1).toBe(lastSurplus * 1 - 2); // 关闭寄存按钮 await expect(async () => { await page.locator('.ant-switch').click(); await expect(page.locator('.ant-switch-checked')).not.toBeVisible(); }).toPass(); await expect(page.locator('.m-table__loading')).toBeHidden(); // 关闭寄存后产品数量 const offSurplus = await code .filter({ has: page.locator('td', { hasText: productNum }) }) .filter({ has: page.locator('td', { hasText: product }) }) .locator('td') .nth(6) .innerText(); expect.soft(offSurplus * 1).toBe(lastOffSurplus * 1 - 5); }); }); test('修改', async ({ page, homeNavigation }) => { const remarkRandom = faker.helpers.fromRegExp(/1[0-9]{10}/); await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '库存管理' }).click(); await page.locator('.tab_option', { hasText: '过期预警表' }).click(); await page.locator('.toolbar', { hasText: '寄存' }).waitFor(); await expect(page.locator('.m-table__loading')).toBeHidden(); await expect(async () => { // 选择门店 await page.locator('.shop_picker').click(); await page.locator('.comSelect_title', { hasText: /^选择$/ }).waitFor({ timeout: 2000 }); }).toPass(); await page.locator('.compicker_part-box .label', { hasText: 'AT测试一店' }).click(); // 点击输入框输入条形码 await page.getByPlaceholder('编码/名称/条码/拼音码').fill('713112'); await page.locator('.search_icon').first().click(); await page.locator('.propertyNo').first().waitFor(); await expect(page.locator('.m-table__loading')).toBeHidden(); // 获取当前失效日期 // 修改失效日期 await page.locator('.invalidTime .on_click_cell_icon').click(); await page.locator('.popup_content .title', { hasText: '选择有效期' }).waitFor(); await page.getByPlaceholder('请选择日期').click(); await page.locator('.ant-calendar-panel').waitFor(); // 点击今天 await page.locator('.ant-calendar-footer-btn').click(); await page.locator('.confirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message').waitFor(); // 修改备注 await page.locator('.remark .on_click_cell_icon').click(); await page.locator('.popup_content .title', { hasText: '修改备注' }).waitFor(); await page.getByPlaceholder('请输入1-100个字符备注内容').fill(remarkRandom); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message').waitFor(); const Time = await page.locator('.invalidTime').innerText(); const expireDay = await page.locator('.expireDays').innerText(); const remark = await page.locator('.remark').first().innerText(); const currentDate = new Date(); const year = currentDate.getFullYear(); const month = String(currentDate.getMonth() + 1).padStart(2, '0'); const day = String(currentDate.getDate()).padStart(2, '0'); const formattedDate = `${year}-${month}-${day}`; expect.soft(Time).toBe(formattedDate); expect.soft(expireDay).toBe('1天后过期'); expect.soft(remark).toBe(remarkRandom); // 修改失效日期 await page.locator('.invalidTime .on_click_cell_icon').click(); await page.locator('.popup_content .title', { hasText: '选择有效期' }).waitFor(); // 点击不限期 await page.locator('.popup_content .content div').first().click(); await page.locator('.confirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.ant-message').waitFor(); }); }); test.describe.serial('盘点', () => { test.beforeEach(async ({ page }) => { // 处理随机的弹窗 await page.addLocatorHandler(page.locator('.popup_content', { hasText: '门店要货' }), async () => { await page.locator('.popup_content .close_icon').click(); await expect(page.locator('.popup_content .close_icon')).not.toBeVisible(); }); }); test('产品盘点', async ({ page, homeNavigation, numberInput }) => { const productA = ProjectName.Product.Product_1.name; //产品A const productB = ProjectName.Product.Product_2.name; //产品B const productNumA = ProjectName.Product.Product_1.num; //产品A const productNumB = ProjectName.Product.Product_2.num; //产品B // 库存总量 let inventoryA; let inventoryB; // 批次数量 let BatchQuantityA; let BatchQuantityB; // 产品余量 let ProductMargin; // 获取单号的ID let billId; /**@type {string} 单号*/ let billNo; await test.step('记录各自批次数量', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).waitFor(); await page.locator('.tab_item', { hasText: '盘点' }).click(); await page.locator('.comBill-cot_lt').waitFor(); // 获取库存总量列数 let inventory; const columns = page.locator('.panel_report thead tr th'); await columns.last().waitFor(); const headers = await columns.allInnerTexts(); inventory = headers.findIndex(headerText => headerText.includes('库存总量')); if (inventory !== -1) { console.log(`"库存总量" 列是第 ${inventory + 1} 列`); } else { throw new Error('没有找到列'); } // 获取批次数量列数 let BatchQuantity; await columns.last().waitFor(); BatchQuantity = headers.findIndex(headerText => headerText.includes('批次数量')); if (inventory !== -1) { console.log(`"批次数量" 列是第 ${BatchQuantity + 1} 列`); } else { throw new Error('没有找到列'); } // 获取各项目库存总量 const ProductLine = page.locator('.panel_report .m-table__body tbody tr'); inventoryA = await ProductLine.filter({ has: page.locator('td', { hasText: productA }) }) .filter({ has: page.locator('td', { hasText: productNumA }) }) .locator('td') .nth(inventory) .innerText(); inventoryB = await ProductLine.filter({ has: page.locator('td', { hasText: productB }) }) .filter({ has: page.locator('td', { hasText: productNumB }) }) .locator('td') .nth(inventory) .innerText(); console.log(inventoryA, inventoryB); // 获取各项目批次数量 BatchQuantityA = Number( await ProductLine.filter({ has: page.locator('td', { hasText: productA }) }) .filter({ has: page.locator('td', { hasText: productNumA }) }) .locator('td') .nth(BatchQuantity) .innerText(), ); BatchQuantityB = Number( await ProductLine.filter({ has: page.locator('td', { hasText: productB }) }) .filter({ has: page.locator('td', { hasText: productNumB }) }) .locator('td') .nth(BatchQuantity) .innerText(), ); console.log(BatchQuantityA, BatchQuantityB); }); await test.step('输入各产品指定数量并查看', async () => { // A 输入数量 await page.locator('.panel_input input').fill(productNumA); // 点击搜索 await page.locator('.panel_input .search_icon').click(); await numberInput.setValue(BatchQuantityA + 1); await numberInput.confirmValue(); // B 输入数量 await page.locator('.panel_input input').fill(productNumB); // 点击搜索 await page.locator('.panel_input .search_icon').click(); await numberInput.setValue(BatchQuantityB + 1); await numberInput.confirmValue(); // 获取批次数量列数 let Batchbill; const billcolumns = page.locator('.bill_report thead tr th'); await billcolumns.last().waitFor(); const headerss = await billcolumns.allInnerTexts(); Batchbill = headerss.findIndex(headerText => headerText.includes('盈/亏')); if (Batchbill !== -1) { console.log(`"盈/亏" 列是第 ${Batchbill + 1} 列`); } else { throw new Error('没有找到列'); } // 校验右侧盈亏 const billLine = page.locator('.bill_report .m-table__body tbody tr'); const ProfitAndLossA = await billLine .filter({ has: page.locator('td', { hasText: productA }) }) .locator('td') .nth(Batchbill) .innerText(); const ProfitAndLossB = await billLine .filter({ has: page.locator('td', { hasText: productB }) }) .locator('td') .nth(Batchbill) .innerText(); expect(ProfitAndLossA).toBe('+1'); expect(ProfitAndLossB).toBe('+1'); // 等待 /stock_bill 请求完成并获取流水ID const [response] = await Promise.all([ page.waitForResponse(async res => { return res.url().includes('/stock_bill') && res.status() === 200; }), page.locator('.operate_button', { hasText: '盘点完成' }).click(), ]); const responseBody = await response.json(); billId = responseBody?.content; console.log('盘点ID' + '=' + billId); // 操作成功 await page.locator('.ant-message', { hasText: '操作成功' }).waitFor(); }); await test.step('查看入库明细并审核', async () => { // 根据ID获取水单单号 const [responses] = await Promise.all([ page.waitForResponse(async res => { return res.url().includes('/stock_bill?s') && res.status() === 200; }), page.locator('.tab_item', { hasText: '出入库管理' }).click(), ]); // 根据ID找到单号 const responseBody = await responses.json(); if (Array.isArray(responseBody?.content?.data)) { let bill = responseBody?.content?.data.find(item => item.id === billId); billNo = bill?.no; console.log('单号' + '=' + billNo); } // 根据单号获取该订单行数 let nowRowA = 0; const allTrA = page.locator('.m-table__body-wrapper .m-table__body tbody tr'); const countA = await allTrA.count(); // 获取单号处于第几行 for (let i = 0; i < countA; i++) { const trA = allTrA.nth(i); const billLine = await trA.locator('.m-table-cell').nth(1).innerText(); // console.log(billLine) if (billLine.includes(billNo)) { nowRowA = i; break; } } await page.locator('.m-table__fixed-right .m-table-cell_btn', { hasText: '明细' }).nth(nowRowA).click(); // 获取入库数量列数 let BePutInStorage; const BPIScolumns = page.locator('.bill_report .m-table__header-wrapper thead th'); await BPIScolumns.last().waitFor(); const BPISheaders = await BPIScolumns.allInnerTexts(); BePutInStorage = BPISheaders.findIndex(headerText => headerText.includes('入库数量')); if (BePutInStorage !== -1) { console.log(`"入库数量" 列是第 ${BePutInStorage + 1} 列`); } else { throw new Error('没有找到列'); } // 入库列数 const BpisLine = page.locator('.bill_report .m-table__body-wrapper .m-table__body tbody'); const BePutInStorageA = await BpisLine.filter({ has: page.locator('td', { hasText: productNumA }) }) .filter({ has: page.locator('td', { hasText: productA }) }) .locator('td') .nth(BePutInStorage) .innerText(); const BePutInStorageB = await BpisLine.filter({ has: page.locator('td', { hasText: productNumB }) }) .filter({ has: page.locator('td', { hasText: productB }) }) .locator('td') .nth(BePutInStorage) .innerText(); expect(BePutInStorageA).toBe('1'); expect(BePutInStorageB).toBe('1'); await page.locator('.primary_button', { hasText: /^审\s核$/ }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.popup_content')).not.toBeVisible(); }); await test.step('最后再次进入库存余量表校验', async () => { // 审核后查看产品余量值 await page.locator('.tab_item', { hasText: '库存管理' }).click(); ProductMargin = page.locator('.table_sub-box .m-table__body-wrapper .m-table__body tbody tr'); const ProductMarginedA = await ProductMargin.filter({ has: page.locator('td', { hasText: productNumA }), }) .filter({ has: page.locator('td', { hasText: productA }) }) .locator('td') .nth(6) .innerText(); const ProductMarginedB = await ProductMargin.filter({ has: page.locator('td', { hasText: productNumB }), }) .filter({ has: page.locator('td', { hasText: productB }) }) .locator('td') .nth(6) .innerText(); expect(ProductMarginedA).toBe(`${BatchQuantityA + 1}`); expect(ProductMarginedB).toBe(`${BatchQuantityB + 1}`); }); }); test('开用盘点', async ({ page, homeNavigation, numberInput }) => { const productC = ProjectName.Product.Product_5.name; //产品C const productD = ProjectName.Product.Product_7.name; //产品D const productNumC = ProjectName.Product.Product_5.num; //产品C const productNumD = ProjectName.Product.Product_7.num; //产品D // 库存总量 let inventoryC; let inventoryD; // 产品余量 let ProductMargin; // 获取单号的ID let billId; /**@type {string} 单号*/ let billNo; await test.step('记录各自批次数量', async () => { // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).waitFor(); await page.locator('.tab_item', { hasText: '盘点' }).click(); await page.locator('.tab_item', { hasText: '盘点' }).locator('.anticon').click(); await page.locator('.ant-dropdown-menu-item', { hasText: '开用盘点' }).click(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); // 获取库存总量列数 let inventory; const columns = page.locator('.panel_report thead tr th'); await columns.last().waitFor(); const headers = await columns.allInnerTexts(); inventory = headers.findIndex(headerText => headerText.includes('开用余量')); if (inventory !== -1) { console.log(`"开用余量" 列是第 ${inventory + 1} 列`); } else { throw new Error('没有找到列'); } // 获取各项目库存总量 const ProductLine = page.locator('.panel_report .m-table__body tbody tr'); inventoryC = Number( await ProductLine.filter({ has: page.locator('td', { hasText: productC }) }) .filter({ has: page.locator('td', { hasText: productNumC }) }) .locator('td') .nth(inventory) .innerText(), ); inventoryD = Number( await ProductLine.filter({ has: page.locator('td', { hasText: productD }) }) .filter({ has: page.locator('td', { hasText: productNumD }) }) .locator('td') .nth(inventory) .innerText(), ); console.log(inventoryC, inventoryD); }); await test.step('输入各产品指定数量并查看', async () => { // C 输入数量 await page.locator('.panel_input input').fill(productNumC); // 点击搜索 await page.locator('.panel_input .search_icon').click(); await page.locator('div').filter({ hasText: /^123$/ }).getByRole('button').nth(3).click(); await numberInput.setValue(inventoryC - 1); await numberInput.confirmValue(); // D 输入数量 await page.locator('.panel_input input').fill(productNumD); // 点击搜索 await page.locator('.panel_input .search_icon').click(); await numberInput.setValue(inventoryD - 1); await numberInput.confirmValue(); // 获取批次数量列数 let Batchbill; const billcolumns = page.locator('.bill_report thead tr th'); await billcolumns.last().waitFor(); const headerss = await billcolumns.allInnerTexts(); Batchbill = headerss.findIndex(headerText => headerText.includes('盈/亏')); if (Batchbill !== -1) { console.log(`"盈/亏" 列是第 ${Batchbill + 1} 列`); } else { throw new Error('没有找到列'); } // 校验右侧盈亏 const billLine = page.locator('.bill_report .m-table__body tbody tr'); const ProfitAndLossC = await billLine .filter({ has: page.locator('td', { hasText: productC }) }) .locator('td') .nth(Batchbill) .innerText(); const ProfitAndLossD = await billLine .filter({ has: page.locator('td', { hasText: productD }) }) .locator('td') .nth(Batchbill) .innerText(); expect(ProfitAndLossC).toBe('-1'); expect(ProfitAndLossD).toBe('-1'); // 等待 /stock_bill 请求完成并获取流水ID const [response] = await Promise.all([ page.waitForResponse(async res => { return res.url().includes('/stock_bill') && res.status() === 200; }), page.locator('.operate_button', { hasText: '盘点完成' }).click(), ]); const responseBody = await response.json(); billId = responseBody?.content; console.log('盘点ID' + '=' + billId); // 操作成功 await page.locator('.ant-message', { hasText: '操作成功' }).waitFor(); }); await test.step('记录库存余量表', async () => { // 收集初始产品余量值 await page.locator('.tab_item', { hasText: '库存管理' }).click(); await page.locator('.ant-switch-checked').waitFor(); ProductMargin = page.locator('.table_sub-box .m-table__body-wrapper .m-table__body tbody tr'); await page.locator('.keyword_search input').fill(productNumC); await page.locator('.keyword_search .ant-input-suffix').click(); await page.locator('.keyword_search .ant-input-suffix .anticon-close-circle').click(); await page.locator('.keyword_search input').fill(productNumD); await page.locator('.keyword_search .ant-input-suffix').click(); }); await test.step('查看出库明细并审核', async () => { await page.locator('.tab_item', { hasText: '出入库管理' }).click(); // 选择出入库单 await page.locator('.outInStock_filter .ant-select-selection__rendered').last().click(); // 根据ID获取水单单号 const [responses] = await Promise.all([ page.waitForResponse(async res => { return res.url().includes('/stock_bill?s') && res.status() === 200; }), page.locator('.ant-select-dropdown-menu-item', { hasText: '出库单' }).click(), ]); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); // 根据ID找到单号 const responseBody = await responses.json(); if (Array.isArray(responseBody?.content?.data)) { let bill = responseBody?.content?.data.find(item => item.id === billId); billNo = bill?.no; console.log('单号' + '=' + billNo); } // 根据单号获取该订单行数 let nowRowA = 0; const allTrA = page.locator('.m-table__body-wrapper .m-table__body tbody tr'); const countA = await allTrA.count(); // 获取单号处于第几行 for (let i = 0; i < countA; i++) { const trA = allTrA.nth(i); const billLine = await trA.locator('.m-table-cell').nth(1).innerText(); // console.log(billLine) if (billLine.includes(billNo)) { nowRowA = i; break; } } await page.locator('.m-table__fixed-right .m-table-cell_btn', { hasText: '明细' }).nth(nowRowA).click(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); // 获取出库数量列数 let OutboundQuantity; const OQcolumns = page.locator('.bill_report .m-table__header-wrapper thead th'); await OQcolumns.last().waitFor(); const OQheaders = await OQcolumns.allInnerTexts(); OutboundQuantity = OQheaders.findIndex(headerText => headerText.includes('出库数量')); if (OutboundQuantity !== -1) { console.log(`"出库数量" 列是第 ${OutboundQuantity + 1} 列`); } else { throw new Error('没有找到列'); } // 出库列数 const OQLine = page.locator('.bill_report .m-table__body-wrapper .m-table__body tbody'); const OutboundQuantityC = await OQLine.filter({ has: page.locator('td', { hasText: productNumC }) }) .filter({ has: page.locator('td', { hasText: productC }) }) .locator('td') .nth(OutboundQuantity) .innerText(); const OutboundQuantityD = await OQLine.filter({ has: page.locator('td', { hasText: productNumD }) }) .filter({ has: page.locator('td', { hasText: productD }) }) .locator('td') .nth(OutboundQuantity) .innerText(); expect(OutboundQuantityC).toBe(1 + ''); expect(OutboundQuantityD).toBe(1 + ''); await page.locator('.primary_button', { hasText: /^审\s核$/ }).click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await expect(page.locator('.popup_content')).not.toBeVisible(); }); await test.step('最后再次进入库存余量表校验', async () => { // 审核后查看产品余量值 await page.locator('.tab_item', { hasText: '库存管理' }).click(); await page.locator('.keyword_search input').fill(productNumC); await page.locator('.keyword_search .ant-input-suffix').click(); const ProductMarginedC = await ProductMargin.filter({ has: page.locator('td', { hasText: productNumC }), }) .filter({ has: page.locator('td', { hasText: productC }) }) .locator('td') .nth(7) .innerText(); await page.locator('.keyword_search .ant-input-suffix .anticon-close-circle').click(); await page.locator('.keyword_search input').fill(productNumD); await page.locator('.keyword_search .ant-input-suffix').click(); const ProductMarginedD = await ProductMargin.filter({ has: page.locator('td', { hasText: productNumD }), }) .filter({ has: page.locator('td', { hasText: productD }) }) .locator('td') .nth(7) .innerText(); await page.locator('.keyword_search .ant-input-suffix .anticon-close-circle').click(); expect(ProductMarginedC).toBe(inventoryC - 1 + ''); expect(ProductMarginedD).toBe(inventoryD - 1 + ''); }); }); test('清理产出的数据', async ({ page, homeNavigation }) => { await test.step('清理产出的数据', async () => { // 最后恢复数据操作 await page.reload(); // 点击库存 await homeNavigation.gotoModule('库存'); await page.locator('.tab_item', { hasText: '出入库管理' }).click(); // 等待加载完毕 await expect(page.locator('.m-table__icon__warp')).not.toBeVisible(); await page.locator('.outInStock_filter .ant-select-selection__rendered').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '入库单' }).click(); await page.locator('.m-table__fixed-right .m-table-cell_btn', { hasText: '反审' }).first().click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); await page.locator('.outInStock_filter .ant-select-selection__rendered').last().click(); await page.locator('.ant-select-dropdown-menu-item', { hasText: '出库单' }).click(); await page.locator('.m-table__fixed-right .m-table-cell_btn', { hasText: '反审' }).first().click(); await page.locator('.comfirm_btn', { hasText: /^确\s认$/ }).click(); }); }); });