bbc-a11y 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/README.md +9 -11
  4. data/Rakefile +2 -2
  5. data/a11y.rb +5 -0
  6. data/bbc-a11y.gemspec +3 -5
  7. data/bin/a11y +2 -2
  8. data/examples/bbc-pages/a11y.rb +2 -6
  9. data/examples/local-web-app/Gemfile +1 -1
  10. data/examples/local-web-app/a11y.rb +10 -22
  11. data/features/check_standards/focusable_controls.feature +62 -0
  12. data/features/check_standards/form_interactions.feature +45 -0
  13. data/features/check_standards/form_labels.feature +55 -0
  14. data/features/check_standards/headings.feature +154 -0
  15. data/features/check_standards/image_alt.feature +39 -0
  16. data/features/check_standards/language.feature +46 -0
  17. data/features/check_standards/main_landmark.feature +39 -0
  18. data/features/check_standards/tab_index.feature +54 -0
  19. data/features/cli/display_failing_result.feature +10 -0
  20. data/features/{exit_status.feature → cli/exit_status.feature} +1 -2
  21. data/features/cli/provide_muting_tips.feature +25 -0
  22. data/features/cli/report_configuration_errors.feature +43 -0
  23. data/features/cli/skipping_standards.feature +15 -0
  24. data/features/cli/specify_url.feature +9 -0
  25. data/features/cli/specify_url_via_config.feature +13 -0
  26. data/features/mute_errors.feature +118 -0
  27. data/features/step_definitions/steps.rb +25 -1
  28. data/lib/bbc/a11y/cli.rb +32 -44
  29. data/lib/bbc/a11y/configuration.rb +56 -22
  30. data/lib/bbc/a11y/linter.rb +42 -0
  31. data/lib/bbc/a11y/standards.rb +43 -0
  32. data/lib/bbc/a11y/standards/anchor_hrefs.rb +18 -0
  33. data/lib/bbc/a11y/standards/content_follows_headings.rb +22 -0
  34. data/lib/bbc/a11y/standards/exactly_one_main_heading.rb +20 -0
  35. data/lib/bbc/a11y/standards/exactly_one_main_landmark.rb +20 -0
  36. data/lib/bbc/a11y/standards/form_labels.rb +39 -0
  37. data/lib/bbc/a11y/standards/form_submit_buttons.rb +21 -0
  38. data/lib/bbc/a11y/standards/heading_hierarchy.rb +34 -0
  39. data/lib/bbc/a11y/standards/image_alt.rb +18 -0
  40. data/lib/bbc/a11y/standards/language_attribute.rb +19 -0
  41. data/lib/bbc/a11y/standards/tab_index.rb +22 -0
  42. data/lib/bbc/a11y/version +1 -1
  43. data/spec/bbc/a11y/cli_spec.rb +22 -15
  44. data/spec/bbc/a11y/configuration_spec.rb +15 -40
  45. data/standards/support/capybara.rb +1 -2
  46. metadata +62 -81
  47. data/features/specify_url_via_cli.feature +0 -10
  48. data/features/specify_url_via_config.feature +0 -16
  49. data/lib/bbc/a11y.rb +0 -17
  50. data/lib/bbc/a11y/cucumber_runner.rb +0 -208
  51. data/lib/bbc/a11y/cucumber_support.rb +0 -56
  52. data/lib/bbc/a11y/cucumber_support/disabled_w3c.rb +0 -37
  53. data/lib/bbc/a11y/cucumber_support/heading_hierarchy.rb +0 -94
  54. data/lib/bbc/a11y/cucumber_support/language_detector.rb +0 -26
  55. data/lib/bbc/a11y/cucumber_support/matchers.rb +0 -21
  56. data/lib/bbc/a11y/cucumber_support/page.rb +0 -94
  57. data/lib/bbc/a11y/cucumber_support/per_page_checks.rb +0 -28
  58. data/lib/bbc/a11y/cucumber_support/w3c.rb +0 -36
  59. data/spec/bbc/a11y/cucumber_support/heading_hierarchy_spec.rb +0 -162
  60. data/spec/bbc/a11y/cucumber_support/matchers_spec.rb +0 -52
  61. data/spec/bbc/a11y/cucumber_support/page_spec.rb +0 -197
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8df36f88dadb635f0d2de52661d26fcce169ecf
4
- data.tar.gz: 9260e8f08cf9846a400900516cf63c8fe789920b
3
+ metadata.gz: 10a369a2db0ae8f7e5b16e92a0f57e12ac3343be
4
+ data.tar.gz: 1b733f1a53afad2c0d200f801ec95ff6ed2ed7c1
5
5
  SHA512:
6
- metadata.gz: b580f97a7dc87d151d4693e259d62b050b4d5c087ff6d485a390daad502f04ef82aabfc648a95c2b941774c2a0dc35348ca89c0759ec578114fe64838b68c800
7
- data.tar.gz: 39ee8ec689f4bae55ab38261388f2a0e672ffe1f78815eb6cddd0a4acc792240a1783db15dd93a97732105f1446cdb579c39940b93958cf67bb0b863f3505e01
6
+ metadata.gz: 79571febea89695f33ae26639f47567dec98e73bed577c5ade2559db0b3235db15c3ec6245c5a6878598eda8f5ef163dd67b8c0df61603fb15c3ffe6779bd8db
7
+ data.tar.gz: de1ff17432e5fe20a0e67572fdbb0b973ff835d86620a12b7f3e63abe28ecb557ec7e7e824c488832c5cad9f19ea45cc962d23e4f084cc5dcc55c48ddff9c1d7
@@ -0,0 +1 @@
1
+ 2.2.3
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Circle CI](https://circleci.com/gh/cucumber-ltd/bbc-a11y.svg?style=svg&circle-token=00d656fd091643ad692c78ca60e30ad95df9563a)](https://circleci.com/gh/cucumber-ltd/bbc-a11y)
2
+
1
3
  # WARNING - PROTOTYPE SOFTWARE
2
4
 
3
5
  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.
@@ -32,24 +34,20 @@ Now install the gem:
32
34
  You'll need to configure a11y with a set of URLs to run the checks against. Create a file `a11y.rb` in the root of your project that looks something like this:
33
35
 
34
36
  ```
35
- BBC::A11y.configure do
36
- page "http://bbc.co.uk"
37
- page "http://bbc.co.uk/news"
38
- end
37
+ page "http://bbc.co.uk"
38
+ page "http://bbc.co.uk/news"
39
39
  ```
40
40
 
41
41
  ### Skipping scenarios
42
42
 
43
- Nobody's perfect. Use `skip_scenario` in the configuration to opt-out of certain checks.
43
+ Nobody's perfect. Use `skip_standard` in the configuration to opt-out of certain checks.
44
44
 
45
45
  ```
46
- BBC::A11y.configure do
47
- page "http://bbc.co.uk" do
48
- skip_scenario /W3C/
49
- end
50
-
51
- page "http://bbc.co.uk/news"
46
+ page "http://bbc.co.uk" do
47
+ skip_standard /W3C/
52
48
  end
49
+
50
+ page "http://bbc.co.uk/news"
53
51
  ```
54
52
 
55
53
  A11y will skip any scenarios from the specifications whose name contains that string.
data/Rakefile CHANGED
@@ -4,9 +4,9 @@ Bundler::GemHelper.install_tasks
4
4
  task default: [:unit, :acceptance]
5
5
 
6
6
  task :unit do
7
- sh "rspec"
7
+ sh "bundle exec rspec"
8
8
  end
9
9
 
10
10
  task :acceptance do
11
- sh "cucumber"
11
+ sh "bundle exec cucumber"
12
12
  end
data/a11y.rb ADDED
@@ -0,0 +1,5 @@
1
+ page "https://bbc.co.uk/news" do
2
+ skip_standard /W3C/
3
+ skip_standard /JavaScript/
4
+ skip_standard /title/
5
+ end
@@ -13,16 +13,14 @@ Gem::Specification.new do |s|
13
13
  s.license = "MIT"
14
14
  s.required_ruby_version = ">= 1.9.3"
15
15
 
16
- s.add_dependency 'cucumber', '~> 2.0.0.rc'
17
- s.add_dependency 'rspec', '~> 3.0'
18
16
  s.add_dependency 'capybara'
19
- s.add_dependency 'poltergeist'
20
- s.add_dependency 'w3c_validators'
21
- s.add_dependency 'cld'
22
17
  s.add_dependency 'colorize'
18
+
19
+ s.add_development_dependency 'rspec', '~> 3.0'
23
20
  s.add_development_dependency 'aruba'
24
21
  s.add_development_dependency 'pry'
25
22
  s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'cucumber'
26
24
 
27
25
  s.rubygems_version = ">= 1.6.1"
28
26
  s.files = `git ls-files`.split("\n").reject {|path| path =~ /\.gitignore$/ }
data/bin/a11y CHANGED
@@ -2,5 +2,5 @@
2
2
  $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
3
3
 
4
4
  require 'bbc/a11y/cli'
5
- require 'bbc/a11y/cucumber_runner'
6
- BBC::A11y::CLI.new($stdin, $stdout, $stderr, ARGV.dup).call(BBC::A11y::CucumberRunner)
5
+
6
+ BBC::A11y::CLI.new($stdin, $stdout, $stderr, ARGV.dup).call
@@ -1,6 +1,2 @@
1
- BBC::A11y.configure do
2
-
3
- page "http://bbc.co.uk/news"
4
- page "http://bbc.co.uk/mundo"
5
-
6
- end
1
+ page "http://bbc.co.uk/news"
2
+ page "http://bbc.co.uk/mundo"
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem 'rack'
4
- gem 'bbc-a11y', path: '..'
4
+ gem 'bbc-a11y', path: '../..'
@@ -36,29 +36,17 @@ class Server
36
36
  end
37
37
 
38
38
  server = Server.new
39
+ server.start
39
40
 
40
- BBC::A11y.configure do
41
-
42
- before_all do
43
- server.start
44
- end
45
-
46
- after_all do
47
- server.stop
48
- end
49
-
50
- page "http://localhost:#{server.port}/perfect.html" do
51
- skip_scenario "W3C"
52
- end
41
+ at_exit do
42
+ server.stop
43
+ end
53
44
 
54
- page "http://localhost:#{server.port}/missing_header.html" do
55
- skip_scenario "W3C"
56
- skip_scenario "Check headings"
45
+ page "http://localhost:#{server.port}/perfect.html" do
46
+ skip_standard "W3C"
47
+ end
57
48
 
58
- customize_world do
59
- def Xassert_title_describes_primary_content_of_document(title, doc)
60
- puts "TODO"
61
- end
62
- end
63
- end
49
+ page "http://localhost:#{server.port}/missing_header.html" do
50
+ skip_standard "W3C"
51
+ skip_standard "Check headings"
64
52
  end
@@ -0,0 +1,62 @@
1
+ Feature: Focusable Controls
2
+
3
+ Controls for JavaScript enhanced interactions **must** be `<a>`, `<button>`,
4
+ or `<input>` elements if that is the only mechanism for controlling them.
5
+
6
+ `<a>` elements used for controls **must** have an `href` attribute.
7
+
8
+ Controls that have no purpose without JavaScript **must not** be added to the
9
+ page before the associated code is available capable of running.
10
+
11
+ Rationale
12
+ =========
13
+
14
+ When creating controls for user interaction with JavaScript enhanced features,
15
+ for example a carousel with previous and next controls, the controls must be
16
+ implemented with elements that provide natively focusable elements with click,
17
+ keydown, and focus events so they are accessible to keyboard as well as
18
+ pointing device users. If there is an alternative method of controlling the
19
+ feature, for example a carousel that automatically displays new content when
20
+ it receives content then controls that are only available to pointing device
21
+ users can be used.
22
+
23
+ In general, use `<a>` elements when there is a URL associated with the
24
+ interaction when JavaScript is not enabled, and `<button>` elements for
25
+ interactions that don't have an associated URL.
26
+
27
+ `<a>` elements without a `href` attribute are not keyboard accessible, and
28
+ therefore must not be used for controls.
29
+
30
+ When there is no core (non-JavaScript) interaction then the control must not
31
+ be added to the document before the associated JavaScript is capable of
32
+ running as this would lead to controls that apparently do nothing, potentially
33
+ causing confusion to users.
34
+
35
+ Scenario: All anchor tags have href attributes
36
+ Given a page with the HTML:
37
+ """
38
+ <button type="button">Open panel</button>
39
+ <ul>
40
+ <li><a href="/news">News</a></li>
41
+ <li><a href="#sporttab">Sport</a></li>
42
+ <li><a href="#entertainmenttab">Entertainment</a></li>
43
+ </ul>
44
+ """
45
+ When I validate the anchor hrefs standards
46
+ Then it passes
47
+
48
+ Scenario: Some anchor tags do not have href attributes
49
+ Given a page with the HTML:
50
+ """
51
+ <ul>
52
+ <li><a>News</a></li>
53
+ <li><a href="#sport">Sport</a></li>
54
+ <li><a>Entertainment</a></li>
55
+ </ul>
56
+ """
57
+ When I validate the anchor hrefs standards
58
+ Then it fails with the message:
59
+ """
60
+ Anchor has no href attribute: /html/body/ul/li[1]/a
61
+ Anchor has no href attribute: /html/body/ul/li[3]/a
62
+ """
@@ -0,0 +1,45 @@
1
+ Feature: Form Interactions
2
+
3
+ Forms must have a submit button and forms must not update the location of the
4
+ page on change, focus, or blur events.
5
+
6
+ All `<form>` elements that take user input (i.e. do not consist only of
7
+ `input[type=hidden]` elements to store state) **must** have a submit button in
8
+ the form of a `<input>[type=submit,image]` or `<button>[type=submit]` element.
9
+
10
+ Changes to the page **must** location must only take place on explicit user
11
+ action i.e. when a submit button is activated. They must not take place when
12
+ change (particularly for `select` elements), focus, or blur events are fired.
13
+
14
+ Rationale
15
+ =========
16
+
17
+ All forms should have a submit button to provide a clear call to action. This
18
+ is particularly important to users with cognitive disabilities, but is also
19
+ beneficial to low vision users as an indication of the end of the form.
20
+
21
+ Scenario: Form with a submit button
22
+ Given a page with the HTML:
23
+ """
24
+ <form action="/search">
25
+ <label for="q">Search term:</label>
26
+ <input type="text" name="q" id="q">
27
+ <input type="submit" value="Search">
28
+ </form>
29
+ """
30
+ When I validate the form submit buttons standards
31
+ Then it passes
32
+
33
+ Scenario: Form with no submit button
34
+ Given a page with the HTML:
35
+ """
36
+ <form action="/search">
37
+ <label for="q">Search term:</label>
38
+ <input type="text" name="q" id="q">
39
+ </form>
40
+ """
41
+ When I validate the form submit buttons standards
42
+ Then it fails with the message:
43
+ """
44
+ Form has no submit button: /html/body/form
45
+ """
@@ -0,0 +1,55 @@
1
+ Feature: Correctly use form labels
2
+
3
+ Form fields that allow input (`select`, and `textarea` elements, and all
4
+ `input` element types other than image, submit, reset, button, or hidden)
5
+ **must** have an associated label, either in the form of a `<label>` element
6
+ or, for simple forms when no visible label is required, a `title` attribute.
7
+
8
+ Rationale
9
+ ---------
10
+
11
+ Form labels are important for all users in order to understand what the form
12
+ field is however they are essential for speech output users who cannot easily
13
+ infer what the form element is by looking at the surrounding content.
14
+
15
+ While there are WAI-ARIA attributes that allow for labelling of forms it is
16
+ not supported in all versions of assistive technologies that BBC users could
17
+ reasonably expect to be able to use.
18
+
19
+ Scenario: All fields have labels or title attributes
20
+ Given a page with the HTML:
21
+ """
22
+ <label for="search">Search the BBC</label>
23
+ <input type="text" id="search" name="q" />
24
+
25
+ <label for="search2">
26
+ Search the BBC
27
+ <input id="search2" type="text" name="q" />
28
+ </label>
29
+
30
+ <input type="text" name="q" title="Search the BBC" />
31
+ """
32
+ When I validate the form labels standards
33
+ Then it passes
34
+
35
+ Scenario: Some fields without labels or title attributes
36
+ Given a page with the HTML:
37
+ """
38
+ <input type="text" name="name" title="Name" />
39
+ <input type="email" name="email" title="Email" />
40
+
41
+ <textarea name="notes"></textarea>
42
+ <select name="preference"></select>
43
+ <input type="text" name="q" value="Search the BBC" />
44
+ <input type="text" name="q" aria-label="Search the BBC" />
45
+ <input type="text" name="q" placeholder="Search the BBC" />
46
+ """
47
+ When I validate the form labels standards
48
+ Then it fails with the message:
49
+ """
50
+ Field has no label or title attribute: /html/body/textarea
51
+ Field has no label or title attribute: /html/body/select
52
+ Field has no label or title attribute: /html/body/input[3]
53
+ Field has no label or title attribute: /html/body/input[4]
54
+ Field has no label or title attribute: /html/body/input[5]
55
+ """
@@ -0,0 +1,154 @@
1
+ Feature: Headings
2
+
3
+ A document **must** have exactly one `<h1>` element.
4
+
5
+ Heading levels after the document `<h1>` element **must** be sequential and **must not** skip heading levels.
6
+
7
+ Heading elements **must** be followed by content.
8
+
9
+ Rationale
10
+ =========
11
+
12
+ A logical heading structure is invaluable for users of screen readers and similar assistive technologies to help navigate content.
13
+
14
+ Users should be able to use the document's `<h1>` identify its main content. Documents should have one main subject.
15
+
16
+ Heading levels should not be skipped as a predictable document outline is an important factor for understandability.
17
+
18
+ Headings should not be used for non-heading purposes, i.e. to identify blocks of content. A heading should always
19
+ be followed either by non-heading content or by a heading of one level deeper.
20
+
21
+ Scenario: No main heading
22
+ Given a page with the HTML:
23
+ """
24
+ <h2>Heading 2</h2>
25
+ """
26
+ When I validate the heading standards
27
+ Then it fails with the message:
28
+ """
29
+ A document must have exactly one heading. Found 0 h1 elements.
30
+ """
31
+
32
+ Scenario: More than one main heading
33
+ Given a page with the HTML:
34
+ """
35
+ <h1>Heading 1</h1>
36
+ <h2>Heading 2</h2>
37
+ <h1>Heading 1</h1>
38
+ """
39
+ When I validate the heading standards
40
+ Then it fails with the message:
41
+ """
42
+ A document must have exactly one heading. Found 2 h1 elements:
43
+ /html/body/h1[1]
44
+ /html/body/h1[2]
45
+ """
46
+
47
+ Scenario: Headings in ascending order
48
+ Given a page with the HTML:
49
+ """
50
+ <h1>Heading 1</h1>
51
+ <h2>Heading 2</h2>
52
+ <h3>Heading 3</h3>
53
+ <h4>Heading 4</h4>
54
+ <h5>Heading 5</h5>
55
+ <h6>Heading 6</h6>
56
+ """
57
+ When I validate the heading standards
58
+ Then it passes
59
+
60
+ Scenario: Headings in invalid order
61
+ Given a page with the HTML:
62
+ """
63
+ <h1>Heading 1</h1>
64
+ <h3>Heading 3</h3>
65
+ <h2>Heading 2</h2>
66
+ """
67
+ When I validate the heading standards
68
+ Then it fails with the message:
69
+ """
70
+ Headings are not in order: h1 is followed by h3
71
+ """
72
+
73
+ Scenario: Headings jump back up more than one level
74
+ Given a page with the HTML:
75
+ """
76
+ <h1>Heading 1</h1>
77
+ <h2>Heading 2</h2>
78
+ <h3>Heading 3</h3>
79
+ <h4>Heading 4</h4>
80
+ <h2>Heading 2b</h2>
81
+ <h3>Heading 3b</h3>
82
+ """
83
+ When I validate the heading standards
84
+ Then it passes
85
+
86
+ Scenario: Heading is hidden
87
+ Given a page with the HTML:
88
+ """
89
+ <h1>Heading 1</h1>
90
+ <h3 style="display:none">Heading 3</h3>
91
+ <h2>Heading 2</h2>
92
+ """
93
+ When I validate the heading standards
94
+ Then it fails with the message:
95
+ """
96
+ Headings are not in order: h1 is followed by h3
97
+ """
98
+
99
+ Scenario: Heading in a script tag
100
+ Given a page with the HTML:
101
+ """
102
+ <h1>Heading 1</h1>
103
+ <script>
104
+ var stuff = "<h3>Heading 3</h3>";
105
+ </script>
106
+ <h2>Heading 2</h2>
107
+ """
108
+ When I validate the heading standards
109
+ Then it passes
110
+
111
+ Scenario: Subheading before the first main heading
112
+ Given a page with the HTML:
113
+ """
114
+ <h3>Ignore me</h3>
115
+ <h1>Heading 1</h1>
116
+ <h2>Heading 2</h2>
117
+ """
118
+ When I validate the heading standards
119
+ Then it passes
120
+
121
+ Scenario: Content between headings
122
+ Given a page with the HTML:
123
+ """
124
+ <div role="main">
125
+ <h1>Main heading</h1>
126
+ <p>non-heading content</p>
127
+ <h2>Another heading</h2>
128
+ <p>non-heading content</p>
129
+ <h3>Main content</h3>
130
+ <h2>Secondary content</h2>
131
+ <p>non-heading content</p>
132
+ <h2>Tertiary content</h2>
133
+ <p>Lorem ipsum…</p>
134
+ </div>
135
+ """
136
+ When I validate the heading standards
137
+ Then it passes
138
+
139
+ Scenario: No content between headings
140
+ Given a page with the HTML:
141
+ """
142
+ <div role="main">
143
+ <h1>Main heading</h1>
144
+ <p>non-heading content</p>
145
+ <h2>Secondary content</h2>
146
+ <h2>Tertiary content</h2>
147
+ <p>non-heading content</p>
148
+ </div>
149
+ """
150
+ When I validate the heading standards
151
+ Then it fails with the message:
152
+ """
153
+ Heading elements must be followed by content. No content follows a h2.
154
+ """