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(axe): input-button-name, role-img-alt, select-name #12700

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
24 changes: 24 additions & 0 deletions lighthouse-cli/test/cli/__snapshots__/index-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ Object {
Object {
"path": "accessibility/image-alt",
},
Object {
"path": "accessibility/input-button-name",
},
Object {
"path": "accessibility/input-image-alt",
},
Expand All @@ -297,6 +300,12 @@ Object {
Object {
"path": "accessibility/object-alt",
},
Object {
"path": "accessibility/role-img-alt",
},
Object {
"path": "accessibility/select-name",
},
Object {
"path": "accessibility/tabindex",
},
Expand Down Expand Up @@ -629,6 +638,11 @@ Object {
"id": "input-image-alt",
"weight": 10,
},
Object {
"group": "a11y-names-labels",
"id": "input-button-name",
"weight": 10,
},
Object {
"group": "a11y-names-labels",
"id": "label",
Expand Down Expand Up @@ -664,6 +678,16 @@ Object {
"id": "object-alt",
"weight": 3,
},
Object {
"group": "a11y-names-labels",
"id": "role-img-alt",
"weight": 3,
},
Object {
"group": "a11y-names-labels",
"id": "select-name",
"weight": 10,
},
Object {
"group": "a11y-navigation",
"id": "tabindex",
Expand Down
49 changes: 49 additions & 0 deletions lighthouse-core/audits/accessibility/input-button-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

/**
* @fileoverview Ensures input buttons have discernible text.
* See base class in axe-audit.js for audit() implementation.
*
* See PR where input-button-name was split out from button-name:
* @url https://github.com/dequelabs/axe-core/pull/1615
*/

const AxeAudit = require('./axe-audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Title of an accesibility audit that evaluates if all input button elements have names accessible to screen readers. This title is descriptive of the successful state and is shown to users when no user action is required. */
title: 'Input buttons have an accessible name',
/** Title of an accesibility audit that evaluates if all input button elements have names accessible to screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
failureTitle: 'Input buttons do not have an accessible name',
/** 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. 'Learn More' becomes link text to additional documentation. */
description: 'When an input button doesn\'t have an accessible name, screen readers announce ' +
'it as "button", making it unusable for users who rely on screen readers. ' +
'[Learn more](https://dequeuniversity.com/rules/axe/4.1/input-button-name?application=lighthouse).',
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

protip: we automatically ignore max-len for lines with URLs. so you dont have to do the string concat bs (which is liable to generating spacing issues)



const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

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

module.exports = InputButtonName;
module.exports.UIStrings = UIStrings;
47 changes: 47 additions & 0 deletions lighthouse-core/audits/accessibility/role-img-alt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

/**
* @fileoverview Ensures elements with [role="img"] have discernible text.
* See base class in axe-audit.js for audit() implementation.
*
* See PR where role-img-alt-name was split out from image-alt:
* @url https://github.com/dequelabs/axe-core/pull/1586
*/


Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change

const AxeAudit = require('./axe-audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Title of an accesibility audit that evaluates if all role=img elements are given names. This title is descriptive of the successful state and is shown to users when no user action is required. */
title: 'Elements with `[role=img]` have an accessible name',
/** Title of an accesibility audit that evaluates if all role=img elements are given names. 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 with `[role=img]` do not have an accessible name',
/** Description of a Lighthouse audit that tells the user *why* they should have accessible names for meter elements. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'When an element doesn\'t have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. [Learn more](https://dequeuniversity.com/rules/axe/4.1/role-img-alt?application=lighthouse).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

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

module.exports = RoleImgAlt;
module.exports.UIStrings = UIStrings;
48 changes: 48 additions & 0 deletions lighthouse-core/audits/accessibility/select-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

/**
* @fileoverview Ensures every select element has a label.
* See base class in axe-audit.js for audit() implementation.
*
* See PR where select-name was split out from label:
* @url https://github.com/dequelabs/axe-core/pull/2448
*/

const AxeAudit = require('./axe-audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Title of an accesibility audit that evaluates if all select elements have corresponding label elements. This title is descriptive of the successful state and is shown to users when no user action is required. */
title: 'Select elements have associated labels',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
title: 'Select elements have associated labels',
title: '`<select>` elements have associated labels',

so translators dont touch it

/** Title of an accesibility audit that evaluates if all select elements have corresponding label elements. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
failureTitle: 'Select elements do not have associated labels',
/** 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. 'Learn More' becomes link text to additional documentation. */
description: 'Labels ensure that dropdowns are announced properly by assistive ' +
'technologies, like screen readers. [Learn ' +
'more](https://dequeuniversity.com/rules/axe/4.1/select-name?application=lighthouse).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

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

module.exports = SelectName;
module.exports.UIStrings = UIStrings;
6 changes: 6 additions & 0 deletions lighthouse-core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ const defaultConfig = {
'accessibility/html-has-lang',
'accessibility/html-lang-valid',
'accessibility/image-alt',
'accessibility/input-button-name',
'accessibility/input-image-alt',
'accessibility/label',
'accessibility/link-name',
Expand All @@ -280,6 +281,8 @@ const defaultConfig = {
'accessibility/meta-refresh',
'accessibility/meta-viewport',
'accessibility/object-alt',
'accessibility/role-img-alt',
'accessibility/select-name',
'accessibility/tabindex',
'accessibility/td-headers-attr',
'accessibility/th-has-data-cells',
Expand Down Expand Up @@ -524,13 +527,16 @@ const defaultConfig = {
{id: 'html-lang-valid', weight: 3, group: 'a11y-language'},
{id: 'image-alt', weight: 10, group: 'a11y-names-labels'},
{id: 'input-image-alt', weight: 10, group: 'a11y-names-labels'},
{id: 'input-button-name', weight: 10, group: 'a11y-names-labels'},
{id: 'label', weight: 10, group: 'a11y-names-labels'},
{id: 'link-name', weight: 3, group: 'a11y-names-labels'},
{id: 'list', weight: 3, group: 'a11y-tables-lists'},
{id: 'listitem', weight: 3, group: 'a11y-tables-lists'},
{id: 'meta-refresh', weight: 10, group: 'a11y-best-practices'},
{id: 'meta-viewport', weight: 10, group: 'a11y-best-practices'},
{id: 'object-alt', weight: 3, group: 'a11y-names-labels'},
{id: 'role-img-alt', weight: 3, group: 'a11y-names-labels'},
{id: 'select-name', weight: 10, group: 'a11y-names-labels'},
{id: 'tabindex', weight: 3, group: 'a11y-navigation'},
{id: 'td-headers-attr', weight: 3, group: 'a11y-tables-lists'},
{id: 'th-has-data-cells', weight: 3, group: 'a11y-tables-lists'},
Expand Down
4 changes: 0 additions & 4 deletions lighthouse-core/gather/gatherers/accessibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ async function runA11yChecks(isTestMode = false) {
'color-contrast': {enabled: !isTestMode}, // See gatherer's test for explanation
'aria-roledescription': {enabled: false},
'scrollable-region-focusable': {enabled: false},
// TODO(paulirish): create audits and enable these 3.
'input-button-name': {enabled: false},
'role-img-alt': {enabled: false},
'select-name': {enabled: false},
},
});

Expand Down
2 changes: 1 addition & 1 deletion lighthouse-core/scripts/i18n/collect-strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ if (require.main === module) {

if (collisions > 0) {
console.log(`MEANING COLLISION: ${collisions} string(s) have the same content.`);
assert.equal(collisions, 30, `The number of duplicate strings have changed, update this assertion if that is expected, or reword strings. Collisions: ${collisionStrings.join('\n')}`);
assert.equal(collisions, 32, `The number of duplicate strings have changed, update this assertion if that is expected, or reword strings. Collisions: ${collisionStrings.join('\n')}`);
}

writeStringsToCtcFiles('en-US', strings);
Expand Down
18 changes: 18 additions & 0 deletions lighthouse-core/test/config/default-config-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,22 @@ describe('Default Config', () => {
}
}
});

it('audit ids are all in groups', () => {
const audits = defaultConfig.audits;

const auditsInCategories = new Set();
for (const category of Object.values(defaultConfig.categories)) {
category.auditRefs.forEach(ref => auditsInCategories.add(ref.id));
}
const categoryAuditsArr = Array.from(auditsInCategories).sort();

// Remove path to get audit IDs
const auditsArr = audits.map(auditPath => auditPath.split('/').slice(-1)[0]).sort()
// As covered in config.js, full-page-screenshot is a special no-category audit
.filter(id => id !== 'full-page-screenshot');

expect(categoryAuditsArr).toMatchObject(auditsArr);
expect(auditsArr).toMatchObject(categoryAuditsArr);
});
});
4 changes: 2 additions & 2 deletions lighthouse-core/test/fraggle-rock/api-test-pptr.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('Fraggle Rock API', () => {

const {auditResults, erroredAudits, failedAudits} = getAuditsBreakdown(lhr);
// TODO(FR-COMPAT): This assertion can be removed when full compatibility is reached.
expect(auditResults.length).toMatchInlineSnapshot(`78`);
expect(auditResults.length).toMatchInlineSnapshot(`81`);

expect(erroredAudits).toHaveLength(0);
expect(failedAudits.map(audit => audit.id)).toContain('label');
Expand Down Expand Up @@ -159,7 +159,7 @@ describe('Fraggle Rock API', () => {
const {lhr} = result;
const {auditResults, failedAudits, erroredAudits} = getAuditsBreakdown(lhr);
// TODO(FR-COMPAT): This assertion can be removed when full compatibility is reached.
expect(auditResults.length).toMatchInlineSnapshot(`151`);
expect(auditResults.length).toMatchInlineSnapshot(`154`);
expect(erroredAudits).toHaveLength(0);

const failedAuditIds = failedAudits.map(audit => audit.id);
Expand Down