bbc-a11y 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/CONTRIBUTING.md +19 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +54 -0
- data/Rakefile +12 -0
- data/bbc-a11y.gemspec +32 -0
- data/bin/a11y +5 -0
- data/example/.a11y.rb +64 -0
- data/example/Gemfile +4 -0
- data/example/Rakefile +3 -0
- data/example/config.ru +1 -0
- data/example/public/missing_header.html +13 -0
- data/example/public/perfect.html +14 -0
- data/example/readme.md +0 -0
- data/features/01_core-purpose.md +24 -0
- data/features/02_validation.feature +31 -0
- data/features/03_javascript.feature +40 -0
- data/features/04_language.feature +58 -0
- data/features/05_page_title.feature +45 -0
- data/features/06_main_landmark.feature +24 -0
- data/features/07_headings.feature +65 -0
- data/features/08_title_attribute.feature +71 -0
- data/features/09_tabindex.feature +38 -0
- data/features/10_form-labels.md +47 -0
- data/features/11_visible-on-focus.md +58 -0
- data/features/13_colour-contrast.md +27 -0
- data/features/14_colour-meaning.md +19 -0
- data/features/15_focusable-controls.md +45 -0
- data/features/16_table.md +109 -0
- data/features/17_control-styles.md +78 -0
- data/features/18_focus-styles.md +36 -0
- data/features/19_form-interactions.md +33 -0
- data/features/20_image-alt.md +34 -0
- data/features/21_min-font-sizes.md +64 -0
- data/features/22_resize-zoom.md +80 -0
- data/features/step_definitions/core_content_steps.rb +3 -0
- data/features/step_definitions/language_steps.rb +21 -0
- data/features/step_definitions/page_steps.rb +46 -0
- data/features/step_definitions/w3c_steps.rb +7 -0
- data/features/support/capybara.rb +38 -0
- data/features/support/skipper.rb +5 -0
- data/features/support/world.rb +3 -0
- data/features/support/world_extender.rb +5 -0
- data/lib/bbc/a11y/cli.rb +49 -0
- data/lib/bbc/a11y/configuration.rb +83 -0
- data/lib/bbc/a11y/cucumber_runner.rb +133 -0
- data/lib/bbc/a11y/cucumber_support/heading_hierarchy.rb +92 -0
- data/lib/bbc/a11y/cucumber_support/language_detector.rb +26 -0
- data/lib/bbc/a11y/cucumber_support/page.rb +81 -0
- data/lib/bbc/a11y/cucumber_support/per_page_checks.rb +28 -0
- data/lib/bbc/a11y/cucumber_support/w3c.rb +36 -0
- data/lib/bbc/a11y/cucumber_support.rb +49 -0
- data/lib/bbc/a11y/version +1 -0
- data/lib/bbc/a11y.rb +4 -0
- data/spec/bbc/a11y/cucumber_support/heading_hierarchy_spec.rb +123 -0
- data/spec/bbc/a11y/cucumber_support/page_spec.rb +130 -0
- metadata +274 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5bde1a661b1feea57cf80e9d0133ae553ca7297e
|
4
|
+
data.tar.gz: e4e4f896df1d9edff57dc0dbd1542b511f6c21e4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4b8a9d07f2f9622b08fd5f546010f0b2ca8a17f886bacedfba5f79f92a6067ffef8c2ca245d8fb7bd1d6d11ddc9d5d14b9475b6fa534dac55d5b17c12d4c675b
|
7
|
+
data.tar.gz: e0a91c494c3b23b79f83a8f54339823a72f3756334b9b837b6e703e443d1614e6dde93c1ca7ad1e010fad7ff1be51390a2baecb2bad2287457e4c702c746e3ff
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# BBC A11y Contributing guidelines
|
2
|
+
|
3
|
+
The standards are all stored in the `features` directory.
|
4
|
+
|
5
|
+
You can run a manual test of your development copy of a11y at any time just by running:
|
6
|
+
|
7
|
+
bundle exec ./bin/a11y <url>
|
8
|
+
|
9
|
+
You can also pick out a specific feature to run:
|
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
|
16
|
+
|
17
|
+
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
|
+
|
19
|
+
To add new behaviour, test-drive changes to the objects in `lib`.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 British Broadcasting Corporation
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# BBC Accessiblity Standards
|
2
|
+
|
3
|
+
This tool runs a set of tests against a given URL to verify whether it meets the BBC accessibility standards.
|
4
|
+
|
5
|
+
## How to use
|
6
|
+
|
7
|
+
Run the `a11y` command, passing a URL:
|
8
|
+
|
9
|
+
e.g.
|
10
|
+
|
11
|
+
a11y http://bbc.co.uk
|
12
|
+
|
13
|
+
You can also pass arguments to Cucumber (which is used internally) by separating the arguments with `--`. Everything
|
14
|
+
after the `--` is passed directly to Cucumber. For example, to skip the tests that require manual interraction:
|
15
|
+
|
16
|
+
a11y http://bbc.co.uk -- -t ~@manual
|
17
|
+
|
18
|
+
## How to install
|
19
|
+
|
20
|
+
A11y is packaged as a Ruby gem, but is not yet available on the public Rubygems server. To install it, you'll need to either build it by hand, or add a reference to the github source in your Gemfile.
|
21
|
+
|
22
|
+
### Prerequisites
|
23
|
+
|
24
|
+
Install Ruby and `gem install bundler`.
|
25
|
+
|
26
|
+
### Adding a11y to your project's Gemfile
|
27
|
+
|
28
|
+
Open your project's `Gemfile` and this line:
|
29
|
+
|
30
|
+
gem 'bbc-a11y`, git: 'git@github.com:mattwynne/bbc-a11y.git'
|
31
|
+
|
32
|
+
Now install the gem:
|
33
|
+
|
34
|
+
bundle install --binstubs
|
35
|
+
|
36
|
+
*Note:* You'll need to make sure every user who wants to run `bundle install` (including your continuous integration environment) has at least read access to this Github project.
|
37
|
+
|
38
|
+
### Build and install the gem manually
|
39
|
+
|
40
|
+
This will install the `a11y` tool globally on your machine.
|
41
|
+
|
42
|
+
1. Clone this repository
|
43
|
+
2. Install dependencies
|
44
|
+
|
45
|
+
~~~
|
46
|
+
cd bbc-a11y
|
47
|
+
bundle install
|
48
|
+
~~~
|
49
|
+
|
50
|
+
3. Install the gem
|
51
|
+
|
52
|
+
~~~
|
53
|
+
bundle exec rake install
|
54
|
+
~~~
|
data/Rakefile
ADDED
data/bbc-a11y.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'bbc-a11y'
|
6
|
+
s.version = File.read(File.expand_path("../lib/bbc/a11y/version", __FILE__))
|
7
|
+
s.authors = ["Matt Wynne", "Ian Pouncey"]
|
8
|
+
s.description = "A tool for testing the compliance of web URLs against the BBC's accessibilty guidelines"
|
9
|
+
s.summary = "bbc-a11y-#{s.version}"
|
10
|
+
s.email = "github@ipouncey.co.uk"
|
11
|
+
s.homepage = "https://cucumber.pro"
|
12
|
+
s.platform = Gem::Platform::RUBY
|
13
|
+
s.license = "MIT"
|
14
|
+
s.required_ruby_version = ">= 1.9.3"
|
15
|
+
|
16
|
+
s.add_dependency 'cucumber', '~> 2.0.0.rc'
|
17
|
+
s.add_dependency 'rspec', '~> 3.0'
|
18
|
+
s.add_dependency 'capybara'
|
19
|
+
s.add_dependency 'selenium-webdriver'
|
20
|
+
s.add_dependency 'w3c_validators'
|
21
|
+
s.add_dependency 'cld'
|
22
|
+
s.add_dependency 'colorize'
|
23
|
+
s.add_development_dependency 'aruba'
|
24
|
+
s.add_development_dependency 'pry'
|
25
|
+
s.add_development_dependency 'rake'
|
26
|
+
|
27
|
+
s.rubygems_version = ">= 1.6.1"
|
28
|
+
s.files = `git ls-files`.split("\n").reject {|path| path =~ /\.gitignore$/ }
|
29
|
+
s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_path = "lib"
|
32
|
+
end
|
data/bin/a11y
ADDED
data/example/.a11y.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
class Server
|
2
|
+
attr_reader :port
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@pid = nil
|
6
|
+
@port = find_available_port
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
@pid = fork { `rackup -p #{port} -q` }
|
11
|
+
@pid = @pid + 1 # because rackup starts a child process
|
12
|
+
sleep(0.1) until responsive?
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
return unless @pid
|
17
|
+
Process.kill("SIGKILL", @pid)
|
18
|
+
Process.wait(@pid)
|
19
|
+
rescue Errno::ECHILD
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def find_available_port
|
25
|
+
server = TCPServer.new('127.0.0.1', 0)
|
26
|
+
server.addr[1]
|
27
|
+
ensure
|
28
|
+
server.close if server
|
29
|
+
end
|
30
|
+
|
31
|
+
def responsive?
|
32
|
+
Net::HTTP.start('localhost', port) { |http| http.get("/perfect.html") }.is_a?(Net::HTTPSuccess)
|
33
|
+
rescue SystemCallError
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
server = Server.new
|
39
|
+
|
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
|
53
|
+
|
54
|
+
page "http://localhost:#{server.port}/missing_header.html" do
|
55
|
+
skip_scenario "W3C"
|
56
|
+
skip_scenario "Check headings"
|
57
|
+
|
58
|
+
customize_world do
|
59
|
+
def Xassert_title_describes_primary_content_of_document(title, doc)
|
60
|
+
puts "TODO"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/example/Gemfile
ADDED
data/example/Rakefile
ADDED
data/example/config.ru
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
run Rack::Directory.new("public")
|
@@ -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/example/readme.md
ADDED
File without changes
|
@@ -0,0 +1,24 @@
|
|
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.
|
@@ -0,0 +1,31 @@
|
|
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
|
@@ -0,0 +1,40 @@
|
|
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
|
+
|
@@ -0,0 +1,58 @@
|
|
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
|
@@ -0,0 +1,45 @@
|
|
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
|
@@ -0,0 +1,24 @@
|
|
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
|
+
|
@@ -0,0 +1,65 @@
|
|
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
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Feature: Correctly use `title` attributes
|
2
|
+
|
3
|
+
`title` attributes **must not** be used for critical information and **must not** repeat content that is already visible and associated with the same control or content.
|
4
|
+
|
5
|
+
Rationale
|
6
|
+
=========
|
7
|
+
|
8
|
+
`title` attributes are inaccessible to keyboard users without additional Assistive Technology. They are dependent on user settings in Screen Readers and similar Assistive Technology.
|
9
|
+
|
10
|
+
Additionally they suffer from discoverability problems: pointing device users are required to hover over page elements and pause before the title tooltip displays, usually with no indication that there is additional content to be displayed.
|
11
|
+
|
12
|
+
Repeating content in visible text and `title` attributes can lead to content clutter and repeated phrases.
|
13
|
+
|
14
|
+
Key recommendations are:
|
15
|
+
|
16
|
+
- Do not use the `title` attribute unless on a form input as title text is not well supported on links on mobile
|
17
|
+
- Do not use `title` attributes and explicit labels together on form fields
|
18
|
+
|
19
|
+
Techniques
|
20
|
+
==========
|
21
|
+
|
22
|
+
Pass:
|
23
|
+
|
24
|
+
<label for="name">Name</label>
|
25
|
+
<input type="text" id="name" name="name" />
|
26
|
+
<label for="email">Email</label>
|
27
|
+
|
28
|
+
<input type="text" id="email" name="email" />
|
29
|
+
|
30
|
+
<button type="button"><img src="/path/to/image/close.png" alt="Close" /></button>
|
31
|
+
|
32
|
+
Fail:
|
33
|
+
|
34
|
+
<input type="text" name="name" title="Name" />
|
35
|
+
<input type="text" name="email" title="Email" />
|
36
|
+
|
37
|
+
<label for="name">Name</label>
|
38
|
+
<input type="text" id="name" name="name" title="Name" />
|
39
|
+
|
40
|
+
<button type="button" title="Close"></button>
|
41
|
+
|
42
|
+
<a href="/news" title="News">News</a>
|
43
|
+
|
44
|
+
Tests
|
45
|
+
=====
|
46
|
+
|
47
|
+
| Procedure | Expected Result | Type |
|
48
|
+
| --------- | --------------- | ---- |
|
49
|
+
| Search source for all uses of the `title` attribute | Ensure no instances contain content that would be required by all users or content that is repeated in associated content | Manual |
|
50
|
+
| Search source for all uses of the `title` attribute | Ensure no instances contain content that is repeated within the element | Automated |
|
51
|
+
| Search source for all '<label>' elements and their associated form fields | Ensure that the associated form field does not have a title attribute | Automated |
|
52
|
+
|
53
|
+
--
|
54
|
+
|
55
|
+
Notes
|
56
|
+
=====
|
57
|
+
|
58
|
+
The first test is non-automatable, and may well have to be removed as it is too ambiguous.
|
59
|
+
|
60
|
+
Scenario: Check the elements with title attributes
|
61
|
+
|
62
|
+
Examples of failure:
|
63
|
+
|
64
|
+
<label for="name">Name</label>
|
65
|
+
<input type="text" id="name" name="name" title="Name" />
|
66
|
+
|
67
|
+
<a href="/news" title="News">News</a>
|
68
|
+
|
69
|
+
When I visit the page
|
70
|
+
Then there must be no elements with a title attribute whose content is repeated within the element
|
71
|
+
And any form fields with associated labels do not have a title attribute
|