bbc-a11y 0.0.9 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|