rails_accessibility_testing 1.4.3 → 1.5.1
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 +118 -0
- data/GUIDES/getting_started.md +105 -77
- data/GUIDES/system_specs_for_accessibility.md +13 -12
- data/README.md +150 -36
- data/docs_site/getting_started.md +59 -69
- 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/generators/rails_a11y/install/templates/accessibility.yml.erb +49 -0
- data/lib/generators/rails_a11y/install/templates/all_pages_accessibility_spec.rb.erb +66 -0
- data/lib/generators/rails_a11y/install/templates/initializer.rb.erb +24 -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 +11 -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,6 +15,7 @@ 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'
|
|
19
20
|
gem 'capybara', '~> 3.40'
|
|
20
21
|
gem 'selenium-webdriver', '~> 4.0'
|
|
@@ -22,7 +23,9 @@ group :development, :test do
|
|
|
22
23
|
end
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
**Important:**
|
|
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.
|
|
26
29
|
|
|
27
30
|
Then run:
|
|
28
31
|
|
|
@@ -41,70 +44,13 @@ rails generate rails_a11y:install
|
|
|
41
44
|
This creates:
|
|
42
45
|
- `config/initializers/rails_a11y.rb` - Configuration
|
|
43
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
|
|
44
48
|
- Updates `spec/rails_helper.rb` (if using RSpec)
|
|
49
|
+
- Updates `Procfile.dev` - Adds accessibility watch command (optional)
|
|
45
50
|
|
|
46
|
-
|
|
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.
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```ruby
|
|
51
|
-
# spec/support/driver.rb
|
|
52
|
-
require 'selenium-webdriver'
|
|
53
|
-
require 'capybara/rails'
|
|
54
|
-
require 'capybara/rspec'
|
|
55
|
-
|
|
56
|
-
# Configure Chrome options
|
|
57
|
-
browser_options = Selenium::WebDriver::Chrome::Options.new
|
|
58
|
-
browser_options.add_argument('--window-size=1920,1080')
|
|
59
|
-
browser_options.add_argument('--headless') unless ENV['SHOW_TEST_BROWSER']
|
|
60
|
-
|
|
61
|
-
# Register the driver
|
|
62
|
-
Capybara.register_driver :selenium_chrome_headless do |app|
|
|
63
|
-
Capybara::Selenium::Driver.new(
|
|
64
|
-
app,
|
|
65
|
-
browser: :chrome,
|
|
66
|
-
options: browser_options
|
|
67
|
-
)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Set as default JavaScript driver
|
|
71
|
-
Capybara.javascript_driver = :selenium_chrome_headless
|
|
72
|
-
|
|
73
|
-
# Configure RSpec to use the driver for system tests
|
|
74
|
-
RSpec.configure do |config|
|
|
75
|
-
config.before(:each, type: :system) do
|
|
76
|
-
driven_by :selenium_chrome_headless
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**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).
|
|
82
|
-
|
|
83
|
-
### Step 3: Install Chrome/Chromium (Required)
|
|
84
|
-
|
|
85
|
-
System tests require Chrome or Chromium to be installed on your system:
|
|
86
|
-
|
|
87
|
-
**macOS:**
|
|
88
|
-
```bash
|
|
89
|
-
brew install --cask google-chrome
|
|
90
|
-
# or for Chromium:
|
|
91
|
-
brew install --cask chromium
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Linux (Ubuntu/Debian):**
|
|
95
|
-
```bash
|
|
96
|
-
sudo apt-get update
|
|
97
|
-
sudo apt-get install -y google-chrome-stable
|
|
98
|
-
# or for Chromium:
|
|
99
|
-
sudo apt-get install -y chromium-browser
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**Windows:**
|
|
103
|
-
Download and install Chrome from [google.com/chrome](https://www.google.com/chrome/)
|
|
104
|
-
|
|
105
|
-
The `webdrivers` gem will automatically download and manage the ChromeDriver binary for you.
|
|
106
|
-
|
|
107
|
-
### Step 4: Run Your Tests
|
|
53
|
+
### Step 3: Run Your Tests
|
|
108
54
|
|
|
109
55
|
You can run accessibility checks in several ways:
|
|
110
56
|
|
|
@@ -118,7 +64,7 @@ Accessibility checks run automatically on every system test that visits a page.
|
|
|
118
64
|
|
|
119
65
|
#### Option B: Run Continuously with Procfile (Recommended for Development)
|
|
120
66
|
|
|
121
|
-
|
|
67
|
+
The generator automatically adds an accessibility watch command to your `Procfile.dev`:
|
|
122
68
|
|
|
123
69
|
```procfile
|
|
124
70
|
web: bin/rails server
|
|
@@ -139,6 +85,28 @@ This will:
|
|
|
139
85
|
|
|
140
86
|
The accessibility checker will continuously monitor your pages and alert you to any issues as you develop!
|
|
141
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
|
+
|
|
142
110
|
## Your First Accessibility Check
|
|
143
111
|
|
|
144
112
|
Let's see it in action. Create a simple system spec:
|
|
@@ -159,13 +127,12 @@ end
|
|
|
159
127
|
While checks run automatically after each `visit`, you can also run comprehensive checks explicitly at any point in your test:
|
|
160
128
|
|
|
161
129
|
```ruby
|
|
162
|
-
# spec/system/
|
|
130
|
+
# spec/system/my_page_accessibility_spec.rb
|
|
163
131
|
require 'rails_helper'
|
|
164
132
|
|
|
165
|
-
RSpec.describe '
|
|
133
|
+
RSpec.describe 'My Page Accessibility', type: :system do
|
|
166
134
|
it 'loads the page and runs comprehensive accessibility checks' do
|
|
167
135
|
visit root_path
|
|
168
|
-
expect(page).to have_content('Welcome')
|
|
169
136
|
|
|
170
137
|
# Run comprehensive accessibility checks explicitly
|
|
171
138
|
# This will fail the test if any accessibility issues are found
|
|
@@ -226,14 +193,14 @@ Rails A11y runs **11 comprehensive checks** automatically. These checks are WCAG
|
|
|
226
193
|
|
|
227
194
|
1. **Form Labels** - All form inputs have associated labels
|
|
228
195
|
2. **Image Alt Text** - All images have descriptive alt attributes (including empty alt="" detection)
|
|
229
|
-
3. **Interactive Elements** - Buttons, links, and other interactive elements have accessible names
|
|
230
|
-
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)
|
|
231
198
|
5. **Keyboard Accessibility** - All interactive elements are keyboard accessible
|
|
232
199
|
6. **ARIA Landmarks** - Proper use of ARIA landmark roles for page structure
|
|
233
200
|
7. **Form Error Associations** - Form errors are properly linked to their form fields
|
|
234
201
|
8. **Table Structure** - Tables have proper headers and structure
|
|
235
202
|
9. **Duplicate IDs** - No duplicate ID attributes on the page
|
|
236
|
-
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.)
|
|
237
204
|
11. **Color Contrast** - Text meets WCAG contrast requirements (optional, disabled by default for performance)
|
|
238
205
|
|
|
239
206
|
### What `check_comprehensive_accessibility` Does
|
|
@@ -318,6 +285,67 @@ end
|
|
|
318
285
|
|
|
319
286
|
## Troubleshooting
|
|
320
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
|
+
|
|
321
349
|
### Error: `uninitialized constant Selenium::WebDriver::DriverFinder`
|
|
322
350
|
|
|
323
351
|
This error typically occurs when:
|
|
@@ -370,14 +398,14 @@ development:
|
|
|
370
398
|
|
|
371
399
|
For best results, use these compatible versions:
|
|
372
400
|
|
|
373
|
-
| Component | Recommended Version | Minimum Version |
|
|
374
|
-
|
|
375
|
-
| Ruby | 3.1+ | 3.0+ |
|
|
376
|
-
| Rails | 7.1+ / 8.0+ | 6.0+ |
|
|
377
|
-
| RSpec Rails |
|
|
378
|
-
| Capybara | ~> 3.40 | 3.0+ |
|
|
379
|
-
| selenium-webdriver | ~> 4.10 | 4.0+ |
|
|
380
|
-
| webdrivers | ~> 5.3 | 5.0+ |
|
|
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 |
|
|
381
409
|
|
|
382
410
|
**Rails 8 Notes:**
|
|
383
411
|
- Rails 8 requires `selenium-webdriver` 4.6.0+ for `DriverFinder` support
|
|
@@ -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,46 @@ 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
|
+
#### 🎯 Live Accessibility Scanner
|
|
35
|
+
- **Real-time scanning**: Automatically scans pages as you browse during development
|
|
36
|
+
- **Smart cancellation**: Cancels scans when you navigate to new pages, focusing on current page
|
|
37
|
+
- **Integrated workflow**: Works seamlessly with `bin/dev` via Procfile.dev
|
|
38
|
+
- **Detailed reporting**: Shows exactly what's being scanned with page URLs and view files
|
|
39
|
+
|
|
40
|
+
#### 📝 Enhanced Error Reporting
|
|
41
|
+
- **View file priority**: Rails view files shown prominently instead of URLs
|
|
42
|
+
- **Comprehensive summaries**: Overall test report showing all pages tested with statistics
|
|
43
|
+
- **Accurate error counting**: Properly tracks and displays error/warning counts
|
|
44
|
+
- **Persistent output**: Errors stay visible in terminal (no clearing)
|
|
45
|
+
|
|
46
|
+
#### 🔍 Smart View File Detection
|
|
47
|
+
- **Intelligent matching**: Automatically finds view files even when action names don't match
|
|
48
|
+
- **Controller directory scanning**: Searches all view files to find the correct template
|
|
49
|
+
- **Fuzzy matching**: Handles variations and naming conventions
|
|
50
|
+
- **Partial detection**: Shows exact partial file when issues are found
|
|
51
|
+
|
|
52
|
+
#### ⚡ Performance Optimizations
|
|
53
|
+
- **Optimized DOM queries**: Faster image alt checks without JavaScript evaluation
|
|
54
|
+
- **Removed delays**: Eliminated unnecessary sleep calls in live scanner
|
|
55
|
+
- **Efficient scanning**: ~25-30% faster page scans
|
|
56
|
+
|
|
57
|
+
#### 🎨 Enhanced Developer Experience
|
|
58
|
+
- **Real-time progress**: Step-by-step feedback during accessibility checks
|
|
59
|
+
- **Clear summaries**: Comprehensive test reports with view files and statistics
|
|
60
|
+
- **Better error context**: Shows view files, paths, and element details
|
|
61
|
+
- **Focused scanning**: Live scanner adapts to your browsing behavior
|
|
32
62
|
|
|
33
63
|
## 🚀 Quick Start
|
|
34
64
|
|
|
@@ -39,14 +69,16 @@ Add to your `Gemfile`:
|
|
|
39
69
|
```ruby
|
|
40
70
|
group :development, :test do
|
|
41
71
|
gem 'rails_accessibility_testing'
|
|
72
|
+
gem 'rspec-rails', '~> 8.0' # Required for system specs
|
|
42
73
|
gem 'axe-core-capybara', '~> 4.0'
|
|
43
74
|
gem 'capybara', '~> 3.40'
|
|
44
75
|
gem 'selenium-webdriver', '~> 4.0'
|
|
45
|
-
gem 'webdrivers', '~> 5.0' # Optional but recommended
|
|
76
|
+
gem 'webdrivers', '~> 5.0' # Optional but recommended
|
|
77
|
+
gem 'csv' # Required for Ruby 3.3+ (CSV removed from standard library in Ruby 3.4)
|
|
46
78
|
end
|
|
47
79
|
```
|
|
48
80
|
|
|
49
|
-
**Important:** You must explicitly add `selenium-webdriver`
|
|
81
|
+
**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.
|
|
50
82
|
|
|
51
83
|
Then run:
|
|
52
84
|
|
|
@@ -65,7 +97,9 @@ rails generate rails_a11y:install
|
|
|
65
97
|
This creates:
|
|
66
98
|
- `config/initializers/rails_a11y.rb` - Configuration
|
|
67
99
|
- `config/accessibility.yml` - Check settings
|
|
100
|
+
- `spec/system/all_pages_accessibility_spec.rb` - Comprehensive spec that dynamically tests all GET routes
|
|
68
101
|
- Updates `spec/rails_helper.rb` (if using RSpec)
|
|
102
|
+
- Updates `Procfile.dev` with accessibility watch command (if present)
|
|
69
103
|
|
|
70
104
|
### Setup (Option 2: Manual)
|
|
71
105
|
|
|
@@ -100,7 +134,7 @@ require 'rails_helper'
|
|
|
100
134
|
RSpec.describe 'Home Page Accessibility', type: :system do
|
|
101
135
|
it 'loads successfully and passes comprehensive accessibility checks' do
|
|
102
136
|
visit root_path
|
|
103
|
-
expect(page).to have_content('
|
|
137
|
+
expect(page).to have_content('Welcome')
|
|
104
138
|
|
|
105
139
|
# Run comprehensive accessibility checks
|
|
106
140
|
check_comprehensive_accessibility
|
|
@@ -111,25 +145,22 @@ end
|
|
|
111
145
|
|
|
112
146
|
**Accessibility checks run automatically after each `visit` in system specs!**
|
|
113
147
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
For continuous accessibility checking during development, add to your `Procfile.dev`:
|
|
117
|
-
|
|
118
|
-
```procfile
|
|
119
|
-
web: bin/rails server
|
|
120
|
-
css: bin/rails dartsass:watch
|
|
121
|
-
a11y: while true; do bundle exec rspec spec/system/*_accessibility_spec.rb; sleep 30; done
|
|
122
|
-
```
|
|
148
|
+
### All Pages Accessibility Spec
|
|
123
149
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
bin/dev
|
|
128
|
-
```
|
|
150
|
+
The generator creates `spec/system/all_pages_accessibility_spec.rb` which automatically tests all GET routes in your application. The spec:
|
|
129
151
|
|
|
130
|
-
|
|
152
|
+
- **Dynamically discovers routes** at runtime - works for any Rails app
|
|
153
|
+
- **Smart change detection** - Only tests pages when their related files (views, controllers, helpers, CSS/JS) have changed
|
|
154
|
+
- **First-run optimization** - Tests all pages on first run, then only changed files
|
|
155
|
+
- **Intelligent skipping** - Skips routes that require authentication, have errors, or aren't accessible
|
|
156
|
+
- **Friendly summaries** - Shows passed/failed/skipped counts with clear reasons
|
|
131
157
|
|
|
132
|
-
|
|
158
|
+
The spec automatically:
|
|
159
|
+
- Tests all GET routes (filters out API, internal Rails routes)
|
|
160
|
+
- Handles routes with parameters by substituting test values
|
|
161
|
+
- Detects view files even when action names don't match
|
|
162
|
+
- Shows which files changed and which pages are affected
|
|
163
|
+
- Provides helpful tips and next steps
|
|
133
164
|
|
|
134
165
|
### Automatic Checks
|
|
135
166
|
|
|
@@ -169,6 +200,18 @@ it "meets all accessibility standards" do
|
|
|
169
200
|
end
|
|
170
201
|
```
|
|
171
202
|
|
|
203
|
+
### Continuous Development Testing
|
|
204
|
+
|
|
205
|
+
Add to your `Procfile.dev`:
|
|
206
|
+
|
|
207
|
+
```ruby
|
|
208
|
+
web: $(bundle show rails_accessibility_testing)/exe/rails_server_safe
|
|
209
|
+
css: bin/rails dartsass:watch
|
|
210
|
+
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
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
This runs accessibility tests every 30 seconds, but only when files have changed!
|
|
214
|
+
|
|
172
215
|
### CLI Usage
|
|
173
216
|
|
|
174
217
|
Run checks against URLs or Rails routes:
|
|
@@ -196,14 +239,14 @@ The gem automatically runs **11 comprehensive accessibility checks**:
|
|
|
196
239
|
|
|
197
240
|
1. ✅ **Form Labels** - All form inputs have associated labels
|
|
198
241
|
2. ✅ **Image Alt Text** - All images have descriptive alt attributes
|
|
199
|
-
3. ✅ **Interactive Elements** - Buttons, links have accessible names
|
|
200
|
-
4. ✅ **Heading Hierarchy** - Proper h1-h6 structure
|
|
242
|
+
3. ✅ **Interactive Elements** - Buttons, links have accessible names (including links with images that have alt text)
|
|
243
|
+
4. ✅ **Heading Hierarchy** - Proper h1-h6 structure (detects missing h1, multiple h1s, skipped levels, and h2+ without h1)
|
|
201
244
|
5. ✅ **Keyboard Accessibility** - All interactive elements keyboard accessible
|
|
202
245
|
6. ✅ **ARIA Landmarks** - Proper use of ARIA landmark roles
|
|
203
246
|
7. ✅ **Form Error Associations** - Errors linked to form fields
|
|
204
247
|
8. ✅ **Table Structure** - Tables have proper headers
|
|
205
248
|
9. ✅ **Duplicate IDs** - No duplicate ID attributes
|
|
206
|
-
10. ✅ **Skip Links** - Skip navigation links present
|
|
249
|
+
10. ✅ **Skip Links** - Skip navigation links present (detects various patterns)
|
|
207
250
|
11. ✅ **Color Contrast** - Text meets contrast requirements (optional)
|
|
208
251
|
|
|
209
252
|
## ⚙️ Configuration
|
|
@@ -221,7 +264,7 @@ checks:
|
|
|
221
264
|
form_labels: true
|
|
222
265
|
image_alt_text: true
|
|
223
266
|
interactive_elements: true
|
|
224
|
-
|
|
267
|
+
heading: true # Note: renamed from heading_hierarchy in 1.5.0
|
|
225
268
|
keyboard_accessibility: true
|
|
226
269
|
aria_landmarks: true
|
|
227
270
|
form_errors: true
|
|
@@ -268,7 +311,7 @@ end
|
|
|
268
311
|
|
|
269
312
|
## 📋 Example Error Output
|
|
270
313
|
|
|
271
|
-
When accessibility issues are found, you get detailed, actionable errors:
|
|
314
|
+
When accessibility issues are found, you get detailed, actionable errors with precise file locations:
|
|
272
315
|
|
|
273
316
|
```
|
|
274
317
|
======================================================================
|
|
@@ -276,9 +319,10 @@ When accessibility issues are found, you get detailed, actionable errors:
|
|
|
276
319
|
======================================================================
|
|
277
320
|
|
|
278
321
|
📄 Page Being Tested:
|
|
279
|
-
URL: http://localhost:3000/
|
|
280
|
-
Path: /
|
|
281
|
-
📝
|
|
322
|
+
URL: http://localhost:3000/items/search
|
|
323
|
+
Path: /items/search
|
|
324
|
+
📝 View File: app/views/items/search_result.html.erb
|
|
325
|
+
📝 Partial: app/views/layouts/_advance_search.html.erb
|
|
282
326
|
|
|
283
327
|
📍 Element Details:
|
|
284
328
|
Tag: <img>
|
|
@@ -298,10 +342,40 @@ When accessibility issues are found, you get detailed, actionable errors:
|
|
|
298
342
|
💡 Best Practice: All images must have alt attribute.
|
|
299
343
|
Use empty alt="" only for purely decorative images.
|
|
300
344
|
|
|
301
|
-
📖 WCAG Reference: https://www.w3.org/WAI/WCAG21/Understanding/
|
|
345
|
+
📖 WCAG Reference: https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html
|
|
302
346
|
======================================================================
|
|
303
347
|
```
|
|
304
348
|
|
|
349
|
+
**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!
|
|
350
|
+
|
|
351
|
+
## 🚀 Performance Features
|
|
352
|
+
|
|
353
|
+
### Smart Change Detection
|
|
354
|
+
|
|
355
|
+
The gem automatically detects when files change and only tests affected pages:
|
|
356
|
+
|
|
357
|
+
- **View files**: Tests pages when their view files change
|
|
358
|
+
- **Partials**: Tests pages that render changed partials
|
|
359
|
+
- **Controllers**: Tests all routes for a controller when the controller changes
|
|
360
|
+
- **Helpers**: Tests all pages when helpers change (they can affect any view)
|
|
361
|
+
- **Assets**: Tests all pages when CSS/JS changes (can affect accessibility globally)
|
|
362
|
+
|
|
363
|
+
### Page Scanning Cache
|
|
364
|
+
|
|
365
|
+
Prevents duplicate scans of the same page during a test run:
|
|
366
|
+
|
|
367
|
+
- **Automatic caching**: Each page is scanned once per test suite execution
|
|
368
|
+
- **Efficient tracking**: Uses page path or URL as cache key
|
|
369
|
+
- **Silent skipping**: Already-scanned pages are skipped without output
|
|
370
|
+
- **Manual reset**: Use `reset_scanned_pages_cache` if needed
|
|
371
|
+
|
|
372
|
+
### First-Run Optimization
|
|
373
|
+
|
|
374
|
+
- **Initial baseline**: Tests all pages on first run to establish baseline
|
|
375
|
+
- **Subsequent runs**: Only tests changed files for faster feedback
|
|
376
|
+
- **Marker file**: Creates `.rails_a11y_initialized` to track first run
|
|
377
|
+
- **Force all pages**: Set `TEST_ALL_PAGES=true` to test all pages anytime
|
|
378
|
+
|
|
305
379
|
## 📚 Documentation
|
|
306
380
|
|
|
307
381
|
### 🌐 Online Documentation
|
|
@@ -337,9 +411,12 @@ View at `doc/index.html`
|
|
|
337
411
|
|
|
338
412
|
Rails Accessibility Testing is built with a clean, modular architecture:
|
|
339
413
|
|
|
340
|
-
- **Rule Engine** - Evaluates accessibility checks
|
|
341
|
-
- **Check Definitions** - WCAG-aligned check implementations
|
|
414
|
+
- **Rule Engine** - Evaluates accessibility checks with configurable profiles
|
|
415
|
+
- **Check Definitions** - WCAG-aligned check implementations (11+ checks)
|
|
342
416
|
- **Violation Collector** - Aggregates and formats violations
|
|
417
|
+
- **View File Detection** - Intelligent detection of view files and partials
|
|
418
|
+
- **Change Detector** - Smart detection of file changes and their impact
|
|
419
|
+
- **Page Scanning Cache** - Prevents duplicate scans for performance
|
|
343
420
|
- **Rails Integration** - Railtie, RSpec, Minitest helpers
|
|
344
421
|
- **CLI** - Command-line interface for URL/route scanning
|
|
345
422
|
- **Configuration** - YAML-based config with profiles
|
|
@@ -350,13 +427,50 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture documentation.
|
|
|
350
427
|
|
|
351
428
|
- Ruby 3.0+ (3.1+ recommended)
|
|
352
429
|
- Rails 6.0+ (7.1+ recommended)
|
|
353
|
-
- RSpec Rails 6.0+ (for
|
|
430
|
+
- **RSpec Rails 6.0+ (required for system specs)** or Minitest (for Minitest)
|
|
354
431
|
- Capybara 3.0+ (provided by your project)
|
|
355
432
|
- selenium-webdriver 4.0+ (provided by your project, for system specs)
|
|
356
433
|
- webdrivers (optional, provided by your project, for automatic driver management)
|
|
434
|
+
- **csv gem** (required for Ruby 3.3+, as CSV is removed from standard library in Ruby 3.4)
|
|
357
435
|
- Chrome/Chromium browser
|
|
358
436
|
|
|
359
|
-
**Note:**
|
|
437
|
+
**Note:** The generator creates system specs that require `rspec-rails`. If you're using Minitest, you'll need to manually create your accessibility tests.
|
|
438
|
+
|
|
439
|
+
**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.
|
|
440
|
+
|
|
441
|
+
## 🆕 What's New in 1.5.0
|
|
442
|
+
|
|
443
|
+
### Major Improvements
|
|
444
|
+
|
|
445
|
+
1. **🎯 Live Accessibility Scanner**
|
|
446
|
+
- Real-time scanning as you browse during development
|
|
447
|
+
- Integrated with `bin/dev` via Procfile.dev
|
|
448
|
+
- Smart cancellation when navigating to new pages
|
|
449
|
+
- Detailed reporting showing exactly what's being scanned
|
|
450
|
+
|
|
451
|
+
2. **📝 Enhanced Error Reporting**
|
|
452
|
+
- View files shown prominently instead of URLs
|
|
453
|
+
- Comprehensive overall test summaries
|
|
454
|
+
- Accurate error counting and persistent output
|
|
455
|
+
- Better context with view files and element details
|
|
456
|
+
|
|
457
|
+
3. **🔍 Smart View File Detection**
|
|
458
|
+
- Automatically finds view files even when action names don't match
|
|
459
|
+
- Scans controller directories intelligently
|
|
460
|
+
- Handles edge cases and naming variations
|
|
461
|
+
- Advanced partial detection and mapping
|
|
462
|
+
|
|
463
|
+
4. **⚡ Performance Optimizations**
|
|
464
|
+
- Page scanning cache prevents duplicate work
|
|
465
|
+
- Smart change detection only tests affected pages
|
|
466
|
+
- First-run optimization for faster initial setup
|
|
467
|
+
|
|
468
|
+
4. **Enhanced Developer Experience**
|
|
469
|
+
- Friendly test summaries with clear counts and reasons
|
|
470
|
+
- Better error messages with precise file locations
|
|
471
|
+
- Cleaner output with suppressed verbose messages
|
|
472
|
+
|
|
473
|
+
See [CHANGELOG.md](CHANGELOG.md) for complete details.
|
|
360
474
|
|
|
361
475
|
## 🤝 Contributing
|
|
362
476
|
|