3771 lines
178 KiB
TypeScript
3771 lines
178 KiB
TypeScript
// @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();
|
||
});
|
||
});
|
||
});
|