44 lines
3.7 KiB
Python
44 lines
3.7 KiB
Python
"""Account for every inherited axe node without upgrading manual requirements."""
|
|
from collections import Counter, defaultdict
|
|
import json
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
ROOT = HERE.parents[3]
|
|
source = ROOT / 'docs/redesign/phase-8/p8-05/evidence/axe.json'
|
|
data = json.loads(source.read_text(encoding='utf-8'))
|
|
groups = defaultdict(list)
|
|
for scan in data['scans']:
|
|
for rule in scan['incomplete']:
|
|
for node in rule['nodes']:
|
|
checks = node.get('any', []) + node.get('all', []) + node.get('none', [])
|
|
keys = sorted(set((check.get('data') or {}).get('messageKey', check['id']) for check in checks))
|
|
component = 'dashboard size selector' if '<select' in node['html'] else 'hidden badge' if 'MuiBadge-invisible' in node['html'] else 'drawer/focus' if rule['id'] == 'aria-hidden-focus' else 'text/control with obscured background'
|
|
groups[(rule['id'], ', '.join(keys), component)].append(dict(scan=scan['name'], target=node['target'], html=node['html'], checks=checks))
|
|
counts = Counter(rule for (rule, _, _), nodes in groups.items() for node in nodes)
|
|
assert sum(counts.values()) == 64, counts
|
|
assert counts == {'color-contrast': 63, 'aria-hidden-focus': 1}, counts
|
|
rows = []
|
|
settled_path = HERE / 'settled-axe.json'
|
|
settled = json.loads(settled_path.read_text(encoding='utf-8')) if settled_path.exists() else []
|
|
if settled:
|
|
assert len(settled) == 4 and sum(len(row['scans']) for row in settled) == 16
|
|
assert not any(scan['violations'] for row in settled for scan in row['scans'])
|
|
assert all(node['ariaHidden'] == 'true' and node['width'] * node['height'] == 0 for row in settled for node in row['badge'])
|
|
assert all(node['ariaHidden'] == 'true' and node['visibility'] == 'hidden' and not node['containsActive'] and node['visibleTabbables'] == 0 for row in settled for node in row['hiddenDrawer'])
|
|
for index, ((rule, reason, component), nodes) in enumerate(sorted(groups.items()), 1):
|
|
# Source evidence identifies an automated measurement limit; it does not prove visible contrast/focus compliance.
|
|
classification = 'Not applicable to invisible zero badge, subject to settled visibility verification' if component == 'hidden badge' else 'Requires manual inspection'
|
|
current = 'Requires manual inspection'
|
|
evidence = 'Contextual foreground/background measurement remains required.'
|
|
if component == 'hidden badge' and settled:
|
|
current = 'Not applicable in tested settled hidden state'
|
|
evidence = 'Four current native EN/NB theme vectors: aria-hidden=true and zero area. Actual reader/live unread-state remains separate.'
|
|
elif component == 'drawer/focus' and settled:
|
|
evidence = 'Shared Dashboard drawer settled predicate, Escape focus and24Tab proof pass. Original Analytics transition cause is not proven; human reader/transition qualification remains.'
|
|
rows.append(dict(id=f'P9-AX-{index:02}', rule=rule, reason=reason, component=component, occurrences=len(nodes), classification=classification, phase9Disposition=current, closureEvidence=evidence, observations=nodes))
|
|
report = dict(source=str(source.relative_to(ROOT)), total=64, counts=counts, groups=rows,
|
|
conclusion='Original observations retained. Ten hidden-badge occurrences are not applicable in the verified current hidden state;53 background cases and the original drawer transition remain human qualifications. Current settled runtime evidence is separate from original-cause proof.')
|
|
(HERE / 'inherited-axe-triage.json').write_text(json.dumps(report, indent=2, ensure_ascii=False) + '\n', encoding='utf-8')
|
|
print(json.dumps([{k: v for k, v in row.items() if k != 'observations'} for row in rows], ensure_ascii=False, indent=2))
|