1
This commit is contained in:
148
scripts/ops/_verify_step_counts.py
Normal file
148
scripts/ops/_verify_step_counts.py
Normal file
@@ -0,0 +1,148 @@
|
||||
"""
|
||||
[一次性验证工具] 用 Playwright 实际模拟 600px 固定步长滚动,
|
||||
记录每个页面实际能截几屏(scrollTop 被 clamp 后的真实值)。
|
||||
|
||||
用法:
|
||||
1. 先启动 Live Server(VS Code 右键 Open with Live Server,端口 5500)
|
||||
2. python scripts/ops/_verify_step_counts.py
|
||||
|
||||
输出:每页的 scrollHeight、maxScrollTop、实际步数、scrollTop 序列。
|
||||
"""
|
||||
import asyncio
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
BASE_URL = "http://127.0.0.1:5500/docs/h5_ui/pages"
|
||||
VIEWPORT_W = 430
|
||||
VIEWPORT_H = 752
|
||||
DPR = 1.5
|
||||
STEP = 600
|
||||
|
||||
PAGES = [
|
||||
"board-finance", "board-coach", "board-customer",
|
||||
"task-detail", "task-detail-callback", "task-detail-priority",
|
||||
"task-detail-relationship", "coach-detail", "customer-detail",
|
||||
"performance", "task-list", "my-profile",
|
||||
"customer-service-records", "performance-records",
|
||||
"chat", "chat-history", "notes",
|
||||
]
|
||||
|
||||
# 维度数映射
|
||||
DIMS = {"board-coach": 4, "board-customer": 8}
|
||||
|
||||
HIDE_FLOAT_JS = """
|
||||
() => {
|
||||
const nav = document.getElementById('bottomNav');
|
||||
if (nav) nav.style.display = 'none';
|
||||
document.querySelectorAll('.ai-float-btn-container').forEach(el => el.style.display = 'none');
|
||||
document.documentElement.style.scrollbarWidth = 'none';
|
||||
const s = document.createElement('style');
|
||||
s.textContent = '::-webkit-scrollbar { display: none !important; }';
|
||||
document.head.appendChild(s);
|
||||
}
|
||||
"""
|
||||
|
||||
EXPAND_ALL_JS = """
|
||||
() => {
|
||||
document.querySelectorAll('[onclick*="More"], [onclick*="expand"], [onclick*="toggle"]').forEach(b => b.click());
|
||||
document.querySelectorAll('[id*="More"], [id*="more"]').forEach(el => {
|
||||
el.classList.remove('hidden');
|
||||
el.style.display = '';
|
||||
});
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
results = []
|
||||
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch(headless=True)
|
||||
context = await browser.new_context(
|
||||
viewport={"width": VIEWPORT_W, "height": VIEWPORT_H},
|
||||
device_scale_factor=DPR,
|
||||
)
|
||||
page = await context.new_page()
|
||||
|
||||
for name in PAGES:
|
||||
url = f"{BASE_URL}/{name}.html"
|
||||
try:
|
||||
await page.goto(url, wait_until="load", timeout=15000)
|
||||
await page.wait_for_timeout(2000)
|
||||
await page.evaluate(HIDE_FLOAT_JS)
|
||||
await page.evaluate(EXPAND_ALL_JS)
|
||||
await page.wait_for_timeout(500)
|
||||
|
||||
# 获取页面高度
|
||||
scroll_height = await page.evaluate("() => document.documentElement.scrollHeight")
|
||||
max_scroll = scroll_height - VIEWPORT_H
|
||||
|
||||
# 模拟固定步长滚动,记录实际 scrollTop
|
||||
actual_steps = []
|
||||
target = 0
|
||||
while True:
|
||||
# 滚动到目标位置
|
||||
await page.evaluate(f"window.scrollTo(0, {target})")
|
||||
await page.wait_for_timeout(200)
|
||||
# 读取实际 scrollTop
|
||||
actual = await page.evaluate(
|
||||
"() => window.pageYOffset || document.documentElement.scrollTop"
|
||||
)
|
||||
actual_steps.append({"target": target, "actual": round(actual)})
|
||||
|
||||
# 如果实际值已经到达 maxScroll 或者目标已超过 maxScroll,结束
|
||||
if actual >= max_scroll - 1 or target >= max_scroll:
|
||||
break
|
||||
target += STEP
|
||||
|
||||
dims = DIMS.get(name, 1)
|
||||
units = len(actual_steps) * dims
|
||||
|
||||
info = {
|
||||
"page": name,
|
||||
"scrollHeight": scroll_height,
|
||||
"maxScroll": round(max_scroll),
|
||||
"steps": len(actual_steps),
|
||||
"dims": dims,
|
||||
"units": units,
|
||||
"sequence": actual_steps,
|
||||
}
|
||||
results.append(info)
|
||||
|
||||
seq_str = ", ".join(str(s["actual"]) for s in actual_steps)
|
||||
print(f" {name:35s} H={scroll_height:5d} max={max_scroll:5.0f}"
|
||||
f" steps={len(actual_steps):2d} dims={dims} units={units:3d}"
|
||||
f" seq=[{seq_str}]")
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ {name}: {e}")
|
||||
results.append({"page": name, "error": str(e)})
|
||||
|
||||
await browser.close()
|
||||
|
||||
# 汇总
|
||||
total = sum(r.get("units", 0) for r in results)
|
||||
print(f"\n总对照处理单元数: {total}")
|
||||
|
||||
# 输出 JSON
|
||||
out_path = Path(__file__).resolve().parents[2] / "export" / "SYSTEM" / "REPORTS" / "h5_page_heights" / "step_counts_verified.json"
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(results, f, ensure_ascii=False, indent=2)
|
||||
print(f"详细数据已写入: {out_path}")
|
||||
|
||||
# Markdown 表格
|
||||
print(f"\n| 页面 | scrollHeight | maxScroll | 步数 | 维度 | 单元 |")
|
||||
print(f"|------|-------------|-----------|------|------|------|")
|
||||
for r in results:
|
||||
if "error" in r:
|
||||
print(f"| {r['page']} | ❌ | | | | |")
|
||||
else:
|
||||
print(f"| {r['page']} | {r['scrollHeight']} | {r['maxScroll']} | {r['steps']} | {r['dims']} | {r['units']} |")
|
||||
print(f"| **合计** | | | | | **{total}** |")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user