diff --git a/lighthouse-core/report/html/renderer/report-ui-features.js b/lighthouse-core/report/html/renderer/report-ui-features.js index 2458fa5e6fb6..bfbdc7e06fb5 100644 --- a/lighthouse-core/report/html/renderer/report-ui-features.js +++ b/lighthouse-core/report/html/renderer/report-ui-features.js @@ -173,9 +173,10 @@ class ReportUIFeatures { }); tablesWithUrls.forEach((tableEl, index) => { - const thirdPartyRows = this._getThirdPartyRows(tableEl, this.json.finalUrl); - // No 3rd parties, no checkbox! - if (!thirdPartyRows.size) return; + const urlItems = this._getUrlItems(tableEl); + const thirdPartyRows = this._getThirdPartyRows(tableEl, urlItems, this.json.finalUrl); + // If all or none of the rows are 3rd party, no checkbox! + if (thirdPartyRows.size === urlItems.length || !thirdPartyRows.size) return; // create input box const filterTemplate = this._dom.cloneTemplate('#tmpl-lh-3p-filter', this._document); @@ -216,10 +217,10 @@ class ReportUIFeatures { * and returns a Map of those rows, mapping from row index to row Element. * @param {HTMLTableElement} el * @param {string} finalUrl + * @param {Array} urlItems * @return {Map} */ - _getThirdPartyRows(el, finalUrl) { - const urlItems = this._dom.findAll('.lh-text__url', el); + _getThirdPartyRows(el, urlItems, finalUrl) { const finalUrlRootDomain = Util.getRootDomain(finalUrl); /** @type {Map} */ @@ -240,6 +241,15 @@ class ReportUIFeatures { return thirdPartyRows; } + /** + * From a table, finds and returns URL items. + * @param {HTMLTableElement} tableEl + * @return {Array} + */ + _getUrlItems(tableEl) { + return this._dom.findAll('.lh-text__url', tableEl); + } + _setupStickyHeaderElements() { this.topbarEl = this._dom.find('.lh-topbar', this._document); this.scoreScaleEl = this._dom.find('.lh-scorescale', this._document); diff --git a/lighthouse-core/test/report/html/renderer/report-ui-features-test.js b/lighthouse-core/test/report/html/renderer/report-ui-features-test.js index 54a3d7852ddc..ca825732d110 100644 --- a/lighthouse-core/test/report/html/renderer/report-ui-features-test.js +++ b/lighthouse-core/test/report/html/renderer/report-ui-features-test.js @@ -124,6 +124,10 @@ describe('ReportUIFeatures', () => { const lhr = JSON.parse(JSON.stringify(sampleResults)); lhr.requestedUrl = lhr.finalUrl = 'http://www.example.com'; const webpAuditItemTemplate = sampleResults.audits['uses-webp-images'].details.items[0]; + const renderBlockingAuditItemTemplate = + sampleResults.audits['render-blocking-resources'].details.items[0]; + const textCompressionAuditItemTemplate = + sampleResults.audits['uses-text-compression'].details.items[0]; // Interleave first/third party URLs to test restoring order. lhr.audits['uses-webp-images'].details.items = [ { @@ -140,6 +144,38 @@ describe('ReportUIFeatures', () => { }, ]; + // Only third party URLs to test that checkbox is hidden + lhr.audits['render-blocking-resources'].details.items = [ + { + ...renderBlockingAuditItemTemplate, + url: 'http://www.cdn.com/script1.js', // Third party. + }, + { + ...renderBlockingAuditItemTemplate, + url: 'http://www.google.com/script2.js', // Third party. + }, + { + ...renderBlockingAuditItemTemplate, + url: 'http://www.notexample.com/script3.js', // Third party. + }, + ]; + + // Only first party URLs to test that checkbox is hidden + lhr.audits['uses-text-compression'].details.items = [ + { + ...textCompressionAuditItemTemplate, + url: 'http://www.example.com/font1.ttf', // First party. + }, + { + ...textCompressionAuditItemTemplate, + url: 'http://www.example.com/font2.ttf', // First party. + }, + { + ...textCompressionAuditItemTemplate, + url: 'http://www.example.com/font3.ttf', // First party. + }, + ]; + // render a report onto the UIFeature dom container = render(lhr); }); @@ -160,7 +196,7 @@ describe('ReportUIFeatures', () => { expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']); }); - it('adds no filter for audits that do not need them', () => { + it('adds no filter for audits in thirdPartyFilterAuditExclusions', () => { const checkboxClassName = 'lh-3p-filter-input'; const yesCheckbox = dom.find(`#uses-webp-images .${checkboxClassName}`, container); @@ -169,6 +205,20 @@ describe('ReportUIFeatures', () => { expect(() => dom.find(`#uses-rel-preconnect .${checkboxClassName}`, container)) .toThrowError('query #uses-rel-preconnect .lh-3p-filter-input not found'); }); + + it('adds no filter for audits with tables containing only third party resources', () => { + const checkboxClassName = 'lh-3p-filter-input'; + + expect(() => dom.find(`#render-blocking-resources .${checkboxClassName}`, container)) + .toThrowError('query #render-blocking-resources .lh-3p-filter-input not found'); + }); + + it('adds no filter for audits with tables containing only first party resources', () => { + const checkboxClassName = 'lh-3p-filter-input'; + + expect(() => dom.find(`#uses-text-compression .${checkboxClassName}`, container)) + .toThrowError('query #uses-text-compression .lh-3p-filter-input not found'); + }); }); });