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

feat(aria-prohibited-attr): add support fallback role #4325

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/checks/aria/aria-prohibited-attr-evaluate.js
Expand Up @@ -33,7 +33,11 @@ export default function ariaProhibitedAttrEvaluate(
) {
const elementsAllowedAriaLabel = options?.elementsAllowedAriaLabel || [];
const { nodeName } = virtualNode.props;
const role = getRole(virtualNode, { chromium: true });
const role = getRole(virtualNode, {
chromium: true,
// this check allows fallback roles. For example, `<div role="foo img" aria-label="...">` is legal.
fallback: true
});

const prohibitedList = listProhibitedAttrs(
role,
Expand All @@ -51,7 +55,7 @@ export default function ariaProhibitedAttrEvaluate(
return false;
}

let messageKey = virtualNode.hasAttr('role') ? 'hasRole' : 'noRole';
let messageKey = role !== null ? 'hasRole' : 'noRole';
messageKey += prohibited.length > 1 ? 'Plural' : 'Singular';
this.data({ role, nodeName, messageKey, prohibited });

Expand Down
33 changes: 33 additions & 0 deletions test/checks/aria/aria-prohibited-attr.js
Expand Up @@ -138,4 +138,37 @@ describe('aria-prohibited-attr', function () {
var params = checkSetup('<svg id="target" aria-label="hello world"></svg>');
assert.isFalse(checkEvaluate.apply(checkContext, params));
});

it('should not allow elements that have an invalid role', function () {
takenspc marked this conversation as resolved.
Show resolved Hide resolved
var params = checkSetup(
'<div id="target" role="foo" aria-label="foo"></div>'
);
assert.isTrue(checkEvaluate.apply(checkContext, params));
assert.deepEqual(checkContext._data, {
nodeName: 'div',
role: null,
messageKey: 'noRoleSingular',
prohibited: ['aria-label']
});
});

it('should allow elements that have fallback roles', function () {
takenspc marked this conversation as resolved.
Show resolved Hide resolved
var params = checkSetup(
'<div id="target" role="foo dialog" aria-label="foo"></div>'
);
assert.isFalse(checkEvaluate.apply(checkContext, params));
});

it('should not allow elements that have multiple invalid roles', function () {
takenspc marked this conversation as resolved.
Show resolved Hide resolved
var params = checkSetup(
'<div id="target" role="foo bar" aria-label="foo"></div>'
);
assert.isTrue(checkEvaluate.apply(checkContext, params));
assert.deepEqual(checkContext._data, {
nodeName: 'div',
role: null,
messageKey: 'noRoleSingular',
prohibited: ['aria-label']
});
});
});
48 changes: 48 additions & 0 deletions test/integration/virtual-rules/aria-prohibited-attr.js
Expand Up @@ -58,4 +58,52 @@ describe('aria-prohibited-attr virtual-rule', () => {
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should fail for invalid role', () => {
const vNode = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'foo',
'aria-label': 'foo'
}
});
vNode.children = [];

const results = axe.runVirtualRule('aria-prohibited-attr', vNode);

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

it('should pass for fallback roles', () => {
const results = axe.runVirtualRule('aria-prohibited-attr', {
nodeName: 'div',
attributes: {
role: 'foo dialog',
'aria-label': 'foo'
}
});

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

it('should fail for multiple invalid roles', () => {
const vNode = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'foo bar',
'aria-label': 'foo'
}
});
vNode.children = [];

const results = axe.runVirtualRule('aria-prohibited-attr', vNode);

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