Automated testing with aXe — A11ycasts #15

everybody, what's up? It's Rob Dodson. Welcome back to the
Ally Casts show. Today I want to
talk about how to do automated accessibility
testing using the aXe library. So if you haven't
heard of it before, aXe is a really useful utility. And one of the
reasons why I like aXe is because they kind of
have this whole mantra, mission statement thing of making sure
that their accessibility tests have zero false positives,
meaning they only test stuff that they're really, really
confident that they can say is either passing or failing. And the reason
why I like that is because if you've got a
really, really big team and you don't have
everyone, maybe, bought into
accessibility testing, and you've got a tool
that's maybe throwing like flaky errors
or something like that, it might be
easy for the team to just disable that thing
or just start ignoring it.

So I love aXe because I like
the idea of zero false positives and making sure that if
something is failing, everyone on your team
can kind of agree, like, hey yeah, that's
an actual issue. So to get started with
aXe, follow me over here to my laptop. Over here, I'm just sort
of showing the GitHub page for aXe. It's made by Deque.

So this is Deque
Labs organization. This is axe-core, which is
kind of like the library that powers everything. And you can scroll down
to the Read Me and see, they kind of talk about their
philosophy, their manifesto, and things like that. There's a few different
ways to use aXe. So for instance,
as it shows here, you can just drop it as
a script tag onto a page and it will start
logging errors that way. That's one way to go about it. But what we're
going to do today is I'm going to show you how to
use it as a Chrome extension, how to use it with
Selenium, and how to use it using the
newly released axe-cli. So let's get started with
the Chrome extension. I'm going to go over
to the Chrome Web Store and just look for aXe,
like a chopping axe.

And you'll know it if you see
this blue triangle thing here. So I'm going to go ahead
and add that to Chrome. Yep. So the extension
is really useful if you just want to
maybe quickly look at a page or a few
pages of your site. You don't have a whole
automated testing workflow setup or anything like that. You just want to look
at a page and be like, what's broken here? So I'm going go over to my blog.

So this is Now, I know that there are
some issues on this site. I found them during the
making of this episode. And I'm going to
leave them in so you can see the process in action. So what I'm going
to do here is I'm going to open up my dev tools. And now that I have that
Chrome extension installed, I've got this
little aXe tab here. So I can click on that, and
there's big Analyze button. I run that and it
will now show me over here on the left some
of the issues that I have. For instance, I have
elements that need to have better color contrast. An HTML element needs
to have a lang attribute to indicate the
language the page uses. And I have some links
that need to have better discernible text. So right now, I have links
that probably just say "more." Whereas it could be a
more fleshed out phrase.

It could be "click here to
read about custom elements" or something like that. So let's check out this
color contrast thing. So I've got 16 violations
that it's showing me here. It tells me which
of the standards that we're failing here. So WCAG 2.0 AA. And also show me
the selector path to get at the elements
that are failing. So here I can see it's
basically these anchor tags that are inside of my post
metadata headers. And what's really cool is I
can click this More Info button and it'll take me to a page
called Deque University, which is sort of a resource
that the folks at Deque run, along with aXe. And that'll just explain
in more detail what exactly is failing here, how
to fix it, and also the severity of the error. So for instance,
you can see here, this is kind of like a
critical failing when we have bad color contrast.

But it's useful so that when
we've got a ton of errors and you're trying to prioritize
which to work on first, you can say, OK, let's deal
with the critical ones first and then we can deal with the
minor ones a little bit later. So I love that they
provide this resource. All right. So that's one way
to go about things. You can use the extensions
to quickly look at a page. Another way to go about things
is to use a tool like Selenium to do automated testing
of your application. Selenium, if you haven't
heard of it before, it's basically a tool that
can drive your browser in an automated fashion.

It can click on
things on the page, open URLs, send keyboard events. So to do that using aXe,
there's another variation that we can use
called axe-webdriver. This is also available
on the GitHubs. If you scroll down
to the Read Me, it'll have getting
started steps. So a few resources that
we need to install. And then there's this
really helpful snippet right here that we can
actually just copy and paste. And we'll walk through
what's happening in the snippet in just a sec. But let's start by installing
these dependencies. We need axe-core, that
library I was showing before. And we're going to
need axe-webdriverjs. So I'll go over to my
terminal, and I've actually already got my little
command ready to go here. So I'm going to
mpm install, save. And I'm saving to
my dev dependencies because this is
probably not something I want to ship in production. This is probably
something I just want during development time. So I'm installing axe-core. I'm also installing
Selenium WebDriver. At the time of this
recording, this is also a dependency of
the axe-webdriver project, so we want to make sure and
install Selenium WebDriver.

And then finally,
axe-webdriverjs. So we'll install all
of those, save them into our package JSON file– so we're good to go there. And then I'm going
to just create an index.js file, open that
up in Visual Studio Code, and I'm going to paste
in that little snippet that we copied
off of their page. So let's talk about what's
happening in this snippet. So the first thing
we're doing is we're grabbing axe-builder,
or axe-webdriverjs. This is basically
going to be a tool that will tell Selenium how to do
automated testing of the page. We're grabbing WebDriver. So that's Selenium WebDriver. This is basically
the tool that's going to automate
opening up a browser and sending commands to it.

Well, we start things
off by creating a new instance of WebDriver
and we tell it which browser we want it to use. So it could use Firefox,
Chrome, Safari, what have you. In this case, I want to change
it from Firefox over to Chrome, just because I did this
demo earlier with Chrome and I've got that all set up. And then once
that's ready, we're going to take our
Selenium instance. We will tell it
which URL to open. So here I'm going to
tell it to open my blog. So I'll change that
to And again, if you were doing
automated testing or something like that, you could spin
up a local server and point to at local host, like,
8080 or something like that. That works. This returns a promise for
when it's finally ready to go. And then we say, all
right, take axe-builder, make sure it has been passed the
instance of Selenium WebDriver, and then tell it to
analyze the current page. And when it does
that, it's going to return a JavaScript
object full of results.

So things that fail,
things that passed. And what I want to do here
is just log those results. I'm actually going
to filter this down to just log violations. So I don't want to see
things that passed just yet. I just care about the
violations, right? And we're going to
see if this matches what the Chrome extension
was outputting earlier. Now, there's one
more thing that we need to do before
this is ready to run. We're also going
to need to install ChromeDriver for Selenium. So every browser has a
sort of specific binary that it needs to
work with Selenium. So Firefox, Safari, Chrome,
they've all got a binary that you've got to go install. If you run aXe right
now and you don't have one of those
binaries installed, it will actually
log a little error and it'll give you the URL to
download the correct binary that you need. So I think I've got
that URL saved here. So it's at chromedriver.sto I will drop that down
in the show notes. We'll go to this
page and you'll just see a bunch of
numbered directories.

It's not super helpful. I wish there was just a button
that was like, get the latest. But basically, you can follow
the number ordering here. You may notice this thing
that says LATEST RELEASE. What it will do is it'll
download a text file and it will tell you the
number of the latest release to download. So you can click this if you
want and get the text file. It'll eventually tell you that
2.27 is the current latest release. The numbers just
go in order, right? So 2.3, 4, 5, 6, 7, 8, and 9. And then it jumps
up to 2.10, 11, 12. So the ordering is a
little funky there. And you just want whatever
is the highest point release at this point, so 2.27. So you click that,
pick your platform. Mine is Mac 64 Zip. And that is going to
download a little binary. And what I've done is
I've taken that binary and I've just dropped it
into my user directory. I created a bin directory and
I dropped ChromeDriver right in there with
another binary that I had from a previous project.

So I'm just dumping
binaries in here. The last thing that
I want to do is I want to set that
directory up on my path so when Unix is trying
to look up that program, it knows which
directory to look into. The way that we do that is I'll
show you how to do it on a Mac. For a PC, Windows,
I'm sure there's some good instructions
out there, but I don't know them
off the top of my head.

I'm not a Windows user. But maybe I can add
something to the show notes. For a Mac, what you want to
do is you want to check out your .bash_profile, or
your Z Shell config file, if you use Z Shell, which I do. But I'll show you how
this with .bash_profile, because most people use Bash. And what we want
to do is we just want to drop in a line that
looks kind of like this. So we're saying, all right,
take our current path, right? So export this path variable. We'll say, take
the current path. So when we say $PATH, that's
basically what we mean. It means sort of use the
path variable, expand it. And then use a colon to stick
one addition to the end of it. So we'll say, use our
user's home directory– so user is Rob Dodson– slash bin, OK? So now we're saying,
hey, when you're looking at programs, when I go
on the terminal, I type Chrome driver.

Look through all the
directories on the path until you get to
my user directory, look in the bin folder, and
you should see something there, right? You can verify that this has
worked after you save all that. Restart your terminal. It's very important to do that
so it loads the new profile. And you can type
which chromedriver, and it should give you
a path to where you've got your ChromeDriver binary. So now we're
actually ready to go. We can run that JavaScript
file that we just created. So I'll do node index
for my index.js file. And this will go out,
it'll hit the web. And now it is logging all of
the violations from my site. And you can see it's basically
the same ones that we had from that Chrome extension.

So it's telling me we've
got color contrast issues, and it's logging all the nodes
with color contrast issues. HTML element needs a
language attribute. And we've got some links
that need better text, right? So this is what you can
do to start adding aXe to your automated test process. And if you go back to the
repo for axe-webdriver and you scroll all the way
down to the bottom there, there's some examples, like
this one running a single rule. This example actually shows
you how to use it with Mocha and chai.

So if you want to integrate
it with some existing test framework, you can
absolutely do that. And there's some
good docs here that show you how to go about that. The last thing that
I want to show off is very similar to the Chrome
extension, and that's axe-cli. So it's basically
the same thing, but we're running it
just from the terminal. We don't have to
write any JavaScript or anything like that.

We can just install it and
run it from the command line whenever we want. So if you go over to
dequelabs/axe-cli, so this is a recently
released project. It bundles up axe-core. It actually bundles up the
Selenium WebDriver stuff as well. And it just lets us
run the whole thing from the command line just
as one single command. So we do mpm install-g axe-cli. So I'll pull that down. mpm does its thing,
boom, all right. And now we're going
to do basically the same thing, but this time– here, I'll just
go to my desktop. So I haven't written
any JavaScript. I'm just on my desktop
in my terminal. And I'm just going to run aXe. And I'll put in my site again. And now this is
going to actually use PhantomJS, though I can tell it
to use Chromedriver if I want.

But it's using PhantomJS to
go and check out my site. It's got very pretty
colors now, and it's logging all of the
issues that it found. So very similar to
the Chrome extension, but I just run it
from my terminal. So I've shown a number of
different ways to get up and running with aXe. So hopefully,
you've got the tools that you need now to start
adding it to your own process. I think that's a really,
really awesome project. I think the folks working on it
are doing really killer work. So definitely, if you like it,
go star it, and support them on Twitter, and
tell them that you think their work is awesome. That about covers it for today. If you have any more
questions for me, as always, you can leave them
in the comments, or you can hit me up on a
social network of your choosing. As always, thank you
so much for watching and I'll see you next time. Hey, if you enjoyed this
episode of Ally Casts, you can always catch more
over in our playlist, or click the little
Subscribe button and you'll get an email
notification whenever we launch new stuff on the channel.

As always, thanks for watching..

As found on YouTube

You May Also Like

About the Author: Wilson Phillips

Leave a Reply

Your email address will not be published. Required fields are marked *