Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
test
autotest-playwright-web-spd
Commits
297e887d
Commit
297e887d
authored
Nov 04, 2026
by
liguangyu06
Browse files
修复基础管理列设置误点顶栏齿轮,统一触发器解析与面板定位。
parent
d14afcfe
Changes
17
Hide whitespace changes
Inline
Side-by-side
data/basic-hospital.data.ts
View file @
297e887d
...
...
@@ -22,9 +22,10 @@ export const basicHospitalData = {
mockOutOfRangeDate
:
'
1999-01-01
'
,
writeDisabledReason
:
'
环境禁止写:SKIP_BASIC_WRITE=1
'
,
paginationPageSizeTo
:
'
20 条/页
'
,
noticeColumnSettingsToggleCandidates
:
[
'
发布科室
'
]
as
const
,
branchColumnSettingsToggleCandidates
:
[
'
院区简称
'
]
as
const
,
financeColumnSettingsToggleCandidates
:
[
'
备注
'
]
as
const
,
noticeColumnSettingsToggleCandidates
:
[
'
发布科室
'
,
'
发布人
'
,
'
是否置顶
'
]
as
const
,
// 与列表实际表头对齐(环境未必有「院区简称」「备注」勾选项)
branchColumnSettingsToggleCandidates
:
[
'
院区地址
'
,
'
院区编号
'
,
'
状态
'
]
as
const
,
financeColumnSettingsToggleCandidates
:
[
'
自动结算日期
'
,
'
开始日期
'
,
'
结束日期
'
]
as
const
,
}
as
const
;
export
function
isBasicWriteAllowed
():
boolean
{
...
...
locators/spd/basic-user-shared.locator.ts
View file @
297e887d
...
...
@@ -60,9 +60,10 @@ export class BasicUserSharedLocators {
}
columnSettingsPanel
():
Locator
{
// 与 pages/spd/helpers/column-settings.helper.ts 的 COLUMN_SETTINGS_PANEL_TEXT_RE 保持一致
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
'
字段设置
'
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/
字段设置
|列展示|列设置/
})
.
first
();
}
...
...
locators/spd/center-report-entry.locator.ts
View file @
297e887d
...
...
@@ -133,8 +133,8 @@ export class CenterReportEntryLocators {
columnSettingsPanel
():
Locator
{
return
this
.
report
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
'
字段设置
'
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/
字段设置
|列展示|列设置/
})
.
first
();
}
...
...
locators/spd/center-report-sheet.locator.ts
View file @
297e887d
...
...
@@ -133,8 +133,8 @@ export class CenterReportSheetLocators {
/** 列设置弹出面板(含「列展示」「字段设置」)。 */
columnSettingsPanel
():
Locator
{
return
this
.
report
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
'
字段设置
'
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/
字段设置
|列展示|列设置/
})
.
first
();
}
...
...
pages/spd/basic-user.page.ts
View file @
297e887d
import
{
expect
,
type
Locator
,
type
Page
}
from
'
@playwright/test
'
;
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
{
BasicUserSharedPage
,
type
UserMeta
}
from
'
./basic-user-shared.page
'
;
import
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
find
UsableColumnSettingsTrigger
,
resolve
UsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
export
type
UserSample
=
{
...
...
@@ -295,27 +294,20 @@ export class BasicUserPage extends BasicUserSharedPage {
}
private
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
triggers
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
triggerCount
=
await
triggers
.
count
();
const
candidates
:
Locator
[]
=
[];
for
(
let
i
=
0
;
i
<
Math
.
min
(
triggerCount
,
4
);
i
+=
1
)
{
candidates
.
push
(
triggers
.
nth
(
i
));
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
locators
.
columnSettingsTrigger
);
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
if
(
!
trigger
)
{
await
this
.
locators
.
tableWrapper
.
scrollIntoViewIfNeeded
().
catch
(()
=>
undefined
);
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
);
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
locators
.
tableWrapper
,
afterScroll
:
async
()
=>
{
await
this
.
locators
.
tableWrapper
.
scrollIntoViewIfNeeded
().
catch
(()
=>
undefined
);
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
@@ -350,6 +342,20 @@ export class BasicUserPage extends BasicUserSharedPage {
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
];
}
...
...
pages/spd/flow-inst.page.ts
View file @
297e887d
import
{
expect
,
type
Locator
,
type
Page
}
from
'
@playwright/test
'
;
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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
import
{
WhFlowSharedPage
}
from
'
./wh-flow-shared.page
'
;
...
...
@@ -48,8 +46,8 @@ export class FlowInstPage extends WhFlowSharedPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -65,29 +63,19 @@ export class FlowInstPage extends WhFlowSharedPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
{
candidates
.
push
(
loc
);
}
}
if
(
candidates
.
length
===
0
)
{
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
;
}
}
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
@@ -122,6 +110,20 @@ export class FlowInstPage extends WhFlowSharedPage {
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
];
}
...
...
pages/spd/helpers/column-settings.helper.ts
View file @
297e887d
import
{
test
,
type
Locator
}
from
'
@playwright/test
'
;
import
{
test
,
type
Frame
Locator
,
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
'
;
/** 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 裁切)。 */
export
async
function
isColumnSettingsTriggerUsable
(
loc
:
Locator
):
Promise
<
boolean
>
{
if
((
await
loc
.
count
().
catch
(()
=>
0
))
===
0
)
{
...
...
@@ -15,16 +97,57 @@ export async function isColumnSettingsTriggerUsable(loc: Locator): Promise<boole
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
(
candidates
:
readonly
Locator
[],
):
Promise
<
Locator
|
undefined
>
{
const
usable
:
Locator
[]
=
[];
for
(
const
loc
of
candidates
)
{
if
(
await
isColumnSettingsTriggerUsable
(
loc
))
{
return
loc
.
first
();
const
first
=
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
u
ndefined
;
return
u
sable
[
0
]
;
}
export
type
RevealColumnSettingsTriggerOptions
=
{
...
...
pages/spd/helpers/spd-protable-list.controls.ts
View file @
297e887d
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
{
ColumnSettingsControls
,
columnSettingsPanelLocator
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./column-settings.helper
'
;
import
{
expectColumnSortByDom
}
from
'
./column-sort.helper
'
;
...
...
@@ -37,11 +36,7 @@ export class SpdProTableListControls {
}
columnSettingsPanel
():
Locator
{
return
this
.
deps
.
listScope
()
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
first
();
return
columnSettingsPanelLocator
(
this
.
deps
.
listScope
());
}
columnSettingsCheckboxRow
(
label
:
string
):
Locator
{
...
...
@@ -60,36 +55,19 @@ export class SpdProTableListControls {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
scope
=
this
.
deps
.
listScope
();
const
settings
=
scope
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
const
count
=
await
settings
.
count
();
for
(
let
i
=
0
;
i
<
count
;
i
+=
1
)
{
candidates
.
push
(
settings
.
nth
(
i
));
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
tableWrapper
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
).
first
());
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
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
;
}
}
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
deps
.
listScope
(),
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
deps
.
skipWhen
(
'
列设置齿轮不可见
'
);
}
...
...
@@ -119,6 +97,22 @@ export class SpdProTableListControls {
if
(
this
.
deps
.
columnSettingsToggleCandidates
.
length
===
0
)
{
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
]
!
;
}
...
...
pages/spd/vendor-auth-final.page.ts
View file @
297e887d
...
...
@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
import
{
vendorAuthFinalData
}
from
'
../../data/vendor-auth-final.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
find
UsableColumnSettingsTrigger
,
resolve
UsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
export
class
VendorAuthFinalPage
extends
VendorAuditPage
{
...
...
@@ -44,8 +43,8 @@ export class VendorAuthFinalPage extends VendorAuditPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -145,18 +144,18 @@ export class VendorAuthFinalPage extends VendorAuditPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
candidates
.
push
(
loc
);
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
tableWrapper
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
).
first
()
);
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
()
,
afterScroll
:
async
()
=>
{
const
body
=
this
.
tableWrapper
().
locator
(
'
.ant-table-body
'
).
first
(
);
await
body
.
evaluate
((
el
)
=>
{
(
el
as
HTMLElement
).
scrollLeft
=
(
el
as
HTMLElement
).
scrollWidth
;
})
.
catch
(()
=>
undefined
);
},
}
);
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-auth-first.page.ts
View file @
297e887d
...
...
@@ -3,13 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
import
{
vendorAuthFirstData
}
from
'
../../data/vendor-auth-first.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
/** 授权变更初审。 */
...
...
@@ -42,8 +40,8 @@ export class VendorAuthFirstPage extends VendorAuditPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -165,18 +163,18 @@ export class VendorAuthFirstPage extends VendorAuditPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
candidates
.
push
(
loc
);
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
tableWrapper
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
).
first
()
);
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
()
,
afterScroll
:
async
()
=>
{
const
body
=
this
.
tableWrapper
().
locator
(
'
.ant-table-body
'
).
first
(
);
await
body
.
evaluate
((
el
)
=>
{
(
el
as
HTMLElement
).
scrollLeft
=
(
el
as
HTMLElement
).
scrollWidth
;
})
.
catch
(()
=>
undefined
);
},
}
);
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-cert-diff.page.ts
View file @
297e887d
...
...
@@ -4,12 +4,11 @@ import { type FilterScope } from '../../core/base.page';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
import
{
vendorCertDiffData
}
from
'
../../data/vendor-cert-diff.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
find
UsableColumnSettingsTrigger
,
resolve
UsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
import
{
skipIfInsufficientForPage2
}
from
'
./helpers/pagination-page2.helper
'
;
...
...
@@ -147,8 +146,8 @@ export class VendorCertDiffPage extends VendorAuditPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -287,18 +286,19 @@ export class VendorCertDiffPage extends VendorAuditPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
filterScope
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
candidates
.
push
(
loc
);
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
tableWrapper
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
).
first
());
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
filterScope
(),
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-cert-final.page.ts
View file @
297e887d
...
...
@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
import
{
vendorCertFinalData
}
from
'
../../data/vendor-cert-final.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
find
UsableColumnSettingsTrigger
,
resolve
UsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
/** 注册证变更终审。 */
...
...
@@ -41,8 +40,8 @@ export class VendorCertFinalPage extends VendorAuditPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -151,18 +150,18 @@ export class VendorCertFinalPage extends VendorAuditPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
candidates
.
push
(
loc
);
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
tableWrapper
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
).
first
()
);
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
()
,
afterScroll
:
async
()
=>
{
const
body
=
this
.
tableWrapper
().
locator
(
'
.ant-table-body
'
).
first
(
);
await
body
.
evaluate
((
el
)
=>
{
(
el
as
HTMLElement
).
scrollLeft
=
(
el
as
HTMLElement
).
scrollWidth
;
})
.
catch
(()
=>
undefined
);
},
}
);
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-cert-first.page.ts
View file @
297e887d
...
...
@@ -3,12 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
import
{
vendorCertFirstData
}
from
'
../../data/vendor-cert-first.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
find
UsableColumnSettingsTrigger
,
resolve
UsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
/** 注册证变更初审。 */
...
...
@@ -41,8 +40,8 @@ export class VendorCertFirstPage extends VendorAuditPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -151,18 +150,18 @@ export class VendorCertFirstPage extends VendorAuditPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
candidates
.
push
(
loc
);
}
if
(
candidates
.
length
===
0
)
{
candidates
.
push
(
this
.
tableWrapper
().
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
).
first
()
);
}
let
trigger
=
await
findUsableColumnSettingsTrigger
(
candidates
);
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
()
,
afterScroll
:
async
()
=>
{
const
body
=
this
.
tableWrapper
().
locator
(
'
.ant-table-body
'
).
first
(
);
await
body
.
evaluate
((
el
)
=>
{
(
el
as
HTMLElement
).
scrollLeft
=
(
el
as
HTMLElement
).
scrollWidth
;
})
.
catch
(()
=>
undefined
);
},
}
);
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-eval-indicator.page.ts
View file @
297e887d
...
...
@@ -2,13 +2,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
vendorEvalIndicatorData
}
from
'
../../data/vendor-eval-indicator.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
import
{
expectColumnSortByDom
,
hasDomSortableColumn
}
from
'
./helpers/column-sort.helper
'
;
...
...
@@ -42,8 +40,8 @@ export class VendorEvalIndicatorPage extends VendorSharedPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -86,39 +84,19 @@ export class VendorEvalIndicatorPage extends VendorSharedPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
{
candidates
.
push
(
loc
);
}
}
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
;
}
}
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-eval-scheme.page.ts
View file @
297e887d
...
...
@@ -3,13 +3,11 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
import
{
vendorEvalSchemeExpandedFilterLabels
}
from
'
../../data/vendor-eval-scheme.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
import
{
expectColumnSortByDom
,
hasDomSortableColumn
}
from
'
./helpers/column-sort.helper
'
;
...
...
@@ -39,8 +37,8 @@ export class VendorEvalSchemePage extends VendorSharedPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -56,39 +54,19 @@ export class VendorEvalSchemePage extends VendorSharedPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
{
candidates
.
push
(
loc
);
}
}
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
;
}
}
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-qual.page.ts
View file @
297e887d
...
...
@@ -10,13 +10,11 @@ import {
}
from
'
../../data/vendor-qual-tab-cases
'
;
import
{
subTabsForMainTab
}
from
'
../../data/vendor-qual-subtabs.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
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
import
{
executeExportReport
}
from
'
./helpers/export-report.helper
'
;
...
...
@@ -62,8 +60,8 @@ export class VendorQualPage extends VendorSharedPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -719,39 +717,19 @@ export class VendorQualPage extends VendorSharedPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
{
candidates
.
push
(
loc
);
}
}
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
;
}
}
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
pages/spd/vendor-query.page.ts
View file @
297e887d
...
...
@@ -2,14 +2,12 @@ import { expect, type Locator, type Page } from '@playwright/test';
import
{
normalizeSampleCellValue
}
from
'
../../core/table-data-column.util
'
;
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
{
VendorSharedPage
}
from
'
./vendor-shared.page
'
;
import
{
ColumnSettingsControls
,
executeColumnSettingsToggleRestore
,
findUsableColumnSettingsTrigger
,
isColumnSettingsTriggerUsable
,
resolveUsableColumnSettingsTrigger
,
}
from
'
./helpers/column-settings.helper
'
;
/** 厂商查询:动作与取数;断言在 tests/spd/vendor-query.spec.ts。 */
...
...
@@ -38,8 +36,8 @@ export class VendorQueryPage extends VendorSharedPage {
columnSettingsPanel
():
Locator
{
return
this
.
page
.
locator
(
'
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示/
})
.
locator
(
'
.ant-popover.cloumn-list:visible,
.ant-popover:visible, .ant-dropdown:visible
'
)
.
filter
({
hasText
:
/字段设置|列展示
|列设置
/
})
.
first
();
}
...
...
@@ -55,40 +53,19 @@ export class VendorQueryPage extends VendorSharedPage {
}
async
resolveColumnSettingsTrigger
():
Promise
<
Locator
>
{
// column-height 为表格密度(分散/中等/紧凑),非列设置;列设置为 anticon-setting(列表工具栏)。
const
settings
=
this
.
page
.
locator
(
COLUMN_SETTINGS_TRIGGER_CSS
);
const
candidates
:
Locator
[]
=
[];
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
>
120
)
{
candidates
.
push
(
loc
);
}
}
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
;
}
}
}
const
trigger
=
await
resolveUsableColumnSettingsTrigger
({
root
:
this
.
page
,
tableWrapper
:
this
.
tableWrapper
(),
afterScroll
:
async
()
=>
{
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
);
},
});
if
(
!
trigger
)
{
await
this
.
skipWhenDataInsufficient
(
'
列设置齿轮不可见
'
);
}
...
...
@@ -123,6 +100,20 @@ export class VendorQueryPage extends VendorSharedPage {
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
];
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment