axe-core-api 2.6.1.pre.acca0cb

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.
@@ -0,0 +1,35 @@
1
+ require_relative "./selector"
2
+
3
+ module Axe
4
+ module API
5
+ class Context
6
+ def initialize
7
+ @inclusion = []
8
+ @exclusion = []
9
+ end
10
+
11
+ def within(*selectors)
12
+ @inclusion.concat selectors.map { |s| Array(Selector.new s) }
13
+ end
14
+
15
+ def excluding(*selectors)
16
+ @exclusion.concat selectors.map { |s| Array(Selector.new s) }
17
+ end
18
+
19
+ def to_hash
20
+ { include: @inclusion, exclude: @exclusion }
21
+ .reject { |k, v| v.empty? }
22
+ end
23
+
24
+ def to_json
25
+ to_hash.to_json
26
+ end
27
+
28
+ def empty?
29
+ to_hash.empty?
30
+ end
31
+
32
+ alias :to_s :to_json
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ require "forwardable"
2
+ require_relative "./rules"
3
+
4
+ module Axe
5
+ module API
6
+ class Options
7
+ extend Forwardable
8
+
9
+ def_delegators :@rules, :according_to, :checking, :checking_only, :skipping
10
+ def_delegator :@custom, :merge!, :with_options
11
+
12
+ def initialize
13
+ @rules = Rules.new
14
+ @custom = {}
15
+ end
16
+
17
+ def to_hash
18
+ @rules.to_hash.merge(@custom)
19
+ end
20
+
21
+ def to_json
22
+ to_hash.to_json
23
+ end
24
+
25
+ def empty?
26
+ to_hash.empty?
27
+ end
28
+
29
+ alias :to_s :to_json
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,48 @@
1
+ require_relative "./value_object"
2
+
3
+ module Axe
4
+ module API
5
+ class Results < ValueObject
6
+ require_relative "./results/rule"
7
+
8
+ values do
9
+ attribute :inapplicable, ::Array[Rule]
10
+ attribute :incomplete, ::Array[Rule]
11
+ attribute :passes, ::Array[Rule]
12
+ attribute :timestamp
13
+ attribute :url, ::String
14
+ attribute :violations, ::Array[Rule]
15
+ end
16
+
17
+ def failure_message
18
+ [
19
+ "",
20
+ violation_count_message,
21
+ "",
22
+ violations_failure_messages,
23
+ ].flatten.join("\n")
24
+ end
25
+
26
+ def to_h
27
+ {
28
+ inapplicable: inapplicable.map(&:to_h),
29
+ incomplete: incomplete.map(&:to_h),
30
+ passes: passes.map(&:to_h),
31
+ timestamp: timestamp,
32
+ url: url,
33
+ violations: violations.map(&:to_h),
34
+ }
35
+ end
36
+
37
+ private
38
+
39
+ def violation_count_message
40
+ "Found #{violations.count} accessibility #{violations.count == 1 ? "violation" : "violations"}:"
41
+ end
42
+
43
+ def violations_failure_messages
44
+ violations.each_with_index.map(&:failure_messages)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ require_relative "../value_object"
2
+ require_relative "../results/node"
3
+
4
+ module Axe
5
+ module API
6
+ class Results
7
+ class Check < ValueObject
8
+ values do
9
+ attribute :data, ::String
10
+ attribute :id, ::Symbol
11
+ attribute :impact, ::Symbol
12
+ attribute :message, ::String
13
+ attribute :relatedNodes, ::Array[Node]
14
+ end
15
+
16
+ def failure_message
17
+ message
18
+ end
19
+
20
+ def to_h
21
+ {
22
+ data: data,
23
+ id: id,
24
+ impact: impact,
25
+ message: message,
26
+ relatedNodes: relatedNodes.map(&:to_h),
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,51 @@
1
+ require_relative "./node"
2
+ require_relative "./check"
3
+
4
+ module Axe
5
+ module API
6
+ class Results
7
+ class CheckedNode < Node
8
+ values do
9
+ attribute :impact, ::Symbol
10
+ attribute :any, ::Array[Check]
11
+ attribute :all, ::Array[Check]
12
+ attribute :none, ::Array[Check]
13
+ attribute :failureSummary, ::Symbol
14
+ attribute :html, ::String
15
+ attribute :target
16
+ end
17
+
18
+ def failure_messages
19
+ [
20
+ super,
21
+ fix(all, "Fix all of the following:"),
22
+ fix(none, "Fix all of the following:"),
23
+ fix(any, "Fix any of the following:"),
24
+ ]
25
+ end
26
+
27
+ def to_h
28
+ {
29
+ all: all.map(&:to_h),
30
+ any: any.map(&:to_h),
31
+ failureSummary: failureSummary,
32
+ html: html,
33
+ impact: impact,
34
+ none: none.map(&:to_h),
35
+ target: target,
36
+ }
37
+ end
38
+
39
+ private
40
+
41
+ def fix(checks, message)
42
+ valid_checks = checks.reject { |c| c.nil? }
43
+ [
44
+ (message unless valid_checks.empty?),
45
+ valid_checks.map(&:failure_message).map { |line| line.prepend("- ") },
46
+ ].compact
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../value_object"
2
+
3
+ module Axe
4
+ module API
5
+ class Results
6
+ class Node < ValueObject
7
+ values do
8
+ attribute :html, ::String
9
+ attribute :target # String or Array[String]
10
+ end
11
+
12
+ def failure_messages
13
+ [selector_message, node_html]
14
+ end
15
+
16
+ def to_h
17
+ {
18
+ html: html,
19
+ target: target,
20
+ }
21
+ end
22
+
23
+ private
24
+
25
+ def selector_message
26
+ "Selector: #{Array(target).join(", ")}"
27
+ end
28
+
29
+ def node_html
30
+ "HTML: #{html.gsub(/^\s*|\n*/, "")}" unless html.nil?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,58 @@
1
+ require_relative "../value_object"
2
+ require_relative "./checked_node"
3
+
4
+ module Axe
5
+ module API
6
+ class Results
7
+ class Rule < ValueObject
8
+ values do
9
+ attribute :id, ::Symbol
10
+ attribute :description, ::String
11
+ attribute :help, ::String
12
+ attribute :helpUrl, ::String
13
+ attribute :impact, ::Symbol
14
+ attribute :tags, ::Array[::Symbol]
15
+ attribute :nodes, ::Array[CheckedNode]
16
+ end
17
+
18
+ def failure_messages(index)
19
+ [
20
+ title_message(index + 1),
21
+ *[
22
+ helpUrl,
23
+ node_count_message,
24
+ "",
25
+ nodes.reject { |n| n.nil? }.map(&:failure_messages).map { |n| n.push("") }.flatten.map(&indent),
26
+ ].flatten.map(&indent),
27
+ ]
28
+ end
29
+
30
+ def to_h
31
+ {
32
+ description: description,
33
+ help: help,
34
+ helpUrl: helpUrl,
35
+ id: id,
36
+ impact: impact,
37
+ nodes: nodes.map(&:to_h),
38
+ tags: tags,
39
+ }
40
+ end
41
+
42
+ private
43
+
44
+ def indent
45
+ ->(line) { line.prepend(" " * 4) unless line.nil? }
46
+ end
47
+
48
+ def title_message(count)
49
+ "#{count}) #{id}: #{help} (#{impact})"
50
+ end
51
+
52
+ def node_count_message
53
+ "The following #{nodes.length} #{nodes.length == 1 ? "node" : "nodes"} violate this rule:"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,37 @@
1
+ module Axe
2
+ module API
3
+ class Rules
4
+ def initialize
5
+ @tags = []
6
+ @included = []
7
+ @excluded = []
8
+ @exclusive = []
9
+ end
10
+
11
+ def according_to(*tags)
12
+ @tags.concat tags.flatten
13
+ end
14
+
15
+ def checking(*rules)
16
+ @included.concat rules.flatten
17
+ end
18
+
19
+ def checking_only(*rules)
20
+ @exclusive.concat rules.flatten
21
+ end
22
+
23
+ def skipping(*rules)
24
+ @excluded.concat rules.flatten
25
+ end
26
+
27
+ def to_hash
28
+ {}.tap do |options|
29
+ # TODO warn that tags + exclusive-rules are incompatible
30
+ options.merge! runOnly: { type: :tag, values: @tags } unless @tags.empty?
31
+ options.merge! runOnly: { type: :rule, values: @exclusive } unless @exclusive.empty?
32
+ options.merge! rules: Hash[@included.product([enabled: true]) + @excluded.product([enabled: false])] unless @included.empty? && @excluded.empty?
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,53 @@
1
+ require "forwardable"
2
+ require "json"
3
+
4
+ require_relative "../../chain_mail/chainable"
5
+ require_relative "./audit"
6
+ require_relative "./context"
7
+ require_relative "./options"
8
+ require_relative "./results"
9
+ require_relative "../core"
10
+
11
+ module Axe
12
+ module API
13
+ class Run
14
+ JS_NAME = "run"
15
+ METHOD_NAME = "#{Core::JS_NAME}.#{JS_NAME}"
16
+
17
+ extend Forwardable
18
+ def_delegators :@context, :within, :excluding
19
+ def_delegators :@options, :according_to, :checking, :checking_only, :skipping, :with_options
20
+
21
+ extend ChainMail::Chainable
22
+ chainable :within, :excluding, :according_to, :checking, :checking_only, :skipping, :with_options
23
+
24
+ def initialize
25
+ @context = Context.new
26
+ @options = Options.new
27
+ end
28
+
29
+ def call(page)
30
+ audit page do |results|
31
+ Audit.new to_js, Results.new(results)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def audit(page)
38
+ yield page.execute_async_script "#{METHOD_NAME}.apply(#{Core::JS_NAME}, arguments)", *js_args
39
+ end
40
+
41
+ def js_args
42
+ [@context, @options]
43
+ .reject(&:empty?)
44
+ .map(&:to_json)
45
+ end
46
+
47
+ def to_js
48
+ str_args = (js_args + ["callback"]).join(", ")
49
+ "#{METHOD_NAME}(#{str_args});"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ module Axe
2
+ module API
3
+ class Selector
4
+ def initialize(s)
5
+ @selector = case s
6
+ when Array then s
7
+ when String, Symbol then [String(s)]
8
+ when Hash then Selector.new(s[:selector]).to_a.unshift s[:iframe]
9
+ else Selector.new(s.selector).to_a.unshift s.iframe
10
+ end
11
+ end
12
+
13
+ def to_a
14
+ @selector
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ require 'virtus'
2
+
3
+ module Axe
4
+ module API
5
+ class ValueObject
6
+ include ::Virtus.value_object mass_assignment: false, nullify_blank: true
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ require "singleton"
2
+ require "forwardable"
3
+ require "json"
4
+
5
+ require_relative "../hooks"
6
+ require_relative "../webdriver_script_adapter/execute_async_script_adapter"
7
+
8
+ module Axe
9
+ class Configuration
10
+ include Singleton
11
+ include Common::Hooks
12
+ extend Forwardable
13
+
14
+ attr_writer :jslib
15
+ attr_accessor :page,
16
+ :jslib_path,
17
+ :skip_iframes
18
+ def_delegators ::WebDriverScriptAdapter,
19
+ :async_results_identifier,
20
+ :async_results_identifier=,
21
+ :max_wait_time,
22
+ :max_wait_time=,
23
+ :wait_interval,
24
+ :wait_interval=
25
+
26
+ # init
27
+ def initialize
28
+ @page = :page
29
+ @skip_iframes = :skip_iframes
30
+ @jslib_path = get_root + "/node_modules/axe-core/axe.min.js"
31
+ end
32
+
33
+ # jslib
34
+ def jslib
35
+ @jslib ||= Pathname.new(@jslib_path).read
36
+ end
37
+
38
+ private
39
+
40
+ def get_root
41
+ Gem::Specification.find_by_name('axe-core-api').gem_dir
42
+ end
43
+ end
44
+ end