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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -7
  3. data/README.md +7 -3
  4. data/Rakefile +1 -2
  5. data/bin/a11y +2 -1
  6. data/features/README.md +4 -0
  7. data/features/exit_status.feature +14 -0
  8. data/features/specify_url_via_cli.feature +10 -0
  9. data/features/specify_url_via_config.feature +16 -0
  10. data/features/step_definitions/steps.rb +13 -0
  11. data/features/support/env.rb +5 -0
  12. data/features/support/web_server.rb +30 -0
  13. data/features/support/web_server/missing_header.html +13 -0
  14. data/features/support/web_server/perfect.html +14 -0
  15. data/lib/bbc/a11y.rb +1 -0
  16. data/lib/bbc/a11y/cli.rb +19 -5
  17. data/lib/bbc/a11y/configuration.rb +6 -1
  18. data/lib/bbc/a11y/cucumber_runner.rb +25 -5
  19. data/lib/bbc/a11y/cucumber_support.rb +9 -2
  20. data/lib/bbc/a11y/cucumber_support/disabled_w3c.rb +37 -0
  21. data/lib/bbc/a11y/cucumber_support/matchers.rb +21 -0
  22. data/lib/bbc/a11y/cucumber_support/page.rb +16 -6
  23. data/lib/bbc/a11y/version +1 -1
  24. data/spec/bbc/a11y/cli_spec.rb +27 -0
  25. data/spec/bbc/a11y/configuration_spec.rb +15 -3
  26. data/spec/bbc/a11y/cucumber_support/matchers_spec.rb +52 -0
  27. data/spec/bbc/a11y/cucumber_support/page_spec.rb +34 -10
  28. data/{features → standards}/01_core-purpose.md +0 -0
  29. data/{features → standards}/02_validation.feature +0 -0
  30. data/{features → standards}/03_javascript.feature +0 -0
  31. data/{features → standards}/04_language.feature +0 -0
  32. data/{features → standards}/05_page_title.feature +0 -0
  33. data/{features → standards}/06_main_landmark.feature +0 -0
  34. data/{features → standards}/07_headings.feature +0 -0
  35. data/{features → standards}/08_title_attribute.feature +0 -0
  36. data/{features → standards}/09_tabindex.feature +8 -1
  37. data/standards/10_form_labels.feature +88 -0
  38. data/{features → standards}/11_visible-on-focus.md +0 -0
  39. data/{features → standards}/13_colour-contrast.md +0 -0
  40. data/{features → standards}/14_colour-meaning.md +0 -0
  41. data/{features → standards}/15_focusable-controls.md +0 -0
  42. data/{features → standards}/16_table.md +0 -0
  43. data/{features → standards}/17_control-styles.md +0 -0
  44. data/{features → standards}/18_focus-styles.md +0 -0
  45. data/{features → standards}/19_form-interactions.md +0 -0
  46. data/{features → standards}/20_image-alt.md +0 -0
  47. data/{features → standards}/21_min-font-sizes.md +0 -0
  48. data/{features → standards}/22_resize-zoom.md +0 -0
  49. data/{features → standards}/step_definitions/core_content_steps.rb +0 -0
  50. data/standards/step_definitions/form_steps.rb +6 -0
  51. data/{features → standards}/step_definitions/language_steps.rb +0 -0
  52. data/{features → standards}/step_definitions/page_steps.rb +6 -2
  53. data/{features → standards}/step_definitions/w3c_steps.rb +0 -0
  54. data/{features → standards}/support/capybara.rb +0 -0
  55. data/{features → standards}/support/skipper.rb +0 -0
  56. data/{features → standards}/support/world.rb +0 -0
  57. data/{features → standards}/support/world_extender.rb +0 -0
  58. metadata +82 -86
  59. data/features/10_form-labels.md +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1a5f15fb23bfa023b502767ac8667ef7b3f27ce
4
- data.tar.gz: 48b3be883a67e39d68fd2c383c38b5e49af2d444
3
+ metadata.gz: 8697bc18c43d39bd843b0dfe9fda7a20ea761fc4
4
+ data.tar.gz: 4e709fc1f14853e37d2d00ed0453de4db887829a
5
5
  SHA512:
6
- metadata.gz: 8f936fb98eef71751d1730c3b7736352b38e4822a75dc8b97a1efadfc81b63caf1d352b8c41697a1a8d4b3492f2e319a99ccc30520de3e9d498edb1c05700c85
7
- data.tar.gz: f6452c73fd7f27d46a390be8d6054ffda5bc21af07b540c49fa60038a51d0491f459dc168b2e21f48dbc0847590fc040be5e647a7e03e71e1ff75246a26780cb
6
+ metadata.gz: 29063edb07ab6454f23b5a0b797e911e278b74ecb7bf4299e64700c8ab16f6c86508829727343fe7f35ded04f354ee9f1a61e4bce18d5ebdada70316c3f30541
7
+ data.tar.gz: a0da88c1f3e550ac193b7d9b87a15c00b8135d42dda11e76a809d0750831d28f32f969c147bf5c43e3ddc3b207399d57af21b589c13e0e22edf1f6dda8c09dfc
@@ -1,18 +1,14 @@
1
1
  # BBC A11y Contributing guidelines
2
2
 
3
- The standards are all stored in the `features` directory.
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 pick out a specific feature to run:
9
+ You can also use cucumber to run one specific test:
10
10
 
11
- bundle exec ./bin/a11y <url> -- features/04_language.feature
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 "W3C"
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
@@ -8,6 +8,5 @@ task :unit do
8
8
  end
9
9
 
10
10
  task :acceptance do
11
- sh "cd examples/local-web-app && rake"
12
- sh "cd examples/bbc-pages && rake"
11
+ sh "cucumber"
13
12
  end
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
- BBC::A11y::CLI.new($stdin, $stdout, $stderr, ARGV.dup).call
5
+ require 'bbc/a11y/cucumber_runner'
6
+ BBC::A11y::CLI.new($stdin, $stdout, $stderr, ARGV.dup).call(BBC::A11y::CucumberRunner)
@@ -0,0 +1,4 @@
1
+ These are the acceptance tests for the a11y tool itself.
2
+
3
+ To read the accessibility standards checks that this tool will run against your app,
4
+ you need to look in the `standards` directory.
@@ -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,5 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 10
5
+ 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>
@@ -1,4 +1,5 @@
1
1
  module BBC
2
2
  module A11y
3
+ TestsFailed = Class.new(StandardError)
3
4
  end
4
5
  end
@@ -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
- CucumberRunner.new(settings, cucumber_args).call
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
- Configuration.parse(File.expand_path(".a11y.rb"))
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| pattern.match test_case.name }
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
- features_path,
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 ||= W3C.new
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