|
| 1 | +# Best Practices for Rails Accessibility Testing |
| 2 | + |
| 3 | +This guide documents recommended practices for configuring and using Rails Accessibility Testing in your Rails application, based on real-world usage and production experience. |
| 4 | + |
| 5 | +## Configuration Best Practices |
| 6 | + |
| 7 | +### 1. Disable by Default for CI/CD Safety |
| 8 | + |
| 9 | +**Recommended:** Set `accessibility_enabled: false` in `config/accessibility.yml` |
| 10 | + |
| 11 | +```yaml |
| 12 | +# config/accessibility.yml |
| 13 | +accessibility_enabled: false |
| 14 | +``` |
| 15 | +
|
| 16 | +**Why?** |
| 17 | +- Prevents accessibility test failures from blocking your entire CI/CD pipeline |
| 18 | +- Allows other RSpec tests to pass even if accessibility tests fail |
| 19 | +- Gives you control over when to run accessibility checks |
| 20 | +- Enables manual testing: `rspec spec/accessibility/all_pages_accessibility_spec.rb` |
| 21 | + |
| 22 | +**When to enable:** |
| 23 | +- Set to `true` when you want accessibility tests to run automatically |
| 24 | +- Use manual invocation for focused accessibility testing |
| 25 | +- Enable in CI only when you're ready to enforce accessibility compliance |
| 26 | + |
| 27 | +**Example:** |
| 28 | +```yaml |
| 29 | +# Default: false |
| 30 | +# (Set to false to allow other RSpec tests to pass in GitHub Actions CI even if accessibility tests fail. |
| 31 | +# When true, any failing accessibility tests will cause the entire CI pipeline to fail.) |
| 32 | +# Set to true to run accessibility checks manually: rspec spec/accessibility/all_pages_accessibility_spec.rb |
| 33 | +accessibility_enabled: false |
| 34 | +``` |
| 35 | + |
| 36 | +### 2. Production Safety Guard |
| 37 | + |
| 38 | +**Recommended:** Wrap configuration in conditional check |
| 39 | + |
| 40 | +```ruby |
| 41 | +# config/initializers/rails_a11y.rb |
| 42 | +if defined?(RailsAccessibilityTesting) |
| 43 | + RailsAccessibilityTesting.configure do |config| |
| 44 | + config.auto_run_checks = false |
| 45 | + # ... other config |
| 46 | + end |
| 47 | +end |
| 48 | +``` |
| 49 | + |
| 50 | +**Why?** |
| 51 | +- Prevents errors if gem is not available in production |
| 52 | +- Allows gem to be excluded from production bundle |
| 53 | +- Safe deployment even if gem configuration is present |
| 54 | + |
| 55 | +### 3. Manual Control Over Automatic Checks |
| 56 | + |
| 57 | +**Recommended:** Set `auto_run_checks = false` in initializer |
| 58 | + |
| 59 | +```ruby |
| 60 | +config.auto_run_checks = false |
| 61 | +``` |
| 62 | + |
| 63 | +**Why?** |
| 64 | +- Gives developers explicit control over when checks run |
| 65 | +- Prevents unexpected test failures during development |
| 66 | +- Allows focused accessibility testing when needed |
| 67 | +- Use `check_comprehensive_accessibility` explicitly in specs when desired |
| 68 | + |
| 69 | +**Alternative:** Enable per-environment |
| 70 | +```ruby |
| 71 | +config.auto_run_checks = Rails.env.development? || Rails.env.test? |
| 72 | +``` |
| 73 | + |
| 74 | +### 4. Use Accessibility-Specific RSpec Type |
| 75 | + |
| 76 | +**Recommended:** Use `type: :accessibility` for accessibility specs |
| 77 | + |
| 78 | +```ruby |
| 79 | +RSpec.describe 'All Pages Accessibility', type: :accessibility do |
| 80 | + # ... |
| 81 | +end |
| 82 | +``` |
| 83 | + |
| 84 | +**Why?** |
| 85 | +- Proper RSpec integration with accessibility helpers |
| 86 | +- Better test organization and filtering |
| 87 | +- Clearer intent in test files |
| 88 | + |
| 89 | +### 5. Improved Error Formatting |
| 90 | + |
| 91 | +**Recommended:** Use unified formatting method for better output |
| 92 | + |
| 93 | +The generator now creates a `format_issues_by_file` helper method that: |
| 94 | +- Groups errors and warnings by file |
| 95 | +- Shows errors first, then warnings |
| 96 | +- Provides better structure and readability |
| 97 | +- Uses proper test assertions (`expect(errors).to be_empty`) |
| 98 | + |
| 99 | +## CI/CD Integration Best Practices |
| 100 | + |
| 101 | +### GitHub Actions |
| 102 | + |
| 103 | +**Recommended approach:** |
| 104 | + |
| 105 | +1. **Keep accessibility disabled by default:** |
| 106 | + ```yaml |
| 107 | + # config/accessibility.yml |
| 108 | + accessibility_enabled: false |
| 109 | + ``` |
| 110 | + |
| 111 | +2. **Run accessibility tests separately:** |
| 112 | + ```yaml |
| 113 | + # .github/workflows/accessibility.yml |
| 114 | + - name: Run accessibility tests |
| 115 | + run: | |
| 116 | + bundle exec rspec spec/accessibility/all_pages_accessibility_spec.rb |
| 117 | + continue-on-error: true # Don't block PRs initially |
| 118 | + ``` |
| 119 | + |
| 120 | +3. **Gradually enforce:** |
| 121 | + - Start with `continue-on-error: true` to see results |
| 122 | + - Fix existing issues |
| 123 | + - Then set `continue-on-error: false` to enforce |
| 124 | + |
| 125 | +### Profile-Based Configuration |
| 126 | + |
| 127 | +Use different profiles for different environments: |
| 128 | + |
| 129 | +```yaml |
| 130 | +# config/accessibility.yml |
| 131 | +development: |
| 132 | + checks: |
| 133 | + color_contrast: false # Skip expensive checks in dev |
| 134 | +
|
| 135 | +test: |
| 136 | + checks: |
| 137 | + # Use global settings |
| 138 | +
|
| 139 | +ci: |
| 140 | + checks: |
| 141 | + color_contrast: true # Full checks in CI |
| 142 | +``` |
| 143 | + |
| 144 | +Then set profile in CI: |
| 145 | +```bash |
| 146 | +RAILS_A11Y_PROFILE=ci bundle exec rspec spec/accessibility/ |
| 147 | +``` |
| 148 | + |
| 149 | +## Development Workflow Best Practices |
| 150 | + |
| 151 | +### 1. Use Static Scanner During Development |
| 152 | + |
| 153 | +Add to `Procfile.dev`: |
| 154 | +```procfile |
| 155 | +a11y: bundle exec a11y_static_scanner |
| 156 | +``` |
| 157 | + |
| 158 | +**Benefits:** |
| 159 | +- Fast feedback without browser |
| 160 | +- Only scans changed files |
| 161 | +- Continuous monitoring as you code |
| 162 | +- Precise file locations and line numbers |
| 163 | + |
| 164 | +### 2. Manual Testing When Needed |
| 165 | + |
| 166 | +Run accessibility tests explicitly: |
| 167 | +```bash |
| 168 | +# Test all pages |
| 169 | +rspec spec/accessibility/all_pages_accessibility_spec.rb |
| 170 | +
|
| 171 | +# Test specific page |
| 172 | +rspec spec/system/home_page_accessibility_spec.rb |
| 173 | +``` |
| 174 | + |
| 175 | +### 3. Fix Issues Incrementally |
| 176 | + |
| 177 | +1. **Start with critical issues** - Focus on errors first |
| 178 | +2. **Fix by file** - Address all issues in one file at a time |
| 179 | +3. **Test incrementally** - Run tests after each fix |
| 180 | +4. **Document exceptions** - Use `ignored_rules` with reasons |
| 181 | + |
| 182 | +## Configuration File Best Practices |
| 183 | + |
| 184 | +### Documentation URLs |
| 185 | + |
| 186 | +Always use the correct documentation URL: |
| 187 | +```yaml |
| 188 | +# See https://rayraycodes.github.io/rails-accessibility-testing/ for full documentation. |
| 189 | +``` |
| 190 | + |
| 191 | +### Comprehensive Comments |
| 192 | + |
| 193 | +Add detailed comments explaining decisions: |
| 194 | +```yaml |
| 195 | +# Global enable/disable flag for all accessibility checks |
| 196 | +# Set to false to completely disable all accessibility checks (manual and automatic) |
| 197 | +# When false, check_comprehensive_accessibility and automatic checks will be skipped |
| 198 | +# Default: false |
| 199 | +# (Set to false to allow other RSpec tests to pass in GitHub Actions CI even if accessibility tests fail. |
| 200 | +# When true, any failing accessibility tests will cause the entire CI pipeline to fail.) |
| 201 | +# Set to true to run accessibility checks manually: rspec spec/accessibility/all_pages_accessibility_spec.rb |
| 202 | +accessibility_enabled: false |
| 203 | +``` |
| 204 | + |
| 205 | +## Test Spec Best Practices |
| 206 | + |
| 207 | +### 1. Use Proper Test Assertions |
| 208 | + |
| 209 | +**Recommended:** |
| 210 | +```ruby |
| 211 | +if errors.any? || warnings.any? |
| 212 | + expect(errors).to be_empty, format_static_errors(errors, warnings) |
| 213 | +else |
| 214 | + puts "\n✅ #{view_file}: No errors found" |
| 215 | +end |
| 216 | +``` |
| 217 | + |
| 218 | +**Why?** |
| 219 | +- Cleaner test output |
| 220 | +- Proper RSpec integration |
| 221 | +- Better error messages |
| 222 | +- Only fails on errors, not warnings |
| 223 | + |
| 224 | +### 2. Improved Error Formatting |
| 225 | + |
| 226 | +Use unified formatting method: |
| 227 | +```ruby |
| 228 | +def format_issues_by_file(issues_by_file, output, issue_type) |
| 229 | + issues_by_file.each_with_index do |(file_path, file_issues), file_index| |
| 230 | + output << "" if file_index > 0 |
| 231 | + output << "📝 #{file_path} (#{file_issues.length} #{issue_type}#{'s' if file_issues.length != 1})" |
| 232 | + # ... format each issue |
| 233 | + end |
| 234 | +end |
| 235 | +``` |
| 236 | + |
| 237 | +**Benefits:** |
| 238 | +- Consistent formatting |
| 239 | +- Better readability |
| 240 | +- Easier to maintain |
| 241 | + |
| 242 | +## Summary |
| 243 | + |
| 244 | +These best practices are based on real-world production usage and help ensure: |
| 245 | + |
| 246 | +1. **CI/CD Safety** - Accessibility tests don't block other tests |
| 247 | +2. **Production Safety** - No errors if gem isn't available |
| 248 | +3. **Developer Control** - Explicit control over when checks run |
| 249 | +4. **Better UX** - Improved error formatting and test output |
| 250 | +5. **Incremental Adoption** - Easy to start and gradually enforce |
| 251 | + |
| 252 | +## Credits |
| 253 | + |
| 254 | +These best practices were refined based on contributions from: |
| 255 | +- **Margarita Barvinok** - Production configuration improvements |
| 256 | +- Real-world usage in Rails applications |
| 257 | +- Community feedback and testing |
| 258 | + |
| 259 | +--- |
| 260 | + |
| 261 | +**Questions?** See the main [README](../README.md) or open an issue. |
0 commit comments