This repository has been archived on 2025-04-22. You can view files and clone it, but cannot push or open issues or pull requests.
hlk_autotest/tests/touch/boss_inventory.spec.ts
2024-12-29 22:04:57 +08:00

3771 lines
178 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

// @ts-check
import { 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 '@/common/userconfig';
test.describe('出入库管理', () => {
test.describe('入库单', () => {
test('入库', async ({ page, homeNavigation, numberInput }) => {
const remark = '入库' + faker.helpers.fromRegExp(/1[0-9]{4}/);
const productA = ProjectName.Product.Product_3;
/** 产品A余量 */
let productASurplus: number;
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();
});
/** 入库单的索引 */
let billEntryIndex: number;
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;
let billNo: string;
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;
let billNo: string;
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; //单价
let billNo: string;
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; //单价
let billNo: string;
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 });
// 获取出库后总数
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);
});
let billNo: string;
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: string, billB: string;
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;
let billNo: string;
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: string;
let billNo: string;
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();
});
});
});