Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support options in aria-allowed-attr and aria-required-attr #673

Merged
merged 8 commits into from
Jan 18, 2018

Conversation

marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Jan 5, 2018

This continues the work to avoid having to manipulate the lookupTable directly. valid-attr and valid-attr-value already used options; this PR adds options to aria-allowed-attr and aria-required-attr. The usage for these checks is now to plumb in an options object with a role and an array of accepted attribute values:

axe.configure({
    checks: [{
        id: 'aria-allowed-attr',
        options: {
            separator: ['aria-valuenow', 'aria-valuemin', 'aria-valuemax']
        }
    }]
});
axe.run(document,  {}, function(error, results) {
    assert.equal(results.violations.length, 0);
    done();
});

Closes #644

cc @waabid @iamrafan

@@ -12,7 +14,7 @@ if (role && allowed) {
for (var i = 0, l = attrs.length; i < l; i++) {
attr = attrs[i];
attrName = attr.name;
if (axe.commons.aria.validateAttr(attrName) && allowed.indexOf(attrName) === -1) {
if (options.indexOf(attrName) === -1 && axe.commons.aria.validateAttr(attrName) && allowed.indexOf(attrName) === -1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You should wrap this line. You may also want to use .includes.

@marcysutton marcysutton changed the title Support options in aria-allowed-attr Support options in aria-allowed-attr and aria-required-attr Jan 6, 2018
@marcysutton
Copy link
Contributor Author

marcysutton commented Jan 6, 2018

I incorporated the small piece of feedback and also added options to required-attr, as well as some integration tests for axe.configure. There are other checks that (indirectly) reference the lookupTable, but they're quite complex (like required-children) so unless there's a specific need for those, I'll keep the scope of this PR small.

Edit: also, I thought about documenting options for these checks but I wasn't sure where that information should live. If anyone has suggestions let me know :)

Copy link
Contributor

@WilcoFiers WilcoFiers left a comment

Choose a reason for hiding this comment

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

Looks good. The one thing I'm hesitant about with this is that this is starting to look a lot like accessibility supported functionality. We haven't got an API design for this yet, and I'm hoping we won't have to break this once settle on a way to do this.

@@ -119,4 +119,11 @@ describe('aria-allowed-attr', function () {
assert.isNull(checkContext._data);
});

describe('options', function () {
it('should allow provided attribute names', function () {
fixture.innerHTML = '<div role="separator" id="target" aria-valuenow="0" aria-valuemin="-2" aria-valuemax="4"></div>';
Copy link
Contributor

Choose a reason for hiding this comment

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

You may want to use fake aria properties instead. Otherwise, once we've added those values, this test becomes invalid.

@@ -57,4 +57,12 @@ describe('aria-required-attr', function () {
axe.commons.aria.requiredAttr = orig;
});

describe('options', function () {
it('should require provided attribute names', function () {
fixture.innerHTML = '<div role="slider" id="target"></div>';
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, you should use a made up role. May I suggest role="McCheddarton"? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Love it! will do.

@@ -1,3 +1,5 @@
options = Array.isArray(options) ? options : [];
Copy link
Contributor

Choose a reason for hiding this comment

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

I was wondering if this should allow per role specification, instead of (or in addition to) a generic "allowed everywhere". So you could do: { separator: ['aria-valuenow', 'aria-valuemin', 'aria-valuemax'] }. You could still allow the array, and you could add a wildcard option for the "generic" case you've got now: { '*': ['always-allowed'] }.

@@ -1,10 +1,21 @@
options = Array.isArray(options) ? options : [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as my comment above. This is a generic "required everywhere". That seems a bit useless. You wouldn't require a particular attribute on every element. You'd need to set certain things to be required for certain roles.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, thanks for the tip!

@marcysutton
Copy link
Contributor Author

The one thing I'm hesitant about with this is that this is starting to look a lot like accessibility supported functionality. We haven't got an API design for this yet, and I'm hoping we won't have to break this once settle on a way to do this.

We can make changes when we're ready, but these options will help support our users now. Options are already used in the codebase in a few places so there's precedent. But perhaps we can hold off from a big documentation push until we decide on an API.

e.g. {separator: ['aria-valuenow', 'aria-valuemin', aria-valuemax']}
@marcysutton
Copy link
Contributor Author

I've updated the PR so the checks now take an object as options:

{ 'separator': ['aria-valuemin', 'aria-valuemax', 'aria-valuenow']}

allowed = axe.commons.aria.allowedAttr(role);

if (Object.keys(options).length) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You can simplify this.

if (Array.isArray(options[role])) {
  allowed = axe.utils.uniqueArray(options[role].concat(allowed));
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I also removed a duplicate to-array file in axe.commons. It was almost exactly the same code duplicated, we don't want to maintain both if we don't have to.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, I was confused by this comment...I've made the change and added it to this PR. Thanks!

Marcy Sutton added 2 commits January 18, 2018 10:07
The exact same code existed in axe.utils and axe.commons (as axe.utils.toArray)
@marcysutton marcysutton merged commit ffae2c0 into develop-2x Jan 18, 2018
marcysutton added a commit that referenced this pull request Jan 18, 2018
* chore: rename lut in tests

* feat: allow options in aria-allowed-attr

* chore: rename options integ. tests for clarity

* feat: add required-attr options, integration tests

* chore: PR feedback for aria-allowed-attr

* feat: use object for ARIA check options

e.g. {separator: ['aria-valuenow', 'aria-valuemin', aria-valuemax']}

* chore: remove duplicate to-array util

The exact same code existed in axe.utils and axe.commons (as axe.utils.toArray)

* chore: simplify ARIA options usage
describe('aria-allowed-attr', function() {
it('should allow an attribute supplied in options', function(done) {
target.setAttribute('role', 'separator');
target.setAttribute('aria-valuenow', '0');
Copy link
Contributor

Choose a reason for hiding this comment

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

In the event that 'aria-valuenow' becomes an allowed attribute in our lookup table, this test won't be testing anything anymore. Just to make the test more future-proof, I suggest using a random value like 'peanutbutter' instead of a real attribute so we can guarantee the test will always be testing the override functionality with a truly unexpected value.

* @return {Array}
*/
axe.utils.uniqueArray = (arr1, arr2) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is super minor, but it'd be nice if this iterated over an arbitrary number of array inputs.

@dylanb dylanb deleted the support-rule-options branch March 8, 2018 19:01
mrtnvh pushed a commit to mrtnvh/axe-core that referenced this pull request Nov 24, 2023
…#673)

* chore(ci): update selenium-webdriver to latest

* fix tests

* udpate webdriverjs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants