diff --git a/__tests__/src/rules/role-supports-aria-props-test.js b/__tests__/src/rules/role-supports-aria-props-test.js index 5aa8019d8..314e7be71 100644 --- a/__tests__/src/rules/role-supports-aria-props-test.js +++ b/__tests__/src/rules/role-supports-aria-props-test.js @@ -50,11 +50,14 @@ const nonAbstractRoles = [...roles.keys()].filter((role) => roles.get(role).abst const createTests = (rolesNames) => rolesNames.reduce((tests, role) => { const { props: propKeyValues, + prohibitedProps, } = roles.get(role); - const validPropsForRole = Object.keys(propKeyValues); + const validPropsForRole = Object.keys(propKeyValues) + .filter((attribute) => prohibitedProps.indexOf(attribute) === -1); const invalidPropsForRole = [...aria.keys()] .map((attribute) => attribute.toLowerCase()) - .filter((attribute) => validPropsForRole.indexOf(attribute) === -1); + .filter((attribute) => validPropsForRole.indexOf(attribute) === -1) + .concat(prohibitedProps); const normalRole = role.toLowerCase(); const allTests = []; @@ -568,5 +571,21 @@ ruleTester.run('role-supports-aria-props', rule, { errors: [errorMessage('aria-checked', 'link', 'a', true)], settings: componentsSettings, }, + { + code: '', + errors: [errorMessage('aria-label', 'generic', 'span', true)], + }, + { + code: '', + errors: [errorMessage('aria-labelledby', 'generic', 'span', true)], + }, + { + code: '
', + errors: [errorMessage('aria-label', 'generic', 'div', true)], + }, + { + code: '', + errors: [errorMessage('aria-labelledby', 'generic', 'div', true)], + }, ].concat(invalidTests).map(parserOptionsMapper), }); diff --git a/__tests__/src/util/getComputedRole-test.js b/__tests__/src/util/getComputedRole-test.js index 33a2d8e0a..59898693c 100644 --- a/__tests__/src/util/getComputedRole-test.js +++ b/__tests__/src/util/getComputedRole-test.js @@ -24,7 +24,7 @@ describe('getComputedRole', () => { describe('lacks implicit', () => { it('should return null', () => { expect(getComputedRole( - 'div', + 'custom-element', [JSXAttributeMock('role', 'beeswax')], )).toBeNull(); }); @@ -43,7 +43,7 @@ describe('getComputedRole', () => { describe('lacks implicit', () => { it('should return null', () => { expect(getComputedRole( - 'div', + 'custom-element', [], )).toBeNull(); }); @@ -62,7 +62,7 @@ describe('getComputedRole', () => { describe('lacks implicit', () => { it('should return null', () => { expect(getComputedRole( - 'div', + 'custom-element', [], )).toBeNull(); }); diff --git a/__tests__/src/util/getExplicitRole-test.js b/__tests__/src/util/getExplicitRole-test.js index 102628c23..38fe88208 100644 --- a/__tests__/src/util/getExplicitRole-test.js +++ b/__tests__/src/util/getExplicitRole-test.js @@ -14,7 +14,7 @@ describe('getExplicitRole', () => { describe('invalid role', () => { it('should return null', () => { expect(getExplicitRole( - 'div', + 'custom-element', [JSXAttributeMock('role', 'beeswax')], )).toBeNull(); }); @@ -22,7 +22,7 @@ describe('getExplicitRole', () => { describe('no role', () => { it('should return null', () => { expect(getExplicitRole( - 'div', + 'custom-element', [], )).toBeNull(); }); diff --git a/__tests__/src/util/getImplicitRole-test.js b/__tests__/src/util/getImplicitRole-test.js index 76176ab6a..ed81ef7a5 100644 --- a/__tests__/src/util/getImplicitRole-test.js +++ b/__tests__/src/util/getImplicitRole-test.js @@ -13,7 +13,7 @@ describe('getImplicitRole', () => { describe('lacks implicit', () => { it('should return null', () => { expect(getImplicitRole( - 'div', + 'custom-element', [], )).toBeNull(); }); diff --git a/src/rules/role-supports-aria-props.js b/src/rules/role-supports-aria-props.js index ec961032f..c1117f2f6 100644 --- a/src/rules/role-supports-aria-props.js +++ b/src/rules/role-supports-aria-props.js @@ -65,9 +65,11 @@ export default { // Make sure it has no aria-* properties defined outside of its property set. const { props: propKeyValues, + prohibitedProps, } = roles.get(roleValue); const invalidAriaPropsForRole = [...aria.keys()] - .filter((attribute) => !(attribute in propKeyValues)); + .filter((attribute) => !(attribute in propKeyValues)) + .concat(prohibitedProps); node.attributes.filter((prop) => ( getPropValue(prop) != null // Ignore the attribute if its value is null or undefined. diff --git a/src/util/implicitRoles/div.js b/src/util/implicitRoles/div.js new file mode 100644 index 000000000..8ea7bffe0 --- /dev/null +++ b/src/util/implicitRoles/div.js @@ -0,0 +1,6 @@ +/** + * Returns the implicit role for a div tag. + */ +export default function getImplicitRoleForDiv() { + return 'generic'; +} diff --git a/src/util/implicitRoles/index.js b/src/util/implicitRoles/index.js index 027b62af4..b7243b8d7 100644 --- a/src/util/implicitRoles/index.js +++ b/src/util/implicitRoles/index.js @@ -7,6 +7,7 @@ import button from './button'; import datalist from './datalist'; import details from './details'; import dialog from './dialog'; +import div from './div'; import form from './form'; import h1 from './h1'; import h2 from './h2'; @@ -29,6 +30,7 @@ import output from './output'; import progress from './progress'; import section from './section'; import select from './select'; +import span from './span'; import tbody from './tbody'; import textarea from './textarea'; import tfoot from './tfoot'; @@ -45,6 +47,7 @@ export default { datalist, details, dialog, + div, form, h1, h2, @@ -67,6 +70,7 @@ export default { progress, section, select, + span, tbody, textarea, tfoot, diff --git a/src/util/implicitRoles/span.js b/src/util/implicitRoles/span.js new file mode 100644 index 000000000..169a7057d --- /dev/null +++ b/src/util/implicitRoles/span.js @@ -0,0 +1,6 @@ +/** + * Returns the implicit role for a span tag. + */ +export default function getImplicitRoleForSpan() { + return 'generic'; +}