Commit 297e887d authored by liguangyu06's avatar liguangyu06
Browse files

修复基础管理列设置误点顶栏齿轮,统一触发器解析与面板定位。

parent d14afcfe
...@@ -22,9 +22,10 @@ export const basicHospitalData = { ...@@ -22,9 +22,10 @@ export const basicHospitalData = {
mockOutOfRangeDate: '1999-01-01', mockOutOfRangeDate: '1999-01-01',
writeDisabledReason: '环境禁止写:SKIP_BASIC_WRITE=1', writeDisabledReason: '环境禁止写:SKIP_BASIC_WRITE=1',
paginationPageSizeTo: '20 条/页', paginationPageSizeTo: '20 条/页',
noticeColumnSettingsToggleCandidates: ['发布科室'] as const, noticeColumnSettingsToggleCandidates: ['发布科室', '发布人', '是否置顶'] as const,
branchColumnSettingsToggleCandidates: ['院区简称'] as const, // 与列表实际表头对齐(环境未必有「院区简称」「备注」勾选项)
financeColumnSettingsToggleCandidates: ['备注'] as const, branchColumnSettingsToggleCandidates: ['院区地址', '院区编号', '状态'] as const,
financeColumnSettingsToggleCandidates: ['自动结算日期', '开始日期', '结束日期'] as const,
} as const; } as const;
export function isBasicWriteAllowed(): boolean { export function isBasicWriteAllowed(): boolean {
......
...@@ -60,9 +60,10 @@ export class BasicUserSharedLocators { ...@@ -60,9 +60,10 @@ export class BasicUserSharedLocators {
} }
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
// 与 pages/spd/helpers/column-settings.helper.ts 的 COLUMN_SETTINGS_PANEL_TEXT_RE 保持一致
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: '字段设置' }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
......
...@@ -133,8 +133,8 @@ export class CenterReportEntryLocators { ...@@ -133,8 +133,8 @@ export class CenterReportEntryLocators {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.report return this.report
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: '字段设置' }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
......
...@@ -133,8 +133,8 @@ export class CenterReportSheetLocators { ...@@ -133,8 +133,8 @@ export class CenterReportSheetLocators {
/** 列设置弹出面板(含「列展示」「字段设置」)。 */ /** 列设置弹出面板(含「列展示」「字段设置」)。 */
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.report return this.report
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: '字段设置' }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
......
import { expect, type Locator, type Page } from '@playwright/test'; import { expect, type Locator, type Page } from '@playwright/test';
import { userData, uniqLogin } from '../../data/user.data'; import { userData, uniqLogin } from '../../data/user.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { BasicUserLocators } from '../../locators/spd/basic-user.locator'; import { BasicUserLocators } from '../../locators/spd/basic-user.locator';
import { BasicUserSharedPage, type UserMeta } from './basic-user-shared.page'; import { BasicUserSharedPage, type UserMeta } from './basic-user-shared.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
export type UserSample = { export type UserSample = {
...@@ -295,27 +294,20 @@ export class BasicUserPage extends BasicUserSharedPage { ...@@ -295,27 +294,20 @@ export class BasicUserPage extends BasicUserSharedPage {
} }
private async resolveColumnSettingsTrigger(): Promise<Locator> { private async resolveColumnSettingsTrigger(): Promise<Locator> {
const triggers = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const triggerCount = await triggers.count(); root: this.page,
const candidates: Locator[] = []; tableWrapper: this.locators.tableWrapper,
for (let i = 0; i < Math.min(triggerCount, 4); i += 1) { afterScroll: async () => {
candidates.push(triggers.nth(i)); await this.locators.tableWrapper.scrollIntoViewIfNeeded().catch(() => undefined);
} const body = this.locators.tableWrapper.locator('.ant-table-body').first();
if (candidates.length === 0) { await body
candidates.push(this.locators.columnSettingsTrigger); .evaluate((el) => {
} (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
let trigger = await findUsableColumnSettingsTrigger(candidates); })
if (!trigger) { .catch(() => undefined);
await this.locators.tableWrapper.scrollIntoViewIfNeeded().catch(() => undefined); await this.waitSettle(200);
const body = this.locators.tableWrapper.locator('.ant-table-body').first(); },
await body });
.evaluate((el) => {
(el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
})
.catch(() => undefined);
await this.waitSettle(200);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
...@@ -350,6 +342,20 @@ export class BasicUserPage extends BasicUserSharedPage { ...@@ -350,6 +342,20 @@ export class BasicUserPage extends BasicUserSharedPage {
return name; return name;
} }
} }
await this.openColumnSettings();
const wrappers = this.locators.columnSettingsPanel().locator('.ant-checkbox-wrapper');
const count = await wrappers.count();
const core = /^(序号|序号列|操作|查看|全选|字段设置|列展示|列设置|行高|分散|中等|紧凑|紧簇|显示|表格设置|重置)$/;
for (let i = 0; i < count; i += 1) {
const raw = ((await wrappers.nth(i).innerText()) ?? '').replace(/\s+/g, '').trim();
if (!raw || core.test(raw)) continue;
const checkbox = wrappers.nth(i).locator('input[type="checkbox"]').first();
if (!(await checkbox.isChecked().catch(() => false))) continue;
await this.closeColumnSettingsPanel();
return raw;
}
await this.closeColumnSettingsPanel();
await this.skipWhenDataInsufficient('列设置中无可 toggle 的已勾选列');
return userData.columnSettingsToggleCandidates[0]; return userData.columnSettingsToggleCandidates[0];
} }
......
import { expect, type Locator, type Page } from '@playwright/test'; import { expect, type Locator, type Page } from '@playwright/test';
import { flowData } from '../../data/flow.data'; import { flowData } from '../../data/flow.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { FlowInstLocators } from '../../locators/spd/flow-inst.locator'; import { FlowInstLocators } from '../../locators/spd/flow-inst.locator';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
import { WhFlowSharedPage } from './wh-flow-shared.page'; import { WhFlowSharedPage } from './wh-flow-shared.page';
...@@ -48,8 +46,8 @@ export class FlowInstPage extends WhFlowSharedPage { ...@@ -48,8 +46,8 @@ export class FlowInstPage extends WhFlowSharedPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -65,29 +63,19 @@ export class FlowInstPage extends WhFlowSharedPage { ...@@ -65,29 +63,19 @@ export class FlowInstPage extends WhFlowSharedPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) { .evaluate((el) => {
candidates.push(loc); (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
} })
} .catch(() => undefined);
if (candidates.length === 0) { await this.waitSettle(200);
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); },
} });
let trigger = await findUsableColumnSettingsTrigger(candidates);
if (!trigger) {
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
if (await isColumnSettingsTriggerUsable(loc)) {
trigger = loc;
break;
}
}
}
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
...@@ -122,6 +110,20 @@ export class FlowInstPage extends WhFlowSharedPage { ...@@ -122,6 +110,20 @@ export class FlowInstPage extends WhFlowSharedPage {
return name; return name;
} }
} }
await this.openColumnSettings();
const wrappers = this.columnSettingsPanel().locator('.ant-checkbox-wrapper');
const count = await wrappers.count();
const core = /^(序号|序号列|操作|查看|全选|字段设置|列展示|列设置|行高|分散|中等|紧凑|紧簇|显示|表格设置|重置)$/;
for (let i = 0; i < count; i += 1) {
const raw = ((await wrappers.nth(i).innerText()) ?? '').replace(/\s+/g, '').trim();
if (!raw || core.test(raw)) continue;
const checkbox = wrappers.nth(i).locator('input[type="checkbox"]').first();
if (!(await checkbox.isChecked().catch(() => false))) continue;
await this.closeColumnSettingsPanel();
return raw;
}
await this.closeColumnSettingsPanel();
await this.skipWhenDataInsufficient('列设置中无可 toggle 的已勾选列');
return flowData.columnSettingsToggleCandidates[0]; return flowData.columnSettingsToggleCandidates[0];
} }
......
import { test, type Locator } from '@playwright/test'; import { test, type FrameLocator, type Locator, type Page } from '@playwright/test';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../../locators/spd/center-report-shared.locator';
import type { TableScrollLayoutControls } from './table-scroll-layout.helper'; import type { TableScrollLayoutControls } from './table-scroll-layout.helper';
/** ProTable 列设置浮层文案(各环境可能是字段设置/列展示/列设置)。 */
export const COLUMN_SETTINGS_PANEL_TEXT_RE = /字段设置|列展示|列设置/;
export type ColumnSettingsRoot = Page | FrameLocator | Locator;
/** 统一列设置面板 Locator,避免各页漏写「列设置」。 */
export function columnSettingsPanelLocator(root: ColumnSettingsRoot): Locator {
return root
.locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: COLUMN_SETTINGS_PANEL_TEXT_RE })
.first();
}
/**
* 收集列设置齿轮候选:优先 ProTable 工具栏,再收内容区(y>minY),排除顶栏壳页 setting。
*/
export async function collectColumnSettingsTriggerCandidates(options: {
root: ColumnSettingsRoot;
tableWrapper?: Locator;
triggerCss?: string;
minY?: number;
}): Promise<Locator[]> {
const triggerCss = options.triggerCss ?? COLUMN_SETTINGS_TRIGGER_CSS;
const minY = options.minY ?? 120;
const { root, tableWrapper } = options;
const candidates: Locator[] = [];
const toolbar = root.locator('.ant-pro-table-list-toolbar').first();
const toolbarItem = toolbar.locator(`.ant-pro-table-list-toolbar-setting-item, ${triggerCss}`);
const toolbarCount = await toolbarItem.count().catch(() => 0);
for (let i = 0; i < toolbarCount; i += 1) {
candidates.push(toolbarItem.nth(i));
}
const settings = root.locator(triggerCss);
const count = await settings.count();
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
const box = await loc.boundingBox().catch(() => null);
if (box && box.y > minY) {
candidates.push(loc);
}
}
if (candidates.length === 0 && tableWrapper) {
candidates.push(tableWrapper.locator(triggerCss).first());
}
if (candidates.length === 0) {
for (let i = 0; i < count; i += 1) {
candidates.push(settings.nth(i));
}
}
return candidates;
}
/** 解析可用列设置齿轮:候选收集 → chrome 过滤 → 必要时横滚重试。 */
export async function resolveUsableColumnSettingsTrigger(options: {
root: ColumnSettingsRoot;
tableWrapper?: Locator;
triggerCss?: string;
afterScroll?: () => Promise<void>;
}): Promise<Locator | undefined> {
let candidates = await collectColumnSettingsTriggerCandidates(options);
let trigger = await findUsableColumnSettingsTrigger(candidates);
if (!trigger && options.afterScroll) {
await options.afterScroll();
candidates = await collectColumnSettingsTriggerCandidates(options);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) {
const settings = options.root.locator(options.triggerCss ?? COLUMN_SETTINGS_TRIGGER_CSS);
const fallback: Locator[] = [];
const count = await settings.count();
for (let i = 0; i < count; i += 1) {
fallback.push(settings.nth(i));
}
trigger = await findUsableColumnSettingsTrigger(fallback);
}
return trigger;
}
/** 列设置齿轮是否可点击(可见或已有盒模型,宽表下常被 overflow 裁切)。 */ /** 列设置齿轮是否可点击(可见或已有盒模型,宽表下常被 overflow 裁切)。 */
export async function isColumnSettingsTriggerUsable(loc: Locator): Promise<boolean> { export async function isColumnSettingsTriggerUsable(loc: Locator): Promise<boolean> {
if ((await loc.count().catch(() => 0)) === 0) { if ((await loc.count().catch(() => 0)) === 0) {
...@@ -15,16 +97,57 @@ export async function isColumnSettingsTriggerUsable(loc: Locator): Promise<boole ...@@ -15,16 +97,57 @@ export async function isColumnSettingsTriggerUsable(loc: Locator): Promise<boole
return !!(box && box.width > 0 && box.height > 0); return !!(box && box.width > 0 && box.height > 0);
} }
/** 从候选 Locator 中找到第一个可用的列设置齿轮。 */ /**
* SPD 壳顶栏也有 setting 图标;点它不会打开 ProTable「字段设置」面板。
* 排除 header / 主题设置,并优先 list-toolbar 内的齿轮。
*/
export async function isChromeHeaderSettingsTrigger(loc: Locator): Promise<boolean> {
return loc
.evaluate((el) => {
const node = el as HTMLElement;
if (node.closest('.ant-layout-header, .theme-setting, .ant-pro-global-header, .ant-layout-sider')) {
return true;
}
if (node.closest('.ant-pro-table-list-toolbar, .ant-pro-table, .ant-table-wrapper, main')) {
return false;
}
const top = node.getBoundingClientRect().top;
return top >= 0 && top < 96;
})
.catch(() => false);
}
async function isToolbarColumnSettingsTrigger(loc: Locator): Promise<boolean> {
return loc
.evaluate((el) => {
const node = el as HTMLElement;
const cls = (node.className || '').toString().toLowerCase();
if (cls.includes('list-toolbar-setting-item')) return true;
return Boolean(node.closest('.ant-pro-table-list-toolbar-setting-item, .ant-pro-table-list-toolbar'));
})
.catch(() => false);
}
/** 从候选 Locator 中找到第一个可用的列设置齿轮(跳过壳页顶栏 setting)。 */
export async function findUsableColumnSettingsTrigger( export async function findUsableColumnSettingsTrigger(
candidates: readonly Locator[], candidates: readonly Locator[],
): Promise<Locator | undefined> { ): Promise<Locator | undefined> {
const usable: Locator[] = [];
for (const loc of candidates) { for (const loc of candidates) {
if (await isColumnSettingsTriggerUsable(loc)) { const first = loc.first();
return loc.first(); if (await isChromeHeaderSettingsTrigger(first)) {
continue;
}
if (await isColumnSettingsTriggerUsable(first)) {
usable.push(first);
}
}
for (const loc of usable) {
if (await isToolbarColumnSettingsTrigger(loc)) {
return loc;
} }
} }
return undefined; return usable[0];
} }
export type RevealColumnSettingsTriggerOptions = { export type RevealColumnSettingsTriggerOptions = {
......
import { expect, test, type FrameLocator, type Locator, type Page } from '@playwright/test'; import { expect, test, type FrameLocator, type Locator, type Page } from '@playwright/test';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../../locators/spd/center-report-shared.locator';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
columnSettingsPanelLocator,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './column-settings.helper'; } from './column-settings.helper';
import { expectColumnSortByDom } from './column-sort.helper'; import { expectColumnSortByDom } from './column-sort.helper';
...@@ -37,11 +36,7 @@ export class SpdProTableListControls { ...@@ -37,11 +36,7 @@ export class SpdProTableListControls {
} }
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.deps return columnSettingsPanelLocator(this.deps.listScope());
.listScope()
.locator('.ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ })
.first();
} }
columnSettingsCheckboxRow(label: string): Locator { columnSettingsCheckboxRow(label: string): Locator {
...@@ -60,36 +55,19 @@ export class SpdProTableListControls { ...@@ -60,36 +55,19 @@ export class SpdProTableListControls {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const scope = this.deps.listScope(); const trigger = await resolveUsableColumnSettingsTrigger({
const settings = scope.locator(COLUMN_SETTINGS_TRIGGER_CSS); root: this.deps.listScope(),
const candidates: Locator[] = []; tableWrapper: this.tableWrapper(),
const count = await settings.count(); afterScroll: async () => {
for (let i = 0; i < count; i += 1) { await this.tableWrapper().scrollIntoViewIfNeeded().catch(() => undefined);
candidates.push(settings.nth(i)); const body = this.tableWrapper().locator('.ant-table-body').first();
} await body
if (candidates.length === 0) { .evaluate((el) => {
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
} })
let trigger = await findUsableColumnSettingsTrigger(candidates); .catch(() => undefined);
if (!trigger) { },
await this.tableWrapper().scrollIntoViewIfNeeded().catch(() => undefined); });
const body = this.tableWrapper().locator('.ant-table-body').first();
await body
.evaluate((el) => {
(el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
})
.catch(() => undefined);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) {
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
if (await isColumnSettingsTriggerUsable(loc)) {
trigger = loc;
break;
}
}
}
if (!trigger) { if (!trigger) {
await this.deps.skipWhen('列设置齿轮不可见'); await this.deps.skipWhen('列设置齿轮不可见');
} }
...@@ -119,6 +97,22 @@ export class SpdProTableListControls { ...@@ -119,6 +97,22 @@ export class SpdProTableListControls {
if (this.deps.columnSettingsToggleCandidates.length === 0) { if (this.deps.columnSettingsToggleCandidates.length === 0) {
await this.deps.skipWhen('未配置 columnSettingsToggleCandidates'); await this.deps.skipWhen('未配置 columnSettingsToggleCandidates');
} }
// 候选列当前未展示:打开列设置,挑一个已勾选且非核心列
await this.openColumnSettings();
const wrappers = this.columnSettingsPanel().locator('.ant-checkbox-wrapper');
const count = await wrappers.count();
const core = /^(序号|序号列|操作|查看|全选|字段设置|列展示|列设置|行高|分散|中等|紧凑|紧簇|显示|表格设置|重置)$/;
for (let i = 0; i < count; i += 1) {
const raw = ((await wrappers.nth(i).innerText()) ?? '').replace(/\s+/g, '').trim();
if (!raw || core.test(raw)) continue;
const checkbox = wrappers.nth(i).locator('input[type="checkbox"]').first();
if (!(await checkbox.isChecked().catch(() => false))) continue;
await this.closeColumnSettingsPanel();
return raw;
}
await this.closeColumnSettingsPanel();
await this.deps.skipWhen('列设置中无可 toggle 的已勾选列');
return this.deps.columnSettingsToggleCandidates[0]!; return this.deps.columnSettingsToggleCandidates[0]!;
} }
......
...@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorAuthFinalData } from '../../data/vendor-auth-final.data'; import { vendorAuthFinalData } from '../../data/vendor-auth-final.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page'; import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
export class VendorAuthFinalPage extends VendorAuditPage { export class VendorAuthFinalPage extends VendorAuditPage {
...@@ -44,8 +43,8 @@ export class VendorAuthFinalPage extends VendorAuditPage { ...@@ -44,8 +43,8 @@ export class VendorAuthFinalPage extends VendorAuditPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -145,18 +144,18 @@ export class VendorAuthFinalPage extends VendorAuditPage { ...@@ -145,18 +144,18 @@ export class VendorAuthFinalPage extends VendorAuditPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) candidates.push(loc); .evaluate((el) => {
} (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
if (candidates.length === 0) { })
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); .catch(() => undefined);
} },
let trigger = await findUsableColumnSettingsTrigger(candidates); });
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -3,13 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -3,13 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorAuthFirstData } from '../../data/vendor-auth-first.data'; import { vendorAuthFirstData } from '../../data/vendor-auth-first.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page'; import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
/** 授权变更初审。 */ /** 授权变更初审。 */
...@@ -42,8 +40,8 @@ export class VendorAuthFirstPage extends VendorAuditPage { ...@@ -42,8 +40,8 @@ export class VendorAuthFirstPage extends VendorAuditPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -165,18 +163,18 @@ export class VendorAuthFirstPage extends VendorAuditPage { ...@@ -165,18 +163,18 @@ export class VendorAuthFirstPage extends VendorAuditPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) candidates.push(loc); .evaluate((el) => {
} (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
if (candidates.length === 0) { })
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); .catch(() => undefined);
} },
let trigger = await findUsableColumnSettingsTrigger(candidates); });
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -4,12 +4,11 @@ import { type FilterScope } from '../../core/base.page'; ...@@ -4,12 +4,11 @@ import { type FilterScope } from '../../core/base.page';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorCertDiffData } from '../../data/vendor-cert-diff.data'; import { vendorCertDiffData } from '../../data/vendor-cert-diff.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page'; import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
import { skipIfInsufficientForPage2 } from './helpers/pagination-page2.helper'; import { skipIfInsufficientForPage2 } from './helpers/pagination-page2.helper';
...@@ -147,8 +146,8 @@ export class VendorCertDiffPage extends VendorAuditPage { ...@@ -147,8 +146,8 @@ export class VendorCertDiffPage extends VendorAuditPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -287,18 +286,19 @@ export class VendorCertDiffPage extends VendorAuditPage { ...@@ -287,18 +286,19 @@ export class VendorCertDiffPage extends VendorAuditPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.filterScope().locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.filterScope(),
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) candidates.push(loc); .evaluate((el) => {
} (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
if (candidates.length === 0) { })
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); .catch(() => undefined);
} await this.waitSettle(200);
let trigger = await findUsableColumnSettingsTrigger(candidates); },
});
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorCertFinalData } from '../../data/vendor-cert-final.data'; import { vendorCertFinalData } from '../../data/vendor-cert-final.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page'; import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
/** 注册证变更终审。 */ /** 注册证变更终审。 */
...@@ -41,8 +40,8 @@ export class VendorCertFinalPage extends VendorAuditPage { ...@@ -41,8 +40,8 @@ export class VendorCertFinalPage extends VendorAuditPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -151,18 +150,18 @@ export class VendorCertFinalPage extends VendorAuditPage { ...@@ -151,18 +150,18 @@ export class VendorCertFinalPage extends VendorAuditPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) candidates.push(loc); .evaluate((el) => {
} (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
if (candidates.length === 0) { })
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); .catch(() => undefined);
} },
let trigger = await findUsableColumnSettingsTrigger(candidates); });
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorCertFirstData } from '../../data/vendor-cert-first.data'; import { vendorCertFirstData } from '../../data/vendor-cert-first.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page'; import { VendorAuditPage, type VendorAuthOpenOptions } from './vendor-audit.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
/** 注册证变更初审。 */ /** 注册证变更初审。 */
...@@ -41,8 +40,8 @@ export class VendorCertFirstPage extends VendorAuditPage { ...@@ -41,8 +40,8 @@ export class VendorCertFirstPage extends VendorAuditPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -151,18 +150,18 @@ export class VendorCertFirstPage extends VendorAuditPage { ...@@ -151,18 +150,18 @@ export class VendorCertFirstPage extends VendorAuditPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) candidates.push(loc); .evaluate((el) => {
} (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
if (candidates.length === 0) { })
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); .catch(() => undefined);
} },
let trigger = await findUsableColumnSettingsTrigger(candidates); });
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -2,13 +2,11 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -2,13 +2,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { vendorEvalIndicatorData } from '../../data/vendor-eval-indicator.data'; import { vendorEvalIndicatorData } from '../../data/vendor-eval-indicator.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorSharedPage } from './vendor-shared.page'; import { VendorSharedPage } from './vendor-shared.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
import { expectColumnSortByDom, hasDomSortableColumn } from './helpers/column-sort.helper'; import { expectColumnSortByDom, hasDomSortableColumn } from './helpers/column-sort.helper';
...@@ -42,8 +40,8 @@ export class VendorEvalIndicatorPage extends VendorSharedPage { ...@@ -42,8 +40,8 @@ export class VendorEvalIndicatorPage extends VendorSharedPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -86,39 +84,19 @@ export class VendorEvalIndicatorPage extends VendorSharedPage { ...@@ -86,39 +84,19 @@ export class VendorEvalIndicatorPage extends VendorSharedPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) { .evaluate((el) => {
candidates.push(loc); (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
} })
} .catch(() => undefined);
if (candidates.length === 0) { await this.waitSettle(200);
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); },
} });
let trigger = await findUsableColumnSettingsTrigger(candidates);
if (!trigger) {
const body = this.tableWrapper().locator('.ant-table-body').first();
await body
.evaluate((el) => {
(el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
})
.catch(() => undefined);
await this.waitSettle(200);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) {
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
if (await isColumnSettingsTriggerUsable(loc)) {
trigger = loc;
break;
}
}
}
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -3,13 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -3,13 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorEvalSchemeExpandedFilterLabels } from '../../data/vendor-eval-scheme.data'; import { vendorEvalSchemeExpandedFilterLabels } from '../../data/vendor-eval-scheme.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorSharedPage } from './vendor-shared.page'; import { VendorSharedPage } from './vendor-shared.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
import { expectColumnSortByDom, hasDomSortableColumn } from './helpers/column-sort.helper'; import { expectColumnSortByDom, hasDomSortableColumn } from './helpers/column-sort.helper';
...@@ -39,8 +37,8 @@ export class VendorEvalSchemePage extends VendorSharedPage { ...@@ -39,8 +37,8 @@ export class VendorEvalSchemePage extends VendorSharedPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -56,39 +54,19 @@ export class VendorEvalSchemePage extends VendorSharedPage { ...@@ -56,39 +54,19 @@ export class VendorEvalSchemePage extends VendorSharedPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) { .evaluate((el) => {
candidates.push(loc); (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
} })
} .catch(() => undefined);
if (candidates.length === 0) { await this.waitSettle(200);
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); },
} });
let trigger = await findUsableColumnSettingsTrigger(candidates);
if (!trigger) {
const body = this.tableWrapper().locator('.ant-table-body').first();
await body
.evaluate((el) => {
(el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
})
.catch(() => undefined);
await this.waitSettle(200);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) {
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
if (await isColumnSettingsTriggerUsable(loc)) {
trigger = loc;
break;
}
}
}
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -10,13 +10,11 @@ import { ...@@ -10,13 +10,11 @@ import {
} from '../../data/vendor-qual-tab-cases'; } from '../../data/vendor-qual-tab-cases';
import { subTabsForMainTab } from '../../data/vendor-qual-subtabs.data'; import { subTabsForMainTab } from '../../data/vendor-qual-subtabs.data';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import { VendorSharedPage } from './vendor-shared.page'; import { VendorSharedPage } from './vendor-shared.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
import { executeExportReport } from './helpers/export-report.helper'; import { executeExportReport } from './helpers/export-report.helper';
...@@ -62,8 +60,8 @@ export class VendorQualPage extends VendorSharedPage { ...@@ -62,8 +60,8 @@ export class VendorQualPage extends VendorSharedPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -719,39 +717,19 @@ export class VendorQualPage extends VendorSharedPage { ...@@ -719,39 +717,19 @@ export class VendorQualPage extends VendorSharedPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); const trigger = await resolveUsableColumnSettingsTrigger({
const candidates: Locator[] = []; root: this.page,
const count = await settings.count(); tableWrapper: this.tableWrapper(),
for (let i = 0; i < count; i += 1) { afterScroll: async () => {
const loc = settings.nth(i); const body = this.tableWrapper().locator('.ant-table-body').first();
const box = await loc.boundingBox().catch(() => null); await body
if (box && box.y > 120) { .evaluate((el) => {
candidates.push(loc); (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
} })
} .catch(() => undefined);
if (candidates.length === 0) { await this.waitSettle(200);
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); },
} });
let trigger = await findUsableColumnSettingsTrigger(candidates);
if (!trigger) {
const body = this.tableWrapper().locator('.ant-table-body').first();
await body
.evaluate((el) => {
(el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
})
.catch(() => undefined);
await this.waitSettle(200);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) {
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
if (await isColumnSettingsTriggerUsable(loc)) {
trigger = loc;
break;
}
}
}
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
......
...@@ -2,14 +2,12 @@ import { expect, type Locator, type Page } from '@playwright/test'; ...@@ -2,14 +2,12 @@ import { expect, type Locator, type Page } from '@playwright/test';
import { normalizeSampleCellValue } from '../../core/table-data-column.util'; import { normalizeSampleCellValue } from '../../core/table-data-column.util';
import { vendorData } from '../../data/vendor.data'; import { vendorData } from '../../data/vendor.data';
import { COLUMN_SETTINGS_TRIGGER_CSS } from '../../locators/spd/center-report-shared.locator';
import type { VendorQualPage } from './vendor-qual.page'; import type { VendorQualPage } from './vendor-qual.page';
import { VendorSharedPage } from './vendor-shared.page'; import { VendorSharedPage } from './vendor-shared.page';
import { import {
ColumnSettingsControls, ColumnSettingsControls,
executeColumnSettingsToggleRestore, executeColumnSettingsToggleRestore,
findUsableColumnSettingsTrigger, resolveUsableColumnSettingsTrigger,
isColumnSettingsTriggerUsable,
} from './helpers/column-settings.helper'; } from './helpers/column-settings.helper';
/** 厂商查询:动作与取数;断言在 tests/spd/vendor-query.spec.ts。 */ /** 厂商查询:动作与取数;断言在 tests/spd/vendor-query.spec.ts。 */
...@@ -38,8 +36,8 @@ export class VendorQueryPage extends VendorSharedPage { ...@@ -38,8 +36,8 @@ export class VendorQueryPage extends VendorSharedPage {
columnSettingsPanel(): Locator { columnSettingsPanel(): Locator {
return this.page return this.page
.locator('.ant-popover:visible, .ant-dropdown:visible') .locator('.ant-popover.cloumn-list:visible, .ant-popover:visible, .ant-dropdown:visible')
.filter({ hasText: /字段设置|列展示/ }) .filter({ hasText: /字段设置|列展示|列设置/ })
.first(); .first();
} }
...@@ -55,40 +53,19 @@ export class VendorQueryPage extends VendorSharedPage { ...@@ -55,40 +53,19 @@ export class VendorQueryPage extends VendorSharedPage {
} }
async resolveColumnSettingsTrigger(): Promise<Locator> { async resolveColumnSettingsTrigger(): Promise<Locator> {
// column-height 为表格密度(分散/中等/紧凑),非列设置;列设置为 anticon-setting(列表工具栏)。 const trigger = await resolveUsableColumnSettingsTrigger({
const settings = this.page.locator(COLUMN_SETTINGS_TRIGGER_CSS); root: this.page,
const candidates: Locator[] = []; tableWrapper: this.tableWrapper(),
const count = await settings.count(); afterScroll: async () => {
for (let i = 0; i < count; i += 1) { const body = this.tableWrapper().locator('.ant-table-body').first();
const loc = settings.nth(i); await body
const box = await loc.boundingBox().catch(() => null); .evaluate((el) => {
if (box && box.y > 120) { (el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
candidates.push(loc); })
} .catch(() => undefined);
} await this.waitSettle(200);
if (candidates.length === 0) { },
candidates.push(this.tableWrapper().locator(COLUMN_SETTINGS_TRIGGER_CSS).first()); });
}
let trigger = await findUsableColumnSettingsTrigger(candidates);
if (!trigger) {
const body = this.tableWrapper().locator('.ant-table-body').first();
await body
.evaluate((el) => {
(el as HTMLElement).scrollLeft = (el as HTMLElement).scrollWidth;
})
.catch(() => undefined);
await this.waitSettle(200);
trigger = await findUsableColumnSettingsTrigger(candidates);
}
if (!trigger) {
for (let i = 0; i < count; i += 1) {
const loc = settings.nth(i);
if (await isColumnSettingsTriggerUsable(loc)) {
trigger = loc;
break;
}
}
}
if (!trigger) { if (!trigger) {
await this.skipWhenDataInsufficient('列设置齿轮不可见'); await this.skipWhenDataInsufficient('列设置齿轮不可见');
} }
...@@ -123,6 +100,20 @@ export class VendorQueryPage extends VendorSharedPage { ...@@ -123,6 +100,20 @@ export class VendorQueryPage extends VendorSharedPage {
return name; return name;
} }
} }
await this.openColumnSettings();
const wrappers = this.columnSettingsPanel().locator('.ant-checkbox-wrapper');
const count = await wrappers.count();
const core = /^(序号|序号列|操作|查看|全选|字段设置|列展示|列设置|行高|分散|中等|紧凑|紧簇|显示|表格设置|重置)$/;
for (let i = 0; i < count; i += 1) {
const raw = ((await wrappers.nth(i).innerText()) ?? '').replace(/\s+/g, '').trim();
if (!raw || core.test(raw)) continue;
const checkbox = wrappers.nth(i).locator('input[type="checkbox"]').first();
if (!(await checkbox.isChecked().catch(() => false))) continue;
await this.closeColumnSettingsPanel();
return raw;
}
await this.closeColumnSettingsPanel();
await this.skipWhenDataInsufficient('列设置中无可 toggle 的已勾选列');
return vendorData.columnSettingsToggleCandidates[0]; return vendorData.columnSettingsToggleCandidates[0];
} }
......
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