|
#!/usr/bin/env python
|
|
# coding: utf-8
|
|
|
|
# Copyright 2024 Christian Lawson-Perfect
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# Convert a WCAG-EM report tool JSON file to reStructuredText
|
|
#
|
|
# This script converts the JSON file you get from the [WCAG-EM Report Tool](https://www.w3.org/WAI/eval/report-tool/) into reStructuredText markup.
|
|
#
|
|
# It needs the following files:
|
|
#
|
|
# * https://raw.githubusercontent.com/w3c/wai-wcag-em-report-tool/main/src/data/wcag.json - The data on WCAG criteria used by the report tool.
|
|
# * https://raw.githubusercontent.com/w3c/wai-wcag-em-report-tool/main/src/locales/en/WCAG.json - The English readable names for WCAG criteria. Save as ``WCAG_text.json``.
|
|
#
|
|
# Usage:
|
|
#
|
|
# python wcag-em-report-to-rst.py product-report.json
|
|
|
|
from collections import defaultdict
|
|
from itertools import groupby
|
|
import json
|
|
import sys
|
|
|
|
# Load the report data, and the WCAG criterion data
|
|
|
|
report_json_filename = sys.argv[1]
|
|
|
|
with open(report_json_filename) as f:
|
|
data = json.load(f)
|
|
|
|
with open('wcag.json') as f:
|
|
wcag = json.load(f)
|
|
|
|
with open('WCAG_text.json') as f:
|
|
wcag_text = json.load(f)
|
|
|
|
wcag_ids = {v['id']: v for v in wcag['2.2'].values()}
|
|
|
|
criteria_names = {k: v['TITLE'] for k,v in wcag_text['SUCCESS_CRITERION'].items()}
|
|
|
|
criteria = defaultdict(list)
|
|
|
|
for item in data['auditSample']:
|
|
id = item['test']['id'][len('WCAG22:'):]
|
|
criteria[id].append(item)
|
|
|
|
|
|
# For each criterion, gather info from the report
|
|
|
|
report = []
|
|
|
|
def indent_lines(text, indent):
|
|
lines = text.split('\n')
|
|
return lines[0]+'\n'.join(indent+line for line in lines[1:])
|
|
|
|
for key, criterion in criteria.items():
|
|
description = ''
|
|
result = ''
|
|
for item in criterion:
|
|
if 'description' in item['result']:
|
|
description = item['result']['description']
|
|
|
|
if 'Website' not in item['subject']['type']:
|
|
continue
|
|
|
|
result = item['result']['outcome']['title']
|
|
|
|
result_map = {
|
|
'Passed': 'Supports',
|
|
'Not present': 'Not Applicable',
|
|
}
|
|
result = result_map.get(result, result)
|
|
|
|
info = wcag_ids[key]
|
|
num = info['num']
|
|
conformanceLevel = info['conformanceLevel']
|
|
name = criteria_names[num]
|
|
|
|
report.append({
|
|
'key': key,
|
|
'description': indent_lines(description, ' '*6),
|
|
'result': result,
|
|
'num': num,
|
|
'conformanceLevel': conformanceLevel,
|
|
'name': name,
|
|
})
|
|
|
|
|
|
# Criteria not assessed
|
|
#
|
|
# The following criteria were not assessed:
|
|
|
|
print("The following criteria were not assessed:\n")
|
|
not_assessed = [n for n in wcag_ids.values() if n['id'] not in criteria]
|
|
for n in not_assessed:
|
|
print(f'''* {n['num']} {n['id']} ({n['conformanceLevel']}) https://www.w3.org/WAI/WCAG22/quickref/#{n['id']}''')
|
|
|
|
print('\n')
|
|
|
|
# Produce ReStructuredText of report
|
|
|
|
for level, items in groupby(sorted(report, key=lambda x: (x['conformanceLevel'], x['num'])), key=lambda x: x['conformanceLevel']):
|
|
header = f'''Table 1: Success Criteria, Level {level}'''
|
|
print(header)
|
|
print('*'*len(header))
|
|
print('''
|
|
.. list-table::
|
|
:header-rows: 1
|
|
|
|
-
|
|
|
|
- Criteria
|
|
- Conformance Level
|
|
- Remarks and Explanations''')
|
|
|
|
for item in items:
|
|
print(''' -
|
|
- .. _vpat-{key}:
|
|
|
|
`{num}: {name} <https://www.w3.org/WAI/WCAG22/quickref/#{key}>`__ (Level {conformanceLevel})
|
|
- {result}
|
|
- {description}'''.format(**item))
|
|
|
|
print('')
|