149 lines
5.3 KiB
Python
149 lines
5.3 KiB
Python
"""
|
||
[一次性验证工具] 用 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())
|