rails_accessibility_testing 1.5.7 → 1.5.8
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 +16 -0
- data/exe/a11y_live_scanner +21 -0
- data/exe/a11y_static_scanner +21 -0
- data/lib/generators/rails_a11y/install/templates/accessibility.yml.erb +6 -0
- data/lib/generators/rails_a11y/install/templates/all_pages_accessibility_spec.rb.erb +1 -1
- data/lib/rails_accessibility_testing/accessibility_helper.rb +23 -0
- data/lib/rails_accessibility_testing/checks/heading_check.rb +7 -1
- data/lib/rails_accessibility_testing/checks/interactive_elements_check.rb +10 -2
- data/lib/rails_accessibility_testing/config/yaml_loader.rb +2 -0
- data/lib/rails_accessibility_testing/erb_extractor.rb +7 -3
- data/lib/rails_accessibility_testing/rspec_integration.rb +16 -0
- data/lib/rails_accessibility_testing/static_file_scanner.rb +14 -2
- data/lib/rails_accessibility_testing/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: deb1a679b569b2ea1335bd383dd3c3c35a604291cd504acf83b02d6bc8093a33
|
|
4
|
+
data.tar.gz: beeb61ac0b6d7ba710485c03f340427943b5580e77b04c5d77b4b2ea2b395e16
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e5712af98873a226fe1d6b834e4c57983897787859adcd4613c24dafd4c2cd60ed9629b6b4865d595dadcfd2452e60766d4ac703a41ffe5ca98a5510801cc9c2
|
|
7
|
+
data.tar.gz: b3d7cad5a19ddd2b502e4e5a44721e8ecfb787c901ffe65d5904cd98daea202d5d4cd04c8da454f28158d98e2d5450166a6cee953681e762f9aad636c4c2f863
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ 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.5.8] - 2024-12-01
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **ERB template detection**: Fixed false positives for empty headings and missing accessible names when ERB output tags (`<%= ... %>`) are present
|
|
12
|
+
- **Static scanning**: ERB tags are now replaced with placeholder text so checks can detect that content will be present at runtime
|
|
13
|
+
- **Scanner process management**: Static and live scanners now stay alive (sleep loop) when `enabled: false` instead of exiting, preventing Foreman from killing other processes
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Global enable/disable flag**: Added `enabled` configuration option in `accessibility.yml` to completely disable all accessibility checks (manual and automatic)
|
|
17
|
+
- **ERB content detection**: `ErbExtractor` now replaces `<%= ... %>` with `"ERB_CONTENT"` placeholder instead of removing it
|
|
18
|
+
- **ERB-aware checks**: `HeadingCheck` and `InteractiveElementsCheck` now detect ERB placeholders and skip empty checks
|
|
19
|
+
|
|
20
|
+
### Improved
|
|
21
|
+
- **Static scanner behavior**: When `enabled: false`, scanner shows message and keeps running instead of exiting
|
|
22
|
+
- **Live scanner behavior**: When `enabled: false`, scanner shows message and keeps running instead of exiting
|
|
23
|
+
|
|
8
24
|
## [1.5.7] - 2024-12-01
|
|
9
25
|
|
|
10
26
|
### Fixed
|
data/exe/a11y_live_scanner
CHANGED
|
@@ -29,6 +29,27 @@ begin
|
|
|
29
29
|
unless defined?(RailsAccessibilityTesting::AccessibilityHelper)
|
|
30
30
|
raise LoadError, "RailsAccessibilityTesting::AccessibilityHelper not found after requiring gem"
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
# Check if accessibility checks are globally disabled
|
|
34
|
+
begin
|
|
35
|
+
require 'rails_accessibility_testing/config/yaml_loader'
|
|
36
|
+
profile = defined?(Rails) && Rails.env.test? ? :test : :development
|
|
37
|
+
config = RailsAccessibilityTesting::Config::YamlLoader.load(profile: profile)
|
|
38
|
+
enabled = config.fetch('enabled', true)
|
|
39
|
+
unless enabled
|
|
40
|
+
puts "⏸️ Accessibility checks are disabled (enabled: false in config/accessibility.yml)"
|
|
41
|
+
puts " Set enabled: true to enable accessibility scanning"
|
|
42
|
+
puts " Scanner process will remain running but will not scan files"
|
|
43
|
+
puts ""
|
|
44
|
+
# Keep process alive so Foreman doesn't kill other processes
|
|
45
|
+
# Sleep indefinitely until interrupted
|
|
46
|
+
loop do
|
|
47
|
+
sleep 60
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
rescue StandardError => e
|
|
51
|
+
# If config can't be loaded, continue (assume enabled)
|
|
52
|
+
end
|
|
32
53
|
rescue LoadError => e
|
|
33
54
|
$stderr.puts "❌ Error loading rails_accessibility_testing gem: #{e.message}"
|
|
34
55
|
$stderr.puts " Make sure the gem is installed: bundle install"
|
data/exe/a11y_static_scanner
CHANGED
|
@@ -23,6 +23,27 @@ begin
|
|
|
23
23
|
require 'rails_accessibility_testing'
|
|
24
24
|
require 'rails_accessibility_testing/static_file_scanner'
|
|
25
25
|
require 'rails_accessibility_testing/file_change_tracker'
|
|
26
|
+
|
|
27
|
+
# Check if accessibility checks are globally disabled
|
|
28
|
+
begin
|
|
29
|
+
require 'rails_accessibility_testing/config/yaml_loader'
|
|
30
|
+
profile = defined?(Rails) && Rails.env.test? ? :test : :development
|
|
31
|
+
config = RailsAccessibilityTesting::Config::YamlLoader.load(profile: profile)
|
|
32
|
+
enabled = config.fetch('enabled', true)
|
|
33
|
+
unless enabled
|
|
34
|
+
puts "⏸️ Accessibility checks are disabled (enabled: false in config/accessibility.yml)"
|
|
35
|
+
puts " Set enabled: true to enable accessibility scanning"
|
|
36
|
+
puts " Scanner process will remain running but will not scan files"
|
|
37
|
+
puts ""
|
|
38
|
+
# Keep process alive so Foreman doesn't kill other processes
|
|
39
|
+
# Sleep indefinitely until interrupted
|
|
40
|
+
loop do
|
|
41
|
+
sleep 60
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
rescue StandardError => e
|
|
45
|
+
# If config can't be loaded, continue (assume enabled)
|
|
46
|
+
end
|
|
26
47
|
rescue LoadError => e
|
|
27
48
|
$stderr.puts "❌ Error loading rails_accessibility_testing gem: #{e.message}"
|
|
28
49
|
$stderr.puts " Make sure the gem is installed: bundle install"
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
# This file configures accessibility checks for your Rails application.
|
|
4
4
|
# See https://github.com/your-org/rails-a11y for full documentation.
|
|
5
5
|
|
|
6
|
+
# Global enable/disable flag
|
|
7
|
+
# Set to false to completely disable all accessibility checks (manual and automatic)
|
|
8
|
+
# When false, check_comprehensive_accessibility and automatic checks will be skipped
|
|
9
|
+
# Default: true
|
|
10
|
+
enabled: true
|
|
11
|
+
|
|
6
12
|
# WCAG compliance level (A, AA, AAA)
|
|
7
13
|
wcag_level: AA
|
|
8
14
|
|
|
@@ -142,7 +142,7 @@ RSpec.describe 'All Pages Accessibility', type: :system do
|
|
|
142
142
|
puts format_static_errors(errors, warnings)
|
|
143
143
|
|
|
144
144
|
if errors.any?
|
|
145
|
-
|
|
145
|
+
puts "Found #{errors.length} accessibility error#{'s' if errors.length != 1} in #{view_file}"
|
|
146
146
|
end
|
|
147
147
|
else
|
|
148
148
|
puts "✅ #{view_file}: No errors found"
|
|
@@ -211,6 +211,9 @@ module RailsAccessibilityTesting
|
|
|
211
211
|
|
|
212
212
|
# Basic accessibility check - runs 5 basic checks
|
|
213
213
|
def check_basic_accessibility
|
|
214
|
+
# Check if accessibility checks are globally disabled
|
|
215
|
+
return if accessibility_disabled?
|
|
216
|
+
|
|
214
217
|
@accessibility_errors ||= []
|
|
215
218
|
@accessibility_warnings ||= []
|
|
216
219
|
|
|
@@ -243,6 +246,11 @@ module RailsAccessibilityTesting
|
|
|
243
246
|
# Uses the RuleEngine and checks from the checks/ folder for consistency
|
|
244
247
|
# @return [Hash] Hash with :errors and :warnings counts
|
|
245
248
|
def check_comprehensive_accessibility
|
|
249
|
+
# Check if accessibility checks are globally disabled - do this FIRST before any output
|
|
250
|
+
if accessibility_disabled?
|
|
251
|
+
return { errors: 0, warnings: 0, page_context: {} }
|
|
252
|
+
end
|
|
253
|
+
|
|
246
254
|
# Note: Page scanning cache is disabled for RSpec tests to ensure accurate error reporting
|
|
247
255
|
# The cache is only used in live scanner to avoid duplicate scans
|
|
248
256
|
|
|
@@ -433,6 +441,21 @@ module RailsAccessibilityTesting
|
|
|
433
441
|
|
|
434
442
|
private
|
|
435
443
|
|
|
444
|
+
# Check if accessibility checks are globally disabled via config
|
|
445
|
+
def accessibility_disabled?
|
|
446
|
+
begin
|
|
447
|
+
require 'rails_accessibility_testing/config/yaml_loader'
|
|
448
|
+
profile = defined?(Rails) && Rails.env.test? ? :test : :development
|
|
449
|
+
config = RailsAccessibilityTesting::Config::YamlLoader.load(profile: profile)
|
|
450
|
+
enabled = config.fetch('enabled', true) # Default to enabled if not specified
|
|
451
|
+
disabled = !enabled # Return true if disabled
|
|
452
|
+
disabled
|
|
453
|
+
rescue StandardError => e
|
|
454
|
+
# If config can't be loaded, assume enabled
|
|
455
|
+
false
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
|
|
436
459
|
# Format timestamp for terminal output (shorter, more readable)
|
|
437
460
|
def format_timestamp_for_terminal
|
|
438
461
|
# Use just time for same-day reports, or full date if different day
|
|
@@ -82,8 +82,14 @@ module RailsAccessibilityTesting
|
|
|
82
82
|
# Check 4: Empty headings (WCAG 4.1.2)
|
|
83
83
|
headings.each do |heading|
|
|
84
84
|
heading_text = heading.text.strip
|
|
85
|
+
|
|
86
|
+
# Check if heading contains ERB placeholder (for static scanning)
|
|
87
|
+
# ErbExtractor replaces <%= ... %> with "ERB_CONTENT" so we can detect it
|
|
88
|
+
has_erb_content = heading_text.include?('ERB_CONTENT')
|
|
89
|
+
|
|
85
90
|
# Check if heading is empty or only contains whitespace/formatting
|
|
86
|
-
if
|
|
91
|
+
# Skip if it contains ERB content (will be populated at runtime)
|
|
92
|
+
if (heading_text.empty? || heading_text.match?(/^\s*$/)) && !has_erb_content
|
|
87
93
|
element_ctx = element_context(heading)
|
|
88
94
|
violations << violation(
|
|
89
95
|
message: "Empty heading detected (<#{heading.tag_name}>) - headings must have accessible text",
|
|
@@ -46,16 +46,24 @@ module RailsAccessibilityTesting
|
|
|
46
46
|
aria_labelledby = element[:"aria-labelledby"]
|
|
47
47
|
title = element[:title]
|
|
48
48
|
|
|
49
|
+
# Check if element contains ERB placeholder (for static scanning)
|
|
50
|
+
# ErbExtractor replaces <%= ... %> with "ERB_CONTENT" so we can detect it
|
|
51
|
+
# If text includes "ERB_CONTENT", it means there's ERB code that will produce content at runtime
|
|
52
|
+
has_erb_content = text.include?('ERB_CONTENT')
|
|
53
|
+
|
|
49
54
|
# Check if element contains an image with alt text (common pattern for logo links)
|
|
50
55
|
has_image_with_alt = false
|
|
51
|
-
if text.empty?
|
|
56
|
+
if text.empty? && !has_erb_content
|
|
52
57
|
# For static scanning, we can't easily check images within elements
|
|
53
58
|
# This check works better in dynamic scanning with Capybara
|
|
54
59
|
# For now, skip image checking in static mode
|
|
55
60
|
has_image_with_alt = false
|
|
56
61
|
end
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
# Text is empty only if it's actually empty AND doesn't contain ERB content
|
|
64
|
+
# If it contains ERB_CONTENT, it will have content at runtime, so it's not empty
|
|
65
|
+
text_empty = text.empty? && !has_erb_content
|
|
66
|
+
|
|
59
67
|
aria_label_empty = aria_label.nil? || aria_label.to_s.strip.empty?
|
|
60
68
|
aria_labelledby_empty = aria_labelledby.nil? || aria_labelledby.to_s.strip.empty?
|
|
61
69
|
title_empty = title.nil? || title.to_s.strip.empty?
|
|
@@ -84,6 +84,7 @@ module RailsAccessibilityTesting
|
|
|
84
84
|
merged_system_specs = base_system_specs.merge(profile_system_specs)
|
|
85
85
|
|
|
86
86
|
base_config.merge(
|
|
87
|
+
'enabled' => profile_config.fetch('enabled', base_config.fetch('enabled', true)), # Profile can override enabled, default to true
|
|
87
88
|
'checks' => merged_checks,
|
|
88
89
|
'summary' => merged_summary,
|
|
89
90
|
'scan_strategy' => profile_config['scan_strategy'] || base_config['scan_strategy'] || 'paths',
|
|
@@ -122,6 +123,7 @@ module RailsAccessibilityTesting
|
|
|
122
123
|
# Default configuration when no file exists
|
|
123
124
|
def default_config
|
|
124
125
|
{
|
|
126
|
+
'enabled' => true, # Global enable/disable flag for all accessibility checks
|
|
125
127
|
'wcag_level' => 'AA',
|
|
126
128
|
'checks' => default_checks,
|
|
127
129
|
'summary' => {
|
|
@@ -126,10 +126,14 @@ module RailsAccessibilityTesting
|
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
-
# Remove ERB tags
|
|
129
|
+
# Remove or replace ERB tags
|
|
130
|
+
# Replace ERB output tags (<%= ... %>) with placeholder text so checks can detect non-empty content
|
|
131
|
+
# Remove ERB logic tags (<% ... %>) as they don't produce output
|
|
130
132
|
def remove_erb_tags
|
|
131
|
-
|
|
132
|
-
@content.gsub!(
|
|
133
|
+
# Replace ERB output tags with placeholder - this allows checks to detect that content will be present
|
|
134
|
+
@content.gsub!(/<%=(.*?)%>/m, 'ERB_CONTENT')
|
|
135
|
+
# Remove ERB logic tags (they don't produce visible content)
|
|
136
|
+
@content.gsub!(/<%[^=][^%]*%>/, '')
|
|
133
137
|
end
|
|
134
138
|
|
|
135
139
|
# Clean up extra whitespace
|
|
@@ -46,6 +46,19 @@ module RailsAccessibilityTesting
|
|
|
46
46
|
|
|
47
47
|
private
|
|
48
48
|
|
|
49
|
+
# Check if accessibility checks are globally disabled via config
|
|
50
|
+
def accessibility_globally_disabled?
|
|
51
|
+
begin
|
|
52
|
+
require 'rails_accessibility_testing/config/yaml_loader'
|
|
53
|
+
profile = defined?(Rails) && Rails.env.test? ? :test : :development
|
|
54
|
+
config = Config::YamlLoader.load(profile: profile)
|
|
55
|
+
enabled = config.fetch('enabled', true) # Default to enabled if not specified
|
|
56
|
+
!enabled # Return true if disabled
|
|
57
|
+
rescue StandardError
|
|
58
|
+
false # If config can't be loaded, assume enabled
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
49
62
|
# Enable automatic spec type inference from file location
|
|
50
63
|
def enable_spec_type_inference(config)
|
|
51
64
|
# Only call if the method exists (requires rspec-rails to be loaded)
|
|
@@ -64,6 +77,9 @@ module RailsAccessibilityTesting
|
|
|
64
77
|
|
|
65
78
|
# Setup automatic accessibility checks
|
|
66
79
|
def setup_automatic_checks(config)
|
|
80
|
+
# Check if accessibility checks are globally disabled
|
|
81
|
+
return if accessibility_globally_disabled?
|
|
82
|
+
|
|
67
83
|
# Use class variable to track results across all examples
|
|
68
84
|
@@accessibility_results = {
|
|
69
85
|
pages_tested: [],
|
|
@@ -32,6 +32,15 @@ module RailsAccessibilityTesting
|
|
|
32
32
|
# @return [Hash] Hash with :errors and :warnings arrays
|
|
33
33
|
def scan
|
|
34
34
|
return { errors: [], warnings: [] } unless File.exist?(@view_file)
|
|
35
|
+
|
|
36
|
+
# Check if accessibility checks are globally disabled
|
|
37
|
+
begin
|
|
38
|
+
config = Config::YamlLoader.load(profile: :test)
|
|
39
|
+
enabled = config.fetch('enabled', true)
|
|
40
|
+
return { errors: [], warnings: [] } unless enabled
|
|
41
|
+
rescue StandardError
|
|
42
|
+
# If config can't be loaded, continue (assume enabled)
|
|
43
|
+
end
|
|
35
44
|
|
|
36
45
|
@file_content = File.read(@view_file)
|
|
37
46
|
|
|
@@ -70,8 +79,11 @@ module RailsAccessibilityTesting
|
|
|
70
79
|
config: config
|
|
71
80
|
)
|
|
72
81
|
rescue StandardError => e
|
|
73
|
-
# If engine fails, return empty results
|
|
74
|
-
|
|
82
|
+
# If engine fails, log error and return empty results
|
|
83
|
+
if defined?(Rails) && Rails.env.development?
|
|
84
|
+
puts "Error in static scanner: #{e.message}"
|
|
85
|
+
puts e.backtrace.first(3).join("\n")
|
|
86
|
+
end
|
|
75
87
|
{ errors: [], warnings: [] }
|
|
76
88
|
end
|
|
77
89
|
end
|