rails_accessibility_testing 1.5.5 → 1.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,529 +5,158 @@ title: Architecture
5
5
 
6
6
  # Architecture Overview
7
7
 
8
- This page provides visual diagrams and explanations of how the Rails Accessibility Testing gem works internally.
8
+ This guide explains how Rails Accessibility Testing works under the hood in simple terms.
9
9
 
10
10
  ---
11
11
 
12
- ## High-Level System Architecture
12
+ ## The Big Picture
13
13
 
14
- The gem integrates seamlessly into your Rails application through multiple layers:
14
+ 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.
15
15
 
16
- ```mermaid
17
- graph TB
18
- subgraph "Rails Application"
19
- App[Your Rails App]
20
- Tests[System Tests/Specs]
21
- Views[Views & Partials]
22
- Routes[Routes & Controllers]
23
- end
24
-
25
- subgraph "Rails Accessibility Testing Gem"
26
- Entry[Gem Entry Point]
27
- Railtie[Rails Integration Layer]
28
-
29
- subgraph "Test Integration"
30
- RSpec[RSpec Integration]
31
- Minitest[Minitest Integration]
32
- AutoHook[Automatic Test Hooks]
33
- end
34
-
35
- subgraph "Core Engine"
36
- RuleEngine[Rule Engine]
37
- Checks[11+ Accessibility Checks]
38
- Collector[Violation Collector]
39
- end
40
-
41
- subgraph "Intelligence Layer"
42
- ViewDetector[View File Detector]
43
- PartialDetector[Partial Detection]
44
- ChangeDetector[Change Detector]
45
- Cache[Page Scanning Cache]
46
- end
47
-
48
- subgraph "Configuration"
49
- YAMLConfig[YAML Config Loader]
50
- Profiles[Profile Manager]
51
- RubyConfig[Ruby Configuration]
52
- end
53
-
54
- subgraph "Output & Reporting"
55
- ErrorBuilder[Error Message Builder]
56
- CLI[CLI Tool]
57
- Reports[Reports & Logs]
58
- end
59
- end
60
-
61
- subgraph "Testing Tools"
62
- Capybara[Capybara]
63
- Selenium[Selenium WebDriver]
64
- AxeCore[axe-core Engine]
65
- end
66
-
67
- Tests --> RSpec
68
- Tests --> Minitest
69
- RSpec --> AutoHook
70
- Minitest --> AutoHook
71
- App --> Railtie
72
- Entry --> Railtie
73
-
74
- AutoHook --> Cache
75
- Cache --> ViewDetector
76
- ViewDetector --> ChangeDetector
77
- ChangeDetector --> RuleEngine
78
- RuleEngine --> YAMLConfig
79
- YAMLConfig --> Profiles
80
- RuleEngine --> Checks
81
- Checks --> Capybara
82
- Capybara --> Selenium
83
- Checks --> AxeCore
84
- Checks --> ViewDetector
85
- ViewDetector --> PartialDetector
86
- PartialDetector --> Views
87
- Checks --> Collector
88
- Collector --> ErrorBuilder
89
- ErrorBuilder --> Reports
90
-
91
- CLI --> RuleEngine
92
- Routes --> ViewDetector
93
-
94
- style Entry fill:#ff6b6b
95
- style RuleEngine fill:#4ecdc4
96
- style Checks fill:#45b7d1
97
- style ViewDetector fill:#96ceb4
98
- style ErrorBuilder fill:#ffeaa7
99
- style Cache fill:#a29bfe
100
- ```
101
-
102
- ---
16
+ ### Core Concept
103
17
 
104
- ## Request Flow - How It Works
105
-
106
- This sequence diagram shows the complete flow when a test runs:
107
-
108
- ```mermaid
109
- sequenceDiagram
110
- participant Dev as Developer
111
- participant Test as Test Suite
112
- participant Hook as Auto Hooks
113
- participant Cache as Scan Cache
114
- participant Detector as View Detector
115
- participant Change as Change Detector
116
- participant Engine as Rule Engine
117
- participant Checks as 11 Check Modules
118
- participant Capybara as Capybara/Browser
119
- participant Collector as Violation Collector
120
- participant Builder as Error Builder
121
- participant Report as Test Report
122
-
123
- Dev->>Test: Run test suite
124
- Test->>Hook: Execute system test
125
- Hook->>Test: visit('/some/path')
126
- Test->>Capybara: Load page
127
- Capybara->>Test: Page loaded
128
-
129
- rect rgb(200, 220, 250)
130
- Note over Hook,Cache: Performance Optimization
131
- Hook->>Cache: Check if page scanned
132
- alt Page already scanned
133
- Cache->>Hook: Skip (cached)
134
- else Not in cache
135
- Cache->>Detector: Continue with scan
136
- end
137
- end
138
-
139
- rect rgb(220, 250, 220)
140
- Note over Detector,Change: Smart Detection
141
- Detector->>Change: Check for file changes
142
- Change->>Change: Analyze views/partials/assets
143
- alt No changes detected
144
- Change->>Hook: Skip scan (no changes)
145
- else Changes detected
146
- Change->>Engine: Proceed with checks
147
- end
148
- end
149
-
150
- rect rgb(250, 220, 220)
151
- Note over Engine,Checks: Accessibility Checks
152
- Engine->>Checks: Run enabled checks
153
- loop For each check (11 total)
154
- Checks->>Capybara: Query DOM elements
155
- Capybara->>Checks: Return elements
156
- Checks->>Checks: Validate WCAG rules
157
- Checks->>Collector: Report violations
158
- end
159
- end
160
-
161
- rect rgb(250, 240, 200)
162
- Note over Collector,Report: Error Reporting
163
- Collector->>Detector: Map violations to files
164
- Detector->>Detector: Find view files
165
- Detector->>Detector: Detect partials
166
- Detector->>Builder: Pass file locations
167
- Builder->>Builder: Format error messages
168
- Builder->>Report: Generate detailed report
169
- end
170
-
171
- alt Violations found
172
- Report->>Test: Fail with detailed errors
173
- Test->>Dev: Show actionable errors
174
- else No violations
175
- Report->>Test: Pass
176
- Test->>Dev: ✓ Accessibility checks passed
177
- end
178
- ```
179
-
180
- ---
181
-
182
- ## Core Components
183
-
184
- ### 1. Entry & Integration Layer
185
-
186
- The gem integrates with Rails through the Railtie system and automatically hooks into your test framework:
18
+ 1. **You run a test** (or the static scanner watches your files).
19
+ 2. **The Gem activates** and scans the content.
20
+ 3. **11 Checks run** to find accessibility violations.
21
+ 4. **Errors are reported** with the exact file and line number to fix.
187
22
 
188
23
  ```mermaid
189
24
  graph LR
190
- A[Rails App Boots] --> B[Railtie Initializes]
191
- B --> C[Load Configuration]
192
- C --> D[Setup Test Hooks]
193
- D --> E1[RSpec Integration]
194
- D --> E2[Minitest Integration]
195
- E1 --> F[Auto-run after each visit]
196
- E2 --> F
197
-
198
- style B fill:#ff6b6b
199
- style E1 fill:#74b9ff
200
- style E2 fill:#a29bfe
25
+ A[Your Code] --> B[Rails A11y Gem]
26
+ B --> C[Compliance Checks]
27
+ C --> D[Clear Error Report]
28
+
29
+ style A fill:#ff6b6b
30
+ style B fill:#4ecdc4
31
+ style C fill:#45b7d1
32
+ style D fill:#ffeaa7
201
33
  ```
202
34
 
203
- **Key Files:**
204
- - `railtie.rb` - Rails initialization
205
- - `rspec_integration.rb` - RSpec auto-hooks
206
- - `integration/minitest_integration.rb` - Minitest helpers
207
-
208
35
  ---
209
36
 
210
- ### 2. Core Rule Engine
211
-
212
- The rule engine orchestrates all accessibility checks:
213
-
214
- ```mermaid
215
- graph TB
216
- A[Rule Engine] --> B[Load Configuration]
217
- B --> C[Apply Profiles]
218
- C --> D[Filter Enabled Checks]
219
- D --> E[Execute Checks in Order]
220
-
221
- E --> F1[Form Labels]
222
- E --> F2[Image Alt Text]
223
- E --> F3[Interactive Elements]
224
- E --> F4[Heading Hierarchy]
225
- E --> F5[Keyboard Access]
226
- E --> F6[ARIA Landmarks]
227
- E --> F7[Form Errors]
228
- E --> F8[Table Structure]
229
- E --> F9[Duplicate IDs]
230
- E --> F10[Skip Links]
231
- E --> F11[Color Contrast]
232
-
233
- F1 --> G[Collect Violations]
234
- F2 --> G
235
- F3 --> G
236
- F4 --> G
237
- F5 --> G
238
- F6 --> G
239
- F7 --> G
240
- F8 --> G
241
- F9 --> G
242
- F10 --> G
243
- F11 --> G
244
-
245
- style A fill:#4ecdc4
246
- style G fill:#ffeaa7
247
- ```
37
+ ## Two Ways to Scan
248
38
 
249
- **Key Features:**
250
- - Profile-based configuration (dev/test/ci)
251
- - Individual check enable/disable
252
- - WCAG 2.1 AA aligned checks
253
- - Violation aggregation
39
+ The gem provides two main ways to check your application. Both share the same "brain" (the Rule Engine) but work differently.
254
40
 
255
- ---
41
+ ### 1. System Tests (Browser-Based)
256
42
 
257
- ### 3. Intelligence Layer (v1.5.0+)
43
+ This is the most accurate method. It runs while your standard Rails system tests (RSpec/Minitest) are executing.
258
44
 
259
- Smart detection and performance optimization:
45
+ * **When it runs:** Automatically when you visit a page in a test (`visit root_path`).
46
+ * **What it does:** It looks at the *rendered* page in the browser (Chrome/Chromium).
47
+ * **Best for:** Finding issues that only appear after JavaScript runs or CSS is applied.
260
48
 
261
49
  ```mermaid
262
- graph TB
263
- subgraph "View Detection System"
264
- A[Page URL] --> B[Route Recognition]
265
- B --> C{Exact Match?}
266
- C -->|Yes| D[Found View File]
267
- C -->|No| E[Fuzzy Matching]
268
- E --> F[Scan Controller Dir]
269
- F --> D
270
- D --> G[Scan for Partials]
271
- G --> H[Map Elements to Partials]
272
- end
273
-
274
- subgraph "Performance System"
275
- I[Page Visit] --> J{In Cache?}
276
- J -->|Yes| K[Skip Scan]
277
- J -->|No| L[Check Changes]
278
- L --> M{Files Changed?}
279
- M -->|No| N[Skip Scan]
280
- M -->|Yes| O[Run Checks]
281
- O --> P[Add to Cache]
282
- end
283
-
284
- style B fill:#96ceb4
285
- style J fill:#a29bfe
286
- style L fill:#fdcb6e
287
- ```
288
-
289
- **Key Features:**
290
- - **View File Detection**: Finds exact view file from URL
291
- - **Partial Detection**: Maps issues to specific partials
292
- - **Change Detection**: Only tests modified pages
293
- - **Page Cache**: Prevents duplicate scans
294
-
295
- ---
296
-
297
- ### 4. Error Reporting System
298
-
299
- Generate actionable error messages with precise file locations:
300
-
301
- ```mermaid
302
- graph TB
303
- A[Violations Collected] --> B[View File Detector]
304
- B --> C{Main View Found?}
305
- C -->|Yes| D[Partial Detector]
306
- C -->|No| E[URL Only]
307
- D --> F{In Partial?}
308
- F -->|Yes| G[Partial Path]
309
- F -->|No| H[Main View Path]
310
-
311
- G --> I[Error Message Builder]
312
- H --> I
313
- E --> I
314
-
315
- I --> J[Format Message]
316
- J --> K[Add Fix Suggestions]
317
- K --> L[Add WCAG Reference]
318
- L --> M[Add Element Context]
319
- M --> N[Formatted Error Report]
320
-
321
- style B fill:#96ceb4
322
- style I fill:#ffeaa7
323
- style N fill:#ff7675
50
+ sequenceDiagram
51
+ participant Test as Your Test
52
+ participant Gem as Rails A11y
53
+ participant Browser as Browser
54
+
55
+ Test->>Browser: visit('/page')
56
+ Browser->>Gem: "Page is ready!"
57
+ Gem->>Browser: "Scan this page now"
58
+ Browser->>Gem: "Found 2 errors"
59
+ Gem->>Test: Fails test with details
324
60
  ```
325
61
 
326
- **Error Report Includes:**
327
- - Page URL and path
328
- - View file and partial location
329
- - Element details (tag, ID, classes)
330
- - Fix suggestions with code examples
331
- - WCAG 2.1 reference links
332
-
333
- ---
62
+ ### 2. Static Scanner (File-Based)
334
63
 
335
- ## Data Flow Example
64
+ This is the fast method for development. It scans your source code files directly without opening a browser.
336
65
 
337
- ### Scenario: Detecting an Image Without Alt Text
66
+ * **When it runs:** Continuously in the background (via `bin/dev`) or manually.
67
+ * **What it does:** Reads your `.html.erb` files, converts them to HTML, and checks them.
68
+ * **Best for:** Instant feedback as you type code.
338
69
 
339
70
  ```mermaid
340
- sequenceDiagram
341
- participant T as Test
342
- participant H as Accessibility Helper
343
- participant C as Page Cache
344
- participant V as View Detector
345
- participant R as Rule Engine
346
- participant I as Image Alt Check
347
- participant P as Partial Detector
348
- participant E as Error Builder
349
-
350
- T->>H: visit('/products/search')
351
- H->>C: Check cache for '/products/search'
352
- C->>H: Not in cache
353
- H->>V: Detect view file
354
- V->>V: Route → products#search_results
355
- V->>V: Find search_results.html.erb
356
- V->>H: View file located
357
- H->>R: Run accessibility checks
358
- R->>I: Execute image alt check
359
- I->>I: Find all img elements
360
- I->>I: Check for alt attribute
361
- I->>I: Found violation: <img src="logo.png">
362
- I->>P: Detect if in partial
363
- P->>P: Scan search_results.html.erb
364
- P->>P: Found render 'shared/header'
365
- P->>P: Element is in _header.html.erb
366
- P->>I: Partial location
367
- I->>R: Report violation with context
368
- R->>E: Build error message
369
- E->>E: Format with file paths
370
- E->>E: Add fix suggestions
371
- E->>T: Fail test with detailed error
71
+ graph LR
72
+ A[ERB File] -->|Read| B[Converter]
73
+ B -->|HTML| C[Scanner]
74
+ C -->|Errors| D[Console Output]
372
75
 
373
- rect rgb(255, 200, 200)
374
- Note over T: Test fails with error showing:<br/>View: products/search_results.html.erb<br/>Partial: shared/_header.html.erb<br/>Fix: Add alt="Company Logo"
375
- end
76
+ style A fill:#ff6b6b
77
+ style C fill:#4ecdc4
376
78
  ```
377
79
 
378
80
  ---
379
81
 
380
- ## Performance Optimization
82
+ ## Key Components
381
83
 
382
- ### Caching & Change Detection Strategy
84
+ Here are the main parts of the gem and what they do:
383
85
 
384
- ```mermaid
385
- graph TB
386
- A[Page Visit] --> B{In Page Cache?}
387
- B -->|Yes| C[Skip Scan]
388
- B -->|No| D{First Run?}
389
- D -->|Yes| E[Scan All Pages]
390
- D -->|No| F{Files Changed?}
391
- F -->|No| G[Skip Scan]
392
- F -->|Yes| H[Smart Scan]
393
-
394
- H --> I{Which Files?}
395
- I -->|View| J[Scan This Page]
396
- I -->|Partial| K[Scan Pages Using Partial]
397
- I -->|Helper| L[Scan All Pages]
398
- I -->|Asset| M[Scan All Pages]
399
-
400
- E --> N[Add to Cache]
401
- J --> N
402
- K --> N
403
- L --> N
404
- M --> N
405
-
406
- style B fill:#a29bfe
407
- style F fill:#fdcb6e
408
- style N fill:#55efc4
409
- ```
86
+ ### 🧠 The Rule Engine
87
+ The "brain" of the operation. It:
88
+ - Reads your configuration (`config/accessibility.yml`).
89
+ - Decides which checks to run.
90
+ - Coordinates the checking process.
410
91
 
411
- ### Impact Analysis
92
+ ### 🕵️ The Checks
93
+ There are **11 specialized agents**, each looking for a specific type of problem:
94
+ 1. **Form Labels** (Do inputs have labels?)
95
+ 2. **Image Alt Text** (Do images have descriptions?)
96
+ 3. **Headings** (Is the document structure logical?)
97
+ 4. **Color Contrast** (Is text readable?)
98
+ 5. ...and 7 others.
412
99
 
413
- Different file changes have different impacts:
100
+ ### 📍 View Detector
101
+ This smart component figures out **where** the error came from.
102
+ - If an error is found on a page, it traces it back to the exact View file (`app/views/...`) or Partial (`_form.html.erb`) that generated it.
414
103
 
415
- | File Type | Impact | Action |
416
- |-----------|--------|--------|
417
- | Main View | Single page | Test that page only |
418
- | Partial | Multiple pages | Test all pages using partial |
419
- | Controller | Controller routes | Test all routes for controller |
420
- | Helper | Global | Test all pages |
421
- | CSS/JS | Global | Test all pages |
422
- | Layout | Global | Test all pages |
104
+ ### Performance System
105
+ To keep your tests fast, the gem uses:
106
+ - **Caching:** Remembers pages it has already scanned so it doesn't scan them twice.
107
+ - **Change Detection:** In the static scanner, it only checks files that you have modified.
423
108
 
424
109
  ---
425
110
 
426
- ## CLI Architecture
111
+ ## How Static Scanning Works (Simplified)
112
+
113
+ The static scanner is a "pipeline" that transforms your Ruby code into something we can test.
427
114
 
428
- Command-line scanning for standalone usage:
115
+ 1. **Watch:** It watches your file system for changes.
116
+ 2. **Extract:** When you save a file, it pulls out the HTML and standardizes Rails helpers (like converting `link_to` to `<a href...>`).
117
+ 3. **Test:** It runs the standard accessibility checks on this "virtual" page.
118
+ 4. **Report:** If it finds issues, it maps them back to the line number in your original file.
429
119
 
430
120
  ```mermaid
431
121
  graph TB
432
- A[rails_a11y CLI] --> B[Command Parser]
433
- B --> C{Command Type?}
434
-
435
- C -->|check| D[URL/Path Scanner]
436
- C -->|generate| E[Generator]
437
-
438
- D --> F[Start Rails Server]
439
- F --> G[Visit URL]
440
- G --> H[Run Checks]
441
- H --> I[Generate Report]
442
-
443
- I --> J{Format?}
444
- J -->|human| K[Pretty Terminal Output]
445
- J -->|json| L[JSON Report File]
446
-
447
- style A fill:#6c5ce7
448
- style I fill:#ffeaa7
449
- ```
450
-
451
- **Commands:**
452
- - `check` - Scan URLs or routes
453
- - `--format json` - Generate JSON reports
454
- - `--profile ci` - Use specific profile
455
-
456
- ---
457
-
458
- ## Extension Points
459
-
460
- ### Adding Custom Checks
461
-
462
- The gem is designed to be extensible:
463
-
464
- ```ruby
465
- # lib/custom_checks/my_check.rb
466
- module RailsAccessibilityTesting
467
- module Checks
468
- class MyCustomCheck < BaseCheck
469
- def self.rule_name
470
- :my_custom_check
471
- end
472
-
473
- def check
474
- violations = []
475
- # Your check logic here
476
- # Access: page, context, partial detection
477
- violations
478
- end
479
- end
480
- end
481
- end
122
+ User[You Save a File] --> Watcher[File Watcher]
123
+ Watcher --> Extractor[HTML Extractor]
124
+ Extractor --> Checker[Accessibility Checks]
125
+ Checker --> Report[Error Message]
126
+
127
+ style User fill:#ff6b6b
128
+ style Checker fill:#4ecdc4
129
+ style Report fill:#ffeaa7
482
130
  ```
483
131
 
484
132
  ---
485
133
 
486
- ## Key Design Patterns
487
-
488
- ### 1. Modular Check System
134
+ ## Configuration & Profiles
489
135
 
490
- Each check is self-contained and independently configurable.
136
+ You can change how the gem behaves using **Profiles**.
491
137
 
492
- ### 2. Progressive Enhancement
138
+ * **Development Profile:**
139
+ * Optimized for speed.
140
+ * Skips slow checks (like color contrast).
141
+ * Runs on changed files only.
142
+ * **CI (Continuous Integration) Profile:**
143
+ * Optimized for thoroughness.
144
+ * Runs ALL checks (including strict ones).
145
+ * Ensures zero violations before merging code.
493
146
 
494
- - **Level 1**: Just add gem → automatic checks
495
- - **Level 2**: Configure via YAML → customize checks
496
- - **Level 3**: Profiles → environment-specific configs
497
- - **Level 4**: Custom checks → extend functionality
498
-
499
- ### 3. Smart Caching & Detection
500
-
501
- Performance optimizations that work transparently:
502
- - Page cache prevents duplicate scans
503
- - Change detection only tests modified files
504
- - First-run establishes baseline, then incremental
505
-
506
- ### 4. Developer Experience First
507
-
508
- Every feature prioritizes DX:
509
- - Automatic hooks (zero configuration)
510
- - Detailed errors (exact file locations)
511
- - Fix suggestions (code examples)
512
- - Beautiful output (color-coded reports)
147
+ Configuration happens in `config/accessibility.yml`.
513
148
 
514
149
  ---
515
150
 
516
- ## Summary
151
+ ## Directory Structure
517
152
 
518
- The Rails Accessibility Testing gem provides:
153
+ Quick map of where important things live in the gem:
519
154
 
520
- **Seamless Integration** - Auto-hooks into Rails test suite
521
- **Intelligent Detection** - Finds exact files to fix
522
- **Performance Optimized** - Smart caching and change detection
523
- **Developer Friendly** - Detailed errors with fix suggestions
524
- ✅ **Highly Configurable** - Profile-based configuration
525
- ✅ **Extensible** - Easy to add custom checks
526
- ✅ **Production Ready** - Comprehensive WCAG 2.1 AA checks
155
+ - **`lib/rails_accessibility_testing/checks/`**: The 11 individual accessibility rules.
156
+ - **`lib/rails_accessibility_testing/engine/`**: The logic that runs the checks.
157
+ - **`lib/rails_accessibility_testing/static_file_scanner.rb`**: The file-based scanning logic.
158
+ - **`exe/`**: Command line tools (like `rails_a11y`).
527
159
 
528
160
  ---
529
161
 
530
- **For more details, see the [ARCHITECTURE.md](https://github.com/rayraycodes/rails-accessibility-testing/blob/main/ARCHITECTURE.md) file in the repository.**
531
-
532
- **Version**: 1.5.0
533
- **Last Updated**: 2025-11-20
162
+ *This architecture is designed to be invisible when it works, and helpful when it finds problems.*