Rails Accessibility Testing

The RSpec + RuboCop of accessibility for Rails

Architecture Overview

This guide explains how Rails Accessibility Testing works under the hood in simple terms.


The Big Picture

The gem sits between your Rails Application and standard accessibility tools (like axe-core). It acts as a bridge that automatically checks your code for issues.

Core Concept

  1. You run a test (or the static scanner watches your files).
  2. The Gem activates and scans the content.
  3. 11 Checks run to find accessibility violations.
  4. Errors are reported with the exact file and line number to fix.
graph LR
    A[Your Code] --> B[Rails A11y Gem]
    B --> C[Compliance Checks]
    C --> D[Clear Error Report]
    
    style A fill:#ff6b6b
    style B fill:#4ecdc4
    style C fill:#45b7d1
    style D fill:#ffeaa7

Two Ways to Scan

The gem provides two main ways to check your application. Both share the same “brain” (the Rule Engine) but work differently.

1. System Tests (Browser-Based)

This is the most accurate method. It runs while your standard Rails system tests (RSpec/Minitest) are executing.

sequenceDiagram
    participant Test as Your Test
    participant Gem as Rails A11y
    participant Browser as Browser
    
    Test->>Browser: visit('/page')
    Browser->>Gem: "Page is ready!"
    Gem->>Browser: "Scan this page now"
    Browser->>Gem: "Found 2 errors"
    Gem->>Test: Fails test with details

2. Static Scanner (File-Based)

This is the fast method for development. It scans your source code files directly without opening a browser.

graph LR
    A[ERB File] -->|Read| B[Converter]
    B -->|HTML| C[Scanner]
    C -->|Errors| D[Console Output]
    
    style A fill:#ff6b6b
    style C fill:#4ecdc4

Key Components

Here are the main parts of the gem and what they do:

🧠 The Rule Engine

The “brain” of the operation. It:

🕵️ The Checks

There are 11 specialized agents, each looking for a specific type of problem:

  1. Form Labels (Do inputs have labels?)
  2. Image Alt Text (Do images have descriptions?)
  3. Headings (Is the document structure logical?)
  4. Color Contrast (Is text readable?)
  5. …and 7 others.

📍 View Detector

This smart component figures out where the error came from.

⚡ Performance System

To keep your tests fast, the gem uses:


How Static Scanning Works (Simplified)

The static scanner is a “pipeline” that transforms your Ruby code into something we can test.

  1. Watch: It watches your file system for changes.
  2. Extract: When you save a file, it pulls out the HTML and standardizes Rails helpers (like converting link_to to <a href...>).
  3. Test: It runs the standard accessibility checks on this “virtual” page.
  4. Report: If it finds issues, it maps them back to the line number in your original file.
graph TB
    User[You Save a File] --> Watcher[File Watcher]
    Watcher --> Extractor[HTML Extractor]
    Extractor --> Checker[Accessibility Checks]
    Checker --> Report[Error Message]
    
    style User fill:#ff6b6b
    style Checker fill:#4ecdc4
    style Report fill:#ffeaa7

Configuration & Profiles

You can change how the gem behaves using Profiles.

Configuration happens in config/accessibility.yml.


Directory Structure

Quick map of where important things live in the gem:


This architecture is designed to be invisible when it works, and helpful when it finds problems.