bbc-a11y 0.0.9 → 0.0.11
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/CONTRIBUTING.md +3 -7
- data/README.md +7 -3
- data/Rakefile +1 -2
- data/bin/a11y +2 -1
- data/features/README.md +4 -0
- data/features/exit_status.feature +14 -0
- data/features/specify_url_via_cli.feature +10 -0
- data/features/specify_url_via_config.feature +16 -0
- data/features/step_definitions/steps.rb +13 -0
- data/features/support/env.rb +5 -0
- data/features/support/web_server.rb +30 -0
- data/features/support/web_server/missing_header.html +13 -0
- data/features/support/web_server/perfect.html +14 -0
- data/lib/bbc/a11y.rb +1 -0
- data/lib/bbc/a11y/cli.rb +19 -5
- data/lib/bbc/a11y/configuration.rb +6 -1
- data/lib/bbc/a11y/cucumber_runner.rb +25 -5
- data/lib/bbc/a11y/cucumber_support.rb +9 -2
- data/lib/bbc/a11y/cucumber_support/disabled_w3c.rb +37 -0
- data/lib/bbc/a11y/cucumber_support/matchers.rb +21 -0
- data/lib/bbc/a11y/cucumber_support/page.rb +16 -6
- data/lib/bbc/a11y/version +1 -1
- data/spec/bbc/a11y/cli_spec.rb +27 -0
- data/spec/bbc/a11y/configuration_spec.rb +15 -3
- data/spec/bbc/a11y/cucumber_support/matchers_spec.rb +52 -0
- data/spec/bbc/a11y/cucumber_support/page_spec.rb +34 -10
- data/{features → standards}/01_core-purpose.md +0 -0
- data/{features → standards}/02_validation.feature +0 -0
- data/{features → standards}/03_javascript.feature +0 -0
- data/{features → standards}/04_language.feature +0 -0
- data/{features → standards}/05_page_title.feature +0 -0
- data/{features → standards}/06_main_landmark.feature +0 -0
- data/{features → standards}/07_headings.feature +0 -0
- data/{features → standards}/08_title_attribute.feature +0 -0
- data/{features → standards}/09_tabindex.feature +8 -1
- data/standards/10_form_labels.feature +88 -0
- data/{features → standards}/11_visible-on-focus.md +0 -0
- data/{features → standards}/13_colour-contrast.md +0 -0
- data/{features → standards}/14_colour-meaning.md +0 -0
- data/{features → standards}/15_focusable-controls.md +0 -0
- data/{features → standards}/16_table.md +0 -0
- data/{features → standards}/17_control-styles.md +0 -0
- data/{features → standards}/18_focus-styles.md +0 -0
- data/{features → standards}/19_form-interactions.md +0 -0
- data/{features → standards}/20_image-alt.md +0 -0
- data/{features → standards}/21_min-font-sizes.md +0 -0
- data/{features → standards}/22_resize-zoom.md +0 -0
- data/{features → standards}/step_definitions/core_content_steps.rb +0 -0
- data/standards/step_definitions/form_steps.rb +6 -0
- data/{features → standards}/step_definitions/language_steps.rb +0 -0
- data/{features → standards}/step_definitions/page_steps.rb +6 -2
- data/{features → standards}/step_definitions/w3c_steps.rb +0 -0
- data/{features → standards}/support/capybara.rb +0 -0
- data/{features → standards}/support/skipper.rb +0 -0
- data/{features → standards}/support/world.rb +0 -0
- data/{features → standards}/support/world_extender.rb +0 -0
- metadata +82 -86
- data/features/10_form-labels.md +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8697bc18c43d39bd843b0dfe9fda7a20ea761fc4
|
4
|
+
data.tar.gz: 4e709fc1f14853e37d2d00ed0453de4db887829a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29063edb07ab6454f23b5a0b797e911e278b74ecb7bf4299e64700c8ab16f6c86508829727343fe7f35ded04f354ee9f1a61e4bce18d5ebdada70316c3f30541
|
7
|
+
data.tar.gz: a0da88c1f3e550ac193b7d9b87a15c00b8135d42dda11e76a809d0750831d28f32f969c147bf5c43e3ddc3b207399d57af21b589c13e0e22edf1f6dda8c09dfc
|
data/CONTRIBUTING.md
CHANGED
@@ -1,18 +1,14 @@
|
|
1
1
|
# BBC A11y Contributing guidelines
|
2
2
|
|
3
|
-
The standards are all stored in the `
|
3
|
+
The standards are all stored in the `standards` directory.
|
4
4
|
|
5
5
|
You can run a manual test of your development copy of a11y at any time just by running:
|
6
6
|
|
7
7
|
bundle exec ./bin/a11y <url>
|
8
8
|
|
9
|
-
You can also
|
9
|
+
You can also use cucumber to run one specific test:
|
10
10
|
|
11
|
-
bundle exec
|
12
|
-
|
13
|
-
Or you can short-cut a11y's command-line interface and just run Cucumber directly:
|
14
|
-
|
15
|
-
URL=<url> bundle exec cucumber features/04_language.feature
|
11
|
+
A11Y_URL=<url> bundle exec cucumber features/04_language.feature
|
16
12
|
|
17
13
|
The step definitions behind these features are shallow wrappers that delegate to objects in `lib/bbc/a11y/`. Those objects are unit-tested to ensure they'll behave as expected when tests pass or fail.
|
18
14
|
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# WARNING - PROTOTYPE SOFTWARE
|
2
|
+
|
3
|
+
This project is still at an experimental / proof-of-concept stage. Please set your expectations appropriately, but *do* [give us as much feedback](https://github.com/cucumber-ltd/bbc-a11y/issues) as you can.
|
4
|
+
|
1
5
|
#BBC Accessiblity Standards
|
2
6
|
|
3
7
|
This tool runs a set of tests against a set of URLs to verify whether each one meets the [BBC accessibility standards](http://www.bbc.co.uk/guidelines/futuremedia/accessibility/).
|
@@ -41,7 +45,7 @@ Nobody's perfect. Use `skip_scenario` in the configuration to opt-out of certain
|
|
41
45
|
```
|
42
46
|
BBC::A11y.configure do
|
43
47
|
page "http://bbc.co.uk" do
|
44
|
-
skip_scenario
|
48
|
+
skip_scenario /W3C/
|
45
49
|
end
|
46
50
|
|
47
51
|
page "http://bbc.co.uk/news"
|
@@ -52,9 +56,9 @@ A11y will skip any scenarios from the specifications whose name contains that st
|
|
52
56
|
|
53
57
|
## Running it
|
54
58
|
|
55
|
-
Once you're configured, you can run the tests using the `a11y` command:
|
59
|
+
Once you're configured, you can run the tests using the `a11y` command, from the directory where your `.a11y.rb` configuration file is stored:
|
56
60
|
|
57
61
|
bundle exec a11y
|
58
62
|
|
59
|
-
This will pick up your `.a11y.rb` configuration file and run the a11y features on each page specified in your configuration.
|
63
|
+
This will pick up your `.a11y.rb` configuration file and run the a11y features on each page specified in your configuration.
|
60
64
|
Output is printed to the console.
|
data/Rakefile
CHANGED
data/bin/a11y
CHANGED
@@ -2,4 +2,5 @@
|
|
2
2
|
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
3
3
|
|
4
4
|
require 'bbc/a11y/cli'
|
5
|
-
|
5
|
+
require 'bbc/a11y/cucumber_runner'
|
6
|
+
BBC::A11y::CLI.new($stdin, $stdout, $stderr, ARGV.dup).call(BBC::A11y::CucumberRunner)
|
data/features/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
@wip
|
2
|
+
Feature: Exit status
|
3
|
+
|
4
|
+
For CI, we need to make sure the process exits with a non-zero
|
5
|
+
status when there's been a failure.
|
6
|
+
|
7
|
+
Scenario: Passing tests
|
8
|
+
When all the tests pass
|
9
|
+
Then the exit status should be 0
|
10
|
+
|
11
|
+
Scenario: Failing test
|
12
|
+
Given a standards-compliant website running at http://localhost:54321
|
13
|
+
When I run `a11y http://localhost:54321/missing_header.html`
|
14
|
+
Then the exit status should be 1
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: Specify URL via the CLI
|
2
|
+
|
3
|
+
Scenario: No config, just pass page URL on command-line
|
4
|
+
Given a standards-compliant website running at http://localhost:54321
|
5
|
+
When I run `a11y http://localhost:54321/perfect.html`
|
6
|
+
Then it should pass with:
|
7
|
+
"""
|
8
|
+
BBC Accesibility: http://localhost:54321/perfect.html
|
9
|
+
-----------------------------------------------------
|
10
|
+
"""
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Specify URL via config
|
2
|
+
|
3
|
+
Scenario: Specify a single page
|
4
|
+
Given a standards-compliant website running at http://localhost:54321
|
5
|
+
And a file named ".a11y.rb" with:
|
6
|
+
"""
|
7
|
+
BBC::A11y.configure do
|
8
|
+
page "http://localhost:54321/perfect.html"
|
9
|
+
end
|
10
|
+
"""
|
11
|
+
When I run `a11y`
|
12
|
+
Then it should pass with:
|
13
|
+
"""
|
14
|
+
BBC Accesibility: http://localhost:54321/perfect.html
|
15
|
+
-----------------------------------------------------
|
16
|
+
"""
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Given(/^a standards-compliant website running at http:\/\/localhost:(\d+)$/) do |port|
|
2
|
+
WebServer.ensure_running_on(port)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given(/^all the tests pass$/) do
|
6
|
+
WebServer.ensure_running_on(54321)
|
7
|
+
step "I run `a11y http://localhost:54321/perfect.html`"
|
8
|
+
end
|
9
|
+
|
10
|
+
Given(/^one test fails$/) do
|
11
|
+
WebServer.ensure_running_on(54321)
|
12
|
+
step "I run `a11y http://localhost:54321/missing_header.html`"
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
|
3
|
+
class WebServer
|
4
|
+
DOCUMENT_ROOT = File.expand_path File.dirname(__FILE__) + '/web_server'
|
5
|
+
class << self
|
6
|
+
def ensure_running_on(port)
|
7
|
+
return if @running
|
8
|
+
server = WEBrick::HTTPServer.new options(port)
|
9
|
+
Thread.new { server.start }
|
10
|
+
at_exit { server.shutdown }
|
11
|
+
@running = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def options(port)
|
15
|
+
default = {
|
16
|
+
:Port => port.to_i,
|
17
|
+
:DocumentRoot => DOCUMENT_ROOT,
|
18
|
+
}
|
19
|
+
disable_logging = {
|
20
|
+
:AccessLog => [],
|
21
|
+
:Logger => WEBrick::Log::new("/dev/null", 7)
|
22
|
+
}
|
23
|
+
unless ENV['DEBUG']
|
24
|
+
default.merge disable_logging
|
25
|
+
else
|
26
|
+
default
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<html lang="en-gb">
|
2
|
+
<head>
|
3
|
+
<title>Missing header</title>
|
4
|
+
</head>
|
5
|
+
|
6
|
+
<body>
|
7
|
+
<p role="main">
|
8
|
+
Here is some text in British English. This is needed so that we can verify that
|
9
|
+
the lang attribute in the html element at the top, which specified en-gb, is
|
10
|
+
correct.
|
11
|
+
</p>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<html lang="en-gb">
|
2
|
+
<head>
|
3
|
+
<title>Perfect page - Main heading</title>
|
4
|
+
</head>
|
5
|
+
|
6
|
+
<body>
|
7
|
+
<h1>Main heading</h1>
|
8
|
+
<p role="main">
|
9
|
+
Here is some text in British English. This is needed so that we can verify that
|
10
|
+
the lang attribute in the html element at the top, which specified en-gb, is
|
11
|
+
correct.
|
12
|
+
</p>
|
13
|
+
</body>
|
14
|
+
</html>
|
data/lib/bbc/a11y.rb
CHANGED
data/lib/bbc/a11y/cli.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'bbc/a11y/cucumber_runner'
|
2
1
|
require 'bbc/a11y/configuration'
|
2
|
+
require 'bbc/a11y'
|
3
3
|
|
4
4
|
module BBC
|
5
5
|
module A11y
|
@@ -14,9 +14,11 @@ module BBC
|
|
14
14
|
@stdin, @stdout, @stderr, @args = stdin, stdout, stderr, args
|
15
15
|
end
|
16
16
|
|
17
|
-
def call
|
17
|
+
def call(runner)
|
18
18
|
trap_interrupt
|
19
|
-
|
19
|
+
runner.new(settings, cucumber_args).call
|
20
|
+
rescue TestsFailed
|
21
|
+
exit 1
|
20
22
|
rescue MissingArgument => error
|
21
23
|
stderr.puts "You missed an argument: #{error.message}"
|
22
24
|
stderr.puts HELP
|
@@ -26,12 +28,24 @@ module BBC
|
|
26
28
|
private
|
27
29
|
|
28
30
|
def settings
|
29
|
-
|
31
|
+
if a11y_args.any?
|
32
|
+
Configuration.for_urls(a11y_args)
|
33
|
+
else
|
34
|
+
Configuration.parse(File.expand_path(".a11y.rb"))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def a11y_args
|
39
|
+
if args.find_index('--')
|
40
|
+
args[0..(args.find_index('--') - 1)]
|
41
|
+
else
|
42
|
+
args
|
43
|
+
end
|
30
44
|
end
|
31
45
|
|
32
46
|
def cucumber_args
|
33
47
|
return [] unless args.include?('--')
|
34
|
-
args[args.find_index('--')+1..-1]
|
48
|
+
args[(args.find_index('--') + 1)..-1]
|
35
49
|
end
|
36
50
|
|
37
51
|
def trap_interrupt
|
@@ -16,6 +16,11 @@ module BBC
|
|
16
16
|
BBC::A11y.configuration
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.for_urls(urls)
|
20
|
+
page_settings = urls.map { |url| PageSettings.new(url) }
|
21
|
+
Settings.new.with_pages(page_settings)
|
22
|
+
end
|
23
|
+
|
19
24
|
class Settings
|
20
25
|
attr_reader :before_all_hooks,
|
21
26
|
:after_all_hooks,
|
@@ -44,7 +49,7 @@ module BBC
|
|
44
49
|
end
|
45
50
|
|
46
51
|
def skip_test_case?(test_case)
|
47
|
-
@scenarios_to_skip.any? { |pattern|
|
52
|
+
@scenarios_to_skip.any? { |pattern| test_case.name.match pattern }
|
48
53
|
end
|
49
54
|
|
50
55
|
def merge(other)
|
@@ -51,6 +51,9 @@ module BBC
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
puts
|
54
|
+
if result.failed?
|
55
|
+
CucumberRunner.test_case_failed
|
56
|
+
end
|
54
57
|
end
|
55
58
|
|
56
59
|
private
|
@@ -135,6 +138,21 @@ module BBC
|
|
135
138
|
|
136
139
|
class CucumberRunner
|
137
140
|
include ConsoleWriter
|
141
|
+
FEATURES_PATH = File.expand_path(File.dirname(__FILE__) + "/../../../standards")
|
142
|
+
|
143
|
+
class << self
|
144
|
+
# need to use a global stash-point for the formatter to talk back to use
|
145
|
+
# until Cucumber gives us a way to add formatter instances that we can
|
146
|
+
# share.
|
147
|
+
def failed_count
|
148
|
+
@failed_count ||= 0
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_case_failed
|
152
|
+
@failed_count ||= 0
|
153
|
+
@failed_count += 1
|
154
|
+
end
|
155
|
+
end
|
138
156
|
|
139
157
|
def initialize(settings, cucumber_args)
|
140
158
|
@settings = settings
|
@@ -152,19 +170,21 @@ module BBC
|
|
152
170
|
end
|
153
171
|
ensure
|
154
172
|
run_after_all_hooks
|
173
|
+
raise BBC::A11y::TestsFailed if self.class.failed_count > 0
|
155
174
|
end
|
156
175
|
|
157
176
|
private
|
158
177
|
|
159
178
|
def configuration
|
160
179
|
return @configuration if @configuration
|
161
|
-
features_path = File.expand_path(File.dirname(__FILE__) + "/../../../features")
|
162
180
|
@configuration = Cucumber::Cli::Configuration.new
|
181
|
+
if !@cucumber_args.any?
|
182
|
+
@cucumber_args = [FEATURES_PATH, "--require", FEATURES_PATH]
|
183
|
+
end
|
163
184
|
# This is ugly, but until Cucumber offers a better API, we have to pass in our settings as though
|
164
185
|
# they were CLI arguments
|
165
|
-
@configuration.parse!(@cucumber_args +
|
166
|
-
|
167
|
-
"--format", "BBC::A11y::CucumberFormatter"])
|
186
|
+
@configuration.parse!(@cucumber_args +
|
187
|
+
["--format", "BBC::A11y::CucumberFormatter"])
|
168
188
|
@configuration
|
169
189
|
end
|
170
190
|
|
@@ -179,7 +199,7 @@ module BBC
|
|
179
199
|
def print_page_header(page_settings)
|
180
200
|
puts
|
181
201
|
puts
|
182
|
-
underline("BBC Accesibility: #{page_settings.url}")
|
202
|
+
puts underline("BBC Accesibility: #{page_settings.url}")
|
183
203
|
end
|
184
204
|
|
185
205
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
require 'bbc/a11y/cucumber_support/disabled_w3c'
|
1
2
|
require 'bbc/a11y/cucumber_support/language_detector'
|
3
|
+
require 'bbc/a11y/cucumber_support/matchers'
|
2
4
|
require 'bbc/a11y/cucumber_support/page'
|
3
|
-
require 'bbc/a11y/cucumber_support/w3c'
|
4
5
|
require 'bbc/a11y/cucumber_support/per_page_checks'
|
6
|
+
require 'bbc/a11y/cucumber_support/w3c'
|
7
|
+
require 'bbc/a11y/configuration'
|
5
8
|
|
6
9
|
module BBC
|
7
10
|
module A11y
|
@@ -17,7 +20,7 @@ module BBC
|
|
17
20
|
|
18
21
|
# Returns an object that can validate URLs
|
19
22
|
def w3c
|
20
|
-
@w3c ||=
|
23
|
+
@w3c ||= DisabledW3C.new
|
21
24
|
end
|
22
25
|
|
23
26
|
# An object that represents the current page being viewed in the browser
|
@@ -43,7 +46,11 @@ module BBC
|
|
43
46
|
end
|
44
47
|
|
45
48
|
end
|
49
|
+
|
50
|
+
CucumberSupport.current_page_settings ||=
|
51
|
+
Configuration::PageSettings.new(ENV['A11Y_URL'])
|
46
52
|
end
|
47
53
|
|
48
54
|
end
|
49
55
|
|
56
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module BBC
|
2
|
+
module A11y
|
3
|
+
module CucumberSupport
|
4
|
+
|
5
|
+
class DisabledW3C
|
6
|
+
|
7
|
+
def validate(url)
|
8
|
+
raise Cucumber::Core::Test::Result::Skipped.new <<-MESSAGE
|
9
|
+
W3C validation is disabled by default as it makes off-netowrk calls
|
10
|
+
to the W3C web service and can be slow and unreliable.
|
11
|
+
|
12
|
+
To enable these checks, include the following code in your .a11y.rb
|
13
|
+
config file:
|
14
|
+
|
15
|
+
BBC::A11y.configure do
|
16
|
+
page "my_page.html" do
|
17
|
+
|
18
|
+
customize_world do
|
19
|
+
def w3c
|
20
|
+
@w3c ||= BBC::A11y::CucumberSupport::W3C.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
MESSAGE
|
27
|
+
end
|
28
|
+
|
29
|
+
def errors
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rspec/matchers'
|
2
|
+
module BBC
|
3
|
+
module A11y
|
4
|
+
module CucumberSupport
|
5
|
+
RSpec::Matchers.define :have_title_attribute_or_associated_label_tag do
|
6
|
+
match do |element|
|
7
|
+
if !element['title'].nil?
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
if id = element['id']
|
11
|
+
return true if element.find_xpath("//*[for=#{id}]")
|
12
|
+
end
|
13
|
+
if element.find_xpath("..")[0].name == "label"
|
14
|
+
return true
|
15
|
+
end
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|