rails_accessibility_testing 1.2.0 → 1.4.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/CHANGELOG.md +39 -0
- data/GUIDES/getting_started.md +62 -12
- data/GUIDES/system_specs_for_accessibility.md +248 -0
- data/README.md +42 -3
- data/lib/rails_accessibility_testing/accessibility_helper.rb +6 -0
- data/lib/rails_accessibility_testing/checks/image_alt_text_check.rb +15 -0
- data/lib/rails_accessibility_testing/cli/command.rb +112 -19
- data/lib/rails_accessibility_testing/config/yaml_loader.rb +3 -1
- data/lib/rails_accessibility_testing/configuration.rb +3 -1
- data/lib/rails_accessibility_testing/engine/rule_engine.rb +3 -1
- data/lib/rails_accessibility_testing/rspec_integration.rb +7 -0
- data/lib/rails_accessibility_testing/version.rb +1 -1
- data/lib/rails_accessibility_testing.rb +2 -2
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5ed11e69796995b294eeaa17e2627e46b3122356d7383e2e1ad3b213c8f2ac78
|
|
4
|
+
data.tar.gz: 410f9e2c88b5e27e0a6319fb62bb854d832f8e74a25d7b3970aaf9b3f07a0fe5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b3c309bbcc50838e5a981cf997c74051e10a79ce0b03d67450ad3e0dac8486d6ed79cfad4cd201e2cd25abf432370d80799a67ca9f136e11e2c055724e5f9dee
|
|
7
|
+
data.tar.gz: d8f2aaaad2e708e83dc4c9f7fd283ec815904557549f33c2f4b491fdeeed6c196b55c759b79effe7074bfda21cb4e3d07ccdefedcf07e065cdf4302f4395b74d
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,44 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.0] - 2025-11-18
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Updated documentation examples to use clearer language ("runs accessibility checks" instead of "passes accessibility checks")
|
|
12
|
+
- Improved test descriptions to accurately reflect that tests will fail if accessibility issues are found
|
|
13
|
+
- Enhanced comments in examples to clarify when success messages appear
|
|
14
|
+
|
|
15
|
+
### Improved
|
|
16
|
+
- Better clarity in documentation about when accessibility checks pass vs fail
|
|
17
|
+
- More accurate test descriptions that don't imply tests will pass when they may fail
|
|
18
|
+
- Improved user understanding of accessibility check behavior
|
|
19
|
+
|
|
20
|
+
## [1.3.0] - 2025-11-18
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- CLI reports now use ErrorMessageBuilder for detailed, formatted error messages
|
|
24
|
+
- CLI reports include comprehensive remediation steps, element details, and WCAG references
|
|
25
|
+
- Better empty alt text detection (checks both Capybara attributes and JavaScript getAttribute)
|
|
26
|
+
- Improved server port detection with better error handling and timeout management
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- CLI default profile changed to `:development` for faster checks (color contrast disabled by default)
|
|
30
|
+
- Improved server wait logic with longer retry times (up to 20 seconds) and better port re-detection
|
|
31
|
+
- Report generation now skips when no URLs are checked (cleaner output when server isn't ready)
|
|
32
|
+
- Port detection now prioritizes common Rails ports (3000, 3001, 4000, 5000) and excludes problematic ports
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- Fixed logger accessor compatibility issue - logger access is now optional to work with older gem versions
|
|
36
|
+
- Fixed CLI connection issues by improving port detection and server readiness checks
|
|
37
|
+
- Fixed CLI showing empty reports when server isn't ready - now shows informative message instead
|
|
38
|
+
- Improved error handling for connection timeouts and connection refused errors
|
|
39
|
+
- Better handling of interrupt signals during server wait operations
|
|
40
|
+
|
|
41
|
+
### Improved
|
|
42
|
+
- CLI error messages are now more detailed and actionable with specific remediation steps
|
|
43
|
+
- Server detection is more reliable with improved timeout handling and error recovery
|
|
44
|
+
- Better user experience when running in Procfile.dev with automatic retries
|
|
45
|
+
|
|
8
46
|
## [1.2.0] - 2024-12-XX
|
|
9
47
|
|
|
10
48
|
### Changed
|
|
@@ -111,6 +149,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
111
149
|
- Compatible with RSpec Rails 6.0+
|
|
112
150
|
- Modular architecture with rule engine and check definitions
|
|
113
151
|
|
|
152
|
+
[1.3.0]: https://github.com/rayraycodes/rails-accessibility-testing/releases/tag/v1.3.0
|
|
114
153
|
[1.2.0]: https://github.com/rayraycodes/rails-accessibility-testing/releases/tag/v1.2.0
|
|
115
154
|
[1.1.6]: https://github.com/rayraycodes/rails-accessibility-testing/releases/tag/v1.1.6
|
|
116
155
|
[1.1.5]: https://github.com/rayraycodes/rails-accessibility-testing/releases/tag/v1.1.5
|
data/GUIDES/getting_started.md
CHANGED
|
@@ -54,7 +54,7 @@ Let's see it in action. Create a simple system spec:
|
|
|
54
54
|
|
|
55
55
|
```ruby
|
|
56
56
|
# spec/system/home_spec.rb
|
|
57
|
-
RSpec.describe "Home Page" do
|
|
57
|
+
RSpec.describe "Home Page", type: :system do
|
|
58
58
|
it "displays the welcome message" do
|
|
59
59
|
visit root_path
|
|
60
60
|
expect(page).to have_content("Welcome")
|
|
@@ -63,6 +63,41 @@ RSpec.describe "Home Page" do
|
|
|
63
63
|
end
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
## Running Comprehensive Checks Explicitly
|
|
67
|
+
|
|
68
|
+
While checks run automatically after each `visit`, you can also run comprehensive checks explicitly at any point in your test:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
# spec/system/home_page_accessibility_spec.rb
|
|
72
|
+
require 'rails_helper'
|
|
73
|
+
|
|
74
|
+
RSpec.describe 'Home Page Accessibility', type: :system do
|
|
75
|
+
it 'loads the page and runs comprehensive accessibility checks' do
|
|
76
|
+
visit root_path
|
|
77
|
+
expect(page).to have_content('Welcome')
|
|
78
|
+
|
|
79
|
+
# Run comprehensive accessibility checks explicitly
|
|
80
|
+
# This will fail the test if any accessibility issues are found
|
|
81
|
+
check_comprehensive_accessibility
|
|
82
|
+
# ✅ This runs all 11 comprehensive checks:
|
|
83
|
+
# - Form labels, Image alt text, Interactive elements
|
|
84
|
+
# - Heading hierarchy, Keyboard accessibility, ARIA landmarks
|
|
85
|
+
# - Form errors, Table structure, Duplicate IDs
|
|
86
|
+
# - Skip links, Color contrast (if enabled)
|
|
87
|
+
# If all checks pass, you'll see: "All comprehensive accessibility checks passed! (11 checks)"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**When to use explicit checks:**
|
|
93
|
+
- When you want to run checks at a specific point in your test (e.g., after filling a form)
|
|
94
|
+
- When you want to ensure checks run even if the test might fail before the automatic check
|
|
95
|
+
- When you want to test multiple pages in one spec and check each one explicitly
|
|
96
|
+
|
|
97
|
+
**Note:** Even if you call `check_comprehensive_accessibility` explicitly, the automatic checks will still run after the test completes (unless the test fails before reaching the explicit check).
|
|
98
|
+
|
|
99
|
+
### Example: Comprehensive Check Output
|
|
100
|
+
|
|
66
101
|
If there are accessibility issues, you'll see detailed error messages like:
|
|
67
102
|
|
|
68
103
|
```
|
|
@@ -96,19 +131,33 @@ If there are accessibility issues, you'll see detailed error messages like:
|
|
|
96
131
|
|
|
97
132
|
## Understanding the Checks
|
|
98
133
|
|
|
99
|
-
Rails A11y runs 11 comprehensive checks:
|
|
134
|
+
Rails A11y runs **11 comprehensive checks** automatically. These checks are WCAG 2.1 AA aligned:
|
|
100
135
|
|
|
101
|
-
1. **Form Labels** - All inputs have associated labels
|
|
102
|
-
2. **Image Alt Text** - All images have alt attributes
|
|
103
|
-
3. **Interactive Elements** - Buttons and
|
|
104
|
-
4. **Heading Hierarchy** - Proper h1-h6 structure
|
|
136
|
+
1. **Form Labels** - All form inputs have associated labels
|
|
137
|
+
2. **Image Alt Text** - All images have descriptive alt attributes (including empty alt="" detection)
|
|
138
|
+
3. **Interactive Elements** - Buttons, links, and other interactive elements have accessible names
|
|
139
|
+
4. **Heading Hierarchy** - Proper h1-h6 structure without skipping levels
|
|
105
140
|
5. **Keyboard Accessibility** - All interactive elements are keyboard accessible
|
|
106
|
-
6. **ARIA Landmarks** - Proper use of ARIA landmark roles
|
|
107
|
-
7. **Form Error Associations** -
|
|
108
|
-
8. **Table Structure** - Tables have proper headers
|
|
109
|
-
9. **Duplicate IDs** - No duplicate ID attributes
|
|
110
|
-
10. **Skip Links** - Skip navigation links present
|
|
111
|
-
11. **Color Contrast** - Text meets contrast requirements (optional)
|
|
141
|
+
6. **ARIA Landmarks** - Proper use of ARIA landmark roles for page structure
|
|
142
|
+
7. **Form Error Associations** - Form errors are properly linked to their form fields
|
|
143
|
+
8. **Table Structure** - Tables have proper headers and structure
|
|
144
|
+
9. **Duplicate IDs** - No duplicate ID attributes on the page
|
|
145
|
+
10. **Skip Links** - Skip navigation links are present for keyboard users
|
|
146
|
+
11. **Color Contrast** - Text meets WCAG contrast requirements (optional, disabled by default for performance)
|
|
147
|
+
|
|
148
|
+
### What `check_comprehensive_accessibility` Does
|
|
149
|
+
|
|
150
|
+
When you call `check_comprehensive_accessibility`, it runs all 11 checks above and provides detailed error messages for any violations found. Each error includes:
|
|
151
|
+
|
|
152
|
+
- **File location hints** - Know exactly which view file to fix
|
|
153
|
+
- **Element details** - Tag, ID, classes, and visible text
|
|
154
|
+
- **Actionable fix instructions** - Code examples showing how to fix the issue
|
|
155
|
+
- **WCAG references** - Links to relevant WCAG guidelines
|
|
156
|
+
|
|
157
|
+
If all checks pass, you'll see:
|
|
158
|
+
```
|
|
159
|
+
✅ All comprehensive accessibility checks passed! (11 checks)
|
|
160
|
+
```
|
|
112
161
|
|
|
113
162
|
## Configuration
|
|
114
163
|
|
|
@@ -171,6 +220,7 @@ end
|
|
|
171
220
|
|
|
172
221
|
## Next Steps
|
|
173
222
|
|
|
223
|
+
- **⭐ Read the [System Specs Guide](system_specs_for_accessibility.md)** - Recommended approach for reliable accessibility testing
|
|
174
224
|
- **Read the [CI Integration Guide](continuous_integration.md)** to set up automated checks
|
|
175
225
|
- **Check out [Writing Accessible Views](writing_accessible_views_in_rails.md)** for best practices
|
|
176
226
|
- **See [Working with Designers](working_with_designers_and_content_authors.md)** for team collaboration
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Using System Specs for Accessibility Testing
|
|
2
|
+
|
|
3
|
+
System specs are the **recommended and most reliable** way to run accessibility checks in your Rails application. This guide shows you how to set up continuous accessibility testing using RSpec system specs.
|
|
4
|
+
|
|
5
|
+
## Why System Specs?
|
|
6
|
+
|
|
7
|
+
✅ **More Reliable** - Runs in the same test environment as your other specs
|
|
8
|
+
✅ **Faster** - No need to wait for external server processes
|
|
9
|
+
✅ **Better Integration** - Works seamlessly with your existing test suite
|
|
10
|
+
✅ **Automatic** - Checks run automatically after each `visit` in system specs
|
|
11
|
+
✅ **Clear Feedback** - Detailed error messages with file locations and fix instructions
|
|
12
|
+
|
|
13
|
+
## Quick Setup
|
|
14
|
+
|
|
15
|
+
### 1. Create System Specs
|
|
16
|
+
|
|
17
|
+
Create system specs for the pages you want to test. Name them with `_accessibility_spec.rb` suffix for clarity:
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# spec/system/home_page_accessibility_spec.rb
|
|
21
|
+
require 'rails_helper'
|
|
22
|
+
|
|
23
|
+
RSpec.describe 'Home Page Accessibility', type: :system do
|
|
24
|
+
it 'loads the page and runs comprehensive accessibility checks' do
|
|
25
|
+
visit root_path
|
|
26
|
+
expect(page).to have_content('Biorepository').or have_content('Welcome')
|
|
27
|
+
|
|
28
|
+
# Run comprehensive accessibility checks
|
|
29
|
+
# This will fail the test if any accessibility issues are found
|
|
30
|
+
check_comprehensive_accessibility
|
|
31
|
+
# ✅ If all checks pass, you'll see: "All comprehensive accessibility checks passed! (11 checks)"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 2. Automatic Checks
|
|
37
|
+
|
|
38
|
+
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
|
+
### 3. Add to Procfile.dev (Optional)
|
|
41
|
+
|
|
42
|
+
For continuous testing during development, add to your `Procfile.dev`:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
web: $(bundle show rails_accessibility_testing)/exe/rails_server_safe
|
|
46
|
+
css: bin/rails dartsass:watch
|
|
47
|
+
a11y: while true; do bundle exec rspec spec/system/*_accessibility_spec.rb; sleep 30; done
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This will run your accessibility specs every 30 seconds while you develop.
|
|
51
|
+
|
|
52
|
+
## Example Specs
|
|
53
|
+
|
|
54
|
+
### Basic Page Check
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
# spec/system/home_page_accessibility_spec.rb
|
|
58
|
+
require 'rails_helper'
|
|
59
|
+
|
|
60
|
+
RSpec.describe 'Home Page Accessibility', type: :system do
|
|
61
|
+
it 'runs accessibility checks on the home page' do
|
|
62
|
+
visit root_path
|
|
63
|
+
# ✅ Comprehensive accessibility checks run automatically after this test!
|
|
64
|
+
# The test will fail if any accessibility issues are found
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Multiple Pages
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
# spec/system/pages_accessibility_spec.rb
|
|
73
|
+
require 'rails_helper'
|
|
74
|
+
|
|
75
|
+
RSpec.describe 'Pages Accessibility', type: :system do
|
|
76
|
+
it 'runs accessibility checks on home page' do
|
|
77
|
+
visit root_path
|
|
78
|
+
# Checks run automatically - test fails if issues found
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'runs accessibility checks on about page' do
|
|
82
|
+
visit about_path
|
|
83
|
+
# Checks run automatically - test fails if issues found
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'runs accessibility checks on contact page' do
|
|
87
|
+
visit contact_path
|
|
88
|
+
# Checks run automatically - test fails if issues found
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### With User Authentication
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
# spec/system/dashboard_accessibility_spec.rb
|
|
97
|
+
require 'rails_helper'
|
|
98
|
+
|
|
99
|
+
RSpec.describe 'Dashboard Accessibility', type: :system do
|
|
100
|
+
before do
|
|
101
|
+
user = FactoryBot.create(:user)
|
|
102
|
+
sign_in user
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'runs accessibility checks on dashboard' do
|
|
106
|
+
visit dashboard_path
|
|
107
|
+
# ✅ Comprehensive accessibility checks run automatically after authentication!
|
|
108
|
+
# The test will fail if any accessibility issues are found
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Skip Checks for Specific Tests
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
it 'does something without accessibility checks', skip_a11y: true do
|
|
117
|
+
visit some_path
|
|
118
|
+
# Accessibility checks won't run for this test
|
|
119
|
+
end
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## What Gets Checked
|
|
123
|
+
|
|
124
|
+
The gem automatically runs **11 comprehensive accessibility checks**:
|
|
125
|
+
|
|
126
|
+
1. ✅ **Form Labels** - All form inputs have associated labels
|
|
127
|
+
2. ✅ **Image Alt Text** - All images have descriptive alt attributes
|
|
128
|
+
3. ✅ **Interactive Elements** - Buttons, links have accessible names
|
|
129
|
+
4. ✅ **Heading Hierarchy** - Proper h1-h6 structure
|
|
130
|
+
5. ✅ **Keyboard Accessibility** - All interactive elements keyboard accessible
|
|
131
|
+
6. ✅ **ARIA Landmarks** - Proper use of ARIA landmark roles
|
|
132
|
+
7. ✅ **Form Error Associations** - Errors linked to form fields
|
|
133
|
+
8. ✅ **Table Structure** - Tables have proper headers
|
|
134
|
+
9. ✅ **Duplicate IDs** - No duplicate ID attributes
|
|
135
|
+
10. ✅ **Skip Links** - Skip navigation links present
|
|
136
|
+
11. ✅ **Color Contrast** - Text meets contrast requirements (optional, disabled by default)
|
|
137
|
+
|
|
138
|
+
## Success Messages
|
|
139
|
+
|
|
140
|
+
When all checks pass, you'll see:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
✅ All comprehensive accessibility checks passed! (11 checks)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Error Messages
|
|
147
|
+
|
|
148
|
+
When issues are found, you get detailed, actionable errors:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
======================================================================
|
|
152
|
+
❌ ACCESSIBILITY ERROR: Page missing H1 heading
|
|
153
|
+
======================================================================
|
|
154
|
+
|
|
155
|
+
📄 Page Being Tested:
|
|
156
|
+
URL: http://127.0.0.1:54384/
|
|
157
|
+
Path: /
|
|
158
|
+
📝 Likely View File: app/views/home/about.html.erb
|
|
159
|
+
|
|
160
|
+
📍 Element Details:
|
|
161
|
+
Tag: <page>
|
|
162
|
+
ID: (none)
|
|
163
|
+
Classes: (none)
|
|
164
|
+
Visible text: Page has no H1 heading
|
|
165
|
+
|
|
166
|
+
🔧 HOW TO FIX:
|
|
167
|
+
Add an <h1> heading to your page:
|
|
168
|
+
|
|
169
|
+
<h1>Main Page Title</h1>
|
|
170
|
+
|
|
171
|
+
Or in Rails ERB:
|
|
172
|
+
<h1><%= @page_title || 'Default Title' %></h1>
|
|
173
|
+
|
|
174
|
+
💡 Best Practice: Every page should have exactly one <h1>.
|
|
175
|
+
It should describe the main purpose of the page.
|
|
176
|
+
|
|
177
|
+
📖 WCAG Reference: https://www.w3.org/WAI/WCAG21/Understanding/
|
|
178
|
+
======================================================================
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Running Specs
|
|
182
|
+
|
|
183
|
+
### Run All Accessibility Specs
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
bundle exec rspec spec/system/*_accessibility_spec.rb
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Run Specific Spec
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
bundle exec rspec spec/system/home_page_accessibility_spec.rb
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Run with Documentation Format
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
bundle exec rspec spec/system/*_accessibility_spec.rb --format documentation
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Continuous Integration
|
|
202
|
+
|
|
203
|
+
Add to your CI configuration:
|
|
204
|
+
|
|
205
|
+
```yaml
|
|
206
|
+
# .github/workflows/ci.yml
|
|
207
|
+
- name: Run Accessibility Tests
|
|
208
|
+
run: bundle exec rspec spec/system/*_accessibility_spec.rb
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Best Practices
|
|
212
|
+
|
|
213
|
+
1. **Name your specs clearly** - Use `_accessibility_spec.rb` suffix
|
|
214
|
+
2. **Test critical paths** - Focus on user-facing pages
|
|
215
|
+
3. **Keep specs simple** - One page per spec is often enough
|
|
216
|
+
4. **Use Procfile.dev** - For continuous testing during development
|
|
217
|
+
5. **Run in CI** - Catch issues before they reach production
|
|
218
|
+
|
|
219
|
+
## Troubleshooting
|
|
220
|
+
|
|
221
|
+
### Checks Not Running
|
|
222
|
+
|
|
223
|
+
Make sure:
|
|
224
|
+
- Your spec has `type: :system`
|
|
225
|
+
- You call `visit` in your test
|
|
226
|
+
- The gem is properly configured in `spec/rails_helper.rb`
|
|
227
|
+
|
|
228
|
+
### Success Message Not Showing
|
|
229
|
+
|
|
230
|
+
The success message appears when all checks pass. If you don't see it, there may be silent failures. Check your RSpec output for any exceptions.
|
|
231
|
+
|
|
232
|
+
### Slow Tests
|
|
233
|
+
|
|
234
|
+
Disable color contrast checking in development:
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
# config/accessibility.yml
|
|
238
|
+
development:
|
|
239
|
+
checks:
|
|
240
|
+
color_contrast: false
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Next Steps
|
|
244
|
+
|
|
245
|
+
- See [Getting Started Guide](getting_started.md) for initial setup
|
|
246
|
+
- See [Continuous Integration Guide](continuous_integration.md) for CI/CD setup
|
|
247
|
+
- See [Writing Accessible Views](writing_accessible_views_in_rails.md) for best practices
|
|
248
|
+
|
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.4.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
|
|
|
@@ -40,6 +40,8 @@ Add to your `Gemfile`:
|
|
|
40
40
|
group :development, :test do
|
|
41
41
|
gem 'rails_accessibility_testing'
|
|
42
42
|
gem 'axe-core-capybara', '~> 4.0'
|
|
43
|
+
# Your existing Capybara, selenium-webdriver, webdrivers gems
|
|
44
|
+
# The gem has minimal dependencies - you control your own driver setup
|
|
43
45
|
end
|
|
44
46
|
```
|
|
45
47
|
|
|
@@ -82,13 +84,45 @@ RailsAccessibilityTesting::Integration::MinitestIntegration.setup!
|
|
|
82
84
|
|
|
83
85
|
## 📖 Usage
|
|
84
86
|
|
|
87
|
+
### System Specs (Recommended)
|
|
88
|
+
|
|
89
|
+
**System specs are the recommended and most reliable way to run accessibility checks.** They're faster, more reliable, and integrate seamlessly with your test suite.
|
|
90
|
+
|
|
91
|
+
Create system specs for your pages:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
# spec/system/home_page_accessibility_spec.rb
|
|
95
|
+
require 'rails_helper'
|
|
96
|
+
|
|
97
|
+
RSpec.describe 'Home Page Accessibility', type: :system do
|
|
98
|
+
it 'loads successfully and passes comprehensive accessibility checks' do
|
|
99
|
+
visit root_path
|
|
100
|
+
expect(page).to have_content('Biorepository').or have_content('Welcome')
|
|
101
|
+
|
|
102
|
+
# Run comprehensive accessibility checks
|
|
103
|
+
check_comprehensive_accessibility
|
|
104
|
+
# ✅ Comprehensive accessibility checks (11 checks) also run automatically after this test!
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Accessibility checks run automatically after each `visit` in system specs!**
|
|
110
|
+
|
|
111
|
+
For continuous testing during development, add to your `Procfile.dev`:
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
a11y: while true; do bundle exec rspec spec/system/*_accessibility_spec.rb; sleep 30; done
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
📖 **[See the full System Specs Guide](GUIDES/system_specs_for_accessibility.md)** for detailed examples and best practices.
|
|
118
|
+
|
|
85
119
|
### Automatic Checks
|
|
86
120
|
|
|
87
121
|
Just write your specs normally - checks run automatically:
|
|
88
122
|
|
|
89
123
|
```ruby
|
|
90
124
|
# spec/system/home_page_spec.rb
|
|
91
|
-
RSpec.describe "Home Page" do
|
|
125
|
+
RSpec.describe "Home Page", type: :system do
|
|
92
126
|
it "displays welcome message" do
|
|
93
127
|
visit root_path
|
|
94
128
|
expect(page).to have_content("Welcome")
|
|
@@ -268,6 +302,7 @@ Complete documentation site with all guides, examples, and API reference. The do
|
|
|
268
302
|
|
|
269
303
|
### Guides
|
|
270
304
|
|
|
305
|
+
- **[System Specs for Accessibility](GUIDES/system_specs_for_accessibility.md)** - ⭐ **Recommended approach** - Using system specs for reliable accessibility testing
|
|
271
306
|
- **[Getting Started](GUIDES/getting_started.md)** - Quick start guide
|
|
272
307
|
- **[Continuous Integration](GUIDES/continuous_integration.md)** - CI/CD setup
|
|
273
308
|
- **[Writing Accessible Views](GUIDES/writing_accessible_views_in_rails.md)** - Best practices
|
|
@@ -301,9 +336,13 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture documentation.
|
|
|
301
336
|
- Ruby 3.0+ (3.1+ recommended)
|
|
302
337
|
- Rails 6.0+ (7.1+ recommended)
|
|
303
338
|
- RSpec Rails 6.0+ (for RSpec) or Minitest (for Minitest)
|
|
304
|
-
- Capybara 3.0+
|
|
339
|
+
- Capybara 3.0+ (provided by your project)
|
|
340
|
+
- selenium-webdriver 4.0+ (provided by your project, for system specs)
|
|
341
|
+
- webdrivers (optional, provided by your project, for automatic driver management)
|
|
305
342
|
- Chrome/Chromium browser
|
|
306
343
|
|
|
344
|
+
**Note:** As of version 1.2.0, the gem has minimal dependencies. You provide and configure Capybara, selenium-webdriver, and webdrivers in your own Gemfile, giving you full control over your test driver setup.
|
|
345
|
+
|
|
307
346
|
## 🤝 Contributing
|
|
308
347
|
|
|
309
348
|
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
@@ -83,6 +83,9 @@ module AccessibilityHelper
|
|
|
83
83
|
# If we collected any errors and this was called directly (not from comprehensive), raise them
|
|
84
84
|
if @accessibility_errors.any? && !@in_comprehensive_check
|
|
85
85
|
raise format_all_errors(@accessibility_errors)
|
|
86
|
+
elsif @accessibility_errors.empty? && !@in_comprehensive_check
|
|
87
|
+
# Show success message when all checks pass
|
|
88
|
+
puts "\n✅ All basic accessibility checks passed! (5 checks: form labels, images, interactive elements, headings, keyboard)"
|
|
86
89
|
end
|
|
87
90
|
end
|
|
88
91
|
|
|
@@ -103,6 +106,9 @@ module AccessibilityHelper
|
|
|
103
106
|
# If we collected any errors, raise them all together
|
|
104
107
|
if @accessibility_errors.any?
|
|
105
108
|
raise format_all_errors(@accessibility_errors)
|
|
109
|
+
else
|
|
110
|
+
# Show success message when all checks pass
|
|
111
|
+
puts "\n✅ All comprehensive accessibility checks passed! (11 checks: form labels, images, interactive elements, headings, keyboard, ARIA landmarks, form errors, table structure, duplicate IDs, skip links, color contrast)"
|
|
106
112
|
end
|
|
107
113
|
end
|
|
108
114
|
|
|
@@ -17,6 +17,10 @@ module RailsAccessibilityTesting
|
|
|
17
17
|
|
|
18
18
|
page.all('img', visible: :all).each do |img|
|
|
19
19
|
has_alt_attribute = page.evaluate_script("arguments[0].hasAttribute('alt')", img.native)
|
|
20
|
+
# Get alt value - might be nil, empty string, or actual text
|
|
21
|
+
alt_value = img[:alt] || ""
|
|
22
|
+
# Also check via JavaScript to be sure
|
|
23
|
+
alt_value_js = page.evaluate_script("arguments[0].getAttribute('alt')", img.native) || ""
|
|
20
24
|
|
|
21
25
|
if has_alt_attribute == false
|
|
22
26
|
element_ctx = element_context(img)
|
|
@@ -27,6 +31,17 @@ module RailsAccessibilityTesting
|
|
|
27
31
|
wcag_reference: "1.1.1",
|
|
28
32
|
remediation: generate_remediation(element_ctx)
|
|
29
33
|
)
|
|
34
|
+
elsif (alt_value.blank? || alt_value_js.blank?) && has_alt_attribute
|
|
35
|
+
# Image has alt attribute but it's empty - warn about this
|
|
36
|
+
# Empty alt is valid for decorative images, but we should check if it's actually decorative
|
|
37
|
+
element_ctx = element_context(img)
|
|
38
|
+
|
|
39
|
+
violations << violation(
|
|
40
|
+
message: "Image has empty alt attribute - ensure this image is purely decorative. If it conveys information, add descriptive alt text.",
|
|
41
|
+
element_context: element_ctx,
|
|
42
|
+
wcag_reference: "1.1.1",
|
|
43
|
+
remediation: generate_remediation(element_ctx)
|
|
44
|
+
)
|
|
30
45
|
end
|
|
31
46
|
end
|
|
32
47
|
|
|
@@ -53,7 +53,7 @@ module RailsAccessibilityTesting
|
|
|
53
53
|
|
|
54
54
|
def parse_options(argv)
|
|
55
55
|
options = {
|
|
56
|
-
profile: :
|
|
56
|
+
profile: :development, # Use development profile by default (faster, no color contrast)
|
|
57
57
|
format: :human,
|
|
58
58
|
output: nil,
|
|
59
59
|
debug: false
|
|
@@ -106,6 +106,9 @@ module RailsAccessibilityTesting
|
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
def run_checks(options, config)
|
|
109
|
+
# Reset wait attempts counter for each run
|
|
110
|
+
@wait_attempts = 0
|
|
111
|
+
|
|
109
112
|
require 'capybara'
|
|
110
113
|
require 'capybara/dsl'
|
|
111
114
|
require 'selenium-webdriver'
|
|
@@ -135,12 +138,49 @@ module RailsAccessibilityTesting
|
|
|
135
138
|
url = normalize_url(target)
|
|
136
139
|
|
|
137
140
|
# Wait for server to be ready (with retries)
|
|
138
|
-
|
|
141
|
+
# If wait fails, try to re-detect port and update URL
|
|
142
|
+
if url.match?(/\Ahttps?:\/\//)
|
|
143
|
+
# First, try to detect the port (might not be ready yet)
|
|
144
|
+
uri = URI.parse(url)
|
|
145
|
+
detected_port = detect_server_port
|
|
146
|
+
|
|
147
|
+
# If we detected a different port, update the URL
|
|
148
|
+
if detected_port != uri.port.to_s
|
|
149
|
+
url = "#{uri.scheme}://#{uri.host}:#{detected_port}#{uri.path}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Now wait for server to be ready
|
|
153
|
+
server_ready = wait_for_server(url, max_retries: 20, retry_delay: 1)
|
|
154
|
+
|
|
155
|
+
# If still not ready, try re-detecting port one more time
|
|
156
|
+
unless server_ready
|
|
157
|
+
new_port = detect_server_port
|
|
158
|
+
if new_port != uri.port.to_s
|
|
159
|
+
url = "#{uri.scheme}://#{uri.host}:#{new_port}#{uri.path}"
|
|
160
|
+
server_ready = wait_for_server(url, max_retries: 20, retry_delay: 1)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# If still not ready, skip this check and try next time
|
|
164
|
+
unless server_ready
|
|
165
|
+
# Server still starting - this is normal, will retry automatically
|
|
166
|
+
# Only show message occasionally to avoid spam (every 3rd attempt)
|
|
167
|
+
@wait_attempts ||= 0
|
|
168
|
+
@wait_attempts += 1
|
|
169
|
+
if @wait_attempts % 3 == 1
|
|
170
|
+
$stderr.puts "Waiting for server to start... (will retry automatically)"
|
|
171
|
+
end
|
|
172
|
+
next
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
139
176
|
|
|
140
177
|
Capybara.visit(url)
|
|
141
178
|
violations = engine.check(Capybara.current_session, context: { url: url })
|
|
142
179
|
all_violations.concat(violations)
|
|
143
180
|
checked_urls << { url: url, violations: violations.count }
|
|
181
|
+
rescue Interrupt
|
|
182
|
+
# Handle interrupt gracefully - exit the loop
|
|
183
|
+
break
|
|
144
184
|
rescue StandardError => e
|
|
145
185
|
$stderr.puts "Error checking #{target}: #{e.message}"
|
|
146
186
|
end
|
|
@@ -180,8 +220,8 @@ module RailsAccessibilityTesting
|
|
|
180
220
|
return target if target.match?(/\Ahttps?:\/\//)
|
|
181
221
|
|
|
182
222
|
# If it's a path and we're using Selenium, construct a full URL
|
|
183
|
-
#
|
|
184
|
-
port =
|
|
223
|
+
# Try to detect the actual port, or use environment variables, or default to 3000
|
|
224
|
+
port = detect_server_port
|
|
185
225
|
base_url = ENV['RAILS_URL'] || "http://localhost:#{port}"
|
|
186
226
|
|
|
187
227
|
# Ensure path starts with /
|
|
@@ -189,7 +229,42 @@ module RailsAccessibilityTesting
|
|
|
189
229
|
"#{base_url}#{path}"
|
|
190
230
|
end
|
|
191
231
|
|
|
192
|
-
def
|
|
232
|
+
def detect_server_port
|
|
233
|
+
# Check environment variables first
|
|
234
|
+
return ENV['PORT'] if ENV['PORT']
|
|
235
|
+
return ENV['RAILS_PORT'] if ENV['RAILS_PORT']
|
|
236
|
+
|
|
237
|
+
# Try to detect port from Rails server - check common Rails ports
|
|
238
|
+
# Check in order: 3000 (most common), then others
|
|
239
|
+
# Prioritize 3000 first as it's the Rails default
|
|
240
|
+
common_ports = [3000, 3001, 4000, 5000]
|
|
241
|
+
|
|
242
|
+
common_ports.each do |port|
|
|
243
|
+
begin
|
|
244
|
+
require 'net/http'
|
|
245
|
+
http = Net::HTTP.new('localhost', port)
|
|
246
|
+
http.open_timeout = 1
|
|
247
|
+
http.read_timeout = 1
|
|
248
|
+
# Try to get a response - check if it looks like a Rails server
|
|
249
|
+
response = http.head('/')
|
|
250
|
+
# Accept 2xx, 3xx, or 4xx responses (server is responding)
|
|
251
|
+
# Reject 5xx as it might be a proxy or error
|
|
252
|
+
if response.code.to_i < 500
|
|
253
|
+
# Additional check: Rails servers usually have certain headers
|
|
254
|
+
# But for now, any HTTP response on these common ports is likely Rails
|
|
255
|
+
return port.to_s
|
|
256
|
+
end
|
|
257
|
+
rescue Errno::ECONNREFUSED, Net::OpenTimeout, Net::ReadTimeout, SocketError, Interrupt, Errno::EHOSTUNREACH, Errno::ETIMEDOUT
|
|
258
|
+
# Port not available or interrupted, try next
|
|
259
|
+
next
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Default to 3000 if nothing found
|
|
264
|
+
'3000'
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def wait_for_server(url, max_retries: 15, retry_delay: 1)
|
|
193
268
|
require 'net/http'
|
|
194
269
|
require 'uri'
|
|
195
270
|
|
|
@@ -199,22 +274,31 @@ module RailsAccessibilityTesting
|
|
|
199
274
|
max_retries.times do |attempt|
|
|
200
275
|
begin
|
|
201
276
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
202
|
-
http.open_timeout =
|
|
203
|
-
http.read_timeout =
|
|
277
|
+
http.open_timeout = 2
|
|
278
|
+
http.read_timeout = 2
|
|
204
279
|
response = http.head('/')
|
|
205
|
-
return if response.code.to_i < 500 # Server is responding
|
|
206
|
-
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Net::OpenTimeout, Net::ReadTimeout, SocketError
|
|
280
|
+
return true if response.code.to_i < 500 # Server is responding
|
|
281
|
+
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Net::OpenTimeout, Net::ReadTimeout, SocketError, Errno::EHOSTUNREACH
|
|
207
282
|
# Server not ready yet
|
|
208
283
|
if attempt < max_retries - 1
|
|
209
|
-
|
|
284
|
+
begin
|
|
285
|
+
sleep(retry_delay)
|
|
286
|
+
rescue Interrupt
|
|
287
|
+
# Handle interrupt gracefully - return false to indicate failure
|
|
288
|
+
return false
|
|
289
|
+
end
|
|
210
290
|
next
|
|
211
291
|
else
|
|
212
|
-
# Last attempt failed
|
|
213
|
-
|
|
214
|
-
return
|
|
292
|
+
# Last attempt failed
|
|
293
|
+
return false
|
|
215
294
|
end
|
|
295
|
+
rescue Interrupt
|
|
296
|
+
# Handle interrupt gracefully
|
|
297
|
+
return false
|
|
216
298
|
end
|
|
217
299
|
end
|
|
300
|
+
|
|
301
|
+
false
|
|
218
302
|
end
|
|
219
303
|
|
|
220
304
|
def resolve_routes(routes)
|
|
@@ -230,6 +314,11 @@ module RailsAccessibilityTesting
|
|
|
230
314
|
end
|
|
231
315
|
|
|
232
316
|
def generate_report(results, options)
|
|
317
|
+
# Don't generate report if no URLs were checked (server not ready)
|
|
318
|
+
if results[:summary][:urls_checked] == 0
|
|
319
|
+
return
|
|
320
|
+
end
|
|
321
|
+
|
|
233
322
|
output = case options[:format]
|
|
234
323
|
when :json
|
|
235
324
|
generate_json_report(results)
|
|
@@ -262,11 +351,14 @@ module RailsAccessibilityTesting
|
|
|
262
351
|
output << ""
|
|
263
352
|
|
|
264
353
|
results[:violations].each_with_index do |violation, index|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
354
|
+
# Use ErrorMessageBuilder for detailed formatted messages
|
|
355
|
+
detailed_message = ErrorMessageBuilder.build(
|
|
356
|
+
error_type: violation.message,
|
|
357
|
+
element_context: violation.element_context || {},
|
|
358
|
+
page_context: violation.page_context || {}
|
|
359
|
+
)
|
|
360
|
+
output << detailed_message
|
|
361
|
+
output << "" if index < results[:violations].count - 1 # Add spacing between violations
|
|
270
362
|
end
|
|
271
363
|
else
|
|
272
364
|
output << "✅ No accessibility violations found!"
|
|
@@ -300,7 +392,8 @@ module RailsAccessibilityTesting
|
|
|
300
392
|
-v, --version Show version
|
|
301
393
|
|
|
302
394
|
Examples:
|
|
303
|
-
rails_a11y
|
|
395
|
+
rails_a11y /home /about
|
|
396
|
+
rails_a11y /
|
|
304
397
|
rails_a11y --urls https://example.com
|
|
305
398
|
rails_a11y --routes home_path about_path --format json --output report.json
|
|
306
399
|
HELP
|
|
@@ -38,7 +38,9 @@ module RailsAccessibilityTesting
|
|
|
38
38
|
|
|
39
39
|
merge_profile_config(parsed, profile)
|
|
40
40
|
rescue StandardError => e
|
|
41
|
-
RailsAccessibilityTesting.config.
|
|
41
|
+
if defined?(RailsAccessibilityTesting) && RailsAccessibilityTesting.config.respond_to?(:logger) && RailsAccessibilityTesting.config.logger
|
|
42
|
+
RailsAccessibilityTesting.config.logger.warn("Failed to load config: #{e.message}")
|
|
43
|
+
end
|
|
42
44
|
default_config
|
|
43
45
|
end
|
|
44
46
|
|
|
@@ -9,11 +9,13 @@ module RailsAccessibilityTesting
|
|
|
9
9
|
# end
|
|
10
10
|
#
|
|
11
11
|
# @attr [Boolean] auto_run_checks Whether to automatically run checks after system specs
|
|
12
|
+
# @attr [Logger, nil] logger Optional logger for accessibility check output
|
|
12
13
|
class Configuration
|
|
13
|
-
attr_accessor :auto_run_checks
|
|
14
|
+
attr_accessor :auto_run_checks, :logger
|
|
14
15
|
|
|
15
16
|
def initialize
|
|
16
17
|
@auto_run_checks = true
|
|
18
|
+
@logger = nil
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
|
|
@@ -38,7 +38,9 @@ module RailsAccessibilityTesting
|
|
|
38
38
|
@violation_collector.add(violations) if violations.any?
|
|
39
39
|
rescue StandardError => e
|
|
40
40
|
# Log but don't fail - one check error shouldn't stop others
|
|
41
|
-
RailsAccessibilityTesting.config.
|
|
41
|
+
if defined?(RailsAccessibilityTesting) && RailsAccessibilityTesting.config.respond_to?(:logger) && RailsAccessibilityTesting.config.logger
|
|
42
|
+
RailsAccessibilityTesting.config.logger.error("Check #{check_class.rule_name} failed: #{e.message}")
|
|
43
|
+
end
|
|
42
44
|
end
|
|
43
45
|
end
|
|
44
46
|
|
|
@@ -48,7 +48,14 @@ module RailsAccessibilityTesting
|
|
|
48
48
|
# Run comprehensive accessibility checks
|
|
49
49
|
instance = example.example_group_instance
|
|
50
50
|
instance.check_comprehensive_accessibility
|
|
51
|
+
|
|
52
|
+
# If we get here without an exception, all checks passed
|
|
53
|
+
# Note: check_comprehensive_accessibility will raise if there are errors,
|
|
54
|
+
# so if we reach this point, checks passed successfully
|
|
55
|
+
$stdout.puts "\n✅ All comprehensive accessibility checks passed! (11 checks)"
|
|
56
|
+
$stdout.flush
|
|
51
57
|
rescue StandardError => e
|
|
58
|
+
# Accessibility check failed - set the exception so test fails
|
|
52
59
|
example.set_exception(e)
|
|
53
60
|
end
|
|
54
61
|
end
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Automatically configures accessibility testing for Rails system specs with
|
|
6
6
|
# comprehensive checks and detailed error messages.
|
|
7
7
|
#
|
|
8
|
-
# @version 1.
|
|
8
|
+
# @version 1.4.0
|
|
9
9
|
# @author Regan Maharjan
|
|
10
10
|
#
|
|
11
11
|
# @example Basic usage
|
|
@@ -38,7 +38,7 @@ begin
|
|
|
38
38
|
require_relative 'rails_accessibility_testing/version'
|
|
39
39
|
rescue LoadError
|
|
40
40
|
module RailsAccessibilityTesting
|
|
41
|
-
VERSION = '1.
|
|
41
|
+
VERSION = '1.4.0'
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_accessibility_testing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Regan Maharjan
|
|
@@ -84,6 +84,7 @@ files:
|
|
|
84
84
|
- CONTRIBUTING.md
|
|
85
85
|
- GUIDES/continuous_integration.md
|
|
86
86
|
- GUIDES/getting_started.md
|
|
87
|
+
- GUIDES/system_specs_for_accessibility.md
|
|
87
88
|
- GUIDES/working_with_designers_and_content_authors.md
|
|
88
89
|
- GUIDES/writing_accessible_views_in_rails.md
|
|
89
90
|
- LICENSE
|