rails_accessibility_testing 1.4.2 → 1.5.0
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 +212 -53
- data/CHANGELOG.md +135 -0
- data/GUIDES/getting_started.md +171 -9
- data/GUIDES/system_specs_for_accessibility.md +13 -12
- data/README.md +139 -36
- data/docs_site/getting_started.md +142 -18
- data/docs_site/index.md +1 -1
- data/exe/a11y_live_scanner +361 -0
- data/exe/rails_server_safe +18 -1
- data/lib/generators/rails_a11y/install/install_generator.rb +137 -0
- data/lib/rails_accessibility_testing/accessibility_helper.rb +547 -24
- data/lib/rails_accessibility_testing/change_detector.rb +17 -104
- data/lib/rails_accessibility_testing/checks/base_check.rb +56 -7
- data/lib/rails_accessibility_testing/checks/heading_check.rb +138 -0
- data/lib/rails_accessibility_testing/checks/image_alt_text_check.rb +7 -7
- data/lib/rails_accessibility_testing/checks/interactive_elements_check.rb +11 -1
- data/lib/rails_accessibility_testing/cli/command.rb +3 -1
- data/lib/rails_accessibility_testing/config/yaml_loader.rb +1 -1
- data/lib/rails_accessibility_testing/engine/rule_engine.rb +49 -5
- data/lib/rails_accessibility_testing/error_message_builder.rb +63 -7
- data/lib/rails_accessibility_testing/middleware/page_visit_logger.rb +81 -0
- data/lib/rails_accessibility_testing/railtie.rb +22 -0
- data/lib/rails_accessibility_testing/rspec_integration.rb +176 -10
- data/lib/rails_accessibility_testing/version.rb +1 -1
- data/lib/rails_accessibility_testing.rb +8 -3
- metadata +8 -4
- data/lib/generators/rails_a11y/install/generator.rb +0 -51
- data/lib/rails_accessibility_testing/checks/heading_hierarchy_check.rb +0 -53
data/GUIDES/getting_started.md
CHANGED
|
@@ -15,10 +15,18 @@ Add to your `Gemfile`:
|
|
|
15
15
|
```ruby
|
|
16
16
|
group :development, :test do
|
|
17
17
|
gem 'rails_accessibility_testing'
|
|
18
|
+
gem 'rspec-rails', '~> 8.0' # Required for system specs
|
|
18
19
|
gem 'axe-core-capybara', '~> 4.0'
|
|
20
|
+
gem 'capybara', '~> 3.40'
|
|
21
|
+
gem 'selenium-webdriver', '~> 4.0'
|
|
22
|
+
gem 'webdrivers', '~> 5.0' # Optional but recommended for automatic driver management
|
|
19
23
|
end
|
|
20
24
|
```
|
|
21
25
|
|
|
26
|
+
**Important:**
|
|
27
|
+
- You must explicitly add `selenium-webdriver` to your Gemfile. It's not automatically included as a dependency.
|
|
28
|
+
- **RSpec Rails is required** - The generator creates system specs that require `rspec-rails`. If you're using Minitest, you'll need to manually create your accessibility tests.
|
|
29
|
+
|
|
22
30
|
Then run:
|
|
23
31
|
|
|
24
32
|
```bash
|
|
@@ -36,7 +44,11 @@ rails generate rails_a11y:install
|
|
|
36
44
|
This creates:
|
|
37
45
|
- `config/initializers/rails_a11y.rb` - Configuration
|
|
38
46
|
- `config/accessibility.yml` - Check settings
|
|
47
|
+
- `spec/system/all_pages_accessibility_spec.rb` - Comprehensive spec that tests all GET routes with smart change detection
|
|
39
48
|
- Updates `spec/rails_helper.rb` (if using RSpec)
|
|
49
|
+
- Updates `Procfile.dev` - Adds accessibility watch command (optional)
|
|
50
|
+
|
|
51
|
+
**Note:** If you already have system tests set up in your Rails application, you can skip to Step 3. If you need help configuring Capybara or installing Chrome, see the [FAQ section](#troubleshooting) below.
|
|
40
52
|
|
|
41
53
|
### Step 3: Run Your Tests
|
|
42
54
|
|
|
@@ -52,7 +64,7 @@ Accessibility checks run automatically on every system test that visits a page.
|
|
|
52
64
|
|
|
53
65
|
#### Option B: Run Continuously with Procfile (Recommended for Development)
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
The generator automatically adds an accessibility watch command to your `Procfile.dev`:
|
|
56
68
|
|
|
57
69
|
```procfile
|
|
58
70
|
web: bin/rails server
|
|
@@ -73,6 +85,28 @@ This will:
|
|
|
73
85
|
|
|
74
86
|
The accessibility checker will continuously monitor your pages and alert you to any issues as you develop!
|
|
75
87
|
|
|
88
|
+
#### Option C: All Pages Spec with Smart Change Detection
|
|
89
|
+
|
|
90
|
+
The generator creates `spec/system/all_pages_accessibility_spec.rb` which automatically tests all GET routes in your application. This spec includes **smart change detection**:
|
|
91
|
+
|
|
92
|
+
- **Only tests pages when their related files change** - Views, controllers, or helpers
|
|
93
|
+
- **Detects changes via Git** - Uncommitted changes in monitored directories (`app/views`, `app/controllers`, `app/helpers`)
|
|
94
|
+
- **File modification tracking** - Files changed in the last 5 minutes
|
|
95
|
+
- **Layout/helper changes** - Automatically tests all pages when layouts or helpers change (they affect everything)
|
|
96
|
+
- **First run** - Tests all pages on first run (when no changes detected)
|
|
97
|
+
- **Manual override** - Set `TEST_ALL_PAGES=true` to force testing all pages regardless of changes
|
|
98
|
+
|
|
99
|
+
This makes your test suite faster and more focused, only running checks when relevant code changes. The spec automatically:
|
|
100
|
+
- Skips routes that require authentication
|
|
101
|
+
- Handles routes with parameters
|
|
102
|
+
- Filters out API routes and Rails internal routes
|
|
103
|
+
- Provides clear skip messages when pages aren't affected by changes
|
|
104
|
+
|
|
105
|
+
Run it manually:
|
|
106
|
+
```bash
|
|
107
|
+
bundle exec rspec spec/system/all_pages_accessibility_spec.rb
|
|
108
|
+
```
|
|
109
|
+
|
|
76
110
|
## Your First Accessibility Check
|
|
77
111
|
|
|
78
112
|
Let's see it in action. Create a simple system spec:
|
|
@@ -93,13 +127,12 @@ end
|
|
|
93
127
|
While checks run automatically after each `visit`, you can also run comprehensive checks explicitly at any point in your test:
|
|
94
128
|
|
|
95
129
|
```ruby
|
|
96
|
-
# spec/system/
|
|
130
|
+
# spec/system/my_page_accessibility_spec.rb
|
|
97
131
|
require 'rails_helper'
|
|
98
132
|
|
|
99
|
-
RSpec.describe '
|
|
133
|
+
RSpec.describe 'My Page Accessibility', type: :system do
|
|
100
134
|
it 'loads the page and runs comprehensive accessibility checks' do
|
|
101
135
|
visit root_path
|
|
102
|
-
expect(page).to have_content('Welcome')
|
|
103
136
|
|
|
104
137
|
# Run comprehensive accessibility checks explicitly
|
|
105
138
|
# This will fail the test if any accessibility issues are found
|
|
@@ -160,14 +193,14 @@ Rails A11y runs **11 comprehensive checks** automatically. These checks are WCAG
|
|
|
160
193
|
|
|
161
194
|
1. **Form Labels** - All form inputs have associated labels
|
|
162
195
|
2. **Image Alt Text** - All images have descriptive alt attributes (including empty alt="" detection)
|
|
163
|
-
3. **Interactive Elements** - Buttons, links, and other interactive elements have accessible names
|
|
164
|
-
4. **Heading Hierarchy** - Proper h1-h6 structure without skipping levels
|
|
196
|
+
3. **Interactive Elements** - Buttons, links, and other interactive elements have accessible names (including links with images that have alt text)
|
|
197
|
+
4. **Heading Hierarchy** - Proper h1-h6 structure without skipping levels (detects missing h1, skipped levels, and h2+ without h1)
|
|
165
198
|
5. **Keyboard Accessibility** - All interactive elements are keyboard accessible
|
|
166
199
|
6. **ARIA Landmarks** - Proper use of ARIA landmark roles for page structure
|
|
167
200
|
7. **Form Error Associations** - Form errors are properly linked to their form fields
|
|
168
201
|
8. **Table Structure** - Tables have proper headers and structure
|
|
169
202
|
9. **Duplicate IDs** - No duplicate ID attributes on the page
|
|
170
|
-
10. **Skip Links** - Skip navigation links are present for keyboard users
|
|
203
|
+
10. **Skip Links** - Skip navigation links are present for keyboard users (detects various patterns: `skip-link`, `skiplink`, `href="#main"`, `href="#maincontent"`, etc.)
|
|
171
204
|
11. **Color Contrast** - Text meets WCAG contrast requirements (optional, disabled by default for performance)
|
|
172
205
|
|
|
173
206
|
### What `check_comprehensive_accessibility` Does
|
|
@@ -250,6 +283,135 @@ end
|
|
|
250
283
|
- **Check out [Writing Accessible Views](writing_accessible_views_in_rails.md)** for best practices
|
|
251
284
|
- **See [Working with Designers](working_with_designers_and_content_authors.md)** for team collaboration
|
|
252
285
|
|
|
286
|
+
## Troubleshooting
|
|
287
|
+
|
|
288
|
+
### How do I configure Capybara for system tests?
|
|
289
|
+
|
|
290
|
+
If you don't already have system tests configured, you need to set up Capybara with a Selenium driver. Create `spec/support/driver.rb`:
|
|
291
|
+
|
|
292
|
+
```ruby
|
|
293
|
+
# spec/support/driver.rb
|
|
294
|
+
require 'selenium-webdriver'
|
|
295
|
+
require 'capybara/rails'
|
|
296
|
+
require 'capybara/rspec'
|
|
297
|
+
|
|
298
|
+
# Configure Chrome options
|
|
299
|
+
browser_options = Selenium::WebDriver::Chrome::Options.new
|
|
300
|
+
browser_options.add_argument('--window-size=1920,1080')
|
|
301
|
+
browser_options.add_argument('--headless') unless ENV['SHOW_TEST_BROWSER']
|
|
302
|
+
|
|
303
|
+
# Register the driver
|
|
304
|
+
Capybara.register_driver :selenium_chrome_headless do |app|
|
|
305
|
+
Capybara::Selenium::Driver.new(
|
|
306
|
+
app,
|
|
307
|
+
browser: :chrome,
|
|
308
|
+
options: browser_options
|
|
309
|
+
)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Set as default JavaScript driver
|
|
313
|
+
Capybara.javascript_driver = :selenium_chrome_headless
|
|
314
|
+
|
|
315
|
+
# Configure RSpec to use the driver for system tests
|
|
316
|
+
RSpec.configure do |config|
|
|
317
|
+
config.before(:each, type: :system) do
|
|
318
|
+
driven_by :selenium_chrome_headless
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Note for Rails 8:** Rails 8 uses `driven_by` to configure system tests. Make sure your `spec/support/driver.rb` is loaded by `rails_helper.rb` (it should be automatically loaded if it's in the `spec/support/` directory).
|
|
324
|
+
|
|
325
|
+
### How do I install Chrome/Chromium?
|
|
326
|
+
|
|
327
|
+
System tests require Chrome or Chromium to be installed on your system:
|
|
328
|
+
|
|
329
|
+
**macOS:**
|
|
330
|
+
```bash
|
|
331
|
+
brew install --cask google-chrome
|
|
332
|
+
# or for Chromium:
|
|
333
|
+
brew install --cask chromium
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Linux (Ubuntu/Debian):**
|
|
337
|
+
```bash
|
|
338
|
+
sudo apt-get update
|
|
339
|
+
sudo apt-get install -y google-chrome-stable
|
|
340
|
+
# or for Chromium:
|
|
341
|
+
sudo apt-get install -y chromium-browser
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Windows:**
|
|
345
|
+
Download and install Chrome from [google.com/chrome](https://www.google.com/chrome/)
|
|
346
|
+
|
|
347
|
+
The `webdrivers` gem will automatically download and manage the ChromeDriver binary for you.
|
|
348
|
+
|
|
349
|
+
### Error: `uninitialized constant Selenium::WebDriver::DriverFinder`
|
|
350
|
+
|
|
351
|
+
This error typically occurs when:
|
|
352
|
+
1. **Missing selenium-webdriver gem** - Make sure you've added `gem 'selenium-webdriver', '~> 4.0'` to your Gemfile
|
|
353
|
+
2. **Version incompatibility** - Ensure you're using compatible versions:
|
|
354
|
+
- `selenium-webdriver` ~> 4.0 (4.6.0+ recommended for Rails 8)
|
|
355
|
+
- `webdrivers` ~> 5.0 (if using webdrivers)
|
|
356
|
+
- `capybara` ~> 3.40
|
|
357
|
+
|
|
358
|
+
**Solution:**
|
|
359
|
+
```bash
|
|
360
|
+
# Update your Gemfile
|
|
361
|
+
gem 'selenium-webdriver', '~> 4.10'
|
|
362
|
+
gem 'webdrivers', '~> 5.3'
|
|
363
|
+
gem 'capybara', '~> 3.40'
|
|
364
|
+
|
|
365
|
+
# Then run
|
|
366
|
+
bundle update selenium-webdriver webdrivers capybara
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Error: Chrome/ChromeDriver not found
|
|
370
|
+
|
|
371
|
+
**Solution:**
|
|
372
|
+
1. Make sure Chrome is installed (see Step 3 above)
|
|
373
|
+
2. If using `webdrivers` gem, it should auto-download ChromeDriver. If not:
|
|
374
|
+
```bash
|
|
375
|
+
bundle exec webdrivers chrome
|
|
376
|
+
```
|
|
377
|
+
3. For manual installation, download from [ChromeDriver downloads](https://chromedriver.chromium.org/downloads)
|
|
378
|
+
|
|
379
|
+
### System tests not running
|
|
380
|
+
|
|
381
|
+
**Check:**
|
|
382
|
+
1. Your spec has `type: :system` metadata
|
|
383
|
+
2. `spec/support/driver.rb` exists and is properly configured
|
|
384
|
+
3. `spec/rails_helper.rb` loads support files (should be automatic)
|
|
385
|
+
4. Chrome is installed and accessible
|
|
386
|
+
|
|
387
|
+
### Tests are slow
|
|
388
|
+
|
|
389
|
+
Disable expensive checks in development:
|
|
390
|
+
```yaml
|
|
391
|
+
# config/accessibility.yml
|
|
392
|
+
development:
|
|
393
|
+
checks:
|
|
394
|
+
color_contrast: false # Disable expensive color contrast checks
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Version Compatibility
|
|
398
|
+
|
|
399
|
+
For best results, use these compatible versions:
|
|
400
|
+
|
|
401
|
+
| Component | Recommended Version | Minimum Version | Required |
|
|
402
|
+
|-----------|-------------------|-----------------|----------|
|
|
403
|
+
| Ruby | 3.1+ | 3.0+ | Yes |
|
|
404
|
+
| Rails | 7.1+ / 8.0+ | 6.0+ | Yes |
|
|
405
|
+
| **RSpec Rails** | **8.0+** | **6.0+** | **Yes (for system specs)** |
|
|
406
|
+
| Capybara | ~> 3.40 | 3.0+ | Yes |
|
|
407
|
+
| selenium-webdriver | ~> 4.10 | 4.0+ | Yes |
|
|
408
|
+
| webdrivers | ~> 5.3 | 5.0+ | Optional |
|
|
409
|
+
|
|
410
|
+
**Rails 8 Notes:**
|
|
411
|
+
- Rails 8 requires `selenium-webdriver` 4.6.0+ for `DriverFinder` support
|
|
412
|
+
- Make sure your `driven_by` configuration is in `spec/support/driver.rb`
|
|
413
|
+
- Rails 8 system tests use `driven_by` instead of direct Capybara configuration
|
|
414
|
+
|
|
253
415
|
## Common Questions
|
|
254
416
|
|
|
255
417
|
### Q: Do I need to change my existing tests?
|
|
@@ -271,8 +433,8 @@ end
|
|
|
271
433
|
## Getting Help
|
|
272
434
|
|
|
273
435
|
- **Documentation:** See the main [README](../README.md)
|
|
274
|
-
- **Issues:** [GitHub Issues](https://github.com/
|
|
275
|
-
- **Email:**
|
|
436
|
+
- **Issues:** [GitHub Issues](https://github.com/rayraycodes/rails-accessibility-testing/issues)
|
|
437
|
+
- **Email:** imregan@umich.edu
|
|
276
438
|
|
|
277
439
|
---
|
|
278
440
|
|
|
@@ -12,18 +12,19 @@ System specs are the **recommended and most reliable** way to run accessibility
|
|
|
12
12
|
|
|
13
13
|
## Quick Setup
|
|
14
14
|
|
|
15
|
-
### 1.
|
|
15
|
+
### 1. Use the Generated Specs
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The generator creates `spec/system/all_pages_accessibility_spec.rb` which automatically tests all GET routes in your application with **smart change detection**. This spec only tests pages when their related files (views, controllers, helpers) have changed, making it fast and focused.
|
|
18
|
+
|
|
19
|
+
You can also create custom system specs for specific pages. Name them with `_accessibility_spec.rb` suffix for clarity:
|
|
18
20
|
|
|
19
21
|
```ruby
|
|
20
|
-
# spec/system/
|
|
22
|
+
# spec/system/my_page_accessibility_spec.rb
|
|
21
23
|
require 'rails_helper'
|
|
22
24
|
|
|
23
|
-
RSpec.describe '
|
|
25
|
+
RSpec.describe 'My Page Accessibility', type: :system do
|
|
24
26
|
it 'loads the page and runs comprehensive accessibility checks' do
|
|
25
27
|
visit root_path
|
|
26
|
-
expect(page).to have_content('Biorepository').or have_content('Welcome')
|
|
27
28
|
|
|
28
29
|
# Run comprehensive accessibility checks
|
|
29
30
|
# This will fail the test if any accessibility issues are found
|
|
@@ -37,27 +38,27 @@ end
|
|
|
37
38
|
|
|
38
39
|
The gem automatically runs comprehensive accessibility checks after each `visit` in system specs. You don't need to call `check_comprehensive_accessibility` manually unless you want to run checks at a specific point in your test.
|
|
39
40
|
|
|
40
|
-
### 3.
|
|
41
|
+
### 3. Continuous Testing with Procfile (Optional)
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
The generator automatically adds an accessibility watch command to your `Procfile.dev`:
|
|
43
44
|
|
|
44
45
|
```ruby
|
|
45
|
-
web:
|
|
46
|
+
web: bin/rails server
|
|
46
47
|
css: bin/rails dartsass:watch
|
|
47
48
|
a11y: while true; do bundle exec rspec spec/system/*_accessibility_spec.rb; sleep 30; done
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
This will run your accessibility specs every 30 seconds while you develop.
|
|
51
|
+
This will run your accessibility specs every 30 seconds while you develop. The `all_pages_accessibility_spec.rb` uses smart change detection to only test pages when their related files change, making it fast and focused.
|
|
51
52
|
|
|
52
53
|
## Example Specs
|
|
53
54
|
|
|
54
55
|
### Basic Page Check
|
|
55
56
|
|
|
56
57
|
```ruby
|
|
57
|
-
# spec/system/
|
|
58
|
+
# spec/system/my_page_accessibility_spec.rb
|
|
58
59
|
require 'rails_helper'
|
|
59
60
|
|
|
60
|
-
RSpec.describe '
|
|
61
|
+
RSpec.describe 'My Page Accessibility', type: :system do
|
|
61
62
|
it 'runs accessibility checks on the home page' do
|
|
62
63
|
visit root_path
|
|
63
64
|
# ✅ Comprehensive accessibility checks run automatically after this test!
|
|
@@ -189,7 +190,7 @@ bundle exec rspec spec/system/*_accessibility_spec.rb
|
|
|
189
190
|
### Run Specific Spec
|
|
190
191
|
|
|
191
192
|
```bash
|
|
192
|
-
bundle exec rspec spec/system/
|
|
193
|
+
bundle exec rspec spec/system/all_pages_accessibility_spec.rb
|
|
193
194
|
```
|
|
194
195
|
|
|
195
196
|
### Run with Documentation Format
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
**The RSpec + RuboCop of accessibility for Rails. Catch WCAG violations before they reach production.**
|
|
9
9
|
|
|
10
|
-
**Current Version:** 1.
|
|
10
|
+
**Current Version:** 1.5.0
|
|
11
11
|
|
|
12
12
|
📖 **[📚 Full Documentation](https://rayraycodes.github.io/rails-accessibility-testing/)** | [💻 GitHub](https://github.com/rayraycodes/rails-accessibility-testing) | [💎 RubyGems](https://rubygems.org/gems/rails_accessibility_testing)
|
|
13
13
|
|
|
@@ -19,16 +19,40 @@ Rails Accessibility Testing fills a critical gap in the Rails testing ecosystem.
|
|
|
19
19
|
|
|
20
20
|
## ✨ Features
|
|
21
21
|
|
|
22
|
+
### Core Capabilities
|
|
22
23
|
- 🚀 **Zero Configuration** - Works out of the box with smart defaults
|
|
23
24
|
- 🎯 **11+ Comprehensive Checks** - WCAG 2.1 AA aligned
|
|
24
|
-
- 📍 **File Location
|
|
25
|
+
- 📍 **Precise File Location** - Know exactly which view file or partial to fix
|
|
25
26
|
- 🔧 **Actionable Error Messages** - Code examples showing how to fix issues
|
|
26
|
-
- ⚡ **Smart Change Detection** - Only runs when relevant code changes
|
|
27
27
|
- 🎨 **Beautiful CLI** - Human-readable and JSON reports
|
|
28
28
|
- 🔌 **Rails Generator** - One command setup
|
|
29
29
|
- 🧪 **RSpec & Minitest** - Works with both test frameworks
|
|
30
30
|
- ⚙️ **YAML Configuration** - Profile-based config (dev/test/CI)
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
### 🆕 Version 1.5.0 Highlights
|
|
33
|
+
|
|
34
|
+
#### Smart View File Detection
|
|
35
|
+
- **Intelligent matching**: Automatically finds view files even when action names don't match (e.g., `search` action → `search_result.html.erb`)
|
|
36
|
+
- **Controller directory scanning**: Searches all view files to find the correct template
|
|
37
|
+
- **Fuzzy matching**: Handles variations and naming conventions
|
|
38
|
+
|
|
39
|
+
#### Advanced Partial Detection
|
|
40
|
+
- **Automatic partial discovery**: Scans view files to detect all rendered partials
|
|
41
|
+
- **Multi-location search**: Finds partials in controller dirs, `shared/`, and `layouts/`
|
|
42
|
+
- **Namespaced support**: Handles paths like `layouts/navbar` or `shared/forms/input`
|
|
43
|
+
- **Element-to-partial mapping**: Shows exact partial file when issues are found
|
|
44
|
+
|
|
45
|
+
#### Performance Optimizations
|
|
46
|
+
- **Page scanning cache**: Prevents duplicate scans of the same page
|
|
47
|
+
- **Smart change detection**: Only tests pages when relevant files change
|
|
48
|
+
- **First-run optimization**: Tests all pages initially, then only changed files
|
|
49
|
+
- **Asset change detection**: Detects CSS/JS changes and their impact
|
|
50
|
+
|
|
51
|
+
#### Enhanced Developer Experience
|
|
52
|
+
- **Friendly test summaries**: Clear passed/failed/skipped counts with reasons
|
|
53
|
+
- **Progress indicators**: Real-time feedback during checks
|
|
54
|
+
- **Cleaner output**: Suppressed verbose skipped test messages
|
|
55
|
+
- **Better error context**: Shows view files, partials, and element details
|
|
32
56
|
|
|
33
57
|
## 🚀 Quick Start
|
|
34
58
|
|
|
@@ -39,12 +63,17 @@ Add to your `Gemfile`:
|
|
|
39
63
|
```ruby
|
|
40
64
|
group :development, :test do
|
|
41
65
|
gem 'rails_accessibility_testing'
|
|
66
|
+
gem 'rspec-rails', '~> 8.0' # Required for system specs
|
|
42
67
|
gem 'axe-core-capybara', '~> 4.0'
|
|
43
|
-
|
|
44
|
-
|
|
68
|
+
gem 'capybara', '~> 3.40'
|
|
69
|
+
gem 'selenium-webdriver', '~> 4.0'
|
|
70
|
+
gem 'webdrivers', '~> 5.0' # Optional but recommended
|
|
71
|
+
gem 'csv' # Required for Ruby 3.3+ (CSV removed from standard library in Ruby 3.4)
|
|
45
72
|
end
|
|
46
73
|
```
|
|
47
74
|
|
|
75
|
+
**Important:** You must explicitly add `selenium-webdriver` and `csv` (for Ruby 3.3+) to your Gemfile. The gem has minimal dependencies - you control your own driver setup.
|
|
76
|
+
|
|
48
77
|
Then run:
|
|
49
78
|
|
|
50
79
|
```bash
|
|
@@ -62,7 +91,9 @@ rails generate rails_a11y:install
|
|
|
62
91
|
This creates:
|
|
63
92
|
- `config/initializers/rails_a11y.rb` - Configuration
|
|
64
93
|
- `config/accessibility.yml` - Check settings
|
|
94
|
+
- `spec/system/all_pages_accessibility_spec.rb` - Comprehensive spec that dynamically tests all GET routes
|
|
65
95
|
- Updates `spec/rails_helper.rb` (if using RSpec)
|
|
96
|
+
- Updates `Procfile.dev` with accessibility watch command (if present)
|
|
66
97
|
|
|
67
98
|
### Setup (Option 2: Manual)
|
|
68
99
|
|
|
@@ -97,7 +128,7 @@ require 'rails_helper'
|
|
|
97
128
|
RSpec.describe 'Home Page Accessibility', type: :system do
|
|
98
129
|
it 'loads successfully and passes comprehensive accessibility checks' do
|
|
99
130
|
visit root_path
|
|
100
|
-
expect(page).to have_content('
|
|
131
|
+
expect(page).to have_content('Welcome')
|
|
101
132
|
|
|
102
133
|
# Run comprehensive accessibility checks
|
|
103
134
|
check_comprehensive_accessibility
|
|
@@ -108,25 +139,22 @@ end
|
|
|
108
139
|
|
|
109
140
|
**Accessibility checks run automatically after each `visit` in system specs!**
|
|
110
141
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
For continuous accessibility checking during development, add to your `Procfile.dev`:
|
|
114
|
-
|
|
115
|
-
```procfile
|
|
116
|
-
web: bin/rails server
|
|
117
|
-
css: bin/rails dartsass:watch
|
|
118
|
-
a11y: while true; do bundle exec rspec spec/system/*_accessibility_spec.rb; sleep 30; done
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Then run:
|
|
142
|
+
### All Pages Accessibility Spec
|
|
122
143
|
|
|
123
|
-
|
|
124
|
-
bin/dev
|
|
125
|
-
```
|
|
144
|
+
The generator creates `spec/system/all_pages_accessibility_spec.rb` which automatically tests all GET routes in your application. The spec:
|
|
126
145
|
|
|
127
|
-
|
|
146
|
+
- **Dynamically discovers routes** at runtime - works for any Rails app
|
|
147
|
+
- **Smart change detection** - Only tests pages when their related files (views, controllers, helpers, CSS/JS) have changed
|
|
148
|
+
- **First-run optimization** - Tests all pages on first run, then only changed files
|
|
149
|
+
- **Intelligent skipping** - Skips routes that require authentication, have errors, or aren't accessible
|
|
150
|
+
- **Friendly summaries** - Shows passed/failed/skipped counts with clear reasons
|
|
128
151
|
|
|
129
|
-
|
|
152
|
+
The spec automatically:
|
|
153
|
+
- Tests all GET routes (filters out API, internal Rails routes)
|
|
154
|
+
- Handles routes with parameters by substituting test values
|
|
155
|
+
- Detects view files even when action names don't match
|
|
156
|
+
- Shows which files changed and which pages are affected
|
|
157
|
+
- Provides helpful tips and next steps
|
|
130
158
|
|
|
131
159
|
### Automatic Checks
|
|
132
160
|
|
|
@@ -166,6 +194,18 @@ it "meets all accessibility standards" do
|
|
|
166
194
|
end
|
|
167
195
|
```
|
|
168
196
|
|
|
197
|
+
### Continuous Development Testing
|
|
198
|
+
|
|
199
|
+
Add to your `Procfile.dev`:
|
|
200
|
+
|
|
201
|
+
```ruby
|
|
202
|
+
web: $(bundle show rails_accessibility_testing)/exe/rails_server_safe
|
|
203
|
+
css: bin/rails dartsass:watch
|
|
204
|
+
a11y: while true; do bin/check_a11y_changes && (test -f bin/rspec && bin/rspec spec/system/*_accessibility_spec.rb --format progress --no-profile || bundle exec rspec spec/system/*_accessibility_spec.rb --format progress --no-profile) 2>&1 | grep -v "^[[:space:]]*[0-9]*)[[:space:]]*All Pages Accessibility checks accessibility" | grep -v "# Skipping" || echo '⏭️ No changes detected, skipping tests'; sleep 30; done
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
This runs accessibility tests every 30 seconds, but only when files have changed!
|
|
208
|
+
|
|
169
209
|
### CLI Usage
|
|
170
210
|
|
|
171
211
|
Run checks against URLs or Rails routes:
|
|
@@ -193,14 +233,14 @@ The gem automatically runs **11 comprehensive accessibility checks**:
|
|
|
193
233
|
|
|
194
234
|
1. ✅ **Form Labels** - All form inputs have associated labels
|
|
195
235
|
2. ✅ **Image Alt Text** - All images have descriptive alt attributes
|
|
196
|
-
3. ✅ **Interactive Elements** - Buttons, links have accessible names
|
|
197
|
-
4. ✅ **Heading Hierarchy** - Proper h1-h6 structure
|
|
236
|
+
3. ✅ **Interactive Elements** - Buttons, links have accessible names (including links with images that have alt text)
|
|
237
|
+
4. ✅ **Heading Hierarchy** - Proper h1-h6 structure (detects missing h1, multiple h1s, skipped levels, and h2+ without h1)
|
|
198
238
|
5. ✅ **Keyboard Accessibility** - All interactive elements keyboard accessible
|
|
199
239
|
6. ✅ **ARIA Landmarks** - Proper use of ARIA landmark roles
|
|
200
240
|
7. ✅ **Form Error Associations** - Errors linked to form fields
|
|
201
241
|
8. ✅ **Table Structure** - Tables have proper headers
|
|
202
242
|
9. ✅ **Duplicate IDs** - No duplicate ID attributes
|
|
203
|
-
10. ✅ **Skip Links** - Skip navigation links present
|
|
243
|
+
10. ✅ **Skip Links** - Skip navigation links present (detects various patterns)
|
|
204
244
|
11. ✅ **Color Contrast** - Text meets contrast requirements (optional)
|
|
205
245
|
|
|
206
246
|
## ⚙️ Configuration
|
|
@@ -218,7 +258,7 @@ checks:
|
|
|
218
258
|
form_labels: true
|
|
219
259
|
image_alt_text: true
|
|
220
260
|
interactive_elements: true
|
|
221
|
-
|
|
261
|
+
heading: true # Note: renamed from heading_hierarchy in 1.5.0
|
|
222
262
|
keyboard_accessibility: true
|
|
223
263
|
aria_landmarks: true
|
|
224
264
|
form_errors: true
|
|
@@ -265,7 +305,7 @@ end
|
|
|
265
305
|
|
|
266
306
|
## 📋 Example Error Output
|
|
267
307
|
|
|
268
|
-
When accessibility issues are found, you get detailed, actionable errors:
|
|
308
|
+
When accessibility issues are found, you get detailed, actionable errors with precise file locations:
|
|
269
309
|
|
|
270
310
|
```
|
|
271
311
|
======================================================================
|
|
@@ -273,9 +313,10 @@ When accessibility issues are found, you get detailed, actionable errors:
|
|
|
273
313
|
======================================================================
|
|
274
314
|
|
|
275
315
|
📄 Page Being Tested:
|
|
276
|
-
URL: http://localhost:3000/
|
|
277
|
-
Path: /
|
|
278
|
-
📝
|
|
316
|
+
URL: http://localhost:3000/items/search
|
|
317
|
+
Path: /items/search
|
|
318
|
+
📝 View File: app/views/items/search_result.html.erb
|
|
319
|
+
📝 Partial: app/views/layouts/_advance_search.html.erb
|
|
279
320
|
|
|
280
321
|
📍 Element Details:
|
|
281
322
|
Tag: <img>
|
|
@@ -295,10 +336,40 @@ When accessibility issues are found, you get detailed, actionable errors:
|
|
|
295
336
|
💡 Best Practice: All images must have alt attribute.
|
|
296
337
|
Use empty alt="" only for purely decorative images.
|
|
297
338
|
|
|
298
|
-
📖 WCAG Reference: https://www.w3.org/WAI/WCAG21/Understanding/
|
|
339
|
+
📖 WCAG Reference: https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html
|
|
299
340
|
======================================================================
|
|
300
341
|
```
|
|
301
342
|
|
|
343
|
+
**Notice:** The error shows both the main view file (`search_result.html.erb`) and the partial where the issue actually occurs (`_advance_search.html.erb`). This makes fixing issues much faster!
|
|
344
|
+
|
|
345
|
+
## 🚀 Performance Features
|
|
346
|
+
|
|
347
|
+
### Smart Change Detection
|
|
348
|
+
|
|
349
|
+
The gem automatically detects when files change and only tests affected pages:
|
|
350
|
+
|
|
351
|
+
- **View files**: Tests pages when their view files change
|
|
352
|
+
- **Partials**: Tests pages that render changed partials
|
|
353
|
+
- **Controllers**: Tests all routes for a controller when the controller changes
|
|
354
|
+
- **Helpers**: Tests all pages when helpers change (they can affect any view)
|
|
355
|
+
- **Assets**: Tests all pages when CSS/JS changes (can affect accessibility globally)
|
|
356
|
+
|
|
357
|
+
### Page Scanning Cache
|
|
358
|
+
|
|
359
|
+
Prevents duplicate scans of the same page during a test run:
|
|
360
|
+
|
|
361
|
+
- **Automatic caching**: Each page is scanned once per test suite execution
|
|
362
|
+
- **Efficient tracking**: Uses page path or URL as cache key
|
|
363
|
+
- **Silent skipping**: Already-scanned pages are skipped without output
|
|
364
|
+
- **Manual reset**: Use `reset_scanned_pages_cache` if needed
|
|
365
|
+
|
|
366
|
+
### First-Run Optimization
|
|
367
|
+
|
|
368
|
+
- **Initial baseline**: Tests all pages on first run to establish baseline
|
|
369
|
+
- **Subsequent runs**: Only tests changed files for faster feedback
|
|
370
|
+
- **Marker file**: Creates `.rails_a11y_initialized` to track first run
|
|
371
|
+
- **Force all pages**: Set `TEST_ALL_PAGES=true` to test all pages anytime
|
|
372
|
+
|
|
302
373
|
## 📚 Documentation
|
|
303
374
|
|
|
304
375
|
### 🌐 Online Documentation
|
|
@@ -334,9 +405,12 @@ View at `doc/index.html`
|
|
|
334
405
|
|
|
335
406
|
Rails Accessibility Testing is built with a clean, modular architecture:
|
|
336
407
|
|
|
337
|
-
- **Rule Engine** - Evaluates accessibility checks
|
|
338
|
-
- **Check Definitions** - WCAG-aligned check implementations
|
|
408
|
+
- **Rule Engine** - Evaluates accessibility checks with configurable profiles
|
|
409
|
+
- **Check Definitions** - WCAG-aligned check implementations (11+ checks)
|
|
339
410
|
- **Violation Collector** - Aggregates and formats violations
|
|
411
|
+
- **View File Detection** - Intelligent detection of view files and partials
|
|
412
|
+
- **Change Detector** - Smart detection of file changes and their impact
|
|
413
|
+
- **Page Scanning Cache** - Prevents duplicate scans for performance
|
|
340
414
|
- **Rails Integration** - Railtie, RSpec, Minitest helpers
|
|
341
415
|
- **CLI** - Command-line interface for URL/route scanning
|
|
342
416
|
- **Configuration** - YAML-based config with profiles
|
|
@@ -347,13 +421,42 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture documentation.
|
|
|
347
421
|
|
|
348
422
|
- Ruby 3.0+ (3.1+ recommended)
|
|
349
423
|
- Rails 6.0+ (7.1+ recommended)
|
|
350
|
-
- RSpec Rails 6.0+ (for
|
|
424
|
+
- **RSpec Rails 6.0+ (required for system specs)** or Minitest (for Minitest)
|
|
351
425
|
- Capybara 3.0+ (provided by your project)
|
|
352
426
|
- selenium-webdriver 4.0+ (provided by your project, for system specs)
|
|
353
427
|
- webdrivers (optional, provided by your project, for automatic driver management)
|
|
428
|
+
- **csv gem** (required for Ruby 3.3+, as CSV is removed from standard library in Ruby 3.4)
|
|
354
429
|
- Chrome/Chromium browser
|
|
355
430
|
|
|
356
|
-
**Note:**
|
|
431
|
+
**Note:** The generator creates system specs that require `rspec-rails`. If you're using Minitest, you'll need to manually create your accessibility tests.
|
|
432
|
+
|
|
433
|
+
**Note:** As of version 1.2.0, the gem has minimal dependencies. You provide and configure Capybara, selenium-webdriver, webdrivers, and csv in your own Gemfile, giving you full control over your test driver setup.
|
|
434
|
+
|
|
435
|
+
## 🆕 What's New in 1.5.0
|
|
436
|
+
|
|
437
|
+
### Major Improvements
|
|
438
|
+
|
|
439
|
+
1. **Smart View File Detection**
|
|
440
|
+
- Automatically finds view files even when action names don't match
|
|
441
|
+
- Scans controller directories intelligently
|
|
442
|
+
- Handles edge cases and naming variations
|
|
443
|
+
|
|
444
|
+
2. **Advanced Partial Detection**
|
|
445
|
+
- Scans view files to discover all rendered partials
|
|
446
|
+
- Maps accessibility issues to exact partial files
|
|
447
|
+
- Supports namespaced partials and multiple locations
|
|
448
|
+
|
|
449
|
+
3. **Performance Optimizations**
|
|
450
|
+
- Page scanning cache prevents duplicate work
|
|
451
|
+
- Smart change detection only tests affected pages
|
|
452
|
+
- First-run optimization for faster initial setup
|
|
453
|
+
|
|
454
|
+
4. **Enhanced Developer Experience**
|
|
455
|
+
- Friendly test summaries with clear counts and reasons
|
|
456
|
+
- Better error messages with precise file locations
|
|
457
|
+
- Cleaner output with suppressed verbose messages
|
|
458
|
+
|
|
459
|
+
See [CHANGELOG.md](CHANGELOG.md) for complete details.
|
|
357
460
|
|
|
358
461
|
## 🤝 Contributing
|
|
359
462
|
|