delete old files
This commit is contained in:
-121
@@ -1,121 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Check each guide URL in guides.csv for WCAG 2.1 AA accessibility
|
||||
issues using the pa11y CLI and report results.
|
||||
|
||||
The script:
|
||||
1. Reads guides.csv in the current directory.
|
||||
2. Runs `pa11y` for each URL with the WCAG2AA standard, requesting JSON.
|
||||
3. Collects the issues for every guide.
|
||||
4. Removes any issue codes that appear in *every* guide.
|
||||
5. Prints the filtered results to the console and writes them to
|
||||
output.txt.
|
||||
|
||||
Prerequisites:
|
||||
npm install -g pa11y
|
||||
|
||||
Usage:
|
||||
python check_wcag.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Set
|
||||
|
||||
GUIDES_CSV = Path(__file__).with_name("guides.csv")
|
||||
OUTPUT_FILE = Path("output.txt")
|
||||
|
||||
|
||||
def run_pa11y(url: str) -> List[dict]:
|
||||
"""
|
||||
Run pa11y on a URL and return the parsed JSON list of issues.
|
||||
|
||||
Returns an empty list if pa11y fails.
|
||||
"""
|
||||
try:
|
||||
cmd_base = ["pa11y"] if shutil.which("pa11y") else ["npx", "pa11y"]
|
||||
result = subprocess.run(
|
||||
[*cmd_base, url, "--standard", "WCAG2AA", "--reporter", "json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print(f"[WARN] pa11y returned code {result.returncode} for {url}", file=sys.stderr)
|
||||
return []
|
||||
return json.loads(result.stdout)
|
||||
except FileNotFoundError:
|
||||
print("Error: pa11y not found. Install it with `npm install -g pa11y`.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError:
|
||||
print(f"[WARN] Could not parse pa11y JSON output for {url}", file=sys.stderr)
|
||||
return []
|
||||
|
||||
|
||||
def read_guides(csv_path: Path) -> List[Dict[str, str]]:
|
||||
"""Load all guides from the CSV into a list of dicts."""
|
||||
with csv_path.open(newline="", encoding="utf-8-sig") as fh:
|
||||
reader = csv.DictReader(fh)
|
||||
return list(reader)
|
||||
|
||||
|
||||
def compute_common_codes(issues_by_guide: Dict[str, List[dict]]) -> Set[str]:
|
||||
"""Return the set of issue codes that appear in every guide."""
|
||||
all_codes_iter = (
|
||||
{issue["code"] for issue in issues} for issues in issues_by_guide.values()
|
||||
)
|
||||
common_codes: Set[str] | None = None
|
||||
for codes in all_codes_iter:
|
||||
if common_codes is None:
|
||||
common_codes = codes
|
||||
else:
|
||||
common_codes &= codes
|
||||
return common_codes or set()
|
||||
|
||||
|
||||
def format_issue(issue: dict) -> str:
|
||||
"""Return a human-readable one-line representation of a pa11y issue."""
|
||||
selector = issue.get("selector", "").strip() or "N/A"
|
||||
return f"[{issue['type']}] {issue['code']}: {issue['message']} (selector: {selector})"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
guides = read_guides(GUIDES_CSV)
|
||||
issues_by_guide: Dict[str, List[dict]] = {}
|
||||
|
||||
print("Auditing guides with pa11y…\n")
|
||||
for guide in guides:
|
||||
name = guide["Name"]
|
||||
url = guide["URL"]
|
||||
print(f"• {name} — {url}")
|
||||
issues = run_pa11y(url)
|
||||
issues_by_guide[name] = issues
|
||||
|
||||
common_codes = compute_common_codes(issues_by_guide)
|
||||
|
||||
lines_out: List[str] = []
|
||||
lines_out.append("\nAccessibility report (WCAG 2.1 AA)")
|
||||
lines_out.append("=" * 40)
|
||||
|
||||
for name, issues in issues_by_guide.items():
|
||||
filtered = [i for i in issues if i["code"] not in common_codes]
|
||||
lines_out.append(f"\nGuide: {name}")
|
||||
if not filtered:
|
||||
lines_out.append(" ✔ No unique issues found.")
|
||||
continue
|
||||
for issue in filtered:
|
||||
lines_out.append(f" • {format_issue(issue)}")
|
||||
|
||||
report_text = "\n".join(lines_out)
|
||||
print("\n" + report_text)
|
||||
OUTPUT_FILE.write_text(report_text, encoding="utf-8")
|
||||
print(f"\nReport written to {OUTPUT_FILE.resolve()}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,143 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Audit each guide URL in guides.csv for WCAG 2.1 AA accessibility issues.
|
||||
|
||||
This variant fetches every page with **curl** first (avoiding the headless
|
||||
browser network request) and then runs **pa11y** on the downloaded HTML
|
||||
file. Issues that appear in *every* guide are filtered out; all others
|
||||
are reported.
|
||||
|
||||
Output: output_curl.txt
|
||||
Usage:
|
||||
python check_wcag_curl.py
|
||||
Prerequisites:
|
||||
• curl (command-line tool, usually pre-installed)
|
||||
• pa11y (npm install -g pa11y # or available via npx)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Set
|
||||
|
||||
GUIDES_CSV = Path(__file__).with_name("guides.csv")
|
||||
OUTPUT_FILE = Path("output_curl.txt")
|
||||
|
||||
|
||||
def fetch_html(url: str) -> str | None:
|
||||
"""Return HTML for the URL using curl, or None on failure."""
|
||||
result = subprocess.run(
|
||||
["curl", "-L", "-sS", url],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print(f"[ERROR] curl failed ({result.returncode}) for {url}", file=sys.stderr)
|
||||
if result.stderr:
|
||||
print(result.stderr, file=sys.stderr)
|
||||
return None
|
||||
return result.stdout
|
||||
|
||||
|
||||
def run_pa11y_on_html(html: str) -> List[dict]:
|
||||
"""Run pa11y on the provided HTML string and return parsed issues list."""
|
||||
# Write HTML to a temporary file
|
||||
with tempfile.NamedTemporaryFile(suffix=".html", delete=False) as tmp:
|
||||
tmp.write(html.encode("utf-8"))
|
||||
tmp_path = Path(tmp.name)
|
||||
|
||||
cmd_base = ["pa11y"] if shutil.which("pa11y") else ["npx", "pa11y"]
|
||||
result = subprocess.run(
|
||||
[*cmd_base, f"file://{tmp_path}", "--standard", "WCAG2AA", "--reporter", "json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
# Clean up temp file
|
||||
tmp_path.unlink(missing_ok=True)
|
||||
|
||||
# pa11y exits 0 (no issues) or 1 (issues found) → both acceptable
|
||||
if result.returncode not in (0, 1):
|
||||
print(f"[ERROR] pa11y failed ({result.returncode})", file=sys.stderr)
|
||||
if result.stderr:
|
||||
print(result.stderr, file=sys.stderr)
|
||||
return []
|
||||
|
||||
if not result.stdout or not result.stdout.strip():
|
||||
print("[WARN] pa11y produced no JSON output", file=sys.stderr)
|
||||
if result.stderr:
|
||||
print(result.stderr, file=sys.stderr)
|
||||
return []
|
||||
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except json.JSONDecodeError:
|
||||
print(result.stdout, file=sys.stderr)
|
||||
print("[WARN] Could not parse pa11y JSON output", file=sys.stderr)
|
||||
return []
|
||||
|
||||
|
||||
def read_guides(csv_path: Path) -> List[Dict[str, str]]:
|
||||
with csv_path.open(newline="", encoding="utf-8-sig") as fh:
|
||||
return list(csv.DictReader(fh))
|
||||
|
||||
|
||||
def compute_common_codes(issues_by_guide: Dict[str, List[dict]]) -> Set[str]:
|
||||
common: Set[str] | None = None
|
||||
for issues in issues_by_guide.values():
|
||||
codes = {i["code"] for i in issues}
|
||||
common = codes if common is None else common & codes
|
||||
return common or set()
|
||||
|
||||
|
||||
def format_issue(issue: dict) -> str:
|
||||
selector = (issue.get("selector") or "").strip() or "N/A"
|
||||
return f"[{issue['type']}] {issue['code']}: {issue['message']} (selector: {selector})"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
guides = read_guides(GUIDES_CSV)
|
||||
issues_by_guide: Dict[str, List[dict]] = {}
|
||||
|
||||
print("Auditing guides with curl + pa11y…\n")
|
||||
for guide in guides:
|
||||
name, url = guide["Name"], guide["URL"]
|
||||
print(f"• {name} — {url}")
|
||||
|
||||
html = fetch_html(url)
|
||||
if html is None:
|
||||
issues_by_guide[name] = []
|
||||
continue
|
||||
|
||||
issues_by_guide[name] = run_pa11y_on_html(html)
|
||||
|
||||
common_codes = compute_common_codes(issues_by_guide)
|
||||
|
||||
lines: List[str] = []
|
||||
lines.append("Accessibility report (WCAG 2.1 AA — unique issues only, curl fetch)")
|
||||
lines.append("=" * 65)
|
||||
|
||||
for name, issues in issues_by_guide.items():
|
||||
unique = [i for i in issues if i["code"] not in common_codes]
|
||||
lines.append(f"\nGuide: {name}")
|
||||
if not unique:
|
||||
lines.append(" ✔ No unique issues found.")
|
||||
continue
|
||||
for issue in unique:
|
||||
lines.append(f" • {format_issue(issue)}")
|
||||
|
||||
report = "\n".join(lines)
|
||||
print("\n" + report)
|
||||
OUTPUT_FILE.write_text(report, encoding="utf-8")
|
||||
print(f"\nReport written to {OUTPUT_FILE.resolve()}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,110 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Audit each guide URL in guides.csv for WCAG 2.1 AA accessibility issues
|
||||
(using pa11y). Writes a report that omits issues appearing in *every*
|
||||
guide.
|
||||
|
||||
Output file: output2.txt
|
||||
Usage:
|
||||
python check_wcag_unique.py
|
||||
Prerequisite:
|
||||
npm install -g pa11y # or have pa11y available via npx
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Set
|
||||
|
||||
GUIDES_CSV = Path(__file__).with_name("guides.csv")
|
||||
OUTPUT_FILE = Path("output2.txt")
|
||||
|
||||
|
||||
def run_pa11y(url: str) -> List[dict]:
|
||||
"""Run pa11y on the URL and return its JSON‐parsed list of issues."""
|
||||
cmd_base = ["pa11y"] if shutil.which("pa11y") else ["npx", "pa11y"]
|
||||
result = subprocess.run(
|
||||
[*cmd_base, url, "--standard", "WCAG2AA", "--reporter", "json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
# pa11y exits 0 (no issues) or 1 (issues found). Treat both as success.
|
||||
if result.returncode not in (0, 1):
|
||||
print(f"[ERROR] pa11y failed with code {result.returncode} for {url}", file=sys.stderr)
|
||||
return []
|
||||
|
||||
# Handle cases where pa11y writes nothing (or only whitespace) to stdout.
|
||||
if result.stdout is None or not result.stdout.strip():
|
||||
if result.stderr:
|
||||
# Forward pa11y’s stderr so you can inspect what happened.
|
||||
print(result.stderr, file=sys.stderr)
|
||||
print(f"[WARN] pa11y produced no JSON output for {url}", file=sys.stderr)
|
||||
return []
|
||||
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except json.JSONDecodeError:
|
||||
# Show the raw (invalid) output to aid troubleshooting.
|
||||
print(result.stdout, file=sys.stderr)
|
||||
print(f"[WARN] Could not parse pa11y JSON output for {url}", file=sys.stderr)
|
||||
return []
|
||||
|
||||
|
||||
def read_guides(csv_path: Path) -> List[Dict[str, str]]:
|
||||
with csv_path.open(newline="", encoding="utf-8-sig") as fh:
|
||||
return list(csv.DictReader(fh))
|
||||
|
||||
|
||||
def compute_common_codes(issues_by_guide: Dict[str, List[dict]]) -> Set[str]:
|
||||
"""Return set of issue codes present in *every* guide."""
|
||||
common: Set[str] | None = None
|
||||
for issues in issues_by_guide.values():
|
||||
codes = {i["code"] for i in issues}
|
||||
common = codes if common is None else common & codes
|
||||
return common or set()
|
||||
|
||||
|
||||
def format_issue(issue: dict) -> str:
|
||||
selector = (issue.get("selector") or "").strip() or "N/A"
|
||||
return f"[{issue['type']}] {issue['code']}: {issue['message']} (selector: {selector})"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
guides = read_guides(GUIDES_CSV)
|
||||
issues_by_guide: Dict[str, List[dict]] = {}
|
||||
|
||||
print("Auditing guides with pa11y…\n")
|
||||
for guide in guides:
|
||||
name, url = guide["Name"], guide["URL"]
|
||||
print(f"• {name} — {url}")
|
||||
issues_by_guide[name] = run_pa11y(url)
|
||||
|
||||
common_codes = compute_common_codes(issues_by_guide)
|
||||
|
||||
lines: List[str] = []
|
||||
lines.append("Accessibility report (WCAG 2.1 AA — unique issues only)")
|
||||
lines.append("=" * 50)
|
||||
|
||||
for name, issues in issues_by_guide.items():
|
||||
unique = [i for i in issues if i["code"] not in common_codes]
|
||||
lines.append(f"\nGuide: {name}")
|
||||
if not unique:
|
||||
lines.append(" ✔ No unique issues found.")
|
||||
continue
|
||||
for issue in unique:
|
||||
lines.append(f" • {format_issue(issue)}")
|
||||
|
||||
report = "\n".join(lines)
|
||||
print("\n" + report)
|
||||
OUTPUT_FILE.write_text(report, encoding="utf-8")
|
||||
print(f"\nReport written to {OUTPUT_FILE.resolve()}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user