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.
- checksums.yaml +4 -4
- data/.travis.yml +9 -0
- data/CONTRIBUTING.md +70 -8
- data/GETTINGSTARTED.md +65 -0
- data/LICENSE +1 -1
- data/README.md +12 -55
- data/Rakefile +1 -1
- data/a11y.rb +1 -3
- data/bbc-a11y.gemspec +0 -1
- data/features/check_standards/01_core_purpose.feature +39 -0
- data/features/check_standards/02_validation.feature +1 -0
- data/features/check_standards/03_progressive_enhancement.feature +3 -0
- data/features/check_standards/{language.feature → 04_indicating_language.feature} +2 -2
- data/features/check_standards/05_page_titles.feature +1 -0
- data/features/check_standards/{main_landmark.feature → 06_main_landmark.feature} +6 -6
- data/features/check_standards/07_headings.feature +222 -0
- data/features/check_standards/{minimum_text_size.feature → 08_minimum_text_size.feature} +22 -2
- data/features/check_standards/09_resizable_text.feature +2 -0
- data/features/check_standards/{tab_index.feature → 10_tab_index.feature} +7 -7
- data/features/check_standards/{title_attribute.feature → 11_title_attributes.feature} +13 -5
- data/features/check_standards/{focusable_controls.feature → 12_focusable_controls.feature} +4 -4
- data/features/check_standards/13_visible_on_focus.feature +1 -0
- data/features/check_standards/14_control_styles.feature +1 -0
- data/features/check_standards/15_focus_styles.feature +1 -0
- data/features/check_standards/16_colour_contrast.feature +1 -0
- data/features/check_standards/17_colour_and_meaning.feature +1 -0
- data/features/check_standards/{image_alt.feature → 18_image_alternatives.feature} +5 -5
- data/features/check_standards/{form_labels.feature → 19_form_labels.feature} +7 -7
- data/features/check_standards/{form_interactions.feature → 20_form_interactions.feature} +6 -6
- data/features/check_standards/21_tables.feature +1 -0
- data/features/cli/display_failing_result.feature +14 -1
- data/features/cli/display_result_summary.feature +15 -1
- data/features/cli/provide_muting_tips.feature +1 -1
- data/features/cli/skipping_standards.feature +1 -1
- data/features/mute_errors.feature +2 -2
- data/features/step_definitions/steps.rb +10 -9
- data/features/support/web_server.rb +0 -11
- data/features/support/web_server/blank.html +7 -0
- data/features/support/web_server/two_headings_failures.html +11 -0
- data/karma.conf.js +1 -1
- data/lib/bbc/a11y/cli.rb +33 -6
- data/lib/bbc/a11y/js/bundle.js +139 -89
- data/lib/bbc/a11y/js/standards.js +67 -20
- data/lib/bbc/a11y/js/standards/{anchorsMustHaveHrefs.js → focusableControls/anchorsMustHaveHrefs.js} +0 -0
- data/lib/bbc/a11y/js/standards/{formsMustHaveSubmitButtons.js → formInteractions/formsMustHaveSubmitButtons.js} +0 -0
- data/lib/bbc/a11y/js/standards/{fieldsMustHaveLabelsOrTitles.js → formLabels/fieldsMustHaveLabelsOrTitles.js} +0 -0
- data/lib/bbc/a11y/js/standards/headings/contentMustFollowHeadings.js +18 -0
- data/lib/bbc/a11y/js/standards/{exactlyOneMainHeading.js → headings/exactlyOneMainHeading.js} +1 -1
- data/lib/bbc/a11y/js/standards/{headingsMustBeInAscendingOrder.js → headings/headingsMustBeInAscendingOrder.js} +0 -0
- data/lib/bbc/a11y/js/standards/{imagesMustHaveAltAttributes.js → imageAlternatives/imagesMustHaveAltAttributes.js} +0 -0
- data/lib/bbc/a11y/js/standards/{htmlMustHaveLangAttribute.js → indicatingLanguage/htmlMustHaveLangAttribute.js} +0 -0
- data/lib/bbc/a11y/js/standards/{exactlyOneMainLandmark.js → mainLandmark/exactlyOneMainLandmark.js} +0 -0
- data/lib/bbc/a11y/js/standards/{minimumTextSize.js → minimumTextSize/textCannotBeTooSmall.js} +3 -3
- data/lib/bbc/a11y/js/standards/{elementsWithZeroTabIndexMustBeFields.js → tabIndex/elementsWithZeroTabIndexMustBeFields.js} +0 -0
- data/lib/bbc/a11y/js/standards/{titleAttributesOnlyOnInputs.js → titleAttributes/titleAttributesOnlyOnInputs.js} +1 -1
- data/lib/bbc/a11y/linter.rb +16 -4
- data/lib/bbc/a11y/runner.rb +0 -1
- data/lib/bbc/a11y/string_colours.rb +15 -0
- data/lib/bbc/a11y/version +1 -1
- data/package.json +3 -0
- data/spec/bbc/a11y/js/a11ySpec.js +15 -6
- data/spec/bbc/a11y/js/minimumTextSizeStandardSpec.js +25 -0
- data/spec/bbc/a11y/js/standardsSpec.js +6 -6
- data/spec/bbc/a11y/string_colours_spec.rb +13 -0
- metadata +68 -102
- data/circle.yml +0 -3
- data/examples/bbc-pages/Gemfile +0 -3
- data/examples/bbc-pages/Rakefile +0 -3
- data/examples/bbc-pages/a11y.rb +0 -2
- data/examples/local-web-app/Gemfile +0 -4
- data/examples/local-web-app/Rakefile +0 -3
- data/examples/local-web-app/a11y.rb +0 -52
- data/examples/local-web-app/config.ru +0 -1
- data/examples/local-web-app/public/missing_header.html +0 -13
- data/examples/local-web-app/public/perfect.html +0 -14
- data/examples/local-web-app/readme.md +0 -0
- data/features/check_standards/headings.feature +0 -153
- data/lib/bbc/a11y/js/standards/contentMustFollowHeadings.js +0 -15
- data/lib/bbc/a11y/standards.rb +0 -45
- data/lib/bbc/a11y/standards/anchor_hrefs.rb +0 -18
- data/lib/bbc/a11y/standards/content_follows_headings.rb +0 -22
- data/lib/bbc/a11y/standards/exactly_one_main_heading.rb +0 -25
- data/lib/bbc/a11y/standards/exactly_one_main_landmark.rb +0 -20
- data/lib/bbc/a11y/standards/form_labels.rb +0 -39
- data/lib/bbc/a11y/standards/form_submit_buttons.rb +0 -21
- data/lib/bbc/a11y/standards/heading_hierarchy.rb +0 -34
- data/lib/bbc/a11y/standards/image_alt.rb +0 -18
- data/lib/bbc/a11y/standards/language_attribute.rb +0 -19
- data/lib/bbc/a11y/standards/tab_index.rb +0 -22
- data/lib/bbc/a11y/standards/title_attribute.rb +0 -31
- data/standards/01_core-purpose.md +0 -24
- data/standards/02_validation.feature +0 -31
- data/standards/03_javascript.feature +0 -40
- data/standards/04_language.feature +0 -58
- data/standards/05_page_title.feature +0 -45
- data/standards/06_main_landmark.feature +0 -24
- data/standards/07_headings.feature +0 -65
- data/standards/08_title_attribute.feature +0 -71
- data/standards/09_tabindex.feature +0 -51
- data/standards/10_form_labels.feature +0 -88
- data/standards/11_visible-on-focus.md +0 -58
- data/standards/13_colour-contrast.md +0 -27
- data/standards/14_colour-meaning.md +0 -19
- data/standards/15_focusable-controls.md +0 -45
- data/standards/16_table.md +0 -109
- data/standards/17_control-styles.md +0 -78
- data/standards/18_focus-styles.md +0 -36
- data/standards/19_form-interactions.md +0 -33
- data/standards/20_image-alt.md +0 -34
- data/standards/21_min-font-sizes.md +0 -64
- data/standards/22_resize-zoom.md +0 -80
- data/standards/step_definitions/core_content_steps.rb +0 -3
- data/standards/step_definitions/form_steps.rb +0 -6
- data/standards/step_definitions/language_steps.rb +0 -21
- data/standards/step_definitions/page_steps.rb +0 -50
- data/standards/step_definitions/w3c_steps.rb +0 -7
- data/standards/support/capybara.rb +0 -53
- data/standards/support/skipper.rb +0 -5
- data/standards/support/world.rb +0 -3
- 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
|
-
|