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

new_audit: add new checks from axe-core 4.8 #15963

Merged
merged 5 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions cli/test/fixtures/a11y/a11y_tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@
<section>
<div id="aria-command-name" role="button"></div>
</section>
<p>aria-conditional-attr</p>
<section>
<input id="aria-conditional-attr" type="checkbox" aria-checked="true">
</section>
<p>aria-dialog-name</p>
<section>
<div role="alertdialog" id="aria-dialog-name" aria-label=""></div>
</section>
<p>aria-deprecated-role</p>
<section>
<div role="directory" id="aria-deprecated-role"></div>
</section>
<p>aria-hidden-focus</p>
<section>
<div id="aria-hidden-focus" aria-hidden="true">
Expand Down Expand Up @@ -68,6 +76,10 @@
<section>
<div id="aria-progressbar-name" role="progressbar">text-in-a-box</div>
</section>
<p>aria-prohibited-attr</p>
<section>
<div id="aria-prohibited-attr" role="presentation" aria-label="Label"></div>
</section>
<p>aria-required-attr</p>
<section>
<div
Expand Down
58 changes: 48 additions & 10 deletions cli/test/smokehouse/test-definitions/a11y.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ const expectations = {
],
},
},
'aria-conditional-attr': {
score: 0,
details: {
items: [
{
node: {
'type': 'node',
'selector': 'body > section > input#aria-conditional-attr',
'snippet': '<input id="aria-conditional-attr" type="checkbox" aria-checked="true">',
'nodeLabel': 'body > section > input#aria-conditional-attr',
'explanation': 'Fix all of the following:\n Remove aria-checked, or set it to "false" to match the real checkbox state',
},
},
],
},
},
'aria-dialog-name': {
score: 0,
details: {
Expand All @@ -98,6 +114,22 @@ const expectations = {
],
},
},
'aria-deprecated-role': {
score: 0,
details: {
items: [
{
node: {
'type': 'node',
'selector': 'body > section > div#aria-deprecated-role',
'snippet': '<div role="directory" id="aria-deprecated-role">',
'nodeLabel': 'body > section > div#aria-deprecated-role',
'explanation': 'Fix all of the following:\n The role used is deprecated: directory',
},
},
],
},
},
'aria-hidden-body': {
score: 1,
details: {
Expand Down Expand Up @@ -186,6 +218,22 @@ const expectations = {
],
},
},
'aria-prohibited-attr': {
score: 0,
details: {
items: [
{
node: {
'type': 'node',
'selector': 'body > section > div#aria-prohibited-attr',
'snippet': '<div id="aria-prohibited-attr" role="presentation" aria-label="Label">',
'nodeLabel': 'Label',
'explanation': 'Fix all of the following:\n aria-label attribute cannot be used with role "null".',
},
},
],
},
},
'aria-treeitem-name': {
score: 0,
details: {
Expand Down Expand Up @@ -298,7 +346,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > div#aria-required-attr',
'path': '2,HTML,1,BODY,25,SECTION,0,DIV',
'snippet': '<div id="aria-required-attr" role="checkbox">',
'explanation': 'Fix any of the following:\n Element does not have text that is visible to screen readers\n aria-label attribute does not exist or is empty\n aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n Element has no title attribute',
'nodeLabel': 'body > section > div#aria-required-attr',
Expand All @@ -308,7 +355,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > div > div#aria-required-parent',
'path': '2,HTML,1,BODY,29,SECTION,0,DIV,0,DIV',
'snippet': '<div id="aria-required-parent" role="option">',
'nodeLabel': 'body > section > div > div#aria-required-parent',
},
Expand All @@ -317,7 +363,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > div#aria-valid-attr',
'path': '2,HTML,1,BODY,35,SECTION,0,DIV',
'snippet': '<div id="aria-valid-attr" role="checkbox" aria-chked="true">',
'nodeLabel': 'body > section > div#aria-valid-attr',
},
Expand All @@ -326,7 +371,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > div#aria-valid-attr-value',
'path': '2,HTML,1,BODY,37,SECTION,0,DIV',
'snippet': '<div id="aria-valid-attr-value" role="checkbox" aria-checked="0">',
'nodeLabel': 'body > section > div#aria-valid-attr-value',
},
Expand Down Expand Up @@ -460,7 +504,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > div#duplicate-id-aria',
'path': '2,HTML,1,BODY,47,SECTION,0,DIV',
'snippet': '<div id="duplicate-id-aria" class="duplicate-id-aria">',
'explanation': 'Fix any of the following:\n Document has multiple elements referenced with ARIA with the same id attribute: duplicate-id-aria',
'nodeLabel': 'body > section > div#duplicate-id-aria',
Expand All @@ -471,7 +514,6 @@ const expectations = {
{
relatedNode: {
'type': 'node',
'path': '2,HTML,1,BODY,47,SECTION,0,DIV,0,DIV',
'selector': 'body > section > div#duplicate-id-aria > div#duplicate-id-aria',
'snippet': '<div id="duplicate-id-aria">',
'nodeLabel': 'body > section > div#duplicate-id-aria > div#duplicate-id-aria',
Expand Down Expand Up @@ -508,7 +550,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > input#form-field-multiple-labels',
'path': '2,HTML,1,BODY,51,SECTION,2,INPUT',
'snippet': '<input type="checkbox" id="form-field-multiple-labels">',
'explanation': 'Fix all of the following:\n Multiple label elements is not widely supported in assistive technologies. Ensure the first label contains all necessary information.',
'nodeLabel': 'body > section > input#form-field-multiple-labels',
Expand All @@ -519,7 +560,6 @@ const expectations = {
{
relatedNode: {
'type': 'node',
'path': '2,HTML,1,BODY,51,SECTION,0,LABEL',
'selector': 'body > section > label#label1',
'snippet': '<label for="form-field-multiple-labels" id="label1">',
'nodeLabel': 'label1',
Expand All @@ -528,7 +568,6 @@ const expectations = {
{
relatedNode: {
'type': 'node',
'path': '2,HTML,1,BODY,51,SECTION,1,LABEL',
'selector': 'body > section > label',
'snippet': '<label for="form-field-multiple-labels">',
'nodeLabel': 'label2',
Expand Down Expand Up @@ -564,7 +603,6 @@ const expectations = {
node: {
'type': 'node',
'selector': 'body > section > h3',
'path': '2,HTML,1,BODY,55,SECTION,1,H3',
'snippet': '<h3>',
'explanation': 'Fix any of the following:\n Heading order invalid',
'nodeLabel': 'sub-sub-header',
Expand Down
44 changes: 44 additions & 0 deletions core/audits/accessibility/aria-conditional-attr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @license
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @fileoverview Ensures that ARIA attributes are used as specified for element roles.
* See base class in axe-audit.js for audit() implementation.
*/

import AxeAudit from './axe-audit.js';
import * as i18n from '../../lib/i18n/i18n.js';

const UIStrings = {
/** Title of an accessibility audit that checks if ARIA attributes are used as specified for element roles. This title is descriptive of the successful state and is shown to users when no user action is required. */
title: 'ARIA attributes are used as specified for element roles',
/** Title of an accessibility audit that checks if ARIA attributes are used as specified for element roles. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
failureTitle: 'ARIA attributes are not used as specified for element roles',
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
description: 'Using ARIA attributes on elements where they are not expected can result in ' +
'unpredictable behavior for assistive technologies. ' +
'[Learn more about conditional ARIA attributes](https://dequeuniversity.com/rules/axe/4.9/aria-conditional-attr).',
};

const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);

class AriaConditionalAttr extends AxeAudit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'aria-conditional-attr',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Accessibility'],
};
}
}

export default AriaConditionalAttr;
export {UIStrings};
43 changes: 43 additions & 0 deletions core/audits/accessibility/aria-deprecated-role.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @license
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @fileoverview Ensures that deprecated ARIA roles are not used.
* See base class in axe-audit.js for audit() implementation.
*/

import AxeAudit from './axe-audit.js';
import * as i18n from '../../lib/i18n/i18n.js';

const UIStrings = {
/** Title of an accessibility audit that checks if deprecated ARIA roles are used. This title is descriptive of the successful state and is shown to users when no user action is required. */
title: 'Deprecated ARIA roles were not used',
/** Title of an accessibility audit that checks if deprecated ARIA roles are used. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
failureTitle: 'Deprecated ARIA roles were used',
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
description: 'Deprecated ARIA roles will not be processed correctly by screen readers. ' +
'[Learn more about deprecated ARIA roles](https://dequeuniversity.com/rules/axe/4.9/aria-deprecated-role).',
};

const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);

class AriaDeprecatedRole extends AxeAudit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'aria-deprecated-role',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Accessibility'],
};
}
}

export default AriaDeprecatedRole;
export {UIStrings};
45 changes: 45 additions & 0 deletions core/audits/accessibility/aria-prohibited-attr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @fileoverview Ensures that deprecated ARIA roles are not used.
* See base class in axe-audit.js for audit() implementation.
*/

import AxeAudit from './axe-audit.js';
import * as i18n from '../../lib/i18n/i18n.js';

const UIStrings = {
/** Title of an accessibility audit that checks if elements use prohibited ARIA attributes. This title is descriptive of the successful state and is shown to users when no user action is required. */
title: 'Elements only use permitted ARIA attributes',
/** Title of an accessibility audit that checks if elements use prohibited ARIA attributes. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
failureTitle: 'Elements use prohibited ARIA attributes',
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
description: 'Element roles can prohibit certain ARIA attributes from being used ' +
'on that element. Using one of these prohibited roles can lead to undefined behavior by ' +
'assistive technology. ' +
'[Learn more about prohibited ARIA roles](https://dequeuniversity.com/rules/axe/4.9/aria-prohibited-attr).',
};

const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);

class AriaProhibitedAttr extends AxeAudit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'aria-prohibited-attr',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Accessibility'],
};
}
}

export default AriaProhibitedAttr;
export {UIStrings};
6 changes: 6 additions & 0 deletions core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,15 @@ const defaultConfig = {
'accessibility/aria-allowed-attr',
'accessibility/aria-allowed-role',
'accessibility/aria-command-name',
'accessibility/aria-conditional-attr',
'accessibility/aria-deprecated-role',
'accessibility/aria-dialog-name',
'accessibility/aria-hidden-body',
'accessibility/aria-hidden-focus',
'accessibility/aria-input-field-name',
'accessibility/aria-meter-name',
'accessibility/aria-progressbar-name',
'accessibility/aria-prohibited-attr',
'accessibility/aria-required-attr',
'accessibility/aria-required-children',
'accessibility/aria-required-parent',
Expand Down Expand Up @@ -455,12 +458,15 @@ const defaultConfig = {
{id: 'aria-allowed-attr', weight: 10, group: 'a11y-aria'},
{id: 'aria-allowed-role', weight: 1, group: 'a11y-aria'},
{id: 'aria-command-name', weight: 7, group: 'a11y-aria'},
{id: 'aria-conditional-attr', weight: 7, group: 'a11y-aria'},
{id: 'aria-deprecated-role', weight: 1, group: 'a11y-aria'},
{id: 'aria-dialog-name', weight: 7, group: 'a11y-aria'},
{id: 'aria-hidden-body', weight: 10, group: 'a11y-aria'},
{id: 'aria-hidden-focus', weight: 7, group: 'a11y-aria'},
{id: 'aria-input-field-name', weight: 7, group: 'a11y-aria'},
{id: 'aria-meter-name', weight: 7, group: 'a11y-aria'},
{id: 'aria-progressbar-name', weight: 7, group: 'a11y-aria'},
{id: 'aria-prohibited-attr', weight: 7, group: 'a11y-aria'},
{id: 'aria-required-attr', weight: 10, group: 'a11y-aria'},
{id: 'aria-required-children', weight: 10, group: 'a11y-aria'},
{id: 'aria-required-parent', weight: 10, group: 'a11y-aria'},
Expand Down
6 changes: 3 additions & 3 deletions core/gather/gatherers/accessibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ async function runA11yChecks() {
'area-alt': {enabled: false},
'aria-allowed-role': {enabled: true},
'aria-braille-equivalent': {enabled: false},
'aria-conditional-attr': {enabled: false},
'aria-deprecated-role': {enabled: false},
'aria-conditional-attr': {enabled: true},
'aria-deprecated-role': {enabled: true},
'aria-dialog-name': {enabled: true},
'aria-prohibited-attr': {enabled: false},
'aria-prohibited-attr': {enabled: true},
'aria-roledescription': {enabled: false},
'aria-treeitem-name': {enabled: true},
'aria-text': {enabled: true},
Expand Down
Loading
Loading