axe-core-api 2.6.1.pre.acca0cb

Sign up to get free protection for your applications and to get access to all the features.
@@ -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