capybara_accessibility_audit 0.1.1 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a45b944f513fa6a1e5bea716098819d9005baacb78fda996ecd1d7fc94a3eda5
4
- data.tar.gz: 892c0eeb76a1b2e8f7dea300da7276d92f869faa84c6618c37d1dcd2825a8f6c
3
+ metadata.gz: 152ffd3d124d45c7cc7cec829bcd30c18a2f97dbc988c23cb7629cfe0e8eaa09
4
+ data.tar.gz: c174479db34168f55e3526e011e833d8fb6d7282392ab1f706d56be2786f1ca4
5
5
  SHA512:
6
- metadata.gz: 36a36b9e23bc852ebcae0511d4af91d9f08063d9161667860a6e2932ac34b172b01b3e9a55502dedf6bf5a054f4d2862df3f6be9d1f6d271870911c61958a9e6
7
- data.tar.gz: d584a87ea944b2e4d5cc5e58afa102ec902885ec0df91ed38a4ba171f49616a6026da0dc31bd583ffdea36c9ffd8621a8758e5328e4723ab77e9efbccf71175b
6
+ metadata.gz: fa0be00cf21080048e5fec94d3cabb82dbe61aca8a5d04ea341d8aef776aefe5fae2936e958e66de86d0c064cea2d61a2c4f22ac764808c9f6d28c09059f385b
7
+ data.tar.gz: 31d70ffeab59611501a8bbf3933137526273b2e871a716d636cf157168b299b0fa5145925b87be58aeebd314bd7937801fc184cff6d257a1979003893ec1a0d9
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # CapybaraAccessibilityAudit
2
2
 
3
3
  Extend your Capybara-powered System Tests to automatically audit the page for
4
- WCAG Stardards-based accessibility violations.
4
+ [WCAG Standards-based accessibility violations](https://www.w3.org/WAI/standards-guidelines/wcag/).
5
5
 
6
6
  ## Usage
7
7
 
@@ -60,9 +60,59 @@ end
60
60
  [aXe]: https://www.deque.com/axe/
61
61
  [axe-core-rspec]: https://github.com/dequelabs/axe-core-gems/blob/develop/packages/axe-core-rspec/README.md#matcher
62
62
 
63
+ ## Active Support instrumentation
64
+
65
+ Capybara Accessibility Audit integrates with [Active Support's
66
+ instrumentation][] through publishing [ActiveSupport::Notifications][].
67
+
68
+ ### `audit.capybara_accessibility_audit` notification
69
+
70
+ Subscribe to `audit.capybara_accessibility_audit` notifications emitted when an
71
+ accessibility audit is automatically conducted. In addition to the
72
+ metadata provided by default (like `name`, `duration`, and `allocations`, etc.),
73
+ the `payload` includes additional information:
74
+
75
+ | Payload | Type | Description |
76
+ | ------------- | ---------------------------------- | ----------- |
77
+ | method | Symbol | The Capybara method that triggered the audit
78
+ | options | [ActiveSupport::OrderedOptions][] | The audit's configuration
79
+ | test | [ActionDispatch::SystemTestCase][] | The test case that triggered the audit
80
+
81
+ > [!NOTE]
82
+ > The `audit.capybara_accessibility_audit` notifications are only published when
83
+ > an audit is conducted automatically. No `audit.capybara_accessibility_audit`
84
+ > notifications will be published when `assert_no_accessibility_violations` is
85
+ > invoked directly.
86
+
87
+ [Active Support's instrumentation]: https://guides.rubyonrails.org/active_support_instrumentation.html
88
+ [ActiveSupport::Notifications]: https://api.rubyonrails.org/classes/ActiveSupport/Notifications.html
89
+ [ActiveSupport::OrderedOptions]: https://api.rubyonrails.org/classes/ActiveSupport/OrderedOptions.html
90
+ [ActionDispatch::SystemTestCase]: https://api.rubyonrails.org/classes/ActionDispatch/SystemTestCase.html
91
+
92
+ ### `report.capybara_accessibility_audit` notification
93
+
94
+ Subscribe to `report.capybara_accessibility_audit` notifications emitted when an
95
+ accessibility audit detects violations. The `payload` includes:
96
+
97
+ | Payload | Type | Description |
98
+ | ------------- | ---------------------------------- | ----------- |
99
+ | report | [Axe::API::Results][] | The underlying axe.js [Results][] object
100
+ | options | [ActiveSupport::OrderedOptions][] | The audit's configuration
101
+ | test | [ActionDispatch::SystemTestCase][] | The test case that triggered the audit
102
+
103
+ [ActiveSupport::OrderedOptions]: https://api.rubyonrails.org/classes/ActiveSupport/OrderedOptions.html
104
+ [ActionDispatch::SystemTestCase]: https://api.rubyonrails.org/classes/ActionDispatch/SystemTestCase.html
105
+ [Axe::API::Results]: https://github.com/dequelabs/axe-core-gems/blob/v4.11.0/packages/axe-core-api/lib/axe/api/results.rb
106
+ [Results]: https://www.deque.com/axe/core-documentation/api-documentation/#results-object
107
+
108
+ > [!NOTE]
109
+ > The `report.capybara_accessibility_audit` notifications are only published when
110
+ > `config.capybara_accessibility_audit.reporter` is configured with
111
+ > `:notification` or `:log`.
112
+
63
113
  ## Frequently Asked Questions
64
114
 
65
- My application already exists, will automated accessibility audits are uncovering violations left and right. Do I have to fix them all at once?
115
+ My application already exists, automated accessibility audits are uncovering violations left and right. Do I have to fix them all at once?
66
116
  ---
67
117
 
68
118
  Your suite has control over which rules are skipped and which rules are
@@ -114,6 +164,28 @@ end
114
164
  As you resolve the violations, you can remove entries from the list of skipped
115
165
  rules.
116
166
 
167
+ How many I conduct a preliminary audit that comprehensively exercises my system test suite without failing tests that result in violations?
168
+ ---
169
+
170
+ You can configure the audit's reporting mechanism. By default, the
171
+ `config.capybara_accessibility_audit.reporter` value is set to `:raise`, which
172
+ will raise violation errors that will fail the test suite.
173
+
174
+ To log violations, rather than raise them, you can configure
175
+ `config.capybara_accessibility_audit.reporter` to `:log`:
176
+
177
+
178
+ ```ruby
179
+ class MySystemTest < ApplicationSystemTestCase
180
+ self.accessibility_audit_reporter = :log
181
+
182
+ test "with overridden accessibility :log reporter" do
183
+ visit examples_path
184
+ # ...
185
+ end
186
+ end
187
+ ```
188
+
117
189
  I've implemented a custom Capybara action to toggle a disclosure element. How can I automatically audit for violations after it's called?
118
190
  ---
119
191
 
@@ -204,6 +276,22 @@ class MySystemTest < ApplicationSystemTestCase
204
276
  end
205
277
  ```
206
278
 
279
+ My pages render on the client. How long does the audit wait for them?
280
+ ---
281
+
282
+ Capybara returns from an action as soon as the driver is done with it, and a
283
+ page that renders on the client keeps changing after that point. The auditor
284
+ therefore waits for the DOM to stay unchanged before it runs `axe`. It waits
285
+ for 100 milliseconds of quiet, and it audits the page as it is after 2000
286
+ milliseconds, so a page that never settles cannot block the suite.
287
+
288
+ To change those values, override them on the auditor:
289
+
290
+ ```ruby
291
+ CapybaraAccessibilityAudit::AxeAuditor.quiet_period_ms = 250
292
+ CapybaraAccessibilityAudit::AxeAuditor.quiet_period_timeout_ms = 5000
293
+ ```
294
+
207
295
  ## Installation
208
296
  Add this line to your application's Gemfile:
209
297
 
@@ -222,3 +310,20 @@ Please read [CONTRIBUTING.md](./CONTRIBUTING.md).
222
310
 
223
311
  ## License
224
312
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
313
+
314
+ <!-- START /templates/footer.md -->
315
+ ## About thoughtbot
316
+
317
+ ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)
318
+
319
+ This repo is maintained and funded by thoughtbot, inc.
320
+ The names and logos for thoughtbot are trademarks of thoughtbot, inc.
321
+
322
+ We love open source software!
323
+ See [our other projects][community].
324
+ We are [available for hire][hire].
325
+
326
+ [community]: https://thoughtbot.com/community?utm_source=github
327
+ [hire]: https://thoughtbot.com/hire-us?utm_source=github
328
+
329
+ <!-- END /templates/footer.md -->
@@ -1,5 +1,5 @@
1
1
  module CapybaraAccessibilityAudit
2
- class Auditor
2
+ class Adapter
3
3
  delegate_missing_to :@test
4
4
 
5
5
  def initialize(test)
@@ -8,7 +8,13 @@ module CapybaraAccessibilityAudit
8
8
 
9
9
  def audit!(method)
10
10
  if accessibility_audit_enabled && method.in?(accessibility_audit_after_methods) && javascript_enabled?
11
- assert_no_accessibility_violations(**accessibility_audit_options)
11
+ ActiveSupport::Notifications.instrument "audit.capybara_accessibility_audit" do |payload|
12
+ payload[:method] = method
13
+ payload[:options] = accessibility_audit_options
14
+ payload[:test] = @test
15
+
16
+ assert_no_accessibility_violations(**accessibility_audit_options)
17
+ end
12
18
  end
13
19
  end
14
20
 
@@ -1,6 +1,3 @@
1
- require "axe-capybara"
2
- require "axe/matchers/be_axe_clean"
3
-
4
1
  module CapybaraAccessibilityAudit
5
2
  module AuditSystemTestExtensions
6
3
  extend ActiveSupport::Concern
@@ -16,11 +13,14 @@ module CapybaraAccessibilityAudit
16
13
  class_attribute :accessibility_audit_after_methods, default: Set.new
17
14
  class_attribute :accessibility_audit_enabled, default: true
18
15
  class_attribute :accessibility_audit_options, default: ActiveSupport::OrderedOptions.new
16
+ class_attribute :accessibility_audit_reporter, default: :raise
17
+
18
+ attr_accessor :accessibility_audit_auditor
19
19
 
20
20
  MODAL_METHODS.each do |method|
21
21
  define_method method do |*arguments, **options, &block|
22
22
  result = super(*arguments, **options) { skip_accessibility_audits(&block) }
23
- result.tap { Auditor.new(self).audit!(method) }
23
+ result.tap { Adapter.new(self).audit!(method) }
24
24
  end
25
25
  end
26
26
  end
@@ -36,7 +36,7 @@ module CapybaraAccessibilityAudit
36
36
  def accessibility_audit_after(*methods)
37
37
  (methods.flatten.to_set - accessibility_audit_after_methods).each do |method|
38
38
  define_method method do |*arguments, **options, &block|
39
- super(*arguments, **options, &block).tap { Auditor.new(self).audit!(method) }
39
+ super(*arguments, **options, &block).tap { Adapter.new(self).audit!(method) }
40
40
  end
41
41
 
42
42
  accessibility_audit_after_methods << method
@@ -90,7 +90,7 @@ module CapybaraAccessibilityAudit
90
90
  accessibility_audit_options.skipping = skipping
91
91
  end
92
92
 
93
- def assert_no_accessibility_violations(**options)
93
+ def assert_no_accessibility_violations(auditor: accessibility_audit_auditor, **options)
94
94
  options.assert_valid_keys(
95
95
  :according_to,
96
96
  :checking,
@@ -101,10 +101,7 @@ module CapybaraAccessibilityAudit
101
101
  )
102
102
  options.compact_blank!
103
103
 
104
- axe_matcher = Axe::Matchers::BeAxeClean.new
105
- axe_matcher = options.inject(axe_matcher) { |matcher, option| matcher.public_send(*option) }
106
-
107
- assert axe_matcher.matches?(page), axe_matcher.failure_message
104
+ auditor.audit(**options)
108
105
  end
109
106
  end
110
107
  end
@@ -0,0 +1,131 @@
1
+ require "axe/api/context"
2
+ require "axe/api/options"
3
+ require "axe/api/results"
4
+ require "axe/configuration"
5
+
6
+ module CapybaraAccessibilityAudit
7
+ class AxeAuditor
8
+ Error = Class.new(StandardError)
9
+
10
+ ERROR_KEY = "capybara_accessibility_audit_error"
11
+
12
+ class_attribute :source, instance_accessor: false, default: Axe::Configuration.instance.jslib
13
+
14
+ class_attribute :quiet_period_ms, instance_accessor: false, default: 100
15
+ class_attribute :quiet_period_timeout_ms, instance_accessor: false, default: 2000
16
+
17
+ def initialize(test, reporter)
18
+ @test = test
19
+ @reporter = reporter
20
+ end
21
+
22
+ def audit(**options)
23
+ settle
24
+ install
25
+
26
+ results = run(options)
27
+
28
+ @reporter.report Axe::API::Results.new(results)
29
+ end
30
+
31
+ private
32
+
33
+ def page
34
+ @test.page
35
+ end
36
+
37
+ def settle
38
+ quiet_period_ms = self.class.quiet_period_ms
39
+ earliest = monotonic_time + quiet_period_ms
40
+ deadline = monotonic_time + self.class.quiet_period_timeout_ms
41
+
42
+ observe_mutations
43
+
44
+ until monotonic_time >= deadline
45
+ if (duration = unchanged_for).nil?
46
+ observe_mutations
47
+ elsif monotonic_time >= earliest && duration >= quiet_period_ms
48
+ break
49
+ end
50
+
51
+ sleep 0.01
52
+ end
53
+ end
54
+
55
+ def monotonic_time
56
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
57
+ end
58
+
59
+ # Records the time of the last change to the DOM. The document keeps the
60
+ # observer that is already there.
61
+ def observe_mutations
62
+ page.execute_script <<~JS
63
+ if (!window.capybaraAccessibilityAudit) {
64
+ window.capybaraAccessibilityAudit = {changedAt: Date.now()}
65
+
66
+ new MutationObserver(() => {
67
+ window.capybaraAccessibilityAudit.changedAt = Date.now()
68
+ }).observe(document, {attributes: true, characterData: true, childList: true, subtree: true})
69
+ }
70
+ JS
71
+ end
72
+
73
+ # Answers how long the DOM has been unchanged, in milliseconds. Answers
74
+ # nil when a page load replaced the document that has the observer. Each
75
+ # call is a short round trip. A single long-lived script would lose its
76
+ # callback when a page load discards the document it runs in.
77
+ def unchanged_for
78
+ duration = page.evaluate_script <<~JS
79
+ window.capybaraAccessibilityAudit ? Date.now() - window.capybaraAccessibilityAudit.changedAt : null
80
+ JS
81
+
82
+ duration if duration.is_a?(Numeric) # :playwright returns null as {}
83
+ end
84
+
85
+ def run(config)
86
+ context, options = split(config)
87
+
88
+ json = page.evaluate_async_script <<~JS, context.as_json, options.as_json, ERROR_KEY
89
+ const [ context, options, errorKey, callback ] = arguments
90
+
91
+ axe.run(context, options)
92
+ .then(JSON.stringify)
93
+ .catch(error => JSON.stringify({ [errorKey]: error.message }))
94
+ .then(callback)
95
+ JS
96
+
97
+ case JSON.parse(json, symbolize_names: true)
98
+ in {capybara_accessibility_audit_error:}
99
+ raise Error, capybara_accessibility_audit_error
100
+ in Hash => report
101
+ report
102
+ else
103
+ raise Error, "Unexpected report structure"
104
+ end
105
+ end
106
+
107
+ def split(config)
108
+ context = Axe::API::Context.new
109
+ options = Axe::API::Options.new
110
+
111
+ config.each do |name, value|
112
+ case name
113
+ when :within, :excluding then context.public_send(name, value)
114
+ else options.public_send(name, value)
115
+ end
116
+ end
117
+
118
+ [context, options]
119
+ end
120
+
121
+ def install
122
+ page.execute_script(self.class.source) unless installed?
123
+ end
124
+
125
+ def installed?
126
+ page.evaluate_script <<~JS
127
+ "axe" in window && typeof axe.run === "function"
128
+ JS
129
+ end
130
+ end
131
+ end
@@ -1,6 +1,7 @@
1
1
  module CapybaraAccessibilityAudit
2
2
  class Engine < ::Rails::Engine
3
3
  config.capybara_accessibility_audit = ActiveSupport::OrderedOptions.new
4
+ config.capybara_accessibility_audit.auditor = AxeAuditor
4
5
  config.capybara_accessibility_audit.audit_after = %i[
5
6
  visit
6
7
  click_button
@@ -9,28 +10,48 @@ module CapybaraAccessibilityAudit
9
10
  click_on
10
11
  ]
11
12
  config.capybara_accessibility_audit.audit_enabled = true
13
+ config.capybara_accessibility_audit.reporter = :raise
12
14
 
13
- ActiveSupport.on_load :action_dispatch_system_test_case do
14
- include CapybaraAccessibilityAudit::AuditSystemTestExtensions
15
+ initializer "capybara_accessibility_audit.minitest" do |app|
16
+ ActiveSupport.on_load :action_dispatch_system_test_case do
17
+ include CapybaraAccessibilityAudit::AuditSystemTestExtensions
15
18
 
16
- self.accessibility_audit_enabled = Rails.configuration.capybara_accessibility_audit.audit_enabled
19
+ self.accessibility_audit_enabled = app.config.capybara_accessibility_audit.audit_enabled
20
+ self.accessibility_audit_reporter = app.config.capybara_accessibility_audit.reporter
17
21
 
18
- accessibility_audit_after Rails.configuration.capybara_accessibility_audit.audit_after
22
+ accessibility_audit_after app.config.capybara_accessibility_audit.audit_after
23
+
24
+ setup do
25
+ auditor_class = app.config.capybara_accessibility_audit.auditor
26
+ reporter_class = CapybaraAccessibilityAudit.reporter_class(accessibility_audit_reporter)
27
+
28
+ self.accessibility_audit_auditor = auditor_class.new(self, reporter_class.new(self))
29
+ end
30
+ end
19
31
  end
20
32
 
21
- if defined?(RSpec)
22
- RSpec.configure do |config|
23
- config.include CapybaraAccessibilityAudit::AuditSystemTestExtensions, type: :system
24
- config.include CapybaraAccessibilityAudit::AuditSystemTestExtensions, type: :feature
33
+ initializer "capybara_accessibility_audit.rspec" do |app|
34
+ if defined?(RSpec)
35
+ require "rspec/core"
25
36
 
26
- configure = proc do
27
- self.accessibility_audit_enabled = Rails.configuration.capybara_accessibility_audit.audit_enabled
37
+ RSpec.configure do |config|
38
+ config.include CapybaraAccessibilityAudit::AuditSystemTestExtensions, type: :system
39
+ config.include CapybaraAccessibilityAudit::AuditSystemTestExtensions, type: :feature
28
40
 
29
- accessibility_audit_after Rails.configuration.capybara_accessibility_audit.audit_after
30
- end
41
+ configure = proc do
42
+ self.accessibility_audit_enabled = app.config.capybara_accessibility_audit.audit_enabled
31
43
 
32
- config.before(type: :system, &configure)
33
- config.before(type: :feature, &configure)
44
+ accessibility_audit_after app.config.capybara_accessibility_audit.audit_after
45
+
46
+ auditor_class = app.config.capybara_accessibility_audit.auditor
47
+ reporter_class = CapybaraAccessibilityAudit.reporter_class(accessibility_audit_reporter)
48
+
49
+ self.accessibility_audit_auditor = auditor_class.new(self, reporter_class.new(self))
50
+ end
51
+
52
+ config.before(type: :system, &configure)
53
+ config.before(type: :feature, &configure)
54
+ end
34
55
  end
35
56
  end
36
57
  end
@@ -0,0 +1,17 @@
1
+ module CapybaraAccessibilityAudit
2
+ class LogSubscriber < ActiveSupport::LogSubscriber
3
+ def report(event)
4
+ report = event.payload[:report]
5
+ test = event.payload[:test]
6
+
7
+ if test.accessibility_audit_reporter == :log
8
+ error color(<<~ERROR, :red)
9
+ [capybara_accessibility_audit] Accessibility audit detected violations in "#{test.class.name}##{test.name}":
10
+ #{report.failure_message}
11
+ ERROR
12
+ end
13
+ end
14
+
15
+ attach_to :capybara_accessibility_audit
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module CapybaraAccessibilityAudit
2
+ class NotificationReporter
3
+ def initialize(test)
4
+ @test = test
5
+ end
6
+
7
+ def report(results)
8
+ if results.violations.present?
9
+ publish(results)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def publish(report)
16
+ ActiveSupport::Notifications.instrument "report.capybara_accessibility_audit", {
17
+ auditor: @test.accessibility_audit_auditor,
18
+ options: @test.accessibility_audit_options,
19
+ report: report,
20
+ test: @test
21
+ }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module CapybaraAccessibilityAudit
2
+ class RaiseReporter
3
+ def initialize(test)
4
+ @test = test
5
+ end
6
+
7
+ def report(results)
8
+ @test.assert results.violations.empty?, -> { results.failure_message }
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module CapybaraAccessibilityAudit
2
- VERSION = "0.1.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -3,7 +3,20 @@ loader = Zeitwerk::Loader.for_gem
3
3
  loader.setup
4
4
 
5
5
  module CapybaraAccessibilityAudit
6
- # Your code goes here...
6
+ extend self
7
+
8
+ def reporter_class(name)
9
+ case name
10
+ when :notification, :log
11
+ NotificationReporter
12
+ when :raise
13
+ RaiseReporter
14
+ when ::Class
15
+ name
16
+ else
17
+ raise ArgumentError.new("unsupported reporter: #{name}")
18
+ end
19
+ end
7
20
  end
8
21
 
9
22
  loader.eager_load
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara_accessibility_audit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Doyle
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-09-26 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '0'
18
+ version: '6.1'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '0'
25
+ version: '6.1'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: capybara
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +38,7 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
40
  - !ruby/object:Gem::Dependency
42
- name: axe-core-capybara
41
+ name: axe-core-api
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - ">="
@@ -66,6 +65,48 @@ dependencies:
66
65
  - - ">="
67
66
  - !ruby/object:Gem::Version
68
67
  version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: bigdecimal
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: drb
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: mutex_m
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
69
110
  description: Accessibility tooling for Capybara
70
111
  email:
71
112
  - sean.p.doyle24@gmail.com
@@ -77,9 +118,13 @@ files:
77
118
  - README.md
78
119
  - Rakefile
79
120
  - lib/capybara_accessibility_audit.rb
121
+ - lib/capybara_accessibility_audit/adapter.rb
80
122
  - lib/capybara_accessibility_audit/audit_system_test_extensions.rb
81
- - lib/capybara_accessibility_audit/auditor.rb
123
+ - lib/capybara_accessibility_audit/axe_auditor.rb
82
124
  - lib/capybara_accessibility_audit/engine.rb
125
+ - lib/capybara_accessibility_audit/log_subscriber.rb
126
+ - lib/capybara_accessibility_audit/notification_reporter.rb
127
+ - lib/capybara_accessibility_audit/raise_reporter.rb
83
128
  - lib/capybara_accessibility_audit/version.rb
84
129
  - lib/tasks/capybara_accessibility_audit.rake
85
130
  homepage: https://github.com/thoughtbot/capybara_accessibility_audit
@@ -89,7 +134,7 @@ metadata:
89
134
  homepage_uri: https://github.com/thoughtbot/capybara_accessibility_audit
90
135
  source_code_uri: https://github.com/thoughtbot/capybara_accessibility_audit
91
136
  changelog_uri: https://github.com/thoughtbot/capybara_accessibility_audit/blob/main/CHANGELOG.md
92
- post_install_message:
137
+ rubygems_mfa_required: 'true'
93
138
  rdoc_options: []
94
139
  require_paths:
95
140
  - lib
@@ -97,15 +142,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
142
  requirements:
98
143
  - - ">="
99
144
  - !ruby/object:Gem::Version
100
- version: '0'
145
+ version: '3.0'
101
146
  required_rubygems_version: !ruby/object:Gem::Requirement
102
147
  requirements:
103
148
  - - ">="
104
149
  - !ruby/object:Gem::Version
105
150
  version: '0'
106
151
  requirements: []
107
- rubygems_version: 3.4.13
108
- signing_key:
152
+ rubygems_version: 4.0.17
109
153
  specification_version: 4
110
154
  summary: Accessibility tooling for Capybara
111
155
  test_files: []