25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

40 satır
2.4 KiB

  1. """Validate real UI exports; run from ute2e. No authentication data is read."""
  2. from pathlib import Path
  3. import struct
  4. import json
  5. import zipfile
  6. import xml.etree.ElementTree as ET
  7. from pypdf import PdfReader
  8. root = Path('reports/guide-closure-20260910')
  9. checks = []
  10. def check(name, passed, detail=''):
  11. checks.append(dict(name=name, status='PASS' if passed else 'FAIL', detail=detail))
  12. pdf = PdfReader(root / 'export-pdf.pdf')
  13. check('PDF 四页可解析且每页含文本', len(pdf.pages) == 4 and all(p.extract_text().strip() for p in pdf.pages), f'{len(pdf.pages)} pages')
  14. with zipfile.ZipFile(root / 'export-ofd.ofd') as z:
  15. xmls = [n for n in z.namelist() if n.lower().endswith('.xml')]
  16. for name in xmls:
  17. ET.fromstring(z.read(name))
  18. check('OFD ZIP 完整、入口和 XML 可解析', z.testzip() is None and 'OFD.xml' in z.namelist() and len(xmls) > 4, f'{len(xmls)} XML files; 未使用第三方 OFD 阅读器认证')
  19. with zipfile.ZipFile(root / 'export-offline.zip') as z:
  20. names = z.namelist()
  21. check('离线 ZIP 完整', z.testzip() is None, f'{len(names)} files')
  22. scripts = [z.read(n) for n in names if n.endswith(('.js', '.html'))]
  23. check('离线脚本没有 Vite 开发缓存引用', not any(b'/.vite-cache/' in s or b'/node_modules/.pnpm/' in s for s in scripts))
  24. glbs = [z.read(n) for n in names if n.lower().endswith('.glb')]
  25. originals = [Path('../../文档/素材') / n for n in ['09-Fox.glb', '08-CesiumMilkTruck.glb']]
  26. def structure(b):
  27. assert b[:4] == b'glTF' and struct.unpack_from('<I', b, 8)[0] == len(b)
  28. doc = json.loads(b[20:20 + struct.unpack_from('<I', b, 12)[0]])
  29. return {k: len(doc.get(k, [])) for k in ['nodes', 'meshes', 'animations', 'materials', 'skins']}
  30. expected = [structure(p.read_bytes()) for p in originals]
  31. actual = [structure(b) for b in glbs]
  32. check('离线狐狸和卡车 GLB 结构及动画保留', expected == actual, '导出按现有逻辑轻量化,卡车从 369980 缩至 318276 字节;非原文件逐字节复制。实际渲染和动画另由浏览器验证。')
  33. check('离线包含本地 Three.js 和解码器', any('three.module' in n for n in names) and any(n.endswith('.wasm') for n in names))
  34. (root / 'artifact-validation.json').write_text(json.dumps(dict(checks=checks), ensure_ascii=False, indent=2), encoding='utf-8')
  35. for item in checks:
  36. print(item['status'], item['name'])
  37. raise SystemExit(any(c['status'] != 'PASS' for c in checks))