Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
R
rentos
Project
Project
Details
Activity
Releases
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
accounting
rentos
Commits
57cf814d
Commit
57cf814d
authored
Oct 14, 2026
by
wenwen.tang
😕
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
test(ui): ui_verify1-7 加 RENTOS_BASE 闸门并适配账期折叠,新增 ui_verify11
parent
9326844a
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
698 additions
and
41 deletions
+698
-41
ui_verify.py
tools/ui_verify.py
+15
-4
ui_verify11.py
tools/ui_verify11.py
+568
-0
ui_verify2.py
tools/ui_verify2.py
+38
-19
ui_verify3.py
tools/ui_verify3.py
+15
-4
ui_verify4.py
tools/ui_verify4.py
+18
-6
ui_verify5.py
tools/ui_verify5.py
+27
-6
ui_verify6.py
tools/ui_verify6.py
+13
-2
ui_verify7.py
tools/ui_verify7.py
+4
-0
No files found.
tools/ui_verify.py
View file @
57cf814d
...
...
@@ -4,9 +4,9 @@
====================================
台账(房租车位费)→ 改单元格 → 增行 → 删行 → 搜索 → 电费手工录入 → 还原现场。
运行:
python tools/ui_verify.py
RENTOS_
BASE=http://127.0.0.1:8901 python tools/ui_verify.py
运行
(该脚本会写数据,默认目标 8899 是【真实台账】,必须走沙箱)
:
python tools/ui_verify
_runner.py tools/ui_verify
.py
RENTOS_
ALLOW_REAL=1 python tools/ui_verify.py # 确需直连真实服务才这样用
覆盖的改造点:
* 只有一张台账「房租车位费」(旧的两张已退休)
...
...
@@ -21,7 +21,18 @@ warnings.filterwarnings("ignore")
from
playwright.sync_api
import
sync_playwright
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
"http://127.0.0.1:8899"
)
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
""
)
if
not
BASE
:
# 该脚本会写数据;未注入 RENTOS_BASE 时默认目标 8899 是【真实台账】,
# 直连会污染权威数据(2026-10-13 曾误写入 17 个测试批次)。
# 正常路径:tools/ui_verify_runner.py(沙箱 + 注入 RENTOS_BASE)。
if
os
.
environ
.
get
(
"RENTOS_ALLOW_REAL"
)
==
"1"
:
BASE
=
"http://127.0.0.1:8899"
else
:
_me
=
os
.
path
.
basename
(
__file__
)
sys
.
exit
(
"已阻止:
%
s 未设置 RENTOS_BASE(默认 8899 是【真实台账】)。
\n
"
" 沙箱运行: python tools/ui_verify_runner.py tools/
%
s
\n
"
" 确需打真实服务:RENTOS_ALLOW_REAL=1 python tools/
%
s"
%
(
_me
,
_me
,
_me
))
OUT
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
"shots"
)
os
.
makedirs
(
OUT
,
exist_ok
=
True
)
...
...
tools/ui_verify11.py
0 → 100644
View file @
57cf814d
This diff is collapsed.
Click to expand it.
tools/ui_verify2.py
View file @
57cf814d
...
...
@@ -2,19 +2,31 @@
"""
界面验证:两张账单发送计划 / 免租期 / 台账锁定与二次确认 / 撤销 / 无「序号」列
运行:
python tools/ui_verify2.py
RENTOS_
BASE=http://127.0.0.1:8901 python tools/ui_verify2.py
运行
(该脚本会写数据,默认目标 8899 是【真实台账】,必须走沙箱)
:
python tools/ui_verify
_runner.py tools/ui_verify
2.py
RENTOS_
ALLOW_REAL=1 python tools/ui_verify2.py # 确需直连真实服务才这样用
"""
import
json
import
os
import
re
import
sys
import
warnings
warnings
.
filterwarnings
(
"ignore"
)
from
playwright.sync_api
import
sync_playwright
# noqa: E402
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
"http://127.0.0.1:8899"
)
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
""
)
if
not
BASE
:
# 该脚本会写数据;未注入 RENTOS_BASE 时默认目标 8899 是【真实台账】,
# 直连会污染权威数据(2026-10-13 曾误写入 17 个测试批次)。
# 正常路径:tools/ui_verify_runner.py(沙箱 + 注入 RENTOS_BASE)。
if
os
.
environ
.
get
(
"RENTOS_ALLOW_REAL"
)
==
"1"
:
BASE
=
"http://127.0.0.1:8899"
else
:
_me
=
os
.
path
.
basename
(
__file__
)
sys
.
exit
(
"已阻止:
%
s 未设置 RENTOS_BASE(默认 8899 是【真实台账】)。
\n
"
" 沙箱运行: python tools/ui_verify_runner.py tools/
%
s
\n
"
" 确需打真实服务:RENTOS_ALLOW_REAL=1 python tools/
%
s"
%
(
_me
,
_me
,
_me
))
OUT
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
"shots2"
)
os
.
makedirs
(
OUT
,
exist_ok
=
True
)
...
...
@@ -49,13 +61,14 @@ def main():
page
.
wait_for_url
(
"**/admin.html"
)
page
.
wait_for_timeout
(
1200
)
# ============================================ 1. 设置页:
两张账单
print
(
"
\n
== 1. 设置页:
两张账单发送计划
=="
)
# ============================================ 1. 设置页:
只剩房租车位费
print
(
"
\n
== 1. 设置页:
只配置「房租车位费」(电费已删)
=="
)
page
.
goto
(
f
"{BASE}/admin.html#/settings"
)
page
.
wait_for_selector
(
"#planRows tr[data-plan]"
,
timeout
=
20000
)
page
.
wait_for_timeout
(
800
)
rows
=
page
.
eval_on_selector_all
(
"#planRows tr[data-plan]"
,
"els=>els.map(e=>e.dataset.plan)"
)
ck
(
"两张账单计划各一行"
,
rows
==
[
"elec"
,
"rent_parking"
],
str
(
rows
))
ck
(
"电费通知单已从定时发送设置里删掉,只剩房租车位费"
,
rows
==
[
"rent_parking"
],
str
(
rows
))
ck
(
"退休的旧账单键已消失"
,
"rent_summary_367"
not
in
rows
and
"rent_contract_8f11f"
not
in
rows
,
str
(
rows
))
for
k
in
rows
:
...
...
@@ -71,24 +84,30 @@ def main():
ck
(
f
"{k} 四个控件齐全"
,
got
[
"en"
]
and
got
[
"adv"
]
and
got
[
"tm"
]
and
got
[
"rf"
],
json
.
dumps
(
got
,
ensure_ascii
=
False
))
names
=
page
.
eval_on_selector_all
(
"#planRows .bill-name"
,
"e=>e.map(x=>x.innerText)"
)
ck
(
"账单名称
= 电费 / 房租车位费
"
,
names
==
[
"
电费收费通知书"
,
"
房租车位费收费通知书"
],
str
(
names
))
ck
(
"账单名称
只剩「房租车位费收费通知书」
"
,
names
==
[
"房租车位费收费通知书"
],
str
(
names
))
ck
(
"页面不再出现「三张账单」"
,
"三张账单"
not
in
page
.
eval_on_selector
(
"#page-settings"
,
"e=>e.innerText"
))
ck
(
"设置页不再重复展示「出租方 · 汇款公司」"
,
"汇款公司"
not
in
page
.
eval_on_selector
(
"#page-settings"
,
"e=>e.innerText"
))
page
.
screenshot
(
path
=
os
.
path
.
join
(
OUT
,
"S1-plans.png"
),
full_page
=
True
)
print
(
"
\n
== 2. 免租期卡片 =="
)
rf
=
page
.
eval_on_selector
(
"#rentfreeBox"
,
"e=>e.innerText"
)
ck
(
"免租期卡片列出两种免租类型"
,
"首N月免租"
in
rf
and
"每年8-9月免租"
in
rf
)
ck
(
"免租期列出 3 段(315室 / 302室 / 303室)"
,
"共 3 段"
in
rf
,
rf
.
split
(
"
\n
"
)[
0
][:
80
])
# 段数跟着台账走(不写死):801/802 登记「每年8-9月免租」后会按年展开
ck
(
"免租期卡片给出「共 N 段」汇总"
,
re
.
search
(
r"共 \d+ 段"
,
rf
)
is
not
None
,
rf
.
split
(
"
\n
"
)[
0
][:
80
])
ck
(
"免租期卡片列出真实台账里的免租房间"
,
all
(
u
in
rf
for
u
in
(
"315室"
,
"302室"
,
"303室"
)),
rf
[:
120
])
ck
(
"免租期表格有 302室"
,
"302室"
in
rf
and
"2026-08-16"
in
rf
)
ck
(
"免租期来源标注为房租车位费台账"
,
"房租车位费"
in
rf
or
"台账"
in
rf
)
page
.
screenshot
(
path
=
os
.
path
.
join
(
OUT
,
"S2-rentfree.png"
),
full_page
=
True
)
# 记下初始计划,最后原样还原(脚本不该改变现场配置)
adv
=
'#planRows tr[data-plan="
elec
"] input[data-f="advance_days"]'
tm
=
'#planRows tr[data-plan="
elec
"] input[data-f="send_time"]'
en
=
'#planRows tr[data-plan="
elec
"] input[data-f="enabled"]'
adv
=
'#planRows tr[data-plan="
rent_parking
"] input[data-f="advance_days"]'
tm
=
'#planRows tr[data-plan="
rent_parking
"] input[data-f="send_time"]'
en
=
'#planRows tr[data-plan="
rent_parking
"] input[data-f="enabled"]'
init
=
{
"master"
:
page
.
input_value
(
"#st-enabled"
),
"adv"
:
page
.
input_value
(
adv
),
"tm"
:
page
.
input_value
(
tm
),
"en"
:
page
.
is_checked
(
en
)}
...
...
@@ -128,10 +147,10 @@ def main():
ck
(
"确认后提前天数=7 已落盘"
,
page
.
input_value
(
adv
)
==
"7"
,
page
.
input_value
(
adv
))
ck
(
"确认后发送时点=07:30 已落盘"
,
page
.
input_value
(
tm
)
==
"07:30"
,
page
.
input_value
(
tm
))
st_txt
=
page
.
eval_on_selector
(
'#planRows tr[data-plan="
elec
"] .plan-state'
,
"e=>e.innerText"
)
ck
(
"状态列给出运行状态(排期说明 /
暂无通知书 / 未启用
)"
,
(
"
缴费期限"
in
st_txt
)
or
(
"还没有可发送的通知书"
in
st_txt
)
or
(
"未启用"
in
st_txt
),
st_txt
.
replace
(
"
\n
"
,
" | "
)[:
110
])
'#planRows tr[data-plan="
rent_parking
"] .plan-state'
,
"e=>e.innerText"
)
ck
(
"状态列给出运行状态(排期说明 /
未启用 / 无待发
)"
,
(
"
推送日"
in
st_txt
)
or
(
"待出单"
in
st_txt
)
or
(
"未启用"
in
st_txt
)
or
(
"无待发"
in
st_txt
),
st_txt
.
replace
(
"
\n
"
,
" | "
)[:
110
])
page
.
screenshot
(
path
=
os
.
path
.
join
(
OUT
,
"S4-saved.png"
),
full_page
=
True
)
print
(
"
\n
== 4b. 关闭总开关时不再排期 =="
)
...
...
@@ -143,10 +162,10 @@ def main():
page
.
reload
(
wait_until
=
"networkidle"
)
page
.
wait_for_selector
(
"#planRows tr[data-plan]"
,
timeout
=
20000
)
page
.
wait_for_timeout
(
600
)
ck
(
"总开关关闭 →
两张账单状态均为 off
"
,
ck
(
"总开关关闭 →
计划状态为「总开关关闭」
"
,
page
.
eval_on_selector_all
(
"#planRows tr[data-plan] .plan-state .l1"
,
"e=>e.map(x=>x.innerText)"
)
==
[
"总开关关闭"
,
"总开关关闭"
],
==
[
"总开关关闭"
],
str
(
page
.
eval_on_selector_all
(
"#planRows tr[data-plan] .plan-state .l1"
,
"e=>e.map(x=>x.innerText)"
)))
...
...
tools/ui_verify3.py
View file @
57cf814d
...
...
@@ -10,9 +10,9 @@
5. 「房租车位费」台账:8F/11F 付款周期 = 3 个月
6. 全程页面无 JS 报错
运行:
python tools/ui_verify
3.py # 默认 http://127.0.0.1:8899
RENTOS_
BASE=http://127.0.0.1:8901 python tools/ui_verify3.py
运行
(该脚本会写数据,默认目标 8899 是【真实台账】,必须走沙箱)
:
python tools/ui_verify
_runner.py tools/ui_verify3.py
RENTOS_
ALLOW_REAL=1 python tools/ui_verify3.py # 确需直连真实服务才这样用
"""
import
base64
import
io
...
...
@@ -24,7 +24,18 @@ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
from
playwright.sync_api
import
sync_playwright
# noqa: E402
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
"http://127.0.0.1:8899"
)
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
""
)
if
not
BASE
:
# 该脚本会写数据;未注入 RENTOS_BASE 时默认目标 8899 是【真实台账】,
# 直连会污染权威数据(2026-10-13 曾误写入 17 个测试批次)。
# 正常路径:tools/ui_verify_runner.py(沙箱 + 注入 RENTOS_BASE)。
if
os
.
environ
.
get
(
"RENTOS_ALLOW_REAL"
)
==
"1"
:
BASE
=
"http://127.0.0.1:8899"
else
:
_me
=
os
.
path
.
basename
(
__file__
)
sys
.
exit
(
"已阻止:
%
s 未设置 RENTOS_BASE(默认 8899 是【真实台账】)。
\n
"
" 沙箱运行: python tools/ui_verify_runner.py tools/
%
s
\n
"
" 确需打真实服务:RENTOS_ALLOW_REAL=1 python tools/
%
s"
%
(
_me
,
_me
,
_me
))
USER
,
PWD
=
"admin"
,
"1989@rent05"
OUT
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
"shots3"
)
PNG_B64
=
(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGA"
...
...
tools/ui_verify4.py
View file @
57cf814d
...
...
@@ -6,14 +6,14 @@
1. 导航出现「公司管理」,深链 #/companies 可直达,共 5 项
2. 租客 / 往来单位名册:加载、类型标签、搜索过滤、录入、行内编辑改名、删除
3. 出租方 · 汇款公司:加载、引用单元数、录入、改名(提示会同步台账)、删除
4. 设置页不再有旧的「汇款公司」编辑卡片
(只剩指引
)
4. 设置页不再有旧的「汇款公司」编辑卡片
,也不再重复展示(名单只在「公司管理」维护
)
5. 选择场景接入:电费录入「单位名称 / 出租方」有候选并在填房间号时自动带出
6. 台账「现租客」列编辑时挂上名册候选
7. 全程页面无 JS 报错,且测试用完即清理(不留脏数据)
运行:
python tools/ui_verify
4.py # 默认 8899
RENTOS_
BASE=http://127.0.0.1:8901 python tools/ui_verify4.py
运行
(该脚本会写数据,默认目标 8899 是【真实台账】,必须走沙箱)
:
python tools/ui_verify
_runner.py tools/ui_verify4.py
RENTOS_
ALLOW_REAL=1 python tools/ui_verify4.py # 确需直连真实服务才这样用
"""
import
io
import
os
...
...
@@ -24,7 +24,18 @@ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
from
playwright.sync_api
import
sync_playwright
# noqa: E402
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
"http://127.0.0.1:8899"
)
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
""
)
if
not
BASE
:
# 该脚本会写数据;未注入 RENTOS_BASE 时默认目标 8899 是【真实台账】,
# 直连会污染权威数据(2026-10-13 曾误写入 17 个测试批次)。
# 正常路径:tools/ui_verify_runner.py(沙箱 + 注入 RENTOS_BASE)。
if
os
.
environ
.
get
(
"RENTOS_ALLOW_REAL"
)
==
"1"
:
BASE
=
"http://127.0.0.1:8899"
else
:
_me
=
os
.
path
.
basename
(
__file__
)
sys
.
exit
(
"已阻止:
%
s 未设置 RENTOS_BASE(默认 8899 是【真实台账】)。
\n
"
" 沙箱运行: python tools/ui_verify_runner.py tools/
%
s
\n
"
" 确需打真实服务:RENTOS_ALLOW_REAL=1 python tools/
%
s"
%
(
_me
,
_me
,
_me
))
USER
,
PWD
=
"admin"
,
"1989@rent05"
OUT
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
"shots4"
)
...
...
@@ -278,7 +289,8 @@ def main():
ck
(
"旧汇款公司编辑区已移除"
,
page
.
eval_on_selector_all
(
"#ownersBox, #btn-save-owners, #btn-reset-owners"
,
"e => e.length"
)
==
0
)
txt
=
page
.
inner_text
(
"#page-settings"
)
ck
(
"留有指向公司管理的指引"
,
"公司管理"
in
txt
)
ck
(
"设置页不再重复展示「出租方 · 汇款公司」(已迁走,不留冗余指引)"
,
"汇款公司"
not
in
txt
,
txt
[:
80
]
.
replace
(
"
\n
"
,
" "
))
page
.
screenshot
(
path
=
os
.
path
.
join
(
OUT
,
"C4-settings.png"
),
full_page
=
True
)
# ============================================================ 5
...
...
tools/ui_verify5.py
View file @
57cf814d
...
...
@@ -23,9 +23,9 @@
* 结束时逐格核对台账「账单起始日」与跑前一致,不一致就报 FAIL;
* 本次生成的产物文件会被清理(批次 JSON 由删除步骤清掉)。
运行:
python tools/ui_verify
5.py # 默认 8899
RENTOS_
BASE=http://127.0.0.1:8901 python tools/ui_verify5.py
运行
(该脚本会写数据,默认目标 8899 是【真实台账】,必须走沙箱)
:
python tools/ui_verify
_runner.py tools/ui_verify5.py
RENTOS_
ALLOW_REAL=1 python tools/ui_verify5.py # 确需直连真实服务才这样用
"""
import
io
import
os
...
...
@@ -37,7 +37,18 @@ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys
.
path
.
insert
(
0
,
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))))
from
playwright.sync_api
import
sync_playwright
# noqa: E402
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
"http://127.0.0.1:8899"
)
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
""
)
if
not
BASE
:
# 该脚本会写数据;未注入 RENTOS_BASE 时默认目标 8899 是【真实台账】,
# 直连会污染权威数据(2026-10-13 曾误写入 17 个测试批次)。
# 正常路径:tools/ui_verify_runner.py(沙箱 + 注入 RENTOS_BASE)。
if
os
.
environ
.
get
(
"RENTOS_ALLOW_REAL"
)
==
"1"
:
BASE
=
"http://127.0.0.1:8899"
else
:
_me
=
os
.
path
.
basename
(
__file__
)
sys
.
exit
(
"已阻止:
%
s 未设置 RENTOS_BASE(默认 8899 是【真实台账】)。
\n
"
" 沙箱运行: python tools/ui_verify_runner.py tools/
%
s
\n
"
" 确需打真实服务:RENTOS_ALLOW_REAL=1 python tools/
%
s"
%
(
_me
,
_me
,
_me
))
OUT
=
os
.
environ
.
get
(
"RENTOS_SHOTS"
,
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
".."
,
"output"
,
"ui_shots"
))
USER
,
PWD
=
"admin"
,
"1989@rent05"
...
...
@@ -275,14 +286,21 @@ def main():
# ============================================ 7. 批次台账 / 类别隔离
print
(
"
\n
7. 批次台账 · 类别隔离"
)
kinds
=
p
.
eval_on_selector_all
(
"#rpBatchList tbody tr td:first-child"
,
# 批次行默认按账期折叠;只展开仍折叠的分组(hash 导航不刷新页面,状态会延续)
js
(
"""() => { document.querySelectorAll('#rpBatchList tbody.pgrp.collapsed tr.grp')
.forEach(tr => tr.click()); }"""
)
p
.
wait_for_timeout
(
500
)
kinds
=
p
.
eval_on_selector_all
(
"#rpBatchList tbody tr.prow td:first-child"
,
"e=>e.map(x=>x.innerText.trim())"
)
ck
(
"房租批次表的「账单」列标出「房租车位费」"
,
kinds
and
all
(
k
==
"房租车位费"
for
k
in
kinds
),
str
(
kinds
[:
3
]))
p
.
goto
(
BASE
+
"/admin.html#/elec"
)
p
.
wait_for_selector
(
"#eGrid"
,
timeout
=
15000
)
p
.
wait_for_timeout
(
1800
)
elec_ids
=
p
.
eval_on_selector_all
(
"#batchList tbody tr td:nth-child(2)"
,
js
(
"""() => { document.querySelectorAll('#batchList tbody.pgrp.collapsed tr.grp')
.forEach(tr => tr.click()); }"""
)
p
.
wait_for_timeout
(
400
)
elec_ids
=
p
.
eval_on_selector_all
(
"#batchList tbody tr.prow td:nth-child(2)"
,
"e=>e.map(x=>x.innerText.trim())"
)
ck
(
"电费页的批次列表不含刚生成的房租批次"
,
(
created_batch
or
"x"
)
not
in
elec_ids
,
str
(
elec_ids
))
...
...
@@ -292,6 +310,9 @@ def main():
p
.
goto
(
BASE
+
"/admin.html#/table/rent_parking"
)
p
.
wait_for_selector
(
"#rpWrap table"
,
timeout
=
20000
)
p
.
wait_for_timeout
(
1200
)
js
(
"""() => { document.querySelectorAll('#rpBatchList tbody.pgrp.collapsed tr.grp')
.forEach(tr => tr.click()); }"""
)
p
.
wait_for_timeout
(
400
)
if
created_batch
:
p
.
click
(
'#rpBatchList button[data-open="
%
s"]'
%
created_batch
)
p
.
wait_for_timeout
(
1500
)
...
...
tools/ui_verify6.py
View file @
57cf814d
...
...
@@ -15,7 +15,7 @@
* 只出 1 行单,跑完**必定删除该批次并回滚账期**(try/finally 兜底);
* 结束时核对台账 AC/AJ 与跑前一致。
运行:python tools/ui_verify
6.py (需先起服务
)
运行:python tools/ui_verify
_runner.py tools/ui_verify6.py (该脚本会写数据,沙箱隔离
)
"""
import
io
import
os
...
...
@@ -25,7 +25,18 @@ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys
.
path
.
insert
(
0
,
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))))
from
playwright.sync_api
import
sync_playwright
# noqa: E402
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
"http://127.0.0.1:8899"
)
BASE
=
os
.
environ
.
get
(
"RENTOS_BASE"
,
""
)
if
not
BASE
:
# 该脚本会写数据;未注入 RENTOS_BASE 时默认目标 8899 是【真实台账】,
# 直连会污染权威数据(2026-10-13 曾误写入 17 个测试批次)。
# 正常路径:tools/ui_verify_runner.py(沙箱 + 注入 RENTOS_BASE)。
if
os
.
environ
.
get
(
"RENTOS_ALLOW_REAL"
)
==
"1"
:
BASE
=
"http://127.0.0.1:8899"
else
:
_me
=
os
.
path
.
basename
(
__file__
)
sys
.
exit
(
"已阻止:
%
s 未设置 RENTOS_BASE(默认 8899 是【真实台账】)。
\n
"
" 沙箱运行: python tools/ui_verify_runner.py tools/
%
s
\n
"
" 确需打真实服务:RENTOS_ALLOW_REAL=1 python tools/
%
s"
%
(
_me
,
_me
,
_me
))
OUT
=
os
.
environ
.
get
(
"RENTOS_SHOTS"
,
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
".."
,
"output"
,
"ui_shots"
))
USER
,
PWD
=
"admin"
,
"1989@rent05"
...
...
tools/ui_verify7.py
View file @
57cf814d
...
...
@@ -247,6 +247,10 @@ def main():
_st
,
_bl
=
api_call
(
"GET"
,
"/api/batches?kind=elec"
)
_elec
=
(
_bl
.
get
(
"batches"
)
or
[])
if
_elec
:
# 批次行默认按账期折叠;只展开仍折叠的分组
js
(
"""() => { document.querySelectorAll('#batchList tbody.pgrp.collapsed tr.grp')
.forEach(tr => tr.click()); }"""
)
p
.
wait_for_timeout
(
500
)
ck
(
"guest 看得到电费批次的「删除」按钮"
,
p
.
eval_on_selector_all
(
"#batchList tbody tr button[data-del]"
,
"es=>es.length>0 && es.every(b=>b.offsetParent!==null)"
))
...
...
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