core(scoreDisplayMode): change 'not-applicable' to 'notApplicable' (#6783)

This commit is contained in:
Shane Exterkamp 2019-01-04 17:16:38 -08:00 коммит произвёл Brendan Kenny
Родитель ca87ea3e79
Коммит c164e7580e
20 изменённых файлов: 146 добавлений и 125 удалений

Просмотреть файл

@ -58,7 +58,7 @@ An object containing the results of the audits, keyed by their name.
| rawValue | <code>boolean&#124;number</code> | The unscored value determined by the audit. Typically this will match the score if there's no additional information to impart. For performance audits, this value is typically a number indicating the metric value. |
| displayValue | `string` | The string to display in the report alongside audit results. If empty, nothing additional is shown. This is typically used to explain additional information such as the number and nature of failing items. |
| score | <code>number</code> | The scored value determined by the audit as a number `0-1`, representing displayed scores of 0-100. |
| scoreDisplayMode | <code>"binary"&#124;"numeric"&#124;"error"&#124;"manual"&#124;"not-applicable"&#124;"informative"</code> | A string identifying how the score should be interpreted for display i.e. is the audit pass/fail (score of 1 or 0), did it fail, should it be ignored, or are there shades of gray (scores between 0-1 inclusive). |
| scoreDisplayMode | <code>"binary"&#124;"numeric"&#124;"error"&#124;"manual"&#124;"notApplicable"&#124;"informative"</code> | A string identifying how the score should be interpreted for display i.e. is the audit pass/fail (score of 1 or 0), did it fail, should it be ignored, or are there shades of gray (scores between 0-1 inclusive). |
| details | `Object` | Extra information found by the audit necessary for display. The structure of this object varies from audit to audit. The structure of this object is somewhat stable between minor version bumps as this object is used to render the HTML report. |

Просмотреть файл

@ -58,10 +58,10 @@ module.exports = [
score: 1,
},
'user-timings': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'critical-request-chains': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'installable-manifest': {
score: 0,
@ -75,22 +75,22 @@ module.exports = [
score: 0,
},
'aria-valid-attr': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'aria-allowed-attr': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'color-contrast': {
score: 1,
},
'image-alt': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'label': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'tabindex': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'content-width': {
score: 1,
@ -121,10 +121,10 @@ module.exports = [
score: 1,
},
'user-timings': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'critical-request-chains': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'installable-manifest': {
score: 1,
@ -136,10 +136,10 @@ module.exports = [
score: 0,
},
'aria-valid-attr': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'aria-allowed-attr': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'color-contrast': {
score: 1,
@ -148,10 +148,10 @@ module.exports = [
score: 0,
},
'label': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'tabindex': {
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
'content-width': {
score: 1,

Просмотреть файл

@ -73,7 +73,7 @@ module.exports = [
},
'robots-txt': {
rawValue: true,
scoreDisplayMode: 'not-applicable',
scoreDisplayMode: 'notApplicable',
},
},
},

Просмотреть файл

@ -34,7 +34,7 @@ class Audit {
BINARY: 'binary',
MANUAL: 'manual',
INFORMATIVE: 'informative',
NOT_APPLICABLE: 'not-applicable',
NOT_APPLICABLE: 'notApplicable',
ERROR: 'error',
};
}

Просмотреть файл

@ -43,11 +43,14 @@ function processForProto(result) {
Object.keys(reportJson.audits).forEach(auditName => {
const audit = reportJson.audits[auditName];
// Rewrite the 'not-applicable' scoreDisplayMode to 'not_applicable'. #6201
// Rewrite 'not-applicable' and 'not_applicable' scoreDisplayMode to 'notApplicable'. #6201, #6783.
if (audit.scoreDisplayMode) {
if (audit.scoreDisplayMode === 'not-applicable') {
// @ts-ignore Breaking the LH.Result type
audit.scoreDisplayMode = 'not_applicable';
// @ts-ignore ts properly flags this as invalid as it should not happen,
// but remains in preprocessor to protect from proto translation errors from
// old LHRs.
// eslint-disable-next-line max-len
if (audit.scoreDisplayMode === 'not-applicable' || audit.scoreDisplayMode === 'not_applicable') {
audit.scoreDisplayMode = 'notApplicable';
}
}
// Drop raw values. #6199

Просмотреть файл

@ -22,7 +22,7 @@
/** @typedef {import('./report-renderer.js')} ReportRenderer */
/** @typedef {import('./details-renderer.js')} DetailsRenderer */
/** @typedef {import('./util.js')} Util */
/** @typedef {'failed'|'manual'|'passed'|'not-applicable'} TopLevelClumpId */
/** @typedef {'failed'|'manual'|'passed'|'notApplicable'} TopLevelClumpId */
class CategoryRenderer {
/**
@ -45,20 +45,20 @@ class CategoryRenderer {
*/
get _clumpDisplayInfo() {
return {
'failed': {
failed: {
className: 'lh-clump--failed',
},
'manual': {
manual: {
title: Util.UIStrings.manualAuditsGroupTitle,
className: 'lh-clump--manual',
},
'passed': {
passed: {
title: Util.UIStrings.passedAuditsGroupTitle,
className: 'lh-clump--passed',
},
'not-applicable': {
notApplicable: {
title: Util.UIStrings.notApplicableAuditsGroupTitle,
className: 'lh-clump--not-applicable',
className: 'lh-clump--notapplicable',
},
};
}
@ -153,7 +153,7 @@ class CategoryRenderer {
*/
_setRatingClass(element, score, scoreDisplayMode) {
const rating = Util.calculateRating(score, scoreDisplayMode);
element.classList.add(`lh-audit--${rating}`, `lh-audit--${scoreDisplayMode}`);
element.classList.add(`lh-audit--${rating}`, `lh-audit--${scoreDisplayMode.toLowerCase()}`);
return element;
}
@ -279,7 +279,7 @@ class CategoryRenderer {
/**
* Renders a clump (a grouping of groups), under a status of failed, manual,
* passed, or not-applicable. The result ends up something like:
* passed, or notApplicable. The result ends up something like:
*
* clump (e.g. 'failed')
* audit 1 (w/o group)
@ -370,7 +370,7 @@ class CategoryRenderer {
*/
_getClumpIdForAuditRef(auditRef) {
const scoreDisplayMode = auditRef.result.scoreDisplayMode;
if (scoreDisplayMode === 'manual' || scoreDisplayMode === 'not-applicable') {
if (scoreDisplayMode === 'manual' || scoreDisplayMode === 'notApplicable') {
return scoreDisplayMode;
}
@ -397,7 +397,7 @@ class CategoryRenderer {
clumps.set('failed', []);
clumps.set('manual', []);
clumps.set('passed', []);
clumps.set('not-applicable', []);
clumps.set('notApplicable', []);
// Sort audits into clumps.
for (const auditRef of category.auditRefs) {

Просмотреть файл

@ -31,7 +31,7 @@ class PwaCategoryRenderer extends CategoryRenderer {
const auditRefs = category.auditRefs;
// Regular audits aren't split up into pass/fail/not-applicable clumps, they're
// Regular audits aren't split up into pass/fail/notApplicable clumps, they're
// all put in a top-level clump that isn't expandable/collapsable.
const regularAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode !== 'manual');
const auditsElem = this._renderAudits(regularAuditRefs, groupDefinitions);

Просмотреть файл

@ -62,12 +62,13 @@ class Util {
if (typeof clone.categories !== 'object') throw new Error('No categories provided.');
clone.reportCategories = Object.values(clone.categories);
// The proto process turns 'not-applicable' into 'not_applicable'. Correct this to support both.
// TODO: remove when underscore/hyphen proto issue is resolved. See #6371, #6201.
// Turn 'not-applicable' and 'not_applicable' into 'notApplicable' to support old reports.
// TODO: remove when underscore/hyphen proto issue is resolved. See #6371, #6201, #6783.
for (const audit of Object.values(clone.audits)) {
// @ts-ignore tsc rightly flags that this value shouldn't occur.
if (audit.scoreDisplayMode === 'not_applicable') {
audit.scoreDisplayMode = 'not-applicable';
// eslint-disable-next-line max-len
if (audit.scoreDisplayMode === 'not_applicable' || audit.scoreDisplayMode === 'not-applicable') {
audit.scoreDisplayMode = 'notApplicable';
}
}
@ -143,7 +144,7 @@ class Util {
static showAsPassed(audit) {
switch (audit.scoreDisplayMode) {
case 'manual':
case 'not-applicable':
case 'notApplicable':
return true;
case 'error':
case 'informative':
@ -163,7 +164,7 @@ class Util {
*/
static calculateRating(score, scoreDisplayMode) {
// Handle edge cases first, manual and not applicable receive 'pass', errored audits receive 'error'
if (scoreDisplayMode === 'manual' || scoreDisplayMode === 'not-applicable') {
if (scoreDisplayMode === 'manual' || scoreDisplayMode === 'notApplicable') {
return RATINGS.PASS.label;
} else if (scoreDisplayMode === 'error') {
return RATINGS.ERROR.label;

Просмотреть файл

@ -604,7 +604,7 @@
content: '';
background-image: var(--check-icon-url);
}
.lh-clump--not-applicable > summary .lh-audit-group__header::before {
.lh-clump--notapplicable > summary .lh-audit-group__header::before {
content: '';
background-image: var(--remove-circle-icon-url);
}

Просмотреть файл

@ -90,7 +90,7 @@ describe('Audit', () => {
const providedResult = {rawValue: true, notApplicable: true};
const result = Audit.generateAuditResult(B, providedResult);
assert.equal(result.score, null);
assert.equal(result.scoreDisplayMode, 'not-applicable');
assert.equal(result.scoreDisplayMode, 'notApplicable');
});
it('sets state of failed audits', () => {

Просмотреть файл

@ -87,7 +87,7 @@ describe('processing for proto', () => {
const expectation = {
'audits': {
'critical-request-chains': {
'scoreDisplayMode': 'not_applicable',
'scoreDisplayMode': 'notApplicable',
'displayValue': 'hello %d | 123',
},
},

Просмотреть файл

@ -59,27 +59,42 @@ describe('CategoryRenderer', () => {
assert.equal(title.textContent, auditRef.result.title);
assert.ok(description.querySelector('a'), 'audit help text contains coverted markdown links');
assert.ok(auditDOM.classList.contains('lh-audit--fail'));
assert.ok(auditDOM.classList.contains(`lh-audit--${auditRef.result.scoreDisplayMode}`));
assert.ok(
auditDOM.classList.contains(`lh-audit--${auditRef.result.scoreDisplayMode.toLowerCase()}`));
});
it('renders an audit explanation when appropriate', () => {
const audit1 = renderer.renderAudit({
scoreDisplayMode: 'binary', score: 0,
result: {description: 'help text', explanation: 'A reason', title: 'Audit title'},
result: {
title: 'Audit title',
explanation: 'A reason',
description: 'help text',
scoreDisplayMode: 'binary',
score: 0,
},
});
assert.ok(audit1.querySelector('.lh-audit-explanation'));
const audit2 = renderer.renderAudit({
scoreDisplayMode: 'binary', score: 0,
result: {description: 'help text', title: 'Audit title'},
result: {
title: 'Audit title',
description: 'help text',
scoreDisplayMode: 'binary',
score: 0,
},
});
assert.ok(!audit2.querySelector('.lh-audit-explanation'));
});
it('renders an informative audit', () => {
const auditDOM = renderer.renderAudit({
id: 'informative', score: 0,
result: {title: 'It informs', description: 'help text', scoreDisplayMode: 'informative'},
id: 'informative',
result: {
title: 'It informs',
description: 'help text',
scoreDisplayMode: 'informative',
score: 0,
},
});
assert.ok(auditDOM.matches('.lh-audit--informative'));
@ -89,10 +104,11 @@ describe('CategoryRenderer', () => {
const auditResult = {
title: 'Audit',
description: 'Learn more',
scoreDisplayMode: 'informative',
warnings: ['It may not have worked!'],
score: 1,
};
const auditDOM = renderer.renderAudit({id: 'foo', score: 1, result: auditResult});
const auditDOM = renderer.renderAudit({id: 'foo', result: auditResult});
const warningEl = auditDOM.querySelector('.lh-warnings');
assert.ok(warningEl, 'did not render warning message');
assert.ok(warningEl.textContent.includes(auditResult.warnings[0]), 'warning message provided');
@ -102,10 +118,11 @@ describe('CategoryRenderer', () => {
const auditResult = {
title: 'Audit',
description: 'Learn more',
scoreDisplayMode: 'informative',
warnings: ['It may not have worked!', 'You should read this, though'],
score: 1,
};
const auditDOM = renderer.renderAudit({id: 'foo', score: 1, result: auditResult});
const auditDOM = renderer.renderAudit({id: 'foo', result: auditResult});
const warningEl = auditDOM.querySelector('.lh-warnings');
assert.ok(warningEl, 'did not render warning message');
assert.ok(warningEl.textContent.includes(auditResult.warnings[0]), '1st warning provided');
@ -158,19 +175,19 @@ describe('CategoryRenderer', () => {
const a11yCategory = sampleResults.reportCategories.find(cat => cat.id === 'accessibility');
const categoryDOM = renderer.render(a11yCategory, sampleResults.categoryGroups);
assert.ok(categoryDOM.querySelector(
'.lh-clump--not-applicable .lh-audit-group__summary'));
'.lh-clump--notapplicable .lh-audit-group__summary'));
const notApplicableCount = a11yCategory.auditRefs.reduce((sum, audit) =>
sum += audit.result.scoreDisplayMode === 'not-applicable' ? 1 : 0, 0);
sum += audit.result.scoreDisplayMode === 'notApplicable' ? 1 : 0, 0);
assert.equal(
categoryDOM.querySelectorAll('.lh-clump--not-applicable .lh-audit').length,
categoryDOM.querySelectorAll('.lh-clump--notapplicable .lh-audit').length,
notApplicableCount,
'score shows informative and dash icon'
);
const bestPracticeCat = sampleResults.reportCategories.find(cat => cat.id === 'best-practices');
const categoryDOM2 = renderer.render(bestPracticeCat, sampleResults.categoryGroups);
assert.ok(!categoryDOM2.querySelector('.lh-clump--not-applicable'));
assert.ok(!categoryDOM2.querySelector('.lh-clump--notapplicable'));
});
describe('category with groups', () => {
@ -202,7 +219,7 @@ describe('CategoryRenderer', () => {
it.skip('renders the failed audits grouped by group', () => {
const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
const failedAudits = category.auditRefs.filter(audit => {
return audit.result.score !== 1 && !audit.result.scoreDisplayMode === 'not-applicable';
return audit.result.score !== 1 && !audit.result.scoreDisplayMode === 'notApplicable';
});
const failedAuditTags = new Set(failedAudits.map(audit => audit.group));
@ -213,7 +230,7 @@ describe('CategoryRenderer', () => {
it('renders the passed audits grouped by group', () => {
const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
const passedAudits = category.auditRefs.filter(audit =>
audit.result.scoreDisplayMode !== 'not-applicable' && audit.result.score === 1);
audit.result.scoreDisplayMode !== 'notApplicable' && audit.result.score === 1);
const passedAuditTags = new Set(passedAudits.map(audit => audit.group));
const passedAuditGroups = categoryDOM.querySelectorAll('.lh-clump--passed .lh-audit-group');
@ -233,7 +250,7 @@ describe('CategoryRenderer', () => {
const failedAudits = elem.querySelectorAll('.lh-clump--failed .lh-audit__index');
const manualAudits = elem.querySelectorAll('.lh-clump--manual .lh-audit__index');
const notApplicableAudits =
elem.querySelectorAll('.lh-clump--not-applicable .lh-audit__index');
elem.querySelectorAll('.lh-clump--notapplicable .lh-audit__index');
const assertAllTheIndices = (nodeList) => {
// Must be at least one for a decent test.

Просмотреть файл

@ -180,12 +180,12 @@ describe('ReportRenderer', () => {
assert.equal(renderer._templateContext, otherDocument);
});
it('renders `not_applicable` audits as `not-applicable`', () => {
it('renders `not_applicable` audits as `notApplicable`', () => {
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResultsOrig));
let notApplicableCount = 0;
Object.values(clonedSampleResult.audits).forEach(audit => {
if (audit.scoreDisplayMode === 'not-applicable') {
if (audit.scoreDisplayMode === 'notApplicable') {
notApplicableCount++;
audit.scoreDisplayMode = 'not_applicable';
}
@ -196,8 +196,7 @@ describe('ReportRenderer', () => {
const container = renderer._dom._document.body;
const reportElement = renderer.renderReport(sampleResults, container);
const notApplicableElementCount = reportElement
.querySelectorAll('.lh-audit--not-applicable').length;
.querySelectorAll('.lh-audit--notapplicable').length;
assert.strictEqual(notApplicableCount, notApplicableElementCount);
});
});

Просмотреть файл

@ -171,12 +171,12 @@ describe('util helpers', () => {
});
describe('#prepareReportResult', () => {
it('corrects underscored `not-applicable` scoreDisplayMode', () => {
it('corrects underscored `notApplicable` scoreDisplayMode', () => {
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
let notApplicableCount = 0;
Object.values(clonedSampleResult.audits).forEach(audit => {
if (audit.scoreDisplayMode === 'not-applicable') {
if (audit.scoreDisplayMode === 'notApplicable') {
notApplicableCount++;
audit.scoreDisplayMode = 'not_applicable';
}

Просмотреть файл

@ -290,7 +290,7 @@
"title": "User Timing marks and measures",
"description": "Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true,
"details": {
"type": "table",
@ -1086,7 +1086,7 @@
"title": "`[accesskey]` values are unique",
"description": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. [Learn more](https://dequeuniversity.com/rules/axe/2.2/accesskeys?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-allowed-attr": {
@ -1094,7 +1094,7 @@
"title": "`[aria-*]` attributes match their roles",
"description": "Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-allowed-attr?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-required-attr": {
@ -1102,7 +1102,7 @@
"title": "`[role]`s have all required `[aria-*]` attributes",
"description": "Some ARIA roles have required attributes that describe the state of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-attr?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-required-children": {
@ -1110,7 +1110,7 @@
"title": "Elements with `[role]` that require specific children `[role]`s, are present",
"description": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-children?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-required-parent": {
@ -1118,7 +1118,7 @@
"title": "`[role]`s are contained by their required parent element",
"description": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-parent?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-roles": {
@ -1126,7 +1126,7 @@
"title": "`[role]` values are valid",
"description": "ARIA roles must have valid values in order to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-roles?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-valid-attr-value": {
@ -1134,7 +1134,7 @@
"title": "`[aria-*]` attributes have valid values",
"description": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr-value?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"aria-valid-attr": {
@ -1142,7 +1142,7 @@
"title": "`[aria-*]` attributes are valid and not misspelled",
"description": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"audio-caption": {
@ -1150,7 +1150,7 @@
"title": "`<audio>` elements contain a `<track>` element with `[kind=\"captions\"]`",
"description": "Captions make audio elements usable for deaf or hearing-impaired users, providing critical information such as who is talking, what they're saying, and other non-speech information. [Learn more](https://dequeuniversity.com/rules/axe/2.2/audio-caption?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"button-name": {
@ -1158,7 +1158,7 @@
"title": "Buttons have an accessible name",
"description": "When a 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/2.2/button-name?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"bypass": {
@ -1223,7 +1223,7 @@
"title": "`<dl>`'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements.",
"description": "When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. [Learn more](https://dequeuniversity.com/rules/axe/2.2/definition-list?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"dlitem": {
@ -1231,7 +1231,7 @@
"title": "Definition list items are wrapped in `<dl>` elements",
"description": "Definition list items (`<dt>` and `<dd>`) must be wrapped in a parent `<dl>` element to ensure that screen readers can properly announce them. [Learn more](https://dequeuniversity.com/rules/axe/2.2/dlitem?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"document-title": {
@ -1265,7 +1265,7 @@
"title": "`<frame>` or `<iframe>` elements have a title",
"description": "Screen reader users rely on frame titles to describe the contents of frames. [Learn more](https://dequeuniversity.com/rules/axe/2.2/frame-title?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"html-has-lang": {
@ -1308,7 +1308,7 @@
"title": "`<html>` element has a valid value for its `[lang]` attribute",
"description": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) helps screen readers announce text properly. [Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"image-alt": {
@ -1371,7 +1371,7 @@
"title": "`<input type=\"image\">` elements have `[alt]` text",
"description": "When an image is being used as an `<input>` button, providing alternative text can help screen reader users understand the purpose of the button. [Learn more](https://dequeuniversity.com/rules/axe/2.2/input-image-alt?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"label": {
@ -1435,7 +1435,7 @@
"title": "Presentational `<table>` elements avoid using `<th>`, `<caption>` or the `[summary]` attribute.",
"description": "A table being used for layout purposes should not include data elements, such as the th or caption elements or the summary attribute, because this can create a confusing experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/layout-table?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"link-name": {
@ -1491,7 +1491,7 @@
"title": "Lists contain only `<li>` elements and script supporting elements (`<script>` and `<template>`).",
"description": "Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. [Learn more](https://dequeuniversity.com/rules/axe/2.2/list?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"listitem": {
@ -1499,7 +1499,7 @@
"title": "List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements",
"description": "Screen readers require list items (`<li>`) to be contained within a parent `<ul>` or `<ol>` to be announced properly. [Learn more](https://dequeuniversity.com/rules/axe/2.2/listitem?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"meta-refresh": {
@ -1507,7 +1507,7 @@
"title": "The document does not use `<meta http-equiv=\"refresh\">`",
"description": "Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. [Learn more](https://dequeuniversity.com/rules/axe/2.2/meta-refresh?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"meta-viewport": {
@ -1528,7 +1528,7 @@
"title": "`<object>` elements have `[alt]` text",
"description": "Screen readers cannot translate non-text content. Adding alt text to `<object>` elements helps screen readers convey meaning to users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/object-alt?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"tabindex": {
@ -1536,7 +1536,7 @@
"title": "No element has a `[tabindex]` value greater than 0",
"description": "A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/2.2/tabindex?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"td-headers-attr": {
@ -1544,7 +1544,7 @@
"title": "Cells in a `<table>` element that use the `[headers]` attribute only refer to other cells of that same table.",
"description": "Screen readers have features to make navigating tables easier. Ensuring `<td>` cells using the `[headers]` attribute only refer to other cells in the same table may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/td-headers-attr?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"th-has-data-cells": {
@ -1552,7 +1552,7 @@
"title": "`<th>` elements and elements with `[role=\"columnheader\"/\"rowheader\"]` have data cells they describe.",
"description": "Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/th-has-data-cells?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"valid-lang": {
@ -1560,7 +1560,7 @@
"title": "`[lang]` attributes have a valid value",
"description": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) on elements helps ensure that text is pronounced correctly by a screen reader. [Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"video-caption": {
@ -1568,7 +1568,7 @@
"title": "`<video>` elements contain a `<track>` element with `[kind=\"captions\"]`",
"description": "When a video provides a caption it is easier for deaf and hearing impaired users to access its information. [Learn more](https://dequeuniversity.com/rules/axe/2.2/video-caption?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"video-description": {
@ -1576,7 +1576,7 @@
"title": "`<video>` elements contain a `<track>` element with `[kind=\"description\"]`",
"description": "Audio descriptions provide relevant information for videos that dialogue cannot, such as facial expressions and scenes. [Learn more](https://dequeuniversity.com/rules/axe/2.2/video-description?application=lighthouse).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"custom-controls-labels": {
@ -2708,7 +2708,7 @@
"title": "Document has a valid `rel=canonical`",
"description": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).",
"score": null,
"scoreDisplayMode": "not-applicable",
"scoreDisplayMode": "notApplicable",
"rawValue": true
},
"mobile-friendly": {

Просмотреть файл

@ -64,9 +64,9 @@ describe('ReportScoring', () => {
it('should weight notApplicable audits as 0', () => {
const resultsByAuditId = {
'my-boolean-audit': {score: 1, extendedInfo: {}, scoreDisplayMode: 'not-applicable'},
'my-boolean-audit': {score: 1, extendedInfo: {}, scoreDisplayMode: 'notApplicable'},
'my-scored-audit': {score: 1},
'my-failed-audit': {score: 0.2, scoreDisplayMode: 'not-applicable'},
'my-failed-audit': {score: 0.2, scoreDisplayMode: 'notApplicable'},
'my-boolean-failed-audit': {score: 0},
};

Просмотреть файл

@ -247,6 +247,7 @@ message AuditResult {
// The audit turned out to not apply to the page. Score is NaN and should be
// ignored.
not_applicable = 4;
notApplicable = 7;
// The audit exists only to tell you to review something yourself. Score is
// NaN and should be ignored
manual = 5;

Просмотреть файл

@ -4,7 +4,7 @@
"description": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. [Learn more](https://dequeuniversity.com/rules/axe/2.2/accesskeys?application=lighthouse).",
"id": "accesskeys",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[accesskey]` values are unique"
},
"appcache-manifest": {
@ -19,56 +19,56 @@
"description": "Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-allowed-attr?application=lighthouse).",
"id": "aria-allowed-attr",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[aria-*]` attributes match their roles"
},
"aria-required-attr": {
"description": "Some ARIA roles have required attributes that describe the state of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-attr?application=lighthouse).",
"id": "aria-required-attr",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[role]`s have all required `[aria-*]` attributes"
},
"aria-required-children": {
"description": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-children?application=lighthouse).",
"id": "aria-required-children",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Elements with `[role]` that require specific children `[role]`s, are present"
},
"aria-required-parent": {
"description": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-parent?application=lighthouse).",
"id": "aria-required-parent",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[role]`s are contained by their required parent element"
},
"aria-roles": {
"description": "ARIA roles must have valid values in order to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-roles?application=lighthouse).",
"id": "aria-roles",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[role]` values are valid"
},
"aria-valid-attr": {
"description": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr?application=lighthouse).",
"id": "aria-valid-attr",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[aria-*]` attributes are valid and not misspelled"
},
"aria-valid-attr-value": {
"description": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr-value?application=lighthouse).",
"id": "aria-valid-attr-value",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[aria-*]` attributes have valid values"
},
"audio-caption": {
"description": "Captions make audio elements usable for deaf or hearing-impaired users, providing critical information such as who is talking, what they're saying, and other non-speech information. [Learn more](https://dequeuniversity.com/rules/axe/2.2/audio-caption?application=lighthouse).",
"id": "audio-caption",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<audio>` elements contain a `<track>` element with `[kind=\"captions\"]`"
},
"bootup-time": {
@ -134,7 +134,7 @@
"description": "When a 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/2.2/button-name?application=lighthouse).",
"id": "button-name",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Buttons have an accessible name"
},
"bypass": {
@ -153,7 +153,7 @@
"description": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).",
"id": "canonical",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Document has a valid `rel=canonical`"
},
"color-contrast": {
@ -370,7 +370,7 @@
"description": "When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. [Learn more](https://dequeuniversity.com/rules/axe/2.2/definition-list?application=lighthouse).",
"id": "definition-list",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<dl>`'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements."
},
"deprecations": {
@ -423,7 +423,7 @@
"description": "Definition list items (`<dt>` and `<dd>`) must be wrapped in a parent `<dl>` element to ensure that screen readers can properly announce them. [Learn more](https://dequeuniversity.com/rules/axe/2.2/dlitem?application=lighthouse).",
"id": "dlitem",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Definition list items are wrapped in `<dl>` elements"
},
"doctype": {
@ -730,7 +730,7 @@
"description": "Screen reader users rely on frame titles to describe the contents of frames. [Learn more](https://dequeuniversity.com/rules/axe/2.2/frame-title?application=lighthouse).",
"id": "frame-title",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<frame>` or `<iframe>` elements have a title"
},
"geolocation-on-start": {
@ -822,7 +822,7 @@
"description": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) helps screen readers announce text properly. [Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).",
"id": "html-lang-valid",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<html>` element has a valid value for its `[lang]` attribute"
},
"http-status-code": {
@ -930,7 +930,7 @@
"description": "When an image is being used as an `<input>` button, providing alternative text can help screen reader users understand the purpose of the button. [Learn more](https://dequeuniversity.com/rules/axe/2.2/input-image-alt?application=lighthouse).",
"id": "input-image-alt",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<input type=\"image\">` elements have `[alt]` text"
},
"installable-manifest": {
@ -1087,7 +1087,7 @@
"description": "A table being used for layout purposes should not include data elements, such as the th or caption elements or the summary attribute, because this can create a confusing experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/layout-table?application=lighthouse).",
"id": "layout-table",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Presentational `<table>` elements avoid using `<th>`, `<caption>` or the `[summary]` attribute."
},
"link-name": {
@ -1154,14 +1154,14 @@
"description": "Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. [Learn more](https://dequeuniversity.com/rules/axe/2.2/list?application=lighthouse).",
"id": "list",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Lists contain only `<li>` elements and script supporting elements (`<script>` and `<template>`)."
},
"listitem": {
"description": "Screen readers require list items (`<li>`) to be contained within a parent `<ul>` or `<ol>` to be announced properly. [Learn more](https://dequeuniversity.com/rules/axe/2.2/listitem?application=lighthouse).",
"id": "listitem",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements"
},
"load-fast-enough-for-pwa": {
@ -1257,7 +1257,7 @@
"description": "Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. [Learn more](https://dequeuniversity.com/rules/axe/2.2/meta-refresh?application=lighthouse).",
"id": "meta-refresh",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "The document does not use `<meta http-equiv=\"refresh\">`"
},
"meta-viewport": {
@ -1646,7 +1646,7 @@
"description": "Screen readers cannot translate non-text content. Adding alt text to `<object>` elements helps screen readers convey meaning to users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/object-alt?application=lighthouse).",
"id": "object-alt",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<object>` elements have `[alt]` text"
},
"offline-start-url": {
@ -1935,21 +1935,21 @@
"description": "A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/2.2/tabindex?application=lighthouse).",
"id": "tabindex",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "No element has a `[tabindex]` value greater than 0"
},
"td-headers-attr": {
"description": "Screen readers have features to make navigating tables easier. Ensuring `<td>` cells using the `[headers]` attribute only refer to other cells in the same table may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/td-headers-attr?application=lighthouse).",
"id": "td-headers-attr",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "Cells in a `<table>` element that use the `[headers]` attribute only refer to other cells of that same table."
},
"th-has-data-cells": {
"description": "Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/2.2/th-has-data-cells?application=lighthouse).",
"id": "th-has-data-cells",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<th>` elements and elements with `[role=\"columnheader\"/\"rowheader\"]` have data cells they describe."
},
"themed-omnibox": {
@ -2135,7 +2135,7 @@
},
"id": "user-timings",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "User Timing marks and measures"
},
"uses-http2": {
@ -2530,21 +2530,21 @@
"description": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) on elements helps ensure that text is pronounced correctly by a screen reader. [Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).",
"id": "valid-lang",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`[lang]` attributes have a valid value"
},
"video-caption": {
"description": "When a video provides a caption it is easier for deaf and hearing impaired users to access its information. [Learn more](https://dequeuniversity.com/rules/axe/2.2/video-caption?application=lighthouse).",
"id": "video-caption",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<video>` elements contain a `<track>` element with `[kind=\"captions\"]`"
},
"video-description": {
"description": "Audio descriptions provide relevant information for videos that dialogue cannot, such as facial expressions and scenes. [Learn more](https://dequeuniversity.com/rules/axe/2.2/video-description?application=lighthouse).",
"id": "video-description",
"score": null,
"scoreDisplayMode": "not_applicable",
"scoreDisplayMode": "notApplicable",
"title": "`<video>` elements contain a `<track>` element with `[kind=\"description\"]`"
},
"viewport": {

6
types/audit.d.ts поставляемый
Просмотреть файл

@ -32,7 +32,7 @@ declare global {
BINARY: 'binary';
MANUAL: 'manual';
INFORMATIVE: 'informative';
NOT_APPLICABLE: 'not-applicable';
NOT_APPLICABLE: 'notApplicable';
ERROR: 'error';
}
@ -120,7 +120,7 @@ declare global {
warnings?: string[];
score?: number;
extendedInfo?: {[p: string]: any};
/** Overrides scoreDisplayMode with not-applicable if set to true */
/** Overrides scoreDisplayMode with notApplicable if set to true */
notApplicable?: boolean;
// TODO(bckenny): define details
details?: object;
@ -139,7 +139,7 @@ declare global {
* 'binary': pass/fail audit (0 and 1 are only possible scores).
* 'numeric': scores of 0-1 (map to displayed scores of 0-100).
* 'informative': the audit is an FYI only, and can't be interpreted as pass/fail. Score is null and should be ignored.
* 'not-applicable': the audit turned out to not apply to the page. Score is null and should be ignored.
* 'notApplicable': the audit turned out to not apply to the page. Score is null and should be ignored.
* 'manual': The audit exists only to tell you to review something yourself. Score is null and should be ignored.
* 'error': There was an error while running the audit (check `errorMessage` for details). Score is null and should be ignored.
*/

4
types/lhr-lite.d.ts поставляемый
Просмотреть файл

@ -62,11 +62,11 @@ declare global {
* 'binary': pass/fail audit (0 and 1 are only possible scores).
* 'numeric': scores of 0-1 (map to displayed scores of 0-100).
* 'informative': the audit is an FYI only, and can't be interpreted as pass/fail. Score is null and should be ignored.
* 'not-applicable': the audit turned out to not apply to the page. Score is null and should be ignored.
* 'notApplicable': the audit turned out to not apply to the page. Score is null and should be ignored.
* 'manual': The audit exists only to tell you to review something yourself. Score is null and should be ignored.
* 'error': There was an error while running the audit (check `errorMessage` for details). Score is null and should be ignored.
*/
scoreDisplayMode: 'binary' | 'numeric' | 'informative' | 'not-applicable' | 'manual' | 'error';
scoreDisplayMode: 'binary' | 'numeric' | 'informative' | 'notApplicable' | 'manual' | 'error';
/** An explanation of audit-related issues encountered on the test page. */
explanation?: string;
/** Extra information provided by some types of audits. */