Commit 6c31a476 authored by liguangyu06's avatar liguangyu06
Browse files

同步基础管理与统计报表用例文档,并更新 Playwright 脚本与 PO。

对齐 CSV/MD/测试点与现网列名及组合查询;补充厂商资质子 Tab 与基础模块复跑脚本。
parent aa8987ce
......@@ -187,15 +187,16 @@ export class AdmitMaterialListPage extends AdmitSharedPage {
/** 组合查询:一次性填满筛选区全部字段后查询(字段以现网搜索条为准)。 */
async filterCombination(): Promise<void> {
await this.ensureFiltersExpanded();
const scope = await this.queryScope();
await this.applyFilterCombination(
[
{ label: '制单日期', kind: 'dateRange', value: '样本' },
{ label: '销售商', kind: 'text', value: '样本' },
{ label: '耗材类型', kind: 'select', value: '样本' },
{ label: '器械注册人', kind: 'text', value: '样本' },
{ label: '注册证号', kind: 'text', value: '样本' },
{ label: '供应商', kind: 'text', value: '样本' },
{ label: '制单日期', kind: 'dateRange' },
{ label: '销售商', aliases: ['进院供应商', '供应商', '销售商名称'], kind: 'text', value: '国' },
{ label: '耗材类型', kind: 'select' },
{ label: '器械注册人', kind: 'text', value: '公' },
{ label: '注册证号', kind: 'text', value: '国' },
{ label: '供应商', aliases: ['进院供应商', '销售商'], kind: 'text', value: '国' },
],
{ scope },
);
......
......@@ -79,24 +79,10 @@ export class AdmitMaterialPage extends AdmitSharedPage {
await this.expectListOrEmpty();
}
async pendingCountMatches(): Promise<void> {
await this.clickTabAndMatchCount('待申请');
}
async generateNeedsSelection(): Promise<void> {
await this.expectNeedsSelection('生成申请单');
}
async detailAndBack(): Promise<void> {
await this.query();
const row = await this.firstRow();
const name = await this.cellText(row, this.listNameColumn);
await this.openPutFromRow(row, '详情');
await expect(this.put()).toContainText(name.slice(0, 8));
await this.leaveWithoutCommit();
await expect(this.button('查询').first()).toBeVisible();
}
async detailReadonly(): Promise<void> {
await this.query();
await this.openPutFromRow(await this.firstRow(), '详情');
......@@ -122,79 +108,10 @@ export class AdmitMaterialPage extends AdmitSharedPage {
await this.leaveWithoutCommit();
}
async editCancel(): Promise<void> {
await this.clickTab('待申请');
const row = await this.skipIfNoAction('编辑', '待申请无编辑');
const name = await this.cellText(row, this.listNameColumn);
await this.openPutFromRow(row, '编辑');
const input = this.putInput(this.listNameColumn);
await this.fill(input, `${name}-取消`, '临时改名');
await this.leaveWithoutCommit();
await this.clickTab('待申请');
const again = await this.skipIfNoAction('编辑', '待申请无编辑');
await this.openPutFromRow(again, '编辑');
await expect(this.putInput(this.listNameColumn)).toHaveValue(name);
await this.leaveWithoutCommit();
}
async editClearName(): Promise<void> {
await this.clickTab('待申请');
const row = await this.skipIfNoAction('编辑', '待申请无编辑');
const name = await this.cellText(row, this.listNameColumn);
await this.openPutFromRow(row, '编辑');
await this.fill(this.putInput(this.listNameColumn), '', '清空产品名称');
await this.saveOnPut();
await this.expectBlockedAndStay();
await this.leaveWithoutCommit();
await this.clickTab('待申请');
const again = await this.rowWithAction('编辑');
expect(again, '取消后原行仍应可编辑').toBeTruthy();
await this.openPutFromRow(again as NonNullable<typeof again>, '编辑');
await expect(this.putInput(this.listNameColumn)).toHaveValue(name);
await this.leaveWithoutCommit();
}
async effectiveNoEdit(): Promise<void> {
await this.skipIfTabEmpty('已生效');
const edit = (await this.listRows()).getByRole('button', { name: /编\s*辑/ });
expect(await edit.count(), '已生效行不应提供编辑').toBe(0);
}
async relateCancel(): Promise<void> {
await this.query();
const total = await this.getTotalCount();
const row = await this.checkFirstRow();
const supplier = await this.cellText(row, '默认进院供应商');
await this.clickToolbarThenCancel('关联产品');
expect(await this.getTotalCount(), '取消关联后总数不变').toBe(total);
expect(await this.cellText(await this.firstRow(), '默认进院供应商')).toBe(supplier);
}
async voidCancel(): Promise<void> {
await this.query();
const voidBefore = await this.readTabCount('已作废');
const row = await this.checkFirstRow();
const name = await this.cellText(row, this.listNameColumn);
await this.clickButton('作废');
const confirm = this.page.locator('.ant-modal-confirm:visible, .ant-modal:visible').last();
await expect(confirm, '作废应出现确认框').toBeVisible();
await expect(confirm.getByRole('button', { name: /取\s*消/ })).toBeVisible();
await expect(confirm.getByRole('button', { name: /确\s*定/ })).toBeVisible();
await this.click(confirm.getByRole('button', { name: /取\s*消/ }).first(), '取消作废');
await expect(this.page.getByText(name.slice(0, 12)).first(), '取消后该行仍在').toBeVisible();
if (voidBefore !== null) {
expect(await this.readTabCount('已作废'), '已作废计数不变').toBe(voidBefore);
}
}
async openLog(): Promise<void> {
await this.query();
const row = await this.skipIfNoAction('日志', '列表无日志入口');
await this.assertBeforeBusinessAction('日志');
await this.click(this.rowAction(row, '日志'), '日志');
const layer = this.page.locator('.ant-modal:visible, .ant-drawer:visible, .put-page:visible').last();
await expect(layer, '日志层应打开').toBeVisible();
await this.assertUiReady('日志');
await this.leaveWithoutCommit();
}
}
......@@ -22,14 +22,15 @@ export class AdmitProductListPage extends AdmitSharedPage {
/** 组合查询:一次性填满筛选区全部字段后查询(字段以现网搜索条为准)。 */
async filterCombination(): Promise<void> {
const scope = await this.queryScope();
await this.ensureFiltersExpanded();
await this.applyFilterCombination(
[
{ label: '制单日期', kind: 'dateRange', value: '样本' },
{ label: '销售商', kind: 'text', value: '样本' },
{ label: '耗材类型', kind: 'select', value: '样本' },
{ label: '器械注册人', kind: 'text', value: '样本' },
{ label: '注册证号', kind: 'text', value: '样本' },
{ label: '供应商', kind: 'text', value: '样本' },
{ label: '制单日期', kind: 'dateRange' },
{ label: '销售商', aliases: ['进院供应商', '供应商', '销售商名称'], kind: 'text', value: '国' },
{ label: '耗材类型', kind: 'select' },
{ label: '器械注册人', kind: 'text', value: '公' },
{ label: '注册证号', kind: 'text', value: '国' },
{ label: '供应商', aliases: ['进院供应商', '销售商'], kind: 'text', value: '国' },
],
{ scope },
);
......
This diff is collapsed.
......@@ -23,7 +23,13 @@ export class AdmitSupplyPage extends AdmitSharedPage {
const supplier = await this.sampleCell('进院供应商');
await this.chooseSelect('进院供应商', supplier);
await this.query();
await this.expectRowsContain('进院供应商', supplier);
const sel = await this.visibleFormSelect('进院供应商');
const selectedRaw = sel
? ((await sel.locator('.ant-select-selection-item').innerText().catch(() => '')) ?? '')
: supplier;
const selected = selectedRaw.replace(/\s/g, '') || supplier.replace(/\s/g, '');
const needle = (selected || supplier).slice(0, Math.min(12, (selected || supplier).length));
await this.expectRowsContain('进院供应商', needle.slice(0, 4));
}
async resetFilters(): Promise<void> {
......
......@@ -96,7 +96,7 @@ export class AdmitTaskPage extends AdmitSharedPage {
const name = await this.cellText(row, this.listNameColumn);
await this.clickButton('批量分配');
const layer = this.page.locator('.put-page:visible, .ant-modal:visible, .ant-drawer:visible').last();
await expect(layer).toBeVisible();
await expect(layer, '批量分配层').toBeVisible({ timeout: 20_000 });
await this.leaveWithoutCommit();
await this.clickTab('待分类');
await expect(this.page.getByText(name.slice(0, 12)).first()).toBeVisible();
......
......@@ -67,25 +67,40 @@ export class BasicNoticePage extends BasicHospitalSharedPage {
}
}
/** 从发布范围下拉里选一项用于筛选(列表格文案与 option 不一致时以 dropdown 为准)。 */
async pickPublishScopeFilter(preferred?: string): Promise<string> {
return this.pickSelectOption(this.locators.publishScopeSelect, preferred);
}
async queryByScope(scope: string): Promise<void> {
await this.selectDropdown(this.locators.publishScopeSelect, scope);
await this.search();
}
async expectScopeResultsMatch(scope: string): Promise<void> {
if (scope === '全部') return;
if (/^全部$/.test(scope.replace(/\s/g, ''))) return;
const count = await this.getDataRowCount();
expect(count, '范围查询应有结果或空态可接受').toBeGreaterThanOrEqual(0);
const needle = scope.replace(/\s/g, '').slice(0, 4);
for (let i = 0; i < Math.min(count, 5); i += 1) {
const text = await this.cellText(this.dataRows().nth(i), '发布范围');
expect(text, `第 ${i + 1} 行发布范围`).toContain(scope);
const text = (await this.cellText(this.dataRows().nth(i), '发布范围')).replace(/\s/g, '');
expect(text.includes(needle) || scope.replace(/\s/g, '').includes(text.slice(0, 4)), `第 ${i + 1} 行发布范围`).toBeTruthy();
}
}
titleQueryKeyword(fullTitle: string): string {
return fullTitle.slice(0, Math.min(fullTitle.length, 8));
}
async queryByTitleAndScope(title: string, scope: string): Promise<void> {
await this.fill(this.locators.noticeTitle, title, '填写公告标题');
if (scope && scope !== '全部') {
await this.selectDropdown(this.locators.publishScopeSelect, scope);
const keyword = this.titleQueryKeyword(title);
await this.fill(this.locators.noticeTitle, keyword, '填写公告标题');
if (scope && !/^全部$/.test(scope.replace(/\s/g, ''))) {
const selected = this.locators.publishScopeSelect.locator('.ant-select-selection-item').first();
const current = ((await selected.innerText().catch(() => '')) ?? '').replace(/\s/g, '');
if (!current.includes(scope.replace(/\s/g, '').slice(0, 4))) {
await this.selectDropdown(this.locators.publishScopeSelect, scope);
}
}
await this.search();
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -39,7 +39,7 @@ export class CenterReportSheetPage extends CenterReportSharedPage {
await this.fillOperationDate(sample.operationDate);
}
/** 填入与抽屉重叠的快捷区字段(产品名称、记账日期)。 */
/** 填入与抽屉重叠的快捷区字段(物料名称、记账日期)。 */
async fillQuickFiltersForDrawerSync(sample: SampleRow): Promise<void> {
await this.applyQuickFields(sample, drawerSyncQuickFields, { onlyIfPresent: true });
}
......
This diff is collapsed.
......@@ -3,6 +3,7 @@ import type { Page } from '@playwright/test';
import { costFinInData } from '../../data/cost-fin-in.data';
import { ReconCostReportSharedPage } from './recon-cost-report-shared.page';
/** 财务入库单:默认财务月份区间见 costFinInData.defaultQuickDateRange(open/search 统一注入)。 */
export class CostFinInPage extends ReconCostReportSharedPage {
constructor(page: Page) {
super(page, costFinInData);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -404,7 +404,7 @@ export class DrawerFormControls {
return;
}
await this.dismissOverlay();
return;
throw new Error(`快捷/抽屉「${label}」未能选中级联选项「${trimmed}」`);
}
if (leaf) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment