axe-core-api 2.6.1.pre.78a535c
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 +7 -0
- data/LICENSE +362 -0
- data/README.md +5 -0
- data/lib/axe/api/a11y_check.rb +69 -0
- data/lib/axe/api/audit.rb +24 -0
- data/lib/axe/api/context.rb +35 -0
- data/lib/axe/api/options.rb +32 -0
- data/lib/axe/api/results.rb +48 -0
- data/lib/axe/api/results/check.rb +32 -0
- data/lib/axe/api/results/checked_node.rb +51 -0
- data/lib/axe/api/results/node.rb +35 -0
- data/lib/axe/api/results/rule.rb +58 -0
- data/lib/axe/api/rules.rb +37 -0
- data/lib/axe/api/run.rb +53 -0
- data/lib/axe/api/selector.rb +18 -0
- data/lib/axe/api/value_object.rb +9 -0
- data/lib/axe/configuration.rb +44 -0
- data/lib/axe/core.rb +45 -0
- data/lib/axe/dsl.rb +15 -0
- data/lib/axe/expectation.rb +33 -0
- data/lib/axe/finds_page.rb +55 -0
- data/lib/axe/matchers/be_accessible.rb +36 -0
- data/lib/chain_mail/chainable.rb +19 -0
- data/lib/hooks.rb +31 -0
- data/lib/loader.rb +25 -0
- data/lib/webdriver_script_adapter/exec_eval_script_adapter.rb +27 -0
- data/lib/webdriver_script_adapter/execute_async_script_adapter.rb +94 -0
- data/lib/webdriver_script_adapter/frame_adapter.rb +84 -0
- data/lib/webdriver_script_adapter/query_selector_adapter.rb +17 -0
- data/node_modules/axe-core/axe.min.js +12 -0
- metadata +200 -0
@@ -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
|
data/lib/axe/api/run.rb
ADDED
@@ -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,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
|