Metadata-Version: 2.4
Name: wcag-checker
Version: 0.2.0
Summary: A comprehensive Python library for checking HTML content against WCAG 2.2 accessibility guidelines
Author: WCAG Checker Team
License: MIT
Project-URL: Homepage, https://github.com/wcag-checker/wcag-checker
Project-URL: Documentation, https://wcag-checker.readthedocs.io
Project-URL: Repository, https://github.com/wcag-checker/wcag-checker
Keywords: wcag,accessibility,a11y,html,validation,wcag22
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: beautifulsoup4>=4.12.0
Requires-Dist: lxml>=4.9.0
Requires-Dist: cssutils>=2.7.0
Requires-Dist: Pillow>=10.0.0
Requires-Dist: colormath>=3.0.0
Requires-Dist: tinycss2>=1.2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"

# 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

```bash
pip install wcag-checker
```

Or install from source:

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

## Quick Start

```python
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.

```python
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.

```python
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.

```python
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.

```python
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)

```python
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

```python
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

```bash
# 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:

```python
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

- [WCAG 2.2 Specification](https://www.w3.org/TR/WCAG22/)
- [WCAG 2.2 Understanding Documents](https://www.w3.org/WAI/WCAG22/Understanding/)
- [WCAG 2.2 Techniques](https://www.w3.org/WAI/WCAG22/Techniques/)
