Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

updating accessibility tests to be compatible with latest axe release #42

Merged
merged 13 commits into from
Jan 16, 2018

Conversation

kschuste
Copy link
Member

@kschuste kschuste commented Jan 5, 2018

Summary

This fixes issue #41. This unlocks the axe-core dependency and will allow it to pull the latest released version of it. The tests have been updated to pass with the latest accessibility rule added by turning it off.

@kschuste kschuste self-assigned this Jan 5, 2018
@emilyrohrbough
Copy link
Contributor

I am wondering if it would make more sense to disable the rule in the axe-service here, such that

 const rules =  {
      'landmark-one-main': { enabled: false },
 };

const axeOptions = {
        runOnly: options.runOnly,
        rules: Object.assign({}, rules, options.rules),
      };

This would remove the need to update each accessibility test.

@emilyrohrbough
Copy link
Contributor

Then again, maybe not if consumers use this to test at an app level.

@mhemesath
Copy link
Contributor

@emilyrohrbough not far off. The service should be configured to allow global options to be passed in through the wdio.conf.js. Those global rules can be accesssed here. We can then append to the injected in script to add a axe.configure() call this tthose options. See doc

@emilyrohrbough
Copy link
Contributor

Ah knew there at to be something at a quick glance

@mhemesath
Copy link
Contributor

The other option of course is that Terra provides its own axe script and disables injection (will probably slightly speed up tests as less commands are executed). Terra can then configure landmarks off manually. FWIW - I think the globa option is a good idea though.

@kschuste
Copy link
Member Author

kschuste commented Jan 8, 2018

@emilyrohrbough @mhemesath updated to apply a global rule for consumers, take a look

src/wdio/conf.js Outdated
@@ -10,6 +10,11 @@ exports.config = {
capabilities: [
{
browserName: 'chrome',
axe: {
rules: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have expected this to be present within the axe config block later in this file

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked more into this and the axe config block is not passed in with the config parameter in the AxeService.js file. The axe config here was previously setting inject = 'true', but in the AxeService.js, this was always hardcoded to true and whatever. The config param matches what is set here in the capabilities; hence, I added the axe config for the rules, I have also now moved the inject config to here and removed the hardcoding from the AxeService.js

@@ -33,7 +33,7 @@ export default class AxeService {
const specifiedViewports = options.viewports || [currentViewportSize];
const axeOptions = {
runOnly: options.runOnly,
rules: options.rules,
rules: Object.assign({}, axeConfig.rules, options.rules),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the global options should be set once upon initialization of the script by appending that config block to line 24

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

append the json config to the javascript source code that is read in on lines 23 and 24?

axeCoreSrc = fs.readFileSync(require.resolve('axe-core'), 'utf8');
axeCoreSrc = axeCoreSrc.replace(/^\/\*.*\*\//, '');

Copy link
Contributor

@mhemesath mhemesath Jan 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we want to append it so that we only need 1 injection command

src/wdio/conf.js Outdated
@@ -10,6 +10,12 @@ exports.config = {
capabilities: [
{
browserName: 'chrome',
axe: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually meant the inverse, why are you putting the config in the capabilities?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as you see in your comment below, I have the config in the capabilities as they are passed into the before function instead of the whole config so I have access to them. Switching to use onPrepare or another function that allows the config to be passed in will not give us access to the global browser object that we are applying the axe config too.

Copy link
Contributor

@mhemesath mhemesath Jan 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you aren't applying it to the global browser object. Your saving off the config as an instnace variable in the AxeService. Then when the browser command injects the axe config, it can call axe.configure with that config.

@@ -11,7 +11,6 @@ export default class AxeService {
// eslint-disable-next-line class-methods-use-this
before(config) {
Copy link
Contributor

@mhemesath mhemesath Jan 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i see why you are putting config in capabilities... this should probably be onPrepare. You can then use the config param to pull the axe config so you don't have to put it in capabilities.

    /**
     * Gets executed once before all workers get launched.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     */
    onPrepare: function (config, capabilities) {
    },

Doc for the config is here http://webdriver.io/guide/testrunner/configurationfile.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving to using onPrepare does not allow us to have access to the global browser variable.
Using before is the earliest we can have access to the browser variable, which before only has the two params of the capabilities and the specs.

src/wdio/conf.js Outdated
@@ -10,6 +10,12 @@ exports.config = {
capabilities: [
{
browserName: 'chrome',
axe: {
inject: true,
rules: {
Copy link
Contributor

@mhemesath mhemesath Jan 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be

options: {
  rules: {}
}

This allows the global options to be separated from our custom options (e.g. inject). That options object will then be directly passed to axe.configure. See https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#api-name-axeconfigure

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated to place the rules inside an options hash

@@ -51,10 +59,6 @@ exports.config = {
global.browser.click('#wdioMouseReset');
},

axe: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understand of webdriver.io, when define a service, the webdriver.io configuration object will passed to that service when the runner starts. From there, since the server has access the configuration object, it can search for its designated config key to pull in its own configuration.

Given this, I feel the axe configuration should be defined with the axe key and moving it to capabilities would be a non-passive change for consumers defining their accessibility configuration.

I did look into the capabilities key. @mhemesath This configuration is being utilized by the selenium grid correct?

@kschuste I do agree in the AxeService.js file below, the defaulted inject: true was unnecessary given we also had it set here in the configuration and it was always overridden with true.

Copy link
Contributor

@mhemesath mhemesath Jan 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did look into the capabilities key. @mhemesath This configuration is being utilized by the selenium grid correct?

Yes that should only be for selenium configuration, putting config in there is kinda hijacking that.

I do agree in the AxeService.js file below, the defaulted inject: true was unnecessary given we also had it set here in the configuration and it was always overridden with true.

The inject option I don't think ever worked, it always defaulted to true.

@emilyrohrbough
Copy link
Contributor

emilyrohrbough commented Jan 10, 2018

So... This PR has generated a bit of discussion, but it also got me thinking. I am not sure we should be disabling the landmark rule in the default configuration. Here are my reasons why

  1. Our consumers could be using this to test accessibility of applications, so they will want this rule enabled.
  2. Consumers should knowingly disable accessibility rules
  3. Few people are building and testing modular components.

Given this, we should probably disable the landmark rule from our webdriver.io configuration in each repository.

@mhemesath
Copy link
Contributor

I am not sure we should be disabling the landmark rule in the default configuration.

@emilyrohrbough Yeah, it is an optional configuration... as you said should probably be pushed to the toolkit specific wdio config file.

@@ -33,7 +32,7 @@ export default class AxeService {
const specifiedViewports = options.viewports || [currentViewportSize];
const axeOptions = {
runOnly: options.runOnly,
rules: options.rules,
rules: Object.assign({}, axeConfig.options.rules, options.rules),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the axeConfig should be set globally using axe.configure when the script is injected.

@kschuste
Copy link
Member Author

kschuste commented Jan 11, 2018

@emilyrohrbough @mhemesath Updated to move the axe configuration to the toolkit specific wdio file and inject the configuration into the axe script.

browser.addCommand('axe', (options = {}) => {
// Conditionally inject axe. This allows consumers to inject it themselves
// in the test examples which would slightly speed up test runs.
if (axeConfig.inject) {
const axeConfig = browser.options.axe;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should default inject to true, change this to

const axeConfig = {
  inject: true,
  ...(browser.options.axe || {}),
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Most will expect this to be true.

@mhemesath
Copy link
Contributor

Other than defaulting inject: true, my only other comment is to update the service documentation so that others know they can set global axe options now.

@emilyrohrbough
Copy link
Contributor

emilyrohrbough commented Jan 12, 2018

I agree with @mhemesath, default to true and updating docs should be good!

EDIT
Side note, I don't think we should be checking in the package.lock file
^ Matt says its fine.

@mjhenkes
Copy link
Contributor

Checking in package.lock is fine. NPM tells you to do it. (And i made the change to allow it.) :)
a7e901e

@kschuste
Copy link
Member Author

updated default to always be true and updated documentation


const axeOptions = axeConfig.options;
if (axeOptions) {
axeCoreSrc = `${axeCoreSrc}\naxe.configure(${JSON.stringify(axeOptions)});`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${axeCoreSrc}\naxe.configure(${JSON.stringify(axeOptions)});;

Is there a cleaner options than the \n between ${axeCoreSrc} and axe.configure(... ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is needed to place the json config on a new line to not have syntax errors when loading the script. maybe could break it apart and append each line separately, but I think this is ok as only appending 1 item to the end of the script

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might be able to get away with a newline in the string literal

Copy link
Contributor

@emilyrohrbough emilyrohrbough Jan 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option for readability could be

const axeConfigrue = `axe.configure(${JSON.stringify(axeOptions)})`;
axeCoreSrc = `${axeCoreSrc}\n${axeConfigure};`;

@@ -5,7 +5,8 @@ Terra toolkit automatically includes the wdio-axe-service which enhances a webdr

Under the key `axe` in the wdio.conf.js you can pass a configuration object with the following structure:

* **inject** - True if the axe script should be injected by the test running. Disable if axe is already included in the test files, which slightly speed up runs. Defaults to true.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep this documentation as a consumer can still set this to false if they wouldn't want to keep the default true.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was removed as was always defaulting to true as we were always ignoring the setting so it never worked

with the changes made we are still hardcoding it to default to true so it is working the same; therefore, removed it from the documentation as was never valid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well we should leave the documentation in place because the option should now actually work

@kschuste
Copy link
Member Author

@mhemesath @emilyrohrbough updated to include documentation and readability

@kschuste kschuste merged commit abe5913 into master Jan 16, 2018
@kschuste kschuste deleted the accessibility-testing-updates branch January 16, 2018 19:22
This was referenced Jan 30, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants