rails_accessibility_testing 1.5.3 → 1.5.5
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.
- checksums.yaml +4 -4
- data/ARCHITECTURE.md +376 -1
- data/CHANGELOG.md +63 -1
- data/GUIDES/getting_started.md +40 -5
- data/GUIDES/system_specs_for_accessibility.md +12 -4
- data/README.md +52 -8
- data/docs_site/Gemfile.lock +89 -0
- data/docs_site/_config.yml +9 -0
- data/docs_site/_includes/header.html +1 -0
- data/docs_site/_layouts/default.html +754 -15
- data/docs_site/architecture.md +533 -0
- data/docs_site/index.md +2 -1
- data/exe/a11y_live_scanner +10 -39
- data/exe/a11y_static_scanner +333 -0
- data/lib/generators/rails_a11y/install/install_generator.rb +19 -30
- data/lib/generators/rails_a11y/install/templates/accessibility.yml.erb +39 -0
- data/lib/generators/rails_a11y/install/templates/all_pages_accessibility_spec.rb.erb +132 -45
- data/lib/rails_accessibility_testing/accessibility_helper.rb +131 -126
- data/lib/rails_accessibility_testing/checks/base_check.rb +14 -5
- data/lib/rails_accessibility_testing/checks/form_errors_check.rb +1 -1
- data/lib/rails_accessibility_testing/checks/form_labels_check.rb +6 -4
- data/lib/rails_accessibility_testing/checks/heading_check.rb +7 -15
- data/lib/rails_accessibility_testing/checks/image_alt_text_check.rb +1 -1
- data/lib/rails_accessibility_testing/checks/interactive_elements_check.rb +12 -8
- data/lib/rails_accessibility_testing/config/yaml_loader.rb +20 -0
- data/lib/rails_accessibility_testing/erb_extractor.rb +141 -0
- data/lib/rails_accessibility_testing/error_message_builder.rb +11 -6
- data/lib/rails_accessibility_testing/file_change_tracker.rb +95 -0
- data/lib/rails_accessibility_testing/line_number_finder.rb +61 -0
- data/lib/rails_accessibility_testing/rspec_integration.rb +74 -33
- data/lib/rails_accessibility_testing/shared_examples.rb +2 -0
- data/lib/rails_accessibility_testing/static_file_scanner.rb +80 -0
- data/lib/rails_accessibility_testing/static_page_adapter.rb +116 -0
- data/lib/rails_accessibility_testing/static_scanning.rb +61 -0
- data/lib/rails_accessibility_testing/version.rb +3 -1
- data/lib/rails_accessibility_testing/violation_converter.rb +80 -0
- data/lib/rails_accessibility_testing.rb +9 -1
- metadata +26 -2
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Architecture
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Architecture Overview
|
|
7
|
+
|
|
8
|
+
This page provides visual diagrams and explanations of how the Rails Accessibility Testing gem works internally.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## High-Level System Architecture
|
|
13
|
+
|
|
14
|
+
The gem integrates seamlessly into your Rails application through multiple layers:
|
|
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
|
+
---
|
|
103
|
+
|
|
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:
|
|
187
|
+
|
|
188
|
+
```mermaid
|
|
189
|
+
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
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Key Files:**
|
|
204
|
+
- `railtie.rb` - Rails initialization
|
|
205
|
+
- `rspec_integration.rb` - RSpec auto-hooks
|
|
206
|
+
- `integration/minitest_integration.rb` - Minitest helpers
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
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
|
+
```
|
|
248
|
+
|
|
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
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### 3. Intelligence Layer (v1.5.0+)
|
|
258
|
+
|
|
259
|
+
Smart detection and performance optimization:
|
|
260
|
+
|
|
261
|
+
```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
|
|
324
|
+
```
|
|
325
|
+
|
|
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
|
+
---
|
|
334
|
+
|
|
335
|
+
## Data Flow Example
|
|
336
|
+
|
|
337
|
+
### Scenario: Detecting an Image Without Alt Text
|
|
338
|
+
|
|
339
|
+
```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
|
|
372
|
+
|
|
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
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Performance Optimization
|
|
381
|
+
|
|
382
|
+
### Caching & Change Detection Strategy
|
|
383
|
+
|
|
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
|
+
```
|
|
410
|
+
|
|
411
|
+
### Impact Analysis
|
|
412
|
+
|
|
413
|
+
Different file changes have different impacts:
|
|
414
|
+
|
|
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 |
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## CLI Architecture
|
|
427
|
+
|
|
428
|
+
Command-line scanning for standalone usage:
|
|
429
|
+
|
|
430
|
+
```mermaid
|
|
431
|
+
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
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Key Design Patterns
|
|
487
|
+
|
|
488
|
+
### 1. Modular Check System
|
|
489
|
+
|
|
490
|
+
Each check is self-contained and independently configurable.
|
|
491
|
+
|
|
492
|
+
### 2. Progressive Enhancement
|
|
493
|
+
|
|
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)
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Summary
|
|
517
|
+
|
|
518
|
+
The Rails Accessibility Testing gem provides:
|
|
519
|
+
|
|
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
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
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
|
data/docs_site/index.md
CHANGED
|
@@ -7,7 +7,7 @@ title: Home
|
|
|
7
7
|
|
|
8
8
|
**The RSpec + RuboCop of accessibility for Rails. Catch WCAG violations before they reach production.**
|
|
9
9
|
|
|
10
|
-
**Version:** 1.
|
|
10
|
+
**Version:** 1.5.5
|
|
11
11
|
|
|
12
12
|
Rails Accessibility Testing is a comprehensive accessibility testing gem that makes accessibility testing as natural as unit testing. It integrates seamlessly into your Rails workflow, catching WCAG 2.1 AA violations as you code—not after deployment.
|
|
13
13
|
|
|
@@ -44,6 +44,7 @@ bundle exec rspec spec/system/
|
|
|
44
44
|
## Documentation
|
|
45
45
|
|
|
46
46
|
- [Getting Started]({{ '/getting_started.html' | relative_url }}) - Quick start guide
|
|
47
|
+
- [Architecture]({{ '/architecture.html' | relative_url }}) - Visual diagrams and internal architecture
|
|
47
48
|
- [Configuration]({{ '/configuration.html' | relative_url }}) - Configuration options
|
|
48
49
|
- [CI Integration]({{ '/ci_integration.html' | relative_url }}) - CI/CD setup
|
|
49
50
|
- [Contributing]({{ '/contributing.html' | relative_url }}) - How to contribute
|
data/exe/a11y_live_scanner
CHANGED
|
@@ -113,54 +113,28 @@ def check_page(path, url = nil)
|
|
|
113
113
|
return nil
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
#
|
|
117
|
-
puts "\n" + "="*70
|
|
118
|
-
puts "🔍 Starting accessibility scan..."
|
|
119
|
-
puts "="*70
|
|
120
|
-
puts "📍 Path: #{path}"
|
|
121
|
-
puts "🔗 URL: #{url || path}"
|
|
122
|
-
puts "⏰ Time: #{Time.now.strftime('%H:%M:%S')}"
|
|
123
|
-
puts "="*70
|
|
124
|
-
puts ""
|
|
125
|
-
|
|
126
|
-
# Visit the page
|
|
127
|
-
puts " 🌐 Loading page..."
|
|
116
|
+
# Visit the page silently
|
|
128
117
|
visit path
|
|
129
118
|
|
|
130
119
|
# Check for cancellation after page load
|
|
131
120
|
if $scan_cancelled || $current_scan_target != path
|
|
132
|
-
puts "⏭️ Scan cancelled - user navigated to different page"
|
|
133
121
|
return nil
|
|
134
122
|
end
|
|
135
123
|
|
|
136
|
-
# Capybara already waits for page load, no need for explicit sleep
|
|
137
|
-
# Only wait if page hasn't loaded (Capybara handles this automatically)
|
|
138
|
-
|
|
139
124
|
# Get page details
|
|
140
125
|
current_url = page.current_url rescue path
|
|
141
|
-
page_title = page.title rescue 'Unknown'
|
|
142
126
|
|
|
143
127
|
# Skip if redirected to sign in
|
|
144
128
|
if current_url.include?('sign_in') || current_url.include?('login')
|
|
145
129
|
puts "⏭️ Skipping #{path}: requires authentication"
|
|
146
|
-
puts " Redirected to: #{current_url}"
|
|
147
130
|
return nil
|
|
148
131
|
end
|
|
149
132
|
|
|
150
133
|
# Check for cancellation before running checks
|
|
151
134
|
if $scan_cancelled || $current_scan_target != path
|
|
152
|
-
puts "⏭️ Scan cancelled - user navigated to different page"
|
|
153
135
|
return nil
|
|
154
136
|
end
|
|
155
137
|
|
|
156
|
-
# Show page details
|
|
157
|
-
puts " ✓ Page loaded successfully"
|
|
158
|
-
puts " 📄 Title: #{page_title}"
|
|
159
|
-
puts " 🔗 Final URL: #{current_url}"
|
|
160
|
-
puts ""
|
|
161
|
-
puts " 🔍 Running accessibility checks..."
|
|
162
|
-
puts ""
|
|
163
|
-
|
|
164
138
|
# Run accessibility checks using Capybara page directly
|
|
165
139
|
# Verify AccessibilityHelper is available
|
|
166
140
|
unless defined?(RailsAccessibilityTesting::AccessibilityHelper)
|
|
@@ -192,12 +166,15 @@ def check_page(path, url = nil)
|
|
|
192
166
|
return nil
|
|
193
167
|
end
|
|
194
168
|
|
|
195
|
-
# Show scan completion
|
|
169
|
+
# Show scan completion - only show errors in live scanner
|
|
196
170
|
puts ""
|
|
197
171
|
puts "="*70
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
172
|
+
if result && result.is_a?(Hash) && result[:errors] && result[:errors] > 0
|
|
173
|
+
puts "❌ Found #{result[:errors]} error#{'s' if result[:errors] != 1} in: #{path}"
|
|
174
|
+
view_file = result[:page_context][:view_file] if result[:page_context]
|
|
175
|
+
puts " 📝 File: #{view_file}" if view_file
|
|
176
|
+
else
|
|
177
|
+
puts "✅ No errors found in: #{path}"
|
|
201
178
|
end
|
|
202
179
|
puts "="*70
|
|
203
180
|
puts ""
|
|
@@ -311,14 +288,8 @@ def run_scanner
|
|
|
311
288
|
save_scanned_page(path, timestamp)
|
|
312
289
|
|
|
313
290
|
# Show that we detected a new page visit
|
|
314
|
-
|
|
315
|
-
puts "
|
|
316
|
-
puts "📥 NEW PAGE VISIT DETECTED"
|
|
317
|
-
puts "="*70
|
|
318
|
-
puts " Path: #{path}"
|
|
319
|
-
puts " URL: #{url}"
|
|
320
|
-
puts " Visited at: #{visit_time.strftime('%H:%M:%S')}"
|
|
321
|
-
puts " Starting scan..."
|
|
291
|
+
puts "\n" + "="*70
|
|
292
|
+
puts "📥 Scanning new page: #{path}"
|
|
322
293
|
puts "="*70
|
|
323
294
|
|
|
324
295
|
# Run check with URL info
|