Skip to content

Commit

Permalink
feat: add groups to config, accessibility renderer (#2057)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce authored and brendankenny committed May 3, 2017
1 parent 90a9dc5 commit cee0dea
Show file tree
Hide file tree
Showing 12 changed files with 2,998 additions and 842 deletions.
18 changes: 16 additions & 2 deletions lighthouse-core/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ function validatePasses(passes, audits, rootPath) {
});
}

function validateCategories(categories, audits, auditResults) {
function validateCategories(categories, audits, auditResults, groups) {
if (!categories) {
return;
}
Expand All @@ -167,6 +167,14 @@ function validateCategories(categories, audits, auditResults) {
if (!auditIds.includes(audit.id)) {
throw new Error(`could not find ${audit.id} audit for category ${categoryId}`);
}

if (categoryId === 'accessibility' && !audit.group) {
throw new Error(`${audit.id} accessibility audit does not have a group`);
}

if (audit.group && !groups[audit.group]) {
throw new Error(`${audit.id} references unknown group ${audit.group}`);
}
});
});
}
Expand Down Expand Up @@ -321,10 +329,11 @@ class Config {
this._audits = Config.requireAudits(configJSON.audits, this._configDir);
this._artifacts = expandArtifacts(configJSON.artifacts);
this._categories = configJSON.categories;
this._groups = configJSON.groups;

// validatePasses must follow after audits are required
validatePasses(configJSON.passes, this._audits, this._configDir);
validateCategories(configJSON.categories, this._audits, this._auditResults);
validateCategories(configJSON.categories, this._audits, this._auditResults, this._groups);
}

/**
Expand Down Expand Up @@ -582,6 +591,11 @@ class Config {
get categories() {
return this._categories;
}

/** @type {Object<string, {title: string, description: string}>|undefined} */
get groups() {
return this._groups;
}
}

module.exports = Config;
104 changes: 69 additions & 35 deletions lighthouse-core/config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,40 @@ module.exports = {
}
}]
}],
"groups": {
"a11y-color-contrast": {
"title": "Color Contrast Is Satisfactory",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-describe-contents": {
"title": "Elements Describe Contents Well",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-well-structured": {
"title": "Elements Are Well Structured",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-aria": {
"title": "ARIA Attributes Follow Best Practices",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-correct-attributes": {
"title": "Elements Use Attributes Correctly",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-element-names": {
"title": "Elements Have Discernable Names",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-language": {
"title": "Page Specifies Valid Language",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
"a11y-meta": {
"title": "Meta Tags Used Properly",
"description": "Screen readers and other assitive technologies require annotations to understand otherwise ambiguous content."
},
},
"categories": {
"pwa": {
"name": "Progressive Web App",
Expand Down Expand Up @@ -631,41 +665,41 @@ module.exports = {
"name": "Accessibility",
"description": "These checks highlight opportunities to [improve the accessibility of your app](https://developers.google.com/web/fundamentals/accessibility).",
"audits": [
{"id": "accesskeys", "weight": 1},
{"id": "aria-allowed-attr", "weight": 1},
{"id": "aria-required-attr", "weight": 1},
{"id": "aria-required-children", "weight": 1},
{"id": "aria-required-parent", "weight": 1},
{"id": "aria-roles", "weight": 1},
{"id": "aria-valid-attr-value", "weight": 1},
{"id": "aria-valid-attr", "weight": 1},
{"id": "audio-caption", "weight": 1},
{"id": "button-name", "weight": 1},
{"id": "bypass", "weight": 1},
{"id": "color-contrast", "weight": 1},
{"id": "definition-list", "weight": 1},
{"id": "dlitem", "weight": 1},
{"id": "document-title", "weight": 1},
{"id": "duplicate-id", "weight": 1},
{"id": "frame-title", "weight": 1},
{"id": "html-has-lang", "weight": 1},
{"id": "html-lang-valid", "weight": 1},
{"id": "image-alt", "weight": 1},
{"id": "input-image-alt", "weight": 1},
{"id": "label", "weight": 1},
{"id": "layout-table", "weight": 1},
{"id": "link-name", "weight": 1},
{"id": "list", "weight": 1},
{"id": "listitem", "weight": 1},
{"id": "meta-refresh", "weight": 1},
{"id": "meta-viewport", "weight": 1},
{"id": "object-alt", "weight": 1},
{"id": "tabindex", "weight": 1},
{"id": "td-headers-attr", "weight": 1},
{"id": "th-has-data-cells", "weight": 1},
{"id": "valid-lang", "weight": 1},
{"id": "video-caption", "weight": 1},
{"id": "video-description", "weight": 1},
{"id": "accesskeys", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "aria-allowed-attr", "weight": 1, "group": "a11y-aria"},
{"id": "aria-required-attr", "weight": 1, "group": "a11y-aria"},
{"id": "aria-required-children", "weight": 1, "group": "a11y-aria"},
{"id": "aria-required-parent", "weight": 1, "group": "a11y-aria"},
{"id": "aria-roles", "weight": 1, "group": "a11y-aria"},
{"id": "aria-valid-attr-value", "weight": 1, "group": "a11y-aria"},
{"id": "aria-valid-attr", "weight": 1, "group": "a11y-aria"},
{"id": "audio-caption", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "button-name", "weight": 1, "group": "a11y-element-names"},
{"id": "bypass", "weight": 1, "group": "a11y-describe-contents"},
{"id": "color-contrast", "weight": 1, "group": "a11y-color-contrast"},
{"id": "definition-list", "weight": 1, "group": "a11y-well-structured"},
{"id": "dlitem", "weight": 1, "group": "a11y-well-structured"},
{"id": "document-title", "weight": 1, "group": "a11y-describe-contents"},
{"id": "duplicate-id", "weight": 1, "group": "a11y-well-structured"},
{"id": "frame-title", "weight": 1, "group": "a11y-describe-contents"},
{"id": "html-has-lang", "weight": 1, "group": "a11y-language"},
{"id": "html-lang-valid", "weight": 1, "group": "a11y-language"},
{"id": "image-alt", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "input-image-alt", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "label", "weight": 1, "group": "a11y-describe-contents"},
{"id": "layout-table", "weight": 1, "group": "a11y-describe-contents"},
{"id": "link-name", "weight": 1, "group": "a11y-element-names"},
{"id": "list", "weight": 1, "group": "a11y-well-structured"},
{"id": "listitem", "weight": 1, "group": "a11y-well-structured"},
{"id": "meta-refresh", "weight": 1, "group": "a11y-meta"},
{"id": "meta-viewport", "weight": 1, "group": "a11y-meta"},
{"id": "object-alt", "weight": 1, "group": "a11y-describe-contents"},
{"id": "tabindex", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "td-headers-attr", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "th-has-data-cells", "weight": 1, "group": "a11y-correct-attributes"},
{"id": "valid-lang", "weight": 1, "group": "a11y-language"},
{"id": "video-caption", "weight": 1, "group": "a11y-describe-contents"},
{"id": "video-description", "weight": 1, "group": "a11y-describe-contents"},
]
},
"best-practices": {
Expand Down
97 changes: 96 additions & 1 deletion lighthouse-core/report/v2/renderer/category-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,23 @@ class CategoryRenderer {

/**
* @param {!ReportRenderer.CategoryJSON} category
* @param {!Object<string, !ReportRenderer.GroupJSON>} groups
* @return {!Element}
*/
render(category) {
render(category, groups) {
switch (category.id) {
case 'accessibility':
return this._renderAccessibilityCategory(category, groups);
default:
return this._renderDefaultCategory(category);
}
}

/**
* @param {!ReportRenderer.CategoryJSON} category
* @return {!Element}
*/
_renderDefaultCategory(category) {
const element = this._dom.createElement('div', 'lh-category');
element.id = category.id;
element.appendChild(this._renderCategoryScore(category));
Expand Down Expand Up @@ -174,6 +188,87 @@ class CategoryRenderer {
element.appendChild(passedElem);
return element;
}

/**
* @param {!Array<!ReportRenderer.AuditJSON>} audits
* @param {!ReportRenderer.GroupJSON} group
* @return {!Element}
*/
_renderAuditGroup(audits, group) {
const auditGroupElem = this._dom.createElement('details',
'lh-audit-group lh-expandable-details');
const auditGroupHeader = this._dom.createElement('div',
'lh-audit-group__header lh-expandable-details__header');
auditGroupHeader.textContent = group.title;

const auditGroupDescription = this._dom.createElement('div', 'lh-audit-group__description');
auditGroupDescription.textContent = group.description;

const auditGroupSummary = this._dom.createElement('summary',
'lh-audit-group__summary lh-expandable-details__summary');
const auditGroupArrow = this._dom.createElement('div', 'lh-toggle-arrow', {
title: 'See audits',
});
auditGroupSummary.appendChild(auditGroupHeader);
auditGroupSummary.appendChild(auditGroupArrow);

auditGroupElem.appendChild(auditGroupSummary);
auditGroupElem.appendChild(auditGroupDescription);
audits.forEach(audit => auditGroupElem.appendChild(this._renderAudit(audit)));
return auditGroupElem;
}

/**
* @param {!ReportRenderer.CategoryJSON} category
* @param {!Object<string, !ReportRenderer.GroupJSON>} groups
* @return {!Element}
*/
_renderAccessibilityCategory(category, groupDefinitions) {
const element = this._dom.createElement('div', 'lh-category');
element.id = category.id;
element.appendChild(this._renderCategoryScore(category));

const auditsGroupedByGroup = category.audits.reduce((indexed, audit) => {
const groupId = audit.group;
const groups = indexed[groupId] || {passed: [], failed: []};

if (audit.score === 100) {
groups.passed.push(audit);
} else {
groups.failed.push(audit);
}

indexed[groupId] = groups;
return indexed;
}, {});

const passedElements = [];
Object.keys(auditsGroupedByGroup).forEach(groupId => {
const group = groupDefinitions[groupId];
const groups = auditsGroupedByGroup[groupId];
if (groups.failed.length) {
const auditGroupElem = this._renderAuditGroup(groups.failed, group);
auditGroupElem.open = true;
element.appendChild(auditGroupElem);
}

if (groups.passed.length) {
const auditGroupElem = this._renderAuditGroup(groups.passed, group);
passedElements.push(auditGroupElem);
}
});

// don't create a passed section if there are no passed
if (!passedElements.length) return element;

const passedElem = this._dom.createElement('details', 'lh-passed-audits');
const passedSummary = this._dom.createElement('summary', 'lh-passed-audits-summary');
passedElem.appendChild(passedSummary);
passedSummary.textContent = `View ${passedElements.length} passed items`;
passedElements.forEach(elem => passedElem.appendChild(elem));
element.appendChild(passedElem);
return element;
}
}

if (typeof module !== 'undefined' && module.exports) {
Expand Down
12 changes: 11 additions & 1 deletion lighthouse-core/report/v2/renderer/report-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class ReportRenderer {
const categories = reportSection.appendChild(this._dom.createElement('div', 'lh-categories'));
for (const category of report.reportCategories) {
scoreHeader.appendChild(this._categoryRenderer.renderScoreGauge(category));
categories.appendChild(this._categoryRenderer.render(category));
categories.appendChild(this._categoryRenderer.render(category, report.reportGroups));
}

reportSection.appendChild(this._renderReportFooter(report));
Expand All @@ -169,6 +169,7 @@ if (typeof module !== 'undefined' && module.exports) {
* id: string,
* weight: number,
* score: number,
* group: string,
* result: {
* description: string,
* debugString: string,
Expand All @@ -195,13 +196,22 @@ ReportRenderer.AuditJSON; // eslint-disable-line no-unused-expressions
*/
ReportRenderer.CategoryJSON; // eslint-disable-line no-unused-expressions

/**
* @typedef {{
* title: string,
* description: string,
* }}
*/
ReportRenderer.GroupJSON; // eslint-disable-line no-unused-expressions

/**
* @typedef {{
* lighthouseVersion: string,
* generatedTime: string,
* initialUrl: string,
* url: string,
* reportCategories: !Array<!ReportRenderer.CategoryJSON>,
* reportGroups: !Object<string, !ReportRenderer.GroupJSON>,
* runtimeConfig: {
* blockedUrlPatterns: !Array<string>,
* environment: !Array<{description: string, enabled: boolean, name: string}>
Expand Down
Loading

0 comments on commit cee0dea

Please sign in to comment.