Skip to content

Commit

Permalink
report: add full-page-screenshot to experimental config (#10716)
Browse files Browse the repository at this point in the history
Co-authored-by: Matt Zeunert <[email protected]>
  • Loading branch information
connorjclark and mattzeunert authored Jul 20, 2020
1 parent 44d0551 commit 3efbf94
Show file tree
Hide file tree
Showing 39 changed files with 1,485 additions and 25 deletions.
Binary file added lighthouse-cli/test/fixtures/screenshot.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions lighthouse-cli/test/fixtures/screenshot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
* Copyright 2020 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.
-->

<style>
body {
background: lightblue url('screenshot.gif') no-repeat fixed center;
}
p {
background-color: white;
}
</style>

<body>
<script>
const params = new URLSearchParams(document.location.search);
if (params.has('width')) document.body.style.width = params.get('width');
if (params.has('height')) document.body.style.height = params.get('height');
</script>

<p>Screenshot tester.</p>
</body>
5 changes: 3 additions & 2 deletions lighthouse-cli/test/smokehouse/report-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,14 @@ function collateResults(localConsole, actual, expected) {
if (expected.artifacts) {
const expectedArtifacts = expected.artifacts;
const artifactNames = /** @type {(keyof LH.Artifacts)[]} */ (Object.keys(expectedArtifacts));
const actualArtifacts = actual.artifacts || {};
artifactAssertions = artifactNames.map(artifactName => {
const actualResult = (actual.artifacts || {})[artifactName];
if (!actualResult) {
if (!(artifactName in actualArtifacts)) {
localConsole.log(log.redify('Error: ') +
`Config run did not generate artifact ${artifactName}`);
}

const actualResult = actualArtifacts[artifactName];
const expectedResult = expectedArtifacts[artifactName];
return makeComparison(artifactName + ' artifact', actualResult, expectedResult);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const expectations = [
{
node: {
'type': 'node',
'boundingRect': {
'width': '>0',
'height': '>0',
},
'selector': '#aria-hidden-focus',
'snippet': '<div id="aria-hidden-focus" aria-hidden="true">\n <button>Focusable Button</button>\n </div>',
'explanation': 'Fix all of the following:\n Focusable content should be disabled or be removed from the DOM',
Expand All @@ -64,6 +68,10 @@ const expectations = [
{
node: {
'type': 'node',
'boundingRect': {
'width': '>0',
'height': '>0',
},
'selector': '#aria-input-field-name',
'snippet': '<div id="aria-input-field-name" role="textbox">text-in-a-box</div>',
'explanation': 'Fix any of the following:\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 or the title attribute is empty',
Expand Down
4 changes: 4 additions & 0 deletions lighthouse-cli/test/smokehouse/test-definitions/core-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ const smokeTests = [{
id: 'source-maps',
expectations: require('./source-maps/expectations.js'),
config: require('./source-maps/source-maps-config.js'),
}, {
id: 'screenshot',
expectations: require('./screenshot/expectations.js'),
config: require('./screenshot/screenshot-config.js'),
}];

module.exports = smokeTests;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @license Copyright 2020 Google Inc. 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';

/**
* @type {Array<Smokehouse.ExpectedRunnerResult>}
*/
const expectations = [
{
artifacts: {
FullPageScreenshot: {
width: '>1000',
height: '>1000',
data: /data:image\/jpeg;base64,.{10000,}$/,
},
},
lhr: {
requestedUrl: 'http://localhost:10200/screenshot.html?width=1000px&height=1000px',
finalUrl: 'http://localhost:10200/screenshot.html?width=1000px&height=1000px',
audits: {},
},
},
{
artifacts: {
FullPageScreenshot: null,
},
lhr: {
requestedUrl: 'http://localhost:10200/screenshot.html?width=5000px&height=5000px',
finalUrl: 'http://localhost:10200/screenshot.html?width=5000px&height=5000px',
runWarnings: [/Full page screenshot is too big/],
audits: {},
},
},
];

module.exports = expectations;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @license Copyright 2020 Google Inc. 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';

const experimentalConfig = require('../../../../../lighthouse-core/config/experimental-config.js');

/** @type {LH.Config.Json} */
module.exports = {
...experimentalConfig,
settings: {
onlyAudits: ['full-page-screenshot'],
emulatedFormFactor: 'desktop',
},
};
1 change: 1 addition & 0 deletions lighthouse-core/audits/accessibility/axe-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class AxeAudit extends Audit {
selector: Array.isArray(node.target) ? node.target.join(' ') : '',
path: node.path,
snippet: node.html || node.snippet,
boundingRect: node.boundingRect,
explanation: node.failureSummary,
nodeLabel: node.nodeLabel,
}),
Expand Down
43 changes: 43 additions & 0 deletions lighthouse-core/audits/full-page-screenshot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @license Copyright 2020 Google Inc. 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';

const Audit = require('./audit.js');

class FullPageScreenshot extends Audit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'full-page-screenshot',
scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
title: 'Full-page screenshot',
description: 'A full-height screenshot of the final rendered page',
requiredArtifacts: ['FullPageScreenshot'],
};
}

/**
* @param {LH.Artifacts} artifacts
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts) {
if (!artifacts.FullPageScreenshot) {
return {score: 0, notApplicable: true};
}

return {
score: 1,
details: {
type: 'full-page-screenshot',
...artifacts.FullPageScreenshot,
},
};
}
}

module.exports = FullPageScreenshot;
1 change: 1 addition & 0 deletions lighthouse-core/audits/largest-contentful-paint-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class LargestContentfulPaintElement extends Audit {
selector: lcpElement.selector,
nodeLabel: lcpElement.nodeLabel,
snippet: lcpElement.snippet,
boundingRect: lcpElement.boundingRect,
}),
});
}
Expand Down
1 change: 1 addition & 0 deletions lighthouse-core/audits/layout-shift-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class LayoutShiftElements extends Audit {
selector: element.selector,
nodeLabel: element.nodeLabel,
snippet: element.snippet,
boundingRect: element.boundingRect,
}),
score: element.score,
};
Expand Down
2 changes: 1 addition & 1 deletion lighthouse-core/audits/seo/font-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function getSelector(node) {

/**
* @param {FailingNodeData['node']} node
* @return {{type: 'node', selector: string, snippet: string}}
* @return {LH.Audit.Details.NodeValue}
*/
function nodeToTableNode(node) {
const attributes = node.attributes || [];
Expand Down
4 changes: 4 additions & 0 deletions lighthouse-core/audits/seo/tap-targets.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const {
allRectsContainedWithinEachOther,
getLargestRect,
getBoundingRectWithPadding,
getBoundingRect,
} = require('../../lib/rect-helpers.js');
const {getTappableRectsFromClientRects} = require('../../lib/tappable-rects.js');
const i18n = require('../../lib/i18n/i18n.js');
Expand Down Expand Up @@ -244,11 +245,14 @@ function getTableItems(overlapFailures) {
* @returns {LH.Audit.Details.NodeValue}
*/
function targetToTableNode(target) {
const boundingRect = getBoundingRect(target.clientRects);

return {
type: 'node',
snippet: target.snippet,
path: target.path,
selector: target.selector,
boundingRect,
nodeLabel: target.nodeLabel,
};
}
Expand Down
7 changes: 7 additions & 0 deletions lighthouse-core/config/experimental-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
const config = {
extends: 'lighthouse:default',
audits: [
'full-page-screenshot',
],
passes: [{
passName: 'defaultPass',
gatherers: [
'full-page-screenshot',
],
}],
categories: {
},
};
Expand Down
13 changes: 12 additions & 1 deletion lighthouse-core/gather/gatherers/accessibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
'use strict';

/* global window, document, getOuterHTMLSnippet, getNodePath, getNodeLabel */
/* global window, document, getOuterHTMLSnippet, getBoundingClientRect, getNodePath, getNodeLabel */

const Gatherer = require('./gatherer.js');
const fs = require('fs');
Expand Down Expand Up @@ -52,6 +52,10 @@ function runA11yChecks() {
},
// @ts-ignore
}).then(axeResult => {
// axe just scrolled the page, scroll back to the top of the page so that element positions
// are relative to the top of the page
document.documentElement.scrollTop = 0;

// @ts-ignore
const augmentAxeNodes = result => {
// @ts-ignore
Expand All @@ -60,6 +64,12 @@ function runA11yChecks() {
node.path = getNodePath(node.element);
// @ts-ignore - getOuterHTMLSnippet put into scope via stringification
node.snippet = getOuterHTMLSnippet(node.element);
// @ts-ignore - getBoundingClientRect put into scope via stringification
const rect = getBoundingClientRect(node.element);
if (rect.width > 0 && rect.height > 0) {
node.boundingRect = rect;
}

// @ts-ignore - getNodeLabel put into scope via stringification
node.nodeLabel = getNodeLabel(node.element);
// avoid circular JSON concerns
Expand Down Expand Up @@ -100,6 +110,7 @@ class Accessibility extends Gatherer {
const driver = passContext.driver;
const expression = `(function () {
${pageFunctions.getOuterHTMLSnippetString};
${pageFunctions.getBoundingClientRectString};
${pageFunctions.getNodePathString};
${pageFunctions.getNodeLabelString};
${axeLibSource};
Expand Down
Loading

0 comments on commit 3efbf94

Please sign in to comment.