[go: nahoru, domu]

Skip to content

Commit

Permalink
core(page-functions): don't try to clone a ShadowRoot (#9079)
Browse files Browse the repository at this point in the history
  • Loading branch information
NickolasBenakis authored and patrickhulce committed Jun 7, 2019
1 parent 0a28612 commit 212b6ac
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 15 deletions.
12 changes: 12 additions & 0 deletions lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@
<object id="5934a"></object>
<object id="5934b"></object>

<div id="shadow-root-container"></div>
<script>
// DOM Size has had trouble with very specific shadow root traversal issues.
// Make sure it can handle reporting of the widest element being a shadow root.
const shadowRootContainer = document.getElementById('shadow-root-container');
const shadowRoot = shadowRootContainer.attachShadow({mode: 'open'});
for (let i = 0; i < 100; i++) {
const span = document.createElement('span');
shadowRoot.appendChild(span);
}
</script>

<script>
// Ensure gatherers still work when individual elements override '.matches'
document.getElementById("5934a").matches = "blahblah";
Expand Down
10 changes: 7 additions & 3 deletions lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,16 @@ module.exports = [
},
'dom-size': {
score: 1,
numericValue: 35,
numericValue: 137,
details: {
items: [
{statistic: 'Total DOM Elements', value: '35'},
{statistic: 'Total DOM Elements', value: '137'},
{statistic: 'Maximum DOM Depth', value: '3'},
{statistic: 'Maximum Child Elements', value: '33'},
{
statistic: 'Maximum Child Elements',
value: '100',
element: {value: '<div id="shadow-root-container">'},
},
],
},
},
Expand Down
30 changes: 19 additions & 11 deletions lighthouse-core/lib/page-functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// @ts-nocheck
'use strict';

/* global window document Node */
/* global window document Node ShadowRoot */

/**
* Helper functions that are passed by `toString()` by Driver to be evaluated in target page.
Expand Down Expand Up @@ -107,24 +107,32 @@ function getElementsInDocument(selector) {

/**
* Gets the opening tag text of the given node.
* @param {Element} element
* @param {Element|ShadowRoot} element
* @param {Array<string>=} ignoreAttrs An optional array of attribute tags to not include in the HTML snippet.
* @return {string}
*/
/* istanbul ignore next */
function getOuterHTMLSnippet(element, ignoreAttrs = []) {
const clone = element.cloneNode();

ignoreAttrs.forEach(attribute =>{
clone.removeAttribute(attribute);
});

const reOpeningTag = /^[\s\S]*?>/;
const match = clone.outerHTML.match(reOpeningTag);
try {
// ShadowRoots are sometimes passed in; use their hosts' outerHTML.
if (element instanceof ShadowRoot) {
element = element.host;
}

return (match && match[0]) || '';
const clone = element.cloneNode();
ignoreAttrs.forEach(attribute =>{
clone.removeAttribute(attribute);
});
const reOpeningTag = /^[\s\S]*?>/;
const match = clone.outerHTML.match(reOpeningTag);
return (match && match[0]) || '';
} catch (_) {
// As a last resort, fall back to localName.
return `<${element.localName}>`;
}
}


/**
* Computes a memory/CPU performance benchmark index to determine rough device class.
* @see https://docs.google.com/spreadsheets/d/1E0gZwKsxegudkjJl8Fki_sOwHKpqgXwt8aBAfuUaB8A/edit?usp=sharing
Expand Down
14 changes: 13 additions & 1 deletion lighthouse-core/test/lib/page-functions-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ describe('Page Functions', () => {
let dom;

beforeAll(() => {
const {document} = new jsdom.JSDOM().window;
const {document, ShadowRoot} = new jsdom.JSDOM().window;
global.ShadowRoot = ShadowRoot;
dom = new DOM(document);
});

afterAll(() => {
global.ShadowRoot = undefined;
});

describe('get outer HTML snippets', () => {
it('gets full HTML snippet', () => {
assert.equal(pageFunctions.getOuterHTMLSnippet(
Expand All @@ -38,6 +43,13 @@ describe('Page Functions', () => {
), '<div id="1">');
});

it('should handle dom nodes that cannot be cloned', () => {
const element = dom.createElement('div');
element.cloneNode = () => {
throw new Error('oops!');
};
assert.equal(pageFunctions.getOuterHTMLSnippet(element), '<div>');
});
it('ignores when attribute not found', () => {
assert.equal(pageFunctions.getOuterHTMLSnippet(
dom.createElement('div', '', {'id': '1', 'style': 'style', 'aria-label': 'label'}),
Expand Down

0 comments on commit 212b6ac

Please sign in to comment.