bbc-a11y 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -0
  3. data/CONTRIBUTING.md +70 -8
  4. data/GETTINGSTARTED.md +65 -0
  5. data/LICENSE +1 -1
  6. data/README.md +12 -55
  7. data/Rakefile +1 -1
  8. data/a11y.rb +1 -3
  9. data/bbc-a11y.gemspec +0 -1
  10. data/features/check_standards/01_core_purpose.feature +39 -0
  11. data/features/check_standards/02_validation.feature +1 -0
  12. data/features/check_standards/03_progressive_enhancement.feature +3 -0
  13. data/features/check_standards/{language.feature → 04_indicating_language.feature} +2 -2
  14. data/features/check_standards/05_page_titles.feature +1 -0
  15. data/features/check_standards/{main_landmark.feature → 06_main_landmark.feature} +6 -6
  16. data/features/check_standards/07_headings.feature +222 -0
  17. data/features/check_standards/{minimum_text_size.feature → 08_minimum_text_size.feature} +22 -2
  18. data/features/check_standards/09_resizable_text.feature +2 -0
  19. data/features/check_standards/{tab_index.feature → 10_tab_index.feature} +7 -7
  20. data/features/check_standards/{title_attribute.feature → 11_title_attributes.feature} +13 -5
  21. data/features/check_standards/{focusable_controls.feature → 12_focusable_controls.feature} +4 -4
  22. data/features/check_standards/13_visible_on_focus.feature +1 -0
  23. data/features/check_standards/14_control_styles.feature +1 -0
  24. data/features/check_standards/15_focus_styles.feature +1 -0
  25. data/features/check_standards/16_colour_contrast.feature +1 -0
  26. data/features/check_standards/17_colour_and_meaning.feature +1 -0
  27. data/features/check_standards/{image_alt.feature → 18_image_alternatives.feature} +5 -5
  28. data/features/check_standards/{form_labels.feature → 19_form_labels.feature} +7 -7
  29. data/features/check_standards/{form_interactions.feature → 20_form_interactions.feature} +6 -6
  30. data/features/check_standards/21_tables.feature +1 -0
  31. data/features/cli/display_failing_result.feature +14 -1
  32. data/features/cli/display_result_summary.feature +15 -1
  33. data/features/cli/provide_muting_tips.feature +1 -1
  34. data/features/cli/skipping_standards.feature +1 -1
  35. data/features/mute_errors.feature +2 -2
  36. data/features/step_definitions/steps.rb +10 -9
  37. data/features/support/web_server.rb +0 -11
  38. data/features/support/web_server/blank.html +7 -0
  39. data/features/support/web_server/two_headings_failures.html +11 -0
  40. data/karma.conf.js +1 -1
  41. data/lib/bbc/a11y/cli.rb +33 -6
  42. data/lib/bbc/a11y/js/bundle.js +139 -89
  43. data/lib/bbc/a11y/js/standards.js +67 -20
  44. data/lib/bbc/a11y/js/standards/{anchorsMustHaveHrefs.js → focusableControls/anchorsMustHaveHrefs.js} +0 -0
  45. data/lib/bbc/a11y/js/standards/{formsMustHaveSubmitButtons.js → formInteractions/formsMustHaveSubmitButtons.js} +0 -0
  46. data/lib/bbc/a11y/js/standards/{fieldsMustHaveLabelsOrTitles.js → formLabels/fieldsMustHaveLabelsOrTitles.js} +0 -0
  47. data/lib/bbc/a11y/js/standards/headings/contentMustFollowHeadings.js +18 -0
  48. data/lib/bbc/a11y/js/standards/{exactlyOneMainHeading.js → headings/exactlyOneMainHeading.js} +1 -1
  49. data/lib/bbc/a11y/js/standards/{headingsMustBeInAscendingOrder.js → headings/headingsMustBeInAscendingOrder.js} +0 -0
  50. data/lib/bbc/a11y/js/standards/{imagesMustHaveAltAttributes.js → imageAlternatives/imagesMustHaveAltAttributes.js} +0 -0
  51. data/lib/bbc/a11y/js/standards/{htmlMustHaveLangAttribute.js → indicatingLanguage/htmlMustHaveLangAttribute.js} +0 -0
  52. data/lib/bbc/a11y/js/standards/{exactlyOneMainLandmark.js → mainLandmark/exactlyOneMainLandmark.js} +0 -0
  53. data/lib/bbc/a11y/js/standards/{minimumTextSize.js → minimumTextSize/textCannotBeTooSmall.js} +3 -3
  54. data/lib/bbc/a11y/js/standards/{elementsWithZeroTabIndexMustBeFields.js → tabIndex/elementsWithZeroTabIndexMustBeFields.js} +0 -0
  55. data/lib/bbc/a11y/js/standards/{titleAttributesOnlyOnInputs.js → titleAttributes/titleAttributesOnlyOnInputs.js} +1 -1
  56. data/lib/bbc/a11y/linter.rb +16 -4
  57. data/lib/bbc/a11y/runner.rb +0 -1
  58. data/lib/bbc/a11y/string_colours.rb +15 -0
  59. data/lib/bbc/a11y/version +1 -1
  60. data/package.json +3 -0
  61. data/spec/bbc/a11y/js/a11ySpec.js +15 -6
  62. data/spec/bbc/a11y/js/minimumTextSizeStandardSpec.js +25 -0
  63. data/spec/bbc/a11y/js/standardsSpec.js +6 -6
  64. data/spec/bbc/a11y/string_colours_spec.rb +13 -0
  65. metadata +68 -102
  66. data/circle.yml +0 -3
  67. data/examples/bbc-pages/Gemfile +0 -3
  68. data/examples/bbc-pages/Rakefile +0 -3
  69. data/examples/bbc-pages/a11y.rb +0 -2
  70. data/examples/local-web-app/Gemfile +0 -4
  71. data/examples/local-web-app/Rakefile +0 -3
  72. data/examples/local-web-app/a11y.rb +0 -52
  73. data/examples/local-web-app/config.ru +0 -1
  74. data/examples/local-web-app/public/missing_header.html +0 -13
  75. data/examples/local-web-app/public/perfect.html +0 -14
  76. data/examples/local-web-app/readme.md +0 -0
  77. data/features/check_standards/headings.feature +0 -153
  78. data/lib/bbc/a11y/js/standards/contentMustFollowHeadings.js +0 -15
  79. data/lib/bbc/a11y/standards.rb +0 -45
  80. data/lib/bbc/a11y/standards/anchor_hrefs.rb +0 -18
  81. data/lib/bbc/a11y/standards/content_follows_headings.rb +0 -22
  82. data/lib/bbc/a11y/standards/exactly_one_main_heading.rb +0 -25
  83. data/lib/bbc/a11y/standards/exactly_one_main_landmark.rb +0 -20
  84. data/lib/bbc/a11y/standards/form_labels.rb +0 -39
  85. data/lib/bbc/a11y/standards/form_submit_buttons.rb +0 -21
  86. data/lib/bbc/a11y/standards/heading_hierarchy.rb +0 -34
  87. data/lib/bbc/a11y/standards/image_alt.rb +0 -18
  88. data/lib/bbc/a11y/standards/language_attribute.rb +0 -19
  89. data/lib/bbc/a11y/standards/tab_index.rb +0 -22
  90. data/lib/bbc/a11y/standards/title_attribute.rb +0 -31
  91. data/standards/01_core-purpose.md +0 -24
  92. data/standards/02_validation.feature +0 -31
  93. data/standards/03_javascript.feature +0 -40
  94. data/standards/04_language.feature +0 -58
  95. data/standards/05_page_title.feature +0 -45
  96. data/standards/06_main_landmark.feature +0 -24
  97. data/standards/07_headings.feature +0 -65
  98. data/standards/08_title_attribute.feature +0 -71
  99. data/standards/09_tabindex.feature +0 -51
  100. data/standards/10_form_labels.feature +0 -88
  101. data/standards/11_visible-on-focus.md +0 -58
  102. data/standards/13_colour-contrast.md +0 -27
  103. data/standards/14_colour-meaning.md +0 -19
  104. data/standards/15_focusable-controls.md +0 -45
  105. data/standards/16_table.md +0 -109
  106. data/standards/17_control-styles.md +0 -78
  107. data/standards/18_focus-styles.md +0 -36
  108. data/standards/19_form-interactions.md +0 -33
  109. data/standards/20_image-alt.md +0 -34
  110. data/standards/21_min-font-sizes.md +0 -64
  111. data/standards/22_resize-zoom.md +0 -80
  112. data/standards/step_definitions/core_content_steps.rb +0 -3
  113. data/standards/step_definitions/form_steps.rb +0 -6
  114. data/standards/step_definitions/language_steps.rb +0 -21
  115. data/standards/step_definitions/page_steps.rb +0 -50
  116. data/standards/step_definitions/w3c_steps.rb +0 -7
  117. data/standards/support/capybara.rb +0 -53
  118. data/standards/support/skipper.rb +0 -5
  119. data/standards/support/world.rb +0 -3
  120. data/standards/support/world_extender.rb +0 -5
@@ -1,21 +0,0 @@
1
- module BBC
2
- module A11y
3
- module Standards
4
- class FormSubmitButtons
5
- def initialize(page)
6
- @page = page
7
- end
8
-
9
- def call(errors)
10
- @page.all("form").each do |form|
11
- submits = form.all("input[type=submit], button[type=submit]")
12
- if submits.empty?
13
- errors << "Form has no submit button: #{form.path}"
14
- end
15
- end
16
- end
17
-
18
- end
19
- end
20
- end
21
- end
@@ -1,34 +0,0 @@
1
- module BBC
2
- module A11y
3
- module Standards
4
-
5
- class HeadingHierarchy
6
- def initialize(page)
7
- @page = page
8
- end
9
-
10
- def call(errors)
11
- heading_levels.each_cons(2).each do |pair|
12
- if pair.last > pair.first + 1
13
- errors << "Headings are not in order: " +
14
- "h#{pair.first} is followed by h#{pair.last}"
15
- end
16
- end
17
- end
18
-
19
- private
20
-
21
- def headings
22
- @page.all('h1, h2, h3, h4, h5, h6', visible: false)
23
- end
24
-
25
- def heading_levels
26
- headings.map do |heading|
27
- heading.tag_name[1].to_i
28
- end
29
- end
30
- end
31
-
32
- end
33
- end
34
- end
@@ -1,18 +0,0 @@
1
- module BBC
2
- module A11y
3
- module Standards
4
- class ImageAlt
5
- def initialize(page)
6
- @page = page
7
- end
8
-
9
- def call(errors)
10
- @page.all("img:not([alt])").each do |img|
11
- errors << "Image has no alt attribute (src=\"#{img['src']}\")"
12
- end
13
- end
14
-
15
- end
16
- end
17
- end
18
- end
@@ -1,19 +0,0 @@
1
- module BBC
2
- module A11y
3
- module Standards
4
- class LanguageAttribute
5
- def initialize(page)
6
- @page = page
7
- end
8
-
9
- def call(errors)
10
- @page.all("html:not([lang])").each do |html|
11
- errors << "The main language must be specified. " +
12
- "<html> tag has no lang attribute."
13
- end
14
- end
15
-
16
- end
17
- end
18
- end
19
- end
@@ -1,22 +0,0 @@
1
- module BBC
2
- module A11y
3
- module Standards
4
- class TabIndex
5
- def initialize(page)
6
- @page = page
7
- end
8
-
9
- def call(errors)
10
- offenders = @page.all("*[tabindex='0']").reject { |el|
11
- ['input', 'button', 'select', 'textarea', 'a'].include? el.tag_name
12
- }
13
- offenders.each do |el|
14
- errors << "tabindex=\"0\" must not be used on <#{el.tag_name}> " +
15
- "elements (not focusable by default)"
16
- end
17
- end
18
-
19
- end
20
- end
21
- end
22
- end
@@ -1,31 +0,0 @@
1
- module BBC
2
- module A11y
3
- module Standards
4
- class TitleAttribute
5
- def initialize(page)
6
- @page = page
7
- end
8
-
9
- def call(errors)
10
- @page.all("[title]").each do |element|
11
- unless form_input? element
12
- errors << "Element (not a form input) has a title " +
13
- "attribute: #{element.path}"
14
- end
15
- end
16
- end
17
-
18
- private
19
-
20
- def form_input?(element)
21
- form_input_tags.include? element.tag_name.downcase
22
- end
23
-
24
- def form_input_tags
25
- ['input', 'button', 'select', 'textarea']
26
- end
27
-
28
- end
29
- end
30
- end
31
- end
@@ -1,24 +0,0 @@
1
- # The core purpose of every document must be defined
2
-
3
- Before design and implementation of a document or feature its core purpose **must** be defined.
4
-
5
- ## Definitions
6
-
7
- ### Core purpose
8
-
9
- The functionality to inform, educate, and entertain without which there would be no purpose for site or document.
10
-
11
- ## Rationale
12
-
13
- While our aim is for all users to have access to all features of BBC apps and sites we recognise that technology both restricts and extends what is possible.
14
-
15
- Additionally GEL is aimed providing the best experience to the broadest range of users, and while it should not discriminate against users with access needs nor does it give special privilege.
16
-
17
- The aim of this guideline is to provide the most accessible base line experience for the core purpose across the broadest range of technology.
18
-
19
- See the following standards for examples of when a defined core purpose is applicable:
20
-
21
- - [Core experience must not rely on JavaScript or CSS]()
22
- - [Minimum text size]()
23
-
24
- It is **not** a reason to ignore accessibility for non-core page elements.
@@ -1,31 +0,0 @@
1
- Feature: HTML Validation
2
-
3
- All documents **must** have a [W3C recommended Doctype](http://www.w3.org/QA/2002/04/valid-dtd-list.html) and
4
- all Markup **must** validate against that Doctype.
5
-
6
- Rationale
7
- =========
8
-
9
- While assistive technologies such as screen readers generally do a good job of interpreting
10
- invalid HTML there will be less risk of problems arising if the document follows a recognised
11
- standard Doctype.
12
-
13
- Techniques
14
- ==========
15
-
16
- Pass:
17
-
18
- <!DOCTYPE html>
19
- <html lang="en-GB">
20
-
21
- Fail:
22
-
23
- <html lang="en-GB">
24
-
25
-
26
- Scenario: Submit to W3C validation Service
27
-
28
- See http://validator.w3.org
29
-
30
- When I submit the page to the W3C Markup Validation Service
31
- Then there should be no errors
@@ -1,40 +0,0 @@
1
- Feature: JavaScript
2
-
3
- Core experience must not rely on JavaScript
4
-
5
- The core purpose of every document **must** be defined.
6
-
7
- The core content of every document must not require JavaScript to be added to the DOM
8
-
9
- Rationale
10
- =========
11
-
12
- We aim to provide a core experience to as broad an audience as possible, allowing
13
- users to choose the software and devices that work best for them in a broad range of circumstances.
14
-
15
- Equally a robust site or application in the more traditional sense minimises its dependencies.
16
- The minimum dependency for a web site should be an internet connection and the ability to parse HTML.
17
-
18
- For this reason all BBC documents must enable their core purpose without relying on CSS or JavaScript.
19
-
20
- CSS and JavaScript can, and should, be used to enhance the user experience beyond this basic level.
21
- For example, a ‘live’ page has a core purpose to provide the latest content about an event to the user.
22
- The core experience is the latest content at the time of the request. The experience enhanced with
23
- JavaScript automatically updates this content without the user having to take action.
24
-
25
- Definitions
26
- ===========
27
-
28
- *Core content* - The content that is provided to users without JavaScript.
29
-
30
- Notes
31
- =====
32
-
33
- This is going to have to be a product specific test. Can we provide a template for this test,
34
- perhaps looking for elements based on provided selectors and make sure they are in the document?
35
-
36
- @manual
37
- Scenario: View the page with JavaScript disabled
38
- When I view the page with JavaScript disabled
39
- Then all core content is available in the DOM
40
-
@@ -1,58 +0,0 @@
1
- Feature: Specify content language
2
-
3
- The main language of the page _must_ be specified.
4
-
5
- Changes to language within the page **must** be indicated.
6
-
7
- Rationale
8
- =========
9
-
10
- Assistive technologies such as screen readers have support for different languages,
11
- allowing for appropriate pronunciation.
12
-
13
- Techniques
14
- ==========
15
-
16
- Pass:
17
-
18
- ```
19
- <!DOCTYPE html>
20
- <html lang="en-GB">
21
- <head>
22
- <title>Language techniques</title>
23
- </head>
24
- <body>
25
- <h1>Techniques for language in HTML</h1>
26
- <p><span lang="es">Cinco de Mayo</span> is Spanish for "fifth of May"</p>
27
- </body>
28
- </html>
29
- ```
30
-
31
- Fail:
32
-
33
- ```
34
- <!DOCTYPE html>
35
- <html>
36
- <head>
37
- <title>Language techniques</title>
38
- </head>
39
- <body>
40
- <h1>Techniques for language in HTML</h1>
41
- <p>Cinco de Mayo is Spanish for "fifth of May"</p>
42
- </body>
43
- </html>
44
- ```
45
-
46
- Scenario: Check main body element lang attribute
47
- When I visit the page
48
- Then the <html> element must have a `lang` attribute
49
- And the main natural language of the page must match that attribute
50
-
51
- Scenario: Check for other elements with lang attributes
52
- When I visit the page
53
- Then all elements with `lang` attribute must have content in that natural language
54
-
55
- @manual
56
- Scenario: Check for areas of the page expressed in other languages, but missing a `lang` attribute
57
- When I visit the page
58
- Then any parts expressed in a natural language different to the main language of the page must have a matching `lang` attribute
@@ -1,45 +0,0 @@
1
- Feature: Page title
2
-
3
- A document **must** have a unique page `<title>` that identifies its main content.
4
-
5
- Rationale
6
- =========
7
-
8
- Document titles help users orientate themselves within web sites and apps. The document `<title>` element
9
- content is often the first thing a speech output user will hear and acts as a confirmation of what page they
10
- have arrived at. Document titles commonly have the same content as the main `<h1>` element.
11
-
12
- Techniques
13
- ==========
14
-
15
- Pass:
16
-
17
- <title>BBC Weather</title>
18
-
19
- Fail:
20
-
21
- <title>BBC</title>
22
-
23
- @manual
24
- Scenario: Check the title
25
-
26
- We can't easily test for the uniqueness of the title, but we can test for the presence of the element
27
- and ensure it has content.
28
-
29
- In terms of prompting for manual tests, could we compare the title element with the content of the first
30
- `<h1>` element on the page, and if the former contains the latter then automatically pass the test.
31
-
32
- For example:
33
-
34
- <title>BBC Weather - Weather in London</title>
35
-
36
- ~
37
-
38
- <h1>Weather in London</h1>
39
-
40
- ...would pass automatically, but a `<title>` element that does not contain the string 'Weather in London'
41
- would be flagged for manual review.
42
-
43
- When I visit the page
44
- Then the document should have a title
45
- And the title should describe the primary content of the document
@@ -1,24 +0,0 @@
1
- Feature: Main landmark
2
-
3
- A page **must** have exactly one element with `role="main"`
4
-
5
- Rationale
6
- =========
7
-
8
- The WAI-ARIA `main` landmark role can be help keyboard users with assistive technologies such as screen readers (and in the future as native browser functionality) to skip directly to the main content of a page, bypassing navigation and other contents that might be before it.
9
-
10
- Techniques
11
- ==========
12
-
13
- Pass:
14
-
15
- <div role="main" id="main-content"></div>
16
-
17
- Fail:
18
-
19
- <div id="main-content"></div>
20
-
21
- Scenario: Check for a single main element
22
- When I visit the page
23
- Then there should be exactly one element with `role="main"`
24
-
@@ -1,65 +0,0 @@
1
- Feature: Correctly use 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
- Techniques
22
- ==========
23
-
24
- Pass:
25
-
26
- <div role="main">
27
- <h1>Main page content</h1>
28
- <p>Lorem ipsum…</p>
29
- <h2>Secondary content</h2>
30
- <h3>Tertiary content one</h2>
31
- <ul>
32
- <li>Lorem</li>
33
- </ul>
34
- <h3>Tertiary content two</h3>
35
- <ul>
36
- <li>Ipsum</li>
37
- </ul>
38
- </div>
39
-
40
- Fail:
41
-
42
- <div role="main">
43
- <h3>Main content</h3>
44
- <h2>Secondary content</h2>
45
- <h2>Tertiary content</h2>
46
- <p>Lorem ipsum…</p>
47
- </div>
48
-
49
- Notes
50
- =====
51
-
52
- For the second test, can we check the next text node after each heading and test that it is
53
- either not part of a heading element, or is part of a heading level of one level higher?
54
-
55
- Questions
56
- =========
57
-
58
- 1. Clarify the note, above!
59
- 2. Presumably it's OK for the hierarchy to jump *up* by more than 1? e.g. h1, h2, h3, h4, h2 is ok?
60
-
61
- Scenario: Check headings
62
- When I visit the page
63
- Then there must be exactly one h1 element
64
- And each heading must be followed by content or a heading of one level deeper (h2-h6)
65
-