From Code to Compliance: Accessibility Testing in Rails Applications
In a previous blog post, How Do You Know When Your App is Not Compliant? , I briefly discussed the importance of the accessibility standards of Web Content Accessibility Guidelines or WCAG , to ensure that everyone, including those with disabilities, can use web applications effectively. In this blog, we are going to further explore the importance of maintaining accessibility compliance, what it means to users, as well as how to use the axe-core-gems for automated accessibility testing to help identify and resolve any gaps that may be currently present in a project.
Accessibility Compliance
The WCAG is a set of recommendations that act as a guideline to help make software more accessible and address the needs of users with ranging disabilities.
Following these guidelines will make content more accessible to a wider range of people with disabilities, including accommodations for blindness and low vision, deafness and hearing loss, limited movement, speech disabilities, photosensitivity, and combinations of these, and some accommodation for learning disabilities and cognitive limitations; but will not address every user need for people with these disabilities.
The foundation and success criteria for accessibility compliance is defined by a set of 4 principles
- Perceivable: This is to ensure that all information as well as user interface components are sensitive and visible to all of the end users senses.
- Operable: This means that all parts of the web content and application are easily operable and address the different needs of their users while interacting with the web application.
- Understandable: The goal here is to make sure that websites operate and share information in ways that users are able to understand and navigate efficiently.
- Robust: It is important to make sure that content creation is robust enough to be interpreted in a reliable way by a wide variety of user agents, including assistive technologies.
So why is accessibility compliance important?
- There are now legal requirements and standards, for example, the Americans with Disabilities Act (ADA) in the U.S., that aims to help protect people with disabilities from discrimination and mandate accessibility for digital content.
- Being compliant with the accessibility guidelines means that your web content is more inclusive while promoting a positive user experience and can help your website reach a larger audience.
Axe-core-gems
axe-core
is an open-source project by Deque Systems that can help provide checks for web accessibility violations currently present in a project, and help any team identify areas that should be addressed to ensure that the application is compliant with standards such as WCAG.
The project repository contains 6 gems:
Getting Started
To get started, determine and configure a webdriver the application will use along with a test framework and choose the 2 respective gems listed above.
For our FastRuby.io
application, we use both RSpec
and Capybara
.
The following gems will be added to the Gemfile
:
# Gemfile
group :test do
gem 'axe-core-rspec'
gem 'axe-core-capybara'
end
Run bundle
to install the gems.
Add the following library to the rails_helper
or spec_helper
file:
# rails_helper.rb
require 'axe-rspec'
This will extend RSpec with the custom matcher BeAxeClean
.
To test this out, I added a new feature test for our home page that will use the be_axe_clean
matcher with the goal to test that our home page is accessible and identify any current violations:
# spec/features/home_page_spec.rb
require "rails_helper"
RSpec.describe "HomePage", js: true do
context "when accessing home page" do
it 'has no accessibility violations' do
visit "/"
expect(page).to be_axe_clean
end
end
end
Running the test produces the following output:
Failures:
1) HomePage when accessing home page has no accessibility violations
Failure/Error: expect(page).to be_axe_clean
Found 4 accessibility violations:
1) aria-prohibited-attr: Elements must only use permitted ARIA attributes (serious)
https://dequeuniversity.com/rules/axe/4.9/aria-prohibited-attr?application=axeAPI
The following 1 node violate this rule:
Selector: #map
HTML: <picture id="map" aria-label="Map of our office in Philadelphia (by Google Maps)">
Fix all of the following:
- aria-label attribute cannot be used on a picture with no valid role attribute.
2) color-contrast: Elements must meet minimum color contrast ratio thresholds (serious)
https://dequeuniversity.com/rules/axe/4.9/color-contrast?application=axeAPI
The following 4 nodes violate this rule:
Selector: .scrollto[href$="#contactus"][role="button"]
HTML: <a role="button" class="btn scrollto" href="#contactus">We should talk!</a>
Fix any of the following:
- Element has insufficient color contrast of 1.92 (foreground color: #f8f8f8, background color: #00d242, font size: 12.0pt (16px), font weight: bold). Expected contrast ratio of 4.5:1
Selector: .submit
HTML: <input type="submit" name="commit" value="SEND MESSAGE" class="btn submit" data-disable-with="SEND MESSAGE">
Fix any of the following:
- Element has insufficient color contrast of 1.92 (foreground color: #f8f8f8, background color: #00d242, font size: 12.0pt (16px), font weight: bold). Expected contrast ratio of 4.5:1
Selector: a[href="https://g.page/OmbuLabs?share"]
HTML: <a href="https://g.page/OmbuLabs?share" target="_blank" class="btn">Get directions</a>
Fix any of the following:
- Element has insufficient color contrast of 1.92 (foreground color: #f8f8f8, background color: #00d242, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1
Selector: .btn-newsletter
HTML: <a class="btn btn-newsletter" href="/newsletter#newsletter-form">Newsletter</a>
Fix any of the following:
- Element has insufficient color contrast of 1.92 (foreground color: #f8f8f8, background color: #00d242, font size: 12.0pt (16px), font weight: bold). Expected contrast ratio of 4.5:1
3) heading-order: Heading levels should only increase by one (moderate)
https://dequeuniversity.com/rules/axe/4.9/heading-order?application=axeAPI
The following 1 node violate this rule:
Selector: h5
HTML: <h5>Our Office</h5>
Fix any of the following:
- Heading order invalid
4) image-alt: Images must have alternate text (critical)
https://dequeuniversity.com/rules/axe/4.9/image-alt?application=axeAPI
The following 1 node violate this rule:
Selector: #map > img[loading="lazy"]
HTML: <img loading="lazy" src="/assets/map-l-5a5b70d81baf3f49d809329aeea17d4234bf0592f5b733414f126377940f9548.png">
Fix any of the following:
- Element does not have an alt attribute
- aria-label attribute does not exist or is empty
- aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
- Element has no title attribute
- Element's default semantics were not overridden with role="none" or role="presentation"
Invocation: axe.run({:exclude=>[]}, {}, callback);
# ./spec/features/home_page_spec.rb:8:in `block (3 levels) in <top (required)>'
Finished in 4.79 seconds (files took 4.98 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/features/home_page_spec.rb:5 # HomePage when accessing home page has no accessibility violations
This is good information that will help our team lay out a plan to make this web page more accessible and we can use these tests to identify any other areas that could use improvement in our application.
Getting specific
We can also use clauses allowed with the be_axe_clean
matcher to get more granular with the areas of a web page that should be tested. There are several clauses that can be included in the test such as:
within
- This is an inclusion clause that will require a valid CSS selector as an argument to target a specific element on a page. It also accepts an array of selectors, or a hash describing iframes with selectors:
context "when accessing the map on the home page" do
it 'has no accessibility violations' do
visit "/"
expect(page).to be_axe_clean.within "#map"
end
end
Will produce:
Failures:
1) HomePage when accessing the map on the home page has no accessibility violations
Failure/Error: expect(page).to be_axe_clean.within "#map"
Found 2 accessibility violations:
1) aria-prohibited-attr: Elements must only use permitted ARIA attributes (serious)
https://dequeuniversity.com/rules/axe/4.9/aria-prohibited-attr?application=axeAPI
The following 1 node violate this rule:
Selector: #map
HTML: <picture id="map" aria-label="Map of our office in Philadelphia (by Google Maps)">
Fix all of the following:
- aria-label attribute cannot be used on a picture with no valid role attribute.
2) image-alt: Images must have alternate text (critical)
https://dequeuniversity.com/rules/axe/4.9/image-alt?application=axeAPI
The following 1 node violate this rule:
Selector: #map > img[loading="lazy"]
HTML: <img loading="lazy" src="/assets/map-l-5a5b70d81baf3f49d809329aeea17d4234bf0592f5b733414f126377940f9548.png">
Fix any of the following:
- Element does not have an alt attribute
- aria-label attribute does not exist or is empty
- aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
- Element has no title attribute
- Element's default semantics were not overridden with role="none" or role="presentation"
Invocation: axe.run({"include"=>[["#map"]]}, {}, callback);
# ./spec/features/home_page_spec.rb:8:in `block (3 levels) in <top (required)>'
Finished in 3.51 seconds (files took 4.74 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/features/home_page_spec.rb:5 # HomePage when accessing the map on the home page has no accessibility violations
according_to
- This is a tag clause that can target a specific accessibility standard to test against. Argument options can be a single tag or an array of tags.
expect(page).to be_axe_clean.according_to :wcag2a
There are many other clauses that can be used in combination with the be_axe_clean
matcher to find very specific instances of violations. More information can be found in the matches section of the gem’s README.
Conclusion
Accessibility testing is an important part of Rails application development that ensures your software is usable by everyone, regardless of their abilities. With the help of automated testing tools, you can identify and resolve accessibility issues early in the development process. Prioritizing accessibility not only improves user experience but also demonstrates a commitment to inclusivity and equal access.
Need help making your Rails application accessible? Let us help!
Happy Coding!