Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
0
01SaaS-test
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
吴珊婧
01SaaS-test
Commits
0dc572c3
Commit
0dc572c3
authored
Jul 07, 2026
by
wushanjing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修复手工录单区服选择校验
parent
17a340be
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
123 additions
and
0 deletions
+123
-0
wanzhanggui_order_page.py
e2e/pages/wanzhanggui_order_page.py
+123
-0
No files found.
e2e/pages/wanzhanggui_order_page.py
View file @
0dc572c3
...
...
@@ -4283,6 +4283,7 @@ class WanzhangguiOrderPage(TenantAuthPage):
self
.
select_first_available_if_placeholder
(
frame
,
"区"
)
self
.
select_first_available_if_placeholder
(
frame
,
"服"
)
self
.
select_service_project
(
frame
)
self
.
ensure_game_region_service_selected
(
frame
)
self
.
align_order_type_with_service_project
(
frame
)
self
.
select_sales_customer
(
frame
)
...
...
@@ -4298,6 +4299,7 @@ class WanzhangguiOrderPage(TenantAuthPage):
self
.
fill_input_by_placeholder
(
frame
,
"小时"
,
order
.
service_hours
)
self
.
fill_input_by_placeholder
(
frame
,
"请输入订单内容"
,
order
.
order_title
)
self
.
fill_number_by_placeholder
(
frame
,
"请输入价格"
,
order
.
receive_price
)
self
.
ensure_game_region_service_selected
(
frame
)
self
.
fill_sub_order_row
(
frame
,
order
)
def
fill_required_fields_after_submit_without_dispatch
(
self
,
frame
:
Frame
,
order
:
ManualOrderData
)
->
None
:
...
...
@@ -4306,6 +4308,7 @@ class WanzhangguiOrderPage(TenantAuthPage):
self
.
fill_input_by_placeholder
(
frame
,
"小时"
,
order
.
service_hours
)
self
.
fill_input_by_placeholder
(
frame
,
"请输入订单内容"
,
order
.
order_title
)
self
.
fill_number_by_placeholder
(
frame
,
"请输入价格"
,
order
.
receive_price
)
self
.
ensure_game_region_service_selected
(
frame
)
def
assert_order_in_pending_accept_status
(
self
,
frame
:
Frame
,
order
:
ManualOrderData
)
->
None
:
self
.
search_order_by_best_identity
(
...
...
@@ -5134,6 +5137,126 @@ class WanzhangguiOrderPage(TenantAuthPage):
if
clicked
:
self
.
page
.
wait_for_timeout
(
800
)
def
ensure_game_region_service_selected
(
self
,
frame
:
Frame
)
->
None
:
for
_
in
range
(
3
):
status
=
self
.
manual_order_game_region_service_status
(
frame
)
missing
=
status
.
get
(
"missing"
,
[])
if
not
missing
:
return
for
field
in
missing
:
self
.
select_manual_order_game_region_field
(
frame
,
str
(
field
))
self
.
page
.
wait_for_timeout
(
800
)
status
=
self
.
manual_order_game_region_service_status
(
frame
)
assert
not
status
.
get
(
"missing"
),
(
f
"手工录单游戏/区/服/服务项目选择未生效;status={status}; "
f
"validation_messages={self.modal_validation_messages(frame)}"
)
def
manual_order_game_region_service_status
(
self
,
frame
:
Frame
)
->
dict
:
return
dict
(
frame
.
evaluate
(
"""() => {
const invalid = text => {
const value = String(text || '').replace(/
\\
s+/g, '').trim();
return !value ||
/^
\\
d+$/.test(value) ||
value.includes('请选择') ||
value.includes('游戏') ||
value === '区' ||
value === '服' ||
value.includes('服务项目');
};
const modal = Array.from(document.querySelectorAll('.ant-modal'))
.filter(el => {
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
}).pop();
if (!modal) return { ok: false, missing: ['modal'], reason: 'no visible modal' };
const selectors = Array.from(modal.querySelectorAll('.ant-select-selector'))
.map((el, index) => ({
index,
text: (el.innerText || el.textContent || '').trim(),
r: el.getBoundingClientRect(),
}))
.filter(item => item.r.width > 0 && item.r.height > 0)
.sort((a, b) => a.r.y - b.r.y || a.r.x - b.r.x);
const byY = new Map();
for (const item of selectors) {
const key = Math.round(item.r.y / 8) * 8;
byY.set(key, [...(byY.get(key) || []), item]);
}
const rows = Array.from(byY.values()).map(items => items.sort((a, b) => a.r.x - b.r.x));
const row = rows.find(items => {
if (items.length < 4) return false;
const text = items.map(item => item.text).join('|');
return /王者|安卓|国服|游戏|服务项目|区|服/.test(text);
});
if (!row) {
return {
ok: false,
missing: ['游戏', '区', '服', '服务项目'],
selectors: selectors.map(item => `${item.index}:${item.text}`),
};
}
const fields = ['游戏', '区', '服', '服务项目'];
const values = {};
const missing = [];
for (let i = 0; i < fields.length; i += 1) {
const value = row[i]?.text || '';
values[fields[i]] = value;
if (!row[i] || invalid(value)) missing.push(fields[i]);
}
return { ok: missing.length === 0, missing, values, row: row.map(item => `${item.index}:${item.text}`) };
}"""
)
)
def
select_manual_order_game_region_field
(
self
,
frame
:
Frame
,
field
:
str
)
->
bool
:
opened
=
frame
.
evaluate
(
"""field => {
const modal = Array.from(document.querySelectorAll('.ant-modal'))
.filter(el => {
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
}).pop();
if (!modal) return { ok: false, reason: 'no visible modal' };
const selectors = Array.from(modal.querySelectorAll('.ant-select-selector'))
.map((el, index) => ({
el,
index,
text: (el.innerText || el.textContent || '').trim(),
r: el.getBoundingClientRect(),
}))
.filter(item => item.r.width > 0 && item.r.height > 0)
.sort((a, b) => a.r.y - b.r.y || a.r.x - b.r.x);
const byY = new Map();
for (const item of selectors) {
const key = Math.round(item.r.y / 8) * 8;
byY.set(key, [...(byY.get(key) || []), item]);
}
const rows = Array.from(byY.values()).map(items => items.sort((a, b) => a.r.x - b.r.x));
const row = rows.find(items => {
if (items.length < 4) return false;
const text = items.map(item => item.text).join('|');
return /王者|安卓|国服|游戏|服务项目|区|服/.test(text);
});
if (!row) return { ok: false, reason: 'game row not found', selectors: selectors.map(item => `${item.index}:${item.text}`) };
const index = { '游戏': 0, '区': 1, '服': 2, '服务项目': 3 }[field];
const selector = row[index];
if (!selector) return { ok: false, reason: `selector not found: ${field}`, row: row.map(item => item.text) };
selector.el.click();
return { ok: true, index: selector.index, before: selector.text };
}"""
,
field
,
)
if
not
opened
.
get
(
"ok"
):
return
False
self
.
page
.
wait_for_timeout
(
1000
)
clicked
=
self
.
click_first_visible_dropdown_option
(
frame
)
if
clicked
:
self
.
page
.
wait_for_timeout
(
800
)
return
clicked
def
visible_dropdown_options
(
self
,
frame
:
Frame
)
->
list
[
str
]:
options
=
frame
.
evaluate
(
"""() => Array.from(document.querySelectorAll(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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