Skip to content

voidstarr/wcag-checker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WCAG Checker

A comprehensive Python library for checking HTML content against WCAG 2.2 accessibility guidelines.

Features

  • Full WCAG 2.2 Coverage: Checks against all 4 principles (Perceivable, Operable, Understandable, Robust) and 86+ success criteria
  • Multiple Conformance Levels: Target Level A, AA, or AAA compliance
  • Flexible Input: Check HTML strings or files
  • Detailed Reports: Generate reports in Text, JSON, HTML, or Markdown format
  • Actionable Feedback: Each issue includes recommendations and technique references

Installation

pip install wcag-checker

Or install from source:

git clone https://github.com/yourusername/wcag-checker
cd wcag-checker
pip install -e .

Quick Start

from wcag_checker import WCAGChecker, ConformanceLevel

# Create a checker
checker = WCAGChecker(level=ConformanceLevel.AA)

# Check HTML content
html = """
<!DOCTYPE html>
<html>
<body>
    <img src="logo.png">
    <a href="page.html">Click here</a>
</body>
</html>
"""

result = checker.check(html)

# View summary
print(result.summary())

# Iterate through issues
for issue in result.issues:
    print(f"[{issue.level.value}] {issue.criterion.id}: {issue.message}")

API Reference

WCAGChecker

The main class for checking HTML content.

from wcag_checker import WCAGChecker, ConformanceLevel

checker = WCAGChecker(
    level=ConformanceLevel.AA,      # Target conformance level (A, AA, or AAA)
    include_notices=True,            # Include informational notices
    enabled_criteria=None,           # Only run specific criteria (set of IDs)
    disabled_criteria=None,          # Skip specific criteria (set of IDs)
)

# Check HTML string
result = checker.check(html_string)

# Check HTML file
result = checker.check_file("path/to/file.html")

CheckResult

Contains the results of an accessibility check.

result = checker.check(html)

# Properties
result.issues          # List of Issue objects
result.checks_run      # Number of checks executed
result.is_compliant    # True if no errors found
result.level           # Target conformance level

# Methods
result.summary()                              # Get text summary
result.filter_by_level(IssueLevel.ERROR)     # Filter by severity
result.filter_by_criterion("1.1.1")          # Filter by WCAG criterion
result.filter_by_principle("perceivable")    # Filter by principle

Issue

Represents an accessibility issue found during checking.

for issue in result.issues:
    issue.criterion      # WCAGCriterion object
    issue.level          # IssueLevel (ERROR, WARNING, NOTICE)
    issue.message        # Description of the issue
    issue.element        # The problematic HTML element
    issue.selector       # CSS selector for the element
    issue.line           # Line number in source
    issue.context        # Surrounding HTML for context
    issue.recommendation # How to fix the issue
    issue.techniques     # WCAG technique references

Report Generation

Generate accessible reports in multiple formats.

from wcag_checker import Report, ReportFormat

result = checker.check(html)
report = Report(result)

# Generate different formats
text_report = report.to_text()
json_report = report.to_json()
html_report = report.to_html()
md_report = report.to_markdown()

# Save to file
report.save("report.html", ReportFormat.HTML)
report.save("report.json", ReportFormat.JSON)

Conformance Levels

  • Level A: Minimum level of conformance (most critical issues)
  • Level AA: Recommended for most websites (A + additional requirements)
  • Level AAA: Highest level of conformance (AA + additional requirements)
from wcag_checker import ConformanceLevel

# Check for Level A only
checker = WCAGChecker(level=ConformanceLevel.A)

# Check for Level AA (includes A)
checker = WCAGChecker(level=ConformanceLevel.AA)

# Check for Level AAA (includes A and AA)
checker = WCAGChecker(level=ConformanceLevel.AAA)

Issue Severity Levels

  • ERROR: Must be fixed for conformance
  • WARNING: Should be reviewed, likely needs fixing
  • NOTICE: Informational, may need manual verification
from wcag_checker import IssueLevel

# Get only errors
errors = result.filter_by_level(IssueLevel.ERROR)

# Exclude notices during checking
checker = WCAGChecker(include_notices=False)

Checks Included

Principle 1: Perceivable

  • 1.1.1 Non-text Content (images, SVGs, objects)
  • 1.2.1 Audio/Video alternatives
  • 1.2.2 Captions for video
  • 1.2.3 Audio descriptions
  • 1.3.1 Info and Relationships (headings, tables, lists, forms)
  • 1.3.5 Identify Input Purpose (autocomplete)
  • 1.4.1 Use of Color
  • 1.4.2 Audio Control

Principle 2: Operable

  • 2.1.1 Keyboard Accessible
  • 2.1.4 Character Key Shortcuts
  • 2.2.1 Timing Adjustable (meta refresh)
  • 2.2.2 Pause, Stop, Hide (blink, marquee)
  • 2.3.1 Three Flashes (animated GIFs)
  • 2.4.1 Bypass Blocks (skip links, landmarks)
  • 2.4.2 Page Titled
  • 2.4.4 Link Purpose
  • 2.4.6 Headings and Labels
  • 2.4.7 Focus Visible
  • 2.5.3 Label in Name
  • 2.5.7 Dragging Movements (WCAG 2.2)
  • 2.5.8 Target Size (WCAG 2.2)

Principle 3: Understandable

  • 3.1.1 Language of Page
  • 3.1.2 Language of Parts
  • 3.2.1 On Focus
  • 3.2.2 On Input
  • 3.2.6 Consistent Help (WCAG 2.2)
  • 3.3.1 Error Identification
  • 3.3.2 Labels or Instructions
  • 3.3.7 Redundant Entry (WCAG 2.2)

Principle 4: Robust

  • 4.1.1 Parsing (duplicate IDs, invalid nesting)
  • 4.1.2 Name, Role, Value (buttons, iframes, ARIA)
  • 4.1.3 Status Messages (live regions)

Command Line Usage

# Check a single file
python -m wcag_checker check page.html

# Check with specific level
python -m wcag_checker check page.html --level AAA

# Generate HTML report
python -m wcag_checker check page.html --format html --output report.html

Extending

You can create custom checks by extending the BaseCheck class:

from wcag_checker.checks.base import BaseCheck, register_check
from wcag_checker.criteria import SC_1_1_1

@register_check
class MyCustomCheck(BaseCheck):
    criterion = SC_1_1_1
    description = "My custom accessibility check"
    
    def check(self):
        issues = []
        # Your checking logic here
        for element in self.soup.find_all('my-element'):
            if not element.get('accessible-attr'):
                issues.append(Issue(
                    criterion=self.criterion,
                    level=IssueLevel.ERROR,
                    message="Missing accessible attribute",
                    element=str(element),
                    selector=self.get_element_selector(element),
                ))
        return issues

License

MIT License - see LICENSE file for details.

References

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages