rails_accessibility_testing 1.1.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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/ARCHITECTURE.md +307 -0
  3. data/CHANGELOG.md +81 -0
  4. data/CODE_OF_CONDUCT.md +125 -0
  5. data/CONTRIBUTING.md +225 -0
  6. data/GUIDES/continuous_integration.md +326 -0
  7. data/GUIDES/getting_started.md +205 -0
  8. data/GUIDES/working_with_designers_and_content_authors.md +398 -0
  9. data/GUIDES/writing_accessible_views_in_rails.md +412 -0
  10. data/LICENSE +22 -0
  11. data/README.md +350 -0
  12. data/docs_site/404.html +11 -0
  13. data/docs_site/Gemfile +11 -0
  14. data/docs_site/Makefile +14 -0
  15. data/docs_site/_config.yml +41 -0
  16. data/docs_site/_includes/header.html +13 -0
  17. data/docs_site/_layouts/default.html +130 -0
  18. data/docs_site/assets/main.scss +4 -0
  19. data/docs_site/ci_integration.md +76 -0
  20. data/docs_site/configuration.md +114 -0
  21. data/docs_site/contributing.md +69 -0
  22. data/docs_site/getting_started.md +57 -0
  23. data/docs_site/index.md +57 -0
  24. data/exe/rails_a11y +12 -0
  25. data/exe/rails_server_safe +41 -0
  26. data/lib/generators/rails_a11y/install/generator.rb +51 -0
  27. data/lib/rails_accessibility_testing/accessibility_helper.rb +701 -0
  28. data/lib/rails_accessibility_testing/change_detector.rb +114 -0
  29. data/lib/rails_accessibility_testing/checks/aria_landmarks_check.rb +33 -0
  30. data/lib/rails_accessibility_testing/checks/base_check.rb +156 -0
  31. data/lib/rails_accessibility_testing/checks/color_contrast_check.rb +56 -0
  32. data/lib/rails_accessibility_testing/checks/duplicate_ids_check.rb +49 -0
  33. data/lib/rails_accessibility_testing/checks/form_errors_check.rb +40 -0
  34. data/lib/rails_accessibility_testing/checks/form_labels_check.rb +62 -0
  35. data/lib/rails_accessibility_testing/checks/heading_hierarchy_check.rb +53 -0
  36. data/lib/rails_accessibility_testing/checks/image_alt_text_check.rb +52 -0
  37. data/lib/rails_accessibility_testing/checks/interactive_elements_check.rb +66 -0
  38. data/lib/rails_accessibility_testing/checks/keyboard_accessibility_check.rb +36 -0
  39. data/lib/rails_accessibility_testing/checks/skip_links_check.rb +24 -0
  40. data/lib/rails_accessibility_testing/checks/table_structure_check.rb +36 -0
  41. data/lib/rails_accessibility_testing/cli/command.rb +259 -0
  42. data/lib/rails_accessibility_testing/config/yaml_loader.rb +131 -0
  43. data/lib/rails_accessibility_testing/configuration.rb +30 -0
  44. data/lib/rails_accessibility_testing/engine/rule_engine.rb +97 -0
  45. data/lib/rails_accessibility_testing/engine/violation.rb +58 -0
  46. data/lib/rails_accessibility_testing/engine/violation_collector.rb +59 -0
  47. data/lib/rails_accessibility_testing/error_message_builder.rb +354 -0
  48. data/lib/rails_accessibility_testing/integration/minitest_integration.rb +74 -0
  49. data/lib/rails_accessibility_testing/rspec_integration.rb +58 -0
  50. data/lib/rails_accessibility_testing/shared_examples.rb +93 -0
  51. data/lib/rails_accessibility_testing/version.rb +4 -0
  52. data/lib/rails_accessibility_testing.rb +83 -0
  53. data/lib/tasks/accessibility.rake +28 -0
  54. metadata +218 -0
@@ -0,0 +1,205 @@
1
+ # Getting Started with Rails A11y
2
+
3
+ Welcome to Rails A11y! This guide will help you get up and running with accessibility testing in your Rails application in just a few minutes.
4
+
5
+ ## What is Rails A11y?
6
+
7
+ Rails A11y is an accessibility testing gem that automatically checks your Rails views for WCAG 2.1 AA compliance. Think of it as RSpec + RuboCop for accessibility—it catches violations as you code, not after deployment.
8
+
9
+ ## Quick Start (5 Minutes)
10
+
11
+ ### Step 1: Install the Gem
12
+
13
+ Add to your `Gemfile`:
14
+
15
+ ```ruby
16
+ group :development, :test do
17
+ gem 'rails_accessibility_testing'
18
+ gem 'axe-core-capybara', '~> 4.0'
19
+ end
20
+ ```
21
+
22
+ Then run:
23
+
24
+ ```bash
25
+ bundle install
26
+ ```
27
+
28
+ ### Step 2: Run the Generator
29
+
30
+ ```bash
31
+ rails generate rails_a11y:install
32
+ ```
33
+
34
+ **Note:** The generator uses the short name `rails_a11y` for convenience. The gem name is `rails_accessibility_testing`.
35
+
36
+ This creates:
37
+ - `config/initializers/rails_a11y.rb` - Configuration
38
+ - `config/accessibility.yml` - Check settings
39
+ - Updates `spec/rails_helper.rb` (if using RSpec)
40
+
41
+ ### Step 3: Run Your Tests
42
+
43
+ That's it! Just run your system specs:
44
+
45
+ ```bash
46
+ bundle exec rspec spec/system/
47
+ ```
48
+
49
+ Accessibility checks run automatically on every system test that visits a page.
50
+
51
+ ## Your First Accessibility Check
52
+
53
+ Let's see it in action. Create a simple system spec:
54
+
55
+ ```ruby
56
+ # spec/system/home_spec.rb
57
+ RSpec.describe "Home Page" do
58
+ it "displays the welcome message" do
59
+ visit root_path
60
+ expect(page).to have_content("Welcome")
61
+ # ✅ Accessibility checks run automatically here!
62
+ end
63
+ end
64
+ ```
65
+
66
+ If there are accessibility issues, you'll see detailed error messages like:
67
+
68
+ ```
69
+ ======================================================================
70
+ ❌ ACCESSIBILITY ERROR: Image missing alt attribute
71
+ ======================================================================
72
+
73
+ 📄 Page Being Tested:
74
+ URL: http://localhost:3000/
75
+ Path: /
76
+ 📝 Likely View File: app/views/pages/home.html.erb
77
+
78
+ 📍 Element Details:
79
+ Tag: <img>
80
+ ID: (none)
81
+ Classes: logo
82
+ Src: /assets/logo.png
83
+
84
+ 🔧 HOW TO FIX:
85
+ Choose ONE of these solutions:
86
+
87
+ 1. Add alt text for informative images:
88
+ <img src="/assets/logo.png" alt="Company Logo">
89
+
90
+ 2. Use Rails image_tag helper:
91
+ <%= image_tag 'logo.png', alt: 'Company Logo' %>
92
+
93
+ 💡 Best Practice: All images must have alt attribute.
94
+ Use empty alt="" only for purely decorative images.
95
+ ```
96
+
97
+ ## Understanding the Checks
98
+
99
+ Rails A11y runs 11 comprehensive checks:
100
+
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 links have accessible names
104
+ 4. **Heading Hierarchy** - Proper h1-h6 structure
105
+ 5. **Keyboard Accessibility** - All interactive elements are keyboard accessible
106
+ 6. **ARIA Landmarks** - Proper use of ARIA landmark roles
107
+ 7. **Form Error Associations** - Errors linked to form fields
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)
112
+
113
+ ## Configuration
114
+
115
+ ### Basic Configuration
116
+
117
+ Edit `config/accessibility.yml`:
118
+
119
+ ```yaml
120
+ wcag_level: AA
121
+
122
+ checks:
123
+ form_labels: true
124
+ image_alt_text: true
125
+ # ... other checks
126
+ color_contrast: false # Disabled by default (expensive)
127
+ ```
128
+
129
+ ### Profile-Specific Configuration
130
+
131
+ Different settings for different environments:
132
+
133
+ ```yaml
134
+ development:
135
+ checks:
136
+ color_contrast: false # Skip in dev for speed
137
+
138
+ ci:
139
+ checks:
140
+ color_contrast: true # Full checks in CI
141
+ ```
142
+
143
+ ### Ignoring Rules Temporarily
144
+
145
+ Sometimes you need to temporarily ignore a rule while fixing issues:
146
+
147
+ ```yaml
148
+ ignored_rules:
149
+ - rule: form_labels
150
+ reason: "Legacy form, scheduled for refactor in Q2"
151
+ comment: "Will be fixed in PR #123"
152
+ ```
153
+
154
+ **Important:** Always include a reason and plan to fix. This is for temporary exceptions, not permanent workarounds.
155
+
156
+ ## Skipping Checks in Tests
157
+
158
+ Sometimes you need to skip accessibility checks for specific tests:
159
+
160
+ ```ruby
161
+ # RSpec
162
+ it "does something", skip_a11y: true do
163
+ # Accessibility checks won't run
164
+ end
165
+
166
+ # Minitest
167
+ test "does something", skip_a11y: true do
168
+ # Accessibility checks won't run
169
+ end
170
+ ```
171
+
172
+ ## Next Steps
173
+
174
+ - **Read the [CI Integration Guide](continuous_integration.md)** to set up automated checks
175
+ - **Check out [Writing Accessible Views](writing_accessible_views_in_rails.md)** for best practices
176
+ - **See [Working with Designers](working_with_designers_and_content_authors.md)** for team collaboration
177
+
178
+ ## Common Questions
179
+
180
+ ### Q: Do I need to change my existing tests?
181
+
182
+ **A:** No! Rails A11y works with your existing system tests. Just run them as usual.
183
+
184
+ ### Q: Will this slow down my tests?
185
+
186
+ **A:** Checks only run when you visit a page in a system test. The checks are fast, and you can disable expensive ones (like color contrast) in development.
187
+
188
+ ### Q: Can I use this with Minitest?
189
+
190
+ **A:** Yes! See the Minitest integration in the main README.
191
+
192
+ ### Q: What if I disagree with a check?
193
+
194
+ **A:** You can disable specific checks in `config/accessibility.yml` or ignore specific rules with a reason.
195
+
196
+ ## Getting Help
197
+
198
+ - **Documentation:** See the main [README](../README.md)
199
+ - **Issues:** [GitHub Issues](https://github.com/your-org/rails-a11y/issues)
200
+ - **Email:** support@example.com
201
+
202
+ ---
203
+
204
+ **Ready to make your Rails app accessible?** Run your tests and start fixing issues! 🚀
205
+
@@ -0,0 +1,398 @@
1
+ # Working with Designers and Content Authors
2
+
3
+ Accessibility is a team effort. This guide helps developers collaborate effectively with designers and content authors to build accessible Rails applications.
4
+
5
+ ## The Team Approach
6
+
7
+ ### Roles and Responsibilities
8
+
9
+ **Developers:**
10
+ - Implement accessible HTML structure
11
+ - Ensure technical accessibility (ARIA, semantics)
12
+ - Run automated checks
13
+ - Fix violations
14
+
15
+ **Designers:**
16
+ - Design with accessibility in mind
17
+ - Ensure sufficient color contrast
18
+ - Design keyboard-friendly interactions
19
+ - Create accessible component patterns
20
+
21
+ **Content Authors:**
22
+ - Write descriptive alt text
23
+ - Create clear link text
24
+ - Structure content logically
25
+ - Write accessible form labels
26
+
27
+ ## For Designers
28
+
29
+ ### Design Principles
30
+
31
+ #### 1. Color Contrast
32
+
33
+ **Requirement:** WCAG AA requires:
34
+ - Normal text: 4.5:1 contrast ratio
35
+ - Large text (18pt+ or 14pt+ bold): 3:1 contrast ratio
36
+
37
+ **Tools:**
38
+ - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
39
+ - [Stark](https://www.getstark.co/) - Figma/Sketch plugin
40
+ - Browser DevTools
41
+
42
+ **Example:**
43
+ ```
44
+ ✅ Good: #000000 on #FFFFFF (21:1)
45
+ ✅ Good: #333333 on #FFFFFF (12.6:1)
46
+ ❌ Bad: #CCCCCC on #FFFFFF (1.6:1)
47
+ ```
48
+
49
+ #### 2. Focus States
50
+
51
+ **Requirement:** All interactive elements must have visible focus indicators.
52
+
53
+ **Design:**
54
+ - Clear, visible outline
55
+ - High contrast
56
+ - Consistent across components
57
+
58
+ **Example:**
59
+ ```css
60
+ button:focus {
61
+ outline: 3px solid #0066cc;
62
+ outline-offset: 2px;
63
+ }
64
+ ```
65
+
66
+ #### 3. Touch Targets
67
+
68
+ **Requirement:** Minimum 44x44px touch targets (mobile).
69
+
70
+ **Design:**
71
+ - Buttons large enough to tap easily
72
+ - Adequate spacing between interactive elements
73
+ - Consider thumb zones on mobile
74
+
75
+ #### 4. Text Sizing
76
+
77
+ **Requirement:** Text must be resizable up to 200% without loss of functionality.
78
+
79
+ **Design:**
80
+ - Use relative units (em, rem, %)
81
+ - Avoid fixed pixel sizes for text
82
+ - Test at 200% zoom
83
+
84
+ ### Design System Patterns
85
+
86
+ #### Accessible Button Styles
87
+
88
+ ```css
89
+ /* Primary button */
90
+ .btn-primary {
91
+ background: #0066cc;
92
+ color: #ffffff;
93
+ padding: 12px 24px;
94
+ min-height: 44px; /* Touch target */
95
+ border: 2px solid transparent;
96
+ }
97
+
98
+ .btn-primary:focus {
99
+ outline: 3px solid #0066cc;
100
+ outline-offset: 2px;
101
+ }
102
+
103
+ .btn-primary:hover {
104
+ background: #0052a3;
105
+ }
106
+ ```
107
+
108
+ #### Accessible Form Styles
109
+
110
+ ```css
111
+ .form-label {
112
+ display: block;
113
+ margin-bottom: 8px;
114
+ font-weight: 600;
115
+ }
116
+
117
+ .form-input {
118
+ padding: 12px;
119
+ border: 2px solid #ccc;
120
+ border-radius: 4px;
121
+ }
122
+
123
+ .form-input:focus {
124
+ outline: 3px solid #0066cc;
125
+ outline-offset: 2px;
126
+ border-color: #0066cc;
127
+ }
128
+
129
+ .form-error {
130
+ color: #d32f2f;
131
+ margin-top: 4px;
132
+ font-size: 0.875rem;
133
+ }
134
+ ```
135
+
136
+ ### Component Specifications
137
+
138
+ When handing off designs, include:
139
+
140
+ 1. **Color specifications** - Hex codes with contrast ratios
141
+ 2. **Focus states** - How focus should look
142
+ 3. **Error states** - How errors are displayed
143
+ 4. **Loading states** - How loading is indicated
144
+ 5. **Keyboard interactions** - Tab order, keyboard shortcuts
145
+
146
+ ### Design Review Checklist
147
+
148
+ - [ ] All text meets contrast requirements
149
+ - [ ] Focus states are visible and clear
150
+ - [ ] Touch targets are at least 44x44px
151
+ - [ ] Color is not the only indicator (e.g., errors)
152
+ - [ ] Interactive elements are clearly identifiable
153
+ - [ ] Layout works at 200% zoom
154
+
155
+ ## For Content Authors
156
+
157
+ ### Writing Alt Text
158
+
159
+ #### Informative Images
160
+
161
+ **Good:**
162
+ ```
163
+ Alt: "A red bicycle parked outside a coffee shop"
164
+ Alt: "Screenshot of the dashboard showing 5 active users"
165
+ ```
166
+
167
+ **Bad:**
168
+ ```
169
+ Alt: "Image" <!-- Too generic -->
170
+ Alt: "Photo" <!-- Not descriptive -->
171
+ Alt: "bicycle.jpg" <!-- Filename, not description -->
172
+ ```
173
+
174
+ #### Decorative Images
175
+
176
+ For purely decorative images, use empty alt:
177
+
178
+ ```erb
179
+ <%= image_tag "border.png", alt: "" %>
180
+ ```
181
+
182
+ #### Complex Images
183
+
184
+ For charts, graphs, or infographics:
185
+
186
+ ```erb
187
+ <%= image_tag "chart.png", alt: "Bar chart showing sales increased 25% from Q1 to Q2" %>
188
+ ```
189
+
190
+ Or provide a detailed description:
191
+
192
+ ```erb
193
+ <figure>
194
+ <%= image_tag "chart.png", alt: "Sales chart" %>
195
+ <figcaption>Sales increased 25% from Q1 ($50k) to Q2 ($62.5k)</figcaption>
196
+ </figure>
197
+ ```
198
+
199
+ ### Writing Link Text
200
+
201
+ #### ✅ Good: Descriptive
202
+
203
+ ```erb
204
+ <%= link_to "Read our privacy policy", privacy_path %>
205
+ <%= link_to "Download the user guide (PDF)", guide_path %>
206
+ ```
207
+
208
+ #### ❌ Bad: Generic
209
+
210
+ ```erb
211
+ <%= link_to "Click here", privacy_path %> <!-- Generic! -->
212
+ <%= link_to "More", article_path(@article) %> <!-- Vague! -->
213
+ <%= link_to "Read more", article_path(@article) %> <!-- Repeated! -->
214
+ ```
215
+
216
+ #### Context Matters
217
+
218
+ If link text is repeated, add context:
219
+
220
+ ```erb
221
+ <article>
222
+ <h2><%= @article.title %></h2>
223
+ <p><%= @article.excerpt %></p>
224
+ <%= link_to "Read full article: #{@article.title}", article_path(@article) %>
225
+ </article>
226
+ ```
227
+
228
+ ### Writing Form Labels
229
+
230
+ #### ✅ Good: Clear and Specific
231
+
232
+ ```erb
233
+ <%= f.label :email, "Email Address" %>
234
+ <%= f.label :phone, "Phone Number (optional)" %>
235
+ <%= f.label :password, "Password (minimum 8 characters)" %>
236
+ ```
237
+
238
+ #### ❌ Bad: Vague
239
+
240
+ ```erb
241
+ <%= f.label :email, "Email" %> <!-- Could be clearer -->
242
+ <%= f.label :field1, "Field 1" %> <!-- Meaningless! -->
243
+ ```
244
+
245
+ ### Structuring Content
246
+
247
+ #### Use Headings Properly
248
+
249
+ ```erb
250
+ <h1>Page Title</h1>
251
+ <h2>Introduction</h2>
252
+ <h2>Features</h2>
253
+ <h3>Feature 1</h3>
254
+ <h3>Feature 2</h3>
255
+ <h2>Conclusion</h2>
256
+ ```
257
+
258
+ #### Use Lists for Related Items
259
+
260
+ ```erb
261
+ <ul>
262
+ <li>First item</li>
263
+ <li>Second item</li>
264
+ <li>Third item</li>
265
+ </ul>
266
+ ```
267
+
268
+ #### Use Semantic HTML
269
+
270
+ ```erb
271
+ <article>
272
+ <header>
273
+ <h1>Article Title</h1>
274
+ <p>By Author Name</p>
275
+ </header>
276
+ <main>
277
+ <!-- Content -->
278
+ </main>
279
+ <footer>
280
+ <p>Published on <%= @article.published_at %></p>
281
+ </footer>
282
+ </article>
283
+ ```
284
+
285
+ ## Collaboration Workflows
286
+
287
+ ### Design Handoff
288
+
289
+ 1. **Designer provides:**
290
+ - Design files with accessibility notes
291
+ - Color specifications with contrast ratios
292
+ - Component specifications
293
+ - Focus state designs
294
+
295
+ 2. **Developer reviews:**
296
+ - Checks contrast ratios
297
+ - Verifies touch target sizes
298
+ - Confirms keyboard navigation
299
+ - Tests with screen reader
300
+
301
+ 3. **Feedback loop:**
302
+ - Developer flags accessibility issues
303
+ - Designer adjusts as needed
304
+ - Iterate until accessible
305
+
306
+ ### Content Review
307
+
308
+ 1. **Content author provides:**
309
+ - Alt text for images
310
+ - Link text
311
+ - Form labels
312
+ - Heading structure
313
+
314
+ 2. **Developer reviews:**
315
+ - Runs Rails A11y checks
316
+ - Verifies alt text quality
317
+ - Checks link text clarity
318
+ - Validates heading hierarchy
319
+
320
+ 3. **Feedback loop:**
321
+ - Developer suggests improvements
322
+ - Content author revises
323
+ - Final review before publish
324
+
325
+ ### Testing Together
326
+
327
+ Schedule regular accessibility reviews:
328
+
329
+ 1. **Design review** - Check designs for accessibility
330
+ 2. **Content review** - Review alt text and copy
331
+ 3. **Implementation review** - Test with screen readers
332
+ 4. **Final review** - Full accessibility audit
333
+
334
+ ## Tools for Collaboration
335
+
336
+ ### Design Tools
337
+
338
+ - **Figma:** [A11y - Focus Orderer](https://www.figma.com/community/plugin/731310036527916373)
339
+ - **Sketch:** [Stark](https://www.getstark.co/)
340
+ - **Adobe XD:** Built-in contrast checker
341
+
342
+ ### Communication
343
+
344
+ - **Slack/Teams:** Share accessibility reports
345
+ - **GitHub:** Comment on PRs with accessibility notes
346
+ - **Notion/Confluence:** Document accessibility patterns
347
+
348
+ ### Testing
349
+
350
+ - **Browser DevTools:** Built-in accessibility inspector
351
+ - **axe DevTools:** Browser extension
352
+ - **WAVE:** Web accessibility evaluation tool
353
+
354
+ ## Common Issues and Solutions
355
+
356
+ ### Issue: Low Contrast Text
357
+
358
+ **Designer:** "But it looks better this way!"
359
+
360
+ **Solution:** Show the contrast ratio. Explain that 1 in 12 men have color blindness. Offer alternative colors that meet contrast requirements.
361
+
362
+ ### Issue: Generic Link Text
363
+
364
+ **Content Author:** "But 'Click here' is clear in context!"
365
+
366
+ **Solution:** Explain that screen reader users navigate by links. Show how "Read privacy policy" is clearer than "Click here" out of context.
367
+
368
+ ### Issue: Missing Alt Text
369
+
370
+ **Content Author:** "The image is decorative, why do I need alt text?"
371
+
372
+ **Solution:** Use empty alt (`alt=""`) for decorative images. This tells screen readers to skip the image.
373
+
374
+ ## Resources
375
+
376
+ ### For Designers
377
+
378
+ - [Inclusive Components](https://inclusive-components.design/)
379
+ - [A11y Project Checklist](https://www.a11yproject.com/checklist/)
380
+ - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
381
+
382
+ ### For Content Authors
383
+
384
+ - [Alt Text Guide](https://www.a11yproject.com/posts/alt-text/)
385
+ - [Writing Link Text](https://www.a11yproject.com/posts/how-to-write-accessible-link-text/)
386
+ - [Heading Structure](https://www.a11yproject.com/posts/how-to-structure-headings/)
387
+
388
+ ## Next Steps
389
+
390
+ 1. **Schedule a team meeting** - Discuss accessibility goals
391
+ 2. **Create style guide** - Document accessibility patterns
392
+ 3. **Set up reviews** - Regular accessibility check-ins
393
+ 4. **Share resources** - Provide training materials
394
+
395
+ ---
396
+
397
+ **Remember:** Accessibility is everyone's responsibility. Working together makes it easier and more effective.
398
+