54 lines
3.0 KiB
Python
54 lines
3.0 KiB
Python
"""최종 Playwright 원문을 보존하며 첨부 실측값과 검증 요약만 별도 파일로 추출한다."""
|
|
import base64
|
|
import json
|
|
from pathlib import Path
|
|
|
|
EVIDENCE = Path(__file__).resolve().parent
|
|
report = json.loads((EVIDENCE / 'browser-results.json').read_text())
|
|
projects = {}
|
|
|
|
|
|
def walk(suite):
|
|
"""중첩 suite를 순회한다. 실제 result가 실패하면 성공 요약을 만들지 않는다."""
|
|
for spec in suite.get('specs', []):
|
|
for test in spec['tests']:
|
|
project = projects.setdefault(test['projectName'], {'passed': 0, 'attachments': {}})
|
|
assert len(test['results']) == 1, '재시도 없는 최종 실행만 성공으로 요약한다.'
|
|
result = test['results'][0]
|
|
assert result['status'] == 'passed', spec['title']
|
|
project['passed'] += 1
|
|
for attachment in result.get('attachments', []):
|
|
if attachment['contentType'] != 'application/json':
|
|
continue
|
|
# 파일 첨부와 base64 본문 첨부의 원문을 같은 방식으로 재사용한다.
|
|
raw = (Path(attachment['path']).read_bytes() if 'path' in attachment
|
|
else base64.b64decode(attachment['body']))
|
|
name = attachment['name'].replace(' ', '-')
|
|
output = EVIDENCE / f"final-{test['projectName']}-{name}.json"
|
|
output.write_bytes(raw)
|
|
project['attachments'][name] = output.name
|
|
for child in suite.get('suites', []):
|
|
walk(child)
|
|
|
|
|
|
walk(report)
|
|
for project in projects.values():
|
|
gains = json.loads((EVIDENCE / project['attachments']['actual-gain-nodes']).read_text())
|
|
audit = json.loads((EVIDENCE / project['attachments']['runtime-audit']).read_text())
|
|
resampled = json.loads((EVIDENCE / project['attachments']['all-voices-resampled-bounds']).read_text())
|
|
project['resampledPeakMaxima'] = {kind: max(row['normalizedPeak'] for row in resampled['rows'] if row['kind'] == kind)
|
|
for kind in ('background', 'voice', 'intro')}
|
|
project['gainCases'] = len(gains['rows'])
|
|
project['observedBackgroundGainValues'] = sorted({r['sources'][0]['observed'] for r in gains['rows']})
|
|
project['scheduledBackgroundGainValues'] = sorted({r['sources'][0]['scheduled'] for r in gains['rows']})
|
|
project['normalFlowAudit'] = {key: len(audit[key]) + len(gains[key])
|
|
for key in ('errors', 'failed', 'external')}
|
|
assert project['normalFlowAudit'] == {'errors': 0, 'failed': 0, 'external': 0}
|
|
project['axeViolations'] = 0 # game/rounds의 실제 axe assertion 통과를 위 status에서 확인했다.
|
|
|
|
summary = {'stats': report['stats'], 'projects': projects,
|
|
'scope': 'System Chrome desktop/mobile emulation; native Web Audio; local built app; intentional fault injections excluded from normal-flow error totals.',
|
|
'sandboxEvidence': 'chrome-sandbox-final.json'}
|
|
(EVIDENCE / 'browser-summary.json').write_text(json.dumps(summary, indent=2) + '\n')
|
|
print(json.dumps(summary, indent=2))
|