Skip to content

Commit

Permalink
Merge branch 'develop' into label-serial
Browse files Browse the repository at this point in the history
  • Loading branch information
straker authored Jul 20, 2020
2 parents 88401e1 + 2b5507e commit bb035cd
Show file tree
Hide file tree
Showing 12 changed files with 839 additions and 62 deletions.
1 change: 1 addition & 0 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ Additionally, there are a number or properties that allow configuration of diffe
| `rules` | n/a | Enable or disable rules using the `enabled` property |
| `reporter` | `v1` | Which reporter to use (see [Configuration](#api-name-axeconfigure)) |
| `resultTypes` | n/a | Limit which result types are processed and aggregated |
| `selector` | `true` | Return CSS selector for elements, optimised for readability |
| `xpath` | `false` | Return xpath selectors for elements |
| `absolutePaths` | `false` | Use absolute paths when creating element selectors |
| `iframes` | `true` | Tell axe to run inside iframes |
Expand Down
28 changes: 11 additions & 17 deletions lib/checks/aria/aria-allowed-attr-evaluate.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import { getNodeAttributes, uniqueArray } from '../../core/utils';
import { implicitRole, allowedAttr, validateAttr } from '../../commons/aria';
import { getRole, allowedAttr, validateAttr } from '../../commons/aria';

function ariaAllowedAttrEvaluate(node, options = {}) {
var invalid = [];
function ariaAllowedAttrEvaluate(node, options) {
const invalid = [];

var attr,
attrName,
allowed,
role = node.getAttribute('role'),
attrs = getNodeAttributes(node);

if (!role) {
role = implicitRole(node);
}

allowed = allowedAttr(role);
const role = getRole(node);
const attrs = getNodeAttributes(node);
let allowed = allowedAttr(role);

// @deprecated: allowed attr options to pass more attrs.
// configure the standards spec instead
if (Array.isArray(options[role])) {
allowed = uniqueArray(options[role].concat(allowed));
}

if (role && allowed) {
for (var i = 0, l = attrs.length; i < l; i++) {
attr = attrs[i];
attrName = attr.name;
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i];
const attrName = attr.name;
if (validateAttr(attrName) && !allowed.includes(attrName)) {
invalid.push(attrName + '="' + attr.nodeValue + '"');
}
Expand Down
1 change: 1 addition & 0 deletions lib/commons/aria/lookup-table.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @deprecated use standards object instead
import implicitHtmlRoles from '../standards/implicit-html-roles';

const isNull = value => value === null;
Expand Down
78 changes: 43 additions & 35 deletions test/checks/aria/allowed-attr.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe('aria-allowed-attr', function() {
afterEach(function() {
fixture.innerHTML = '';
checkContext.reset();
axe.reset();
});

it('should detect incorrectly used attributes', function() {
Expand Down Expand Up @@ -114,63 +115,70 @@ describe('aria-allowed-attr', function() {

describe('options', function() {
it('should allow provided attribute names for a role', function() {
axe.commons.aria.lookupTable.role.mcheddarton = {
type: 'widget',
attributes: {
allowed: ['aria-checked']
},
owned: null,
nameFrom: ['author'],
context: null
};
axe.configure({
standards: {
ariaRoles: {
mccheddarton: {
allowedAttrs: ['aria-checked']
}
}
}
});

fixture.innerHTML =
'<div role="mccheddarton" id="target" aria-checked="true" aria-snuggles="true"></div>';
'<div role="mccheddarton" id="target" aria-checked="true" aria-selected="true"></div>';
var target = fixture.children[0];
flatTreeSetup(fixture);

assert.isFalse(
axe.testUtils
.getCheckEvaluate('aria-allowed-attr')
.call(checkContext, target)
);

assert.isTrue(
axe.testUtils
.getCheckEvaluate('aria-allowed-attr')
.call(checkContext, target, {
mccheddarton: ['aria-checked', 'aria-snuggles']
mccheddarton: ['aria-checked', 'aria-selected']
})
);
delete axe.commons.aria.lookupTable.role.mccheddarton;
});

it('should handle multiple roles provided in options', function() {
axe.commons.aria.lookupTable.role.mcheddarton = {
type: 'widget',
attributes: {
allowed: ['aria-checked']
},
owned: null,
nameFrom: ['author'],
context: null
};
axe.commons.aria.lookupTable.role.bagley = {
type: 'widget',
attributes: {
allowed: ['aria-checked']
},
owned: null,
nameFrom: ['author'],
context: null
};
axe.configure({
standards: {
ariaRoles: {
mcheddarton: {
allowedAttrs: ['aria-checked']
},
bagley: {
allowedAttrs: ['aria-checked']
}
}
}
});

fixture.innerHTML =
'<div role="bagley" id="target" aria-snuggles2="true"></div>';
'<div role="bagley" id="target" aria-selected="true"></div>';
var target = fixture.children[0];
var options = {
mccheddarton: ['aria-snuggles'],
bagley: ['aria-snuggles2']
mccheddarton: ['aria-selected'],
bagley: ['aria-selected']
};
flatTreeSetup(fixture);

assert.isFalse(
axe.testUtils
.getCheckEvaluate('aria-allowed-attr')
.call(checkContext, target)
);

assert.isTrue(
axe.testUtils
.getCheckEvaluate('aria-allowed-attr')
.call(checkContext, target, options)
);
delete axe.commons.aria.lookupTable.role.mccheddarton;
delete axe.commons.aria.lookupTable.role.bagley;
});
});
});
9 changes: 0 additions & 9 deletions test/commons/aria/get-explicit-role.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ describe('aria.getExplicitRole', function() {
var roleDefinitions = aria.lookupTable.role;
var flatTreeSetup = axe.testUtils.flatTreeSetup;

var orig;
beforeEach(function() {
orig = axe.commons.aria.lookupTable.role;
});

afterEach(function() {
axe.commons.aria.lookupTable.role = orig;
});

it('returns valid roles', function() {
var node = document.createElement('div');
node.setAttribute('role', 'button');
Expand Down
152 changes: 152 additions & 0 deletions test/integration/virtual-rules/area-alt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
describe('area-alt', function() {
it('should pass for aria-label', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
'aria-label': 'foobar'
}
});
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should incomplete for aria-labelledby', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
'aria-labelledby': 'foobar'
}
});
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 1);
});

it('should pass for alt', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
alt: 'foobar'
}
});
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should pass for title', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
title: 'foobar'
}
});
// children are required since titleText comes after subtree text
// in accessible name calculation
child.children = [];
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should fail when alt contains only whitespace', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
alt: ' \t \n '
}
});
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should fail when aria-label is empty', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
'aria-label': ''
}
});
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should fail when title is empty', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'map'
});
var child = new axe.SerialVirtualNode({
nodeName: 'area',
attributes: {
href: 'foobar',
title: ''
}
});
child.children = [];
child.parent = node;
node.children = [child];

var results = axe.runVirtualRule('area-alt', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});
});
Loading

0 comments on commit bb035cd

Please sign in to comment.