lighthouse 8.0.0-dev.20210709 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/architecture.md +101 -0
- package/docs/authenticated-pages.md +44 -0
- package/docs/bug-labels.md +35 -0
- package/docs/configuration.md +213 -0
- package/docs/emulation.md +32 -0
- package/docs/error-reporting.md +42 -0
- package/docs/hacking-tips.md +55 -0
- package/docs/headless-chrome.md +119 -0
- package/docs/lantern.md +55 -0
- package/docs/new-audits.md +99 -0
- package/docs/performance-budgets.md +187 -0
- package/docs/plugins.md +374 -0
- package/docs/puppeteer.md +95 -0
- package/docs/readme.md +164 -0
- package/docs/recipes/auth/README.md +129 -0
- package/docs/recipes/auth/example-lh-auth.js +81 -0
- package/docs/recipes/auth/package.json +11 -0
- package/docs/recipes/auth/server/public/dashboard-unauthenticated.html +21 -0
- package/docs/recipes/auth/server/public/dashboard.html +25 -0
- package/docs/recipes/auth/server/public/home-unauthenticated.html +27 -0
- package/docs/recipes/auth/server/public/home.html +17 -0
- package/docs/recipes/auth/server/public/unauthenticated.html +22 -0
- package/docs/recipes/auth/server/server.js +85 -0
- package/docs/recipes/custom-audit/custom-config.js +36 -0
- package/docs/recipes/custom-audit/package.json +8 -0
- package/docs/recipes/custom-audit/readme.md +32 -0
- package/docs/recipes/custom-audit/searchable-audit.js +46 -0
- package/docs/recipes/custom-audit/searchable-gatherer.js +32 -0
- package/docs/recipes/custom-gatherer-puppeteer/custom-audit.js +34 -0
- package/{root.js → docs/recipes/custom-gatherer-puppeteer/custom-config.js} +23 -2
- package/docs/recipes/custom-gatherer-puppeteer/custom-gatherer.js +51 -0
- package/docs/recipes/custom-gatherer-puppeteer/package.json +13 -0
- package/docs/recipes/custom-gatherer-puppeteer/readme.md +7 -0
- package/docs/recipes/custom-gatherer-puppeteer/test.sh +9 -0
- package/docs/recipes/gulp/gulpfile.js +79 -0
- package/docs/recipes/gulp/package.json +12 -0
- package/docs/recipes/gulp/public/index.html +22 -0
- package/docs/recipes/gulp/readme.md +6 -0
- package/docs/recipes/integration-test/README.md +14 -0
- package/docs/recipes/integration-test/example-lh-auth.test.js +160 -0
- package/docs/recipes/integration-test/package.json +9 -0
- package/docs/recipes/lighthouse-plugin-example/audits/preload-as.js +46 -0
- package/docs/recipes/lighthouse-plugin-example/package.json +11 -0
- package/docs/recipes/lighthouse-plugin-example/plugin-recipe-screenshot.png +0 -0
- package/docs/recipes/lighthouse-plugin-example/plugin.js +24 -0
- package/docs/recipes/lighthouse-plugin-example/readme.md +53 -0
- package/docs/releasing.md +164 -0
- package/docs/scoring.md +79 -0
- package/docs/throttling.md +150 -0
- package/docs/understanding-results.md +209 -0
- package/docs/v8-perf-faq.md +244 -0
- package/docs/variability.md +150 -0
- package/jest.config.js +0 -3
- package/lighthouse-cli/bin.js +8 -6
- package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/lighthouse-core/audits/apple-touch-icon.js +0 -1
- package/lighthouse-core/audits/audit.js +3 -3
- package/lighthouse-core/audits/autocomplete.js +2 -2
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +14 -29
- package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +15 -55
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +4 -8
- package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +8 -15
- package/lighthouse-core/audits/byte-efficiency/total-byte-weight.js +9 -10
- package/lighthouse-core/audits/byte-efficiency/unminified-css.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js +2 -2
- package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +24 -46
- package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
- package/lighthouse-core/audits/critical-request-chains.js +0 -1
- package/lighthouse-core/audits/csp-xss.js +1 -1
- package/lighthouse-core/audits/diagnostics.js +0 -1
- package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +0 -1
- package/lighthouse-core/audits/dobetterweb/inspector-issues.js +1 -1
- package/lighthouse-core/audits/dobetterweb/notification-on-start.js +0 -1
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +0 -1
- package/lighthouse-core/audits/final-screenshot.js +4 -8
- package/lighthouse-core/audits/font-display.js +0 -1
- package/lighthouse-core/audits/installable-manifest.js +3 -4
- package/lighthouse-core/audits/largest-contentful-paint-element.js +0 -1
- package/lighthouse-core/audits/long-tasks.js +1 -1
- package/lighthouse-core/audits/maskable-icon.js +0 -1
- package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -4
- package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -4
- package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -4
- package/lighthouse-core/audits/metrics/interactive.js +2 -4
- package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -4
- package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -4
- package/lighthouse-core/audits/metrics/speed-index.js +2 -4
- package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -10
- package/lighthouse-core/audits/metrics.js +2 -4
- package/lighthouse-core/audits/performance-budget.js +0 -1
- package/lighthouse-core/audits/predictive-perf.js +6 -9
- package/lighthouse-core/audits/preload-fonts.js +1 -11
- package/lighthouse-core/audits/preload-lcp-image.js +5 -18
- package/lighthouse-core/audits/redirects.js +8 -10
- package/lighthouse-core/audits/screenshot-thumbnails.js +13 -28
- package/lighthouse-core/audits/seo/canonical.js +1 -2
- package/lighthouse-core/audits/seo/font-size.js +4 -4
- package/lighthouse-core/audits/seo/hreflang.js +2 -3
- package/lighthouse-core/audits/seo/http-status-code.js +16 -21
- package/lighthouse-core/audits/seo/is-crawlable.js +3 -4
- package/lighthouse-core/audits/seo/robots-txt.js +2 -2
- package/lighthouse-core/audits/seo/tap-targets.js +5 -5
- package/lighthouse-core/audits/server-response-time.js +2 -20
- package/lighthouse-core/audits/splash-screen.js +0 -1
- package/lighthouse-core/audits/themed-omnibox.js +0 -1
- package/lighthouse-core/audits/third-party-facades.js +0 -1
- package/lighthouse-core/audits/third-party-summary.js +3 -1
- package/lighthouse-core/audits/timing-budget.js +2 -4
- package/lighthouse-core/audits/uses-rel-preconnect.js +9 -14
- package/lighthouse-core/audits/uses-rel-preload.js +2 -13
- package/lighthouse-core/computed/main-thread-tasks.js +2 -2
- package/lighthouse-core/computed/metrics/cumulative-layout-shift.js +3 -3
- package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +6 -6
- package/lighthouse-core/computed/metrics/first-contentful-paint.js +8 -9
- package/lighthouse-core/computed/metrics/first-meaningful-paint.js +9 -10
- package/lighthouse-core/computed/metrics/interactive.js +24 -25
- package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +6 -6
- package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +6 -6
- package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +6 -6
- package/lighthouse-core/computed/metrics/lantern-metric.js +8 -16
- package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +7 -7
- package/lighthouse-core/computed/metrics/largest-contentful-paint.js +9 -10
- package/lighthouse-core/computed/metrics/max-potential-fid.js +11 -8
- package/lighthouse-core/computed/metrics/metric.js +5 -32
- package/lighthouse-core/computed/metrics/speed-index.js +5 -6
- package/lighthouse-core/computed/metrics/timing-summary.js +45 -55
- package/lighthouse-core/computed/metrics/total-blocking-time.js +29 -36
- package/lighthouse-core/computed/page-dependency-graph.js +14 -14
- package/lighthouse-core/computed/resource-summary.js +7 -3
- package/lighthouse-core/computed/speedline.js +3 -3
- package/lighthouse-core/computed/trace-of-tab.js +86 -15
- package/lighthouse-core/computed/user-timings.js +5 -5
- package/lighthouse-core/config/default-config.js +0 -1
- package/lighthouse-core/fraggle-rock/config/config.js +7 -9
- package/lighthouse-core/fraggle-rock/config/default-config.js +2 -40
- package/lighthouse-core/fraggle-rock/config/filters.js +6 -39
- package/lighthouse-core/fraggle-rock/config/validation.js +4 -4
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +19 -54
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +10 -21
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +2 -2
- package/lighthouse-core/gather/driver/prepare.js +0 -3
- package/lighthouse-core/gather/fetcher.js +2 -0
- package/lighthouse-core/gather/gather-runner.js +14 -2
- package/lighthouse-core/gather/gatherers/image-elements.js +61 -24
- package/lighthouse-core/gather/gatherers/inspector-issues.js +2 -2
- package/lighthouse-core/gather/gatherers/script-elements.js +12 -45
- package/lighthouse-core/gather/gatherers/seo/font-size.js +5 -5
- package/lighthouse-core/gather/gatherers/seo/tap-targets.js +12 -64
- package/lighthouse-core/gather/gatherers/service-worker.js +3 -20
- package/lighthouse-core/gather/gatherers/trace-compat.js +1 -1
- package/lighthouse-core/gather/gatherers/trace-elements.js +3 -15
- package/lighthouse-core/gather/gatherers/trace.js +4 -13
- package/lighthouse-core/gather/gatherers/viewport-dimensions.js +1 -1
- package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +2 -13
- package/lighthouse-core/lib/emulation.js +2 -0
- package/lighthouse-core/lib/i18n/i18n.js +2 -2
- package/lighthouse-core/lib/i18n/locales/ar-XB.json +141 -141
- package/lighthouse-core/lib/i18n/locales/ar.json +143 -143
- package/lighthouse-core/lib/i18n/locales/bg.json +143 -143
- package/lighthouse-core/lib/i18n/locales/ca.json +141 -141
- package/lighthouse-core/lib/i18n/locales/cs.json +141 -141
- package/lighthouse-core/lib/i18n/locales/da.json +141 -141
- package/lighthouse-core/lib/i18n/locales/de.json +142 -142
- package/lighthouse-core/lib/i18n/locales/el.json +141 -141
- package/lighthouse-core/lib/i18n/locales/en-GB.json +141 -141
- package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +6659 -0
- package/lighthouse-core/lib/i18n/locales/en-US.json +144 -150
- package/lighthouse-core/lib/i18n/locales/en-XA.json +141 -141
- package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +6628 -0
- package/lighthouse-core/lib/i18n/locales/en-XL.json +144 -150
- package/lighthouse-core/lib/i18n/locales/es-419.json +141 -141
- package/lighthouse-core/lib/i18n/locales/es.json +141 -141
- package/lighthouse-core/lib/i18n/locales/fi.json +143 -143
- package/lighthouse-core/lib/i18n/locales/fil.json +142 -142
- package/lighthouse-core/lib/i18n/locales/fr.json +141 -141
- package/lighthouse-core/lib/i18n/locales/he.json +142 -142
- package/lighthouse-core/lib/i18n/locales/hi.json +143 -143
- package/lighthouse-core/lib/i18n/locales/hr.json +141 -141
- package/lighthouse-core/lib/i18n/locales/hu.json +143 -143
- package/lighthouse-core/lib/i18n/locales/id.json +143 -143
- package/lighthouse-core/lib/i18n/locales/it.json +143 -143
- package/lighthouse-core/lib/i18n/locales/ja.json +143 -143
- package/lighthouse-core/lib/i18n/locales/ko.json +143 -143
- package/lighthouse-core/lib/i18n/locales/lt.json +143 -143
- package/lighthouse-core/lib/i18n/locales/lv.json +143 -143
- package/lighthouse-core/lib/i18n/locales/nl.json +141 -141
- package/lighthouse-core/lib/i18n/locales/no.json +141 -141
- package/lighthouse-core/lib/i18n/locales/pl.json +141 -141
- package/lighthouse-core/lib/i18n/locales/pt-PT.json +141 -141
- package/lighthouse-core/lib/i18n/locales/pt.json +141 -141
- package/lighthouse-core/lib/i18n/locales/ro.json +144 -144
- package/lighthouse-core/lib/i18n/locales/ru.json +143 -143
- package/lighthouse-core/lib/i18n/locales/sk.json +142 -142
- package/lighthouse-core/lib/i18n/locales/sl.json +141 -141
- package/lighthouse-core/lib/i18n/locales/sr-Latn.json +143 -143
- package/lighthouse-core/lib/i18n/locales/sr.json +143 -143
- package/lighthouse-core/lib/i18n/locales/sv.json +142 -142
- package/lighthouse-core/lib/i18n/locales/ta.json +141 -141
- package/lighthouse-core/lib/i18n/locales/te.json +143 -143
- package/lighthouse-core/lib/i18n/locales/th.json +143 -143
- package/lighthouse-core/lib/i18n/locales/tr.json +143 -143
- package/lighthouse-core/lib/i18n/locales/uk.json +141 -141
- package/lighthouse-core/lib/i18n/locales/vi.json +143 -143
- package/lighthouse-core/lib/i18n/locales/zh-HK.json +141 -141
- package/lighthouse-core/lib/i18n/locales/zh-TW.json +143 -143
- package/lighthouse-core/lib/i18n/locales/zh.json +143 -143
- package/lighthouse-core/lib/lh-error.js +2 -2
- package/lighthouse-core/lib/minify-trace.js +1 -1
- package/lighthouse-core/lib/network-request.js +1 -17
- package/lighthouse-core/lib/page-functions.js +5 -6
- package/lighthouse-core/lib/rect-helpers.js +3 -3
- package/lighthouse-core/lib/sd-validation/assets/jsonldcontext.json +7137 -0
- package/lighthouse-core/lib/sd-validation/assets/schema-tree.json +9900 -0
- package/{report/report-assets.js → lighthouse-core/lib/sd-validation/helpers/walk-object.js} +20 -12
- package/lighthouse-core/lib/sd-validation/json-expander.js +56 -0
- package/lighthouse-core/lib/sd-validation/json-linter.js +49 -0
- package/lighthouse-core/lib/sd-validation/jsonld-keyword-validator.js +50 -0
- package/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path.js +60 -0
- package/lighthouse-core/lib/sd-validation/schema-validator.js +146 -0
- package/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext.js +30 -0
- package/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree.js +97 -0
- package/lighthouse-core/lib/sd-validation/sd-validation.js +77 -0
- package/lighthouse-core/lib/tappable-rects.js +1 -1
- package/lighthouse-core/lib/tracehouse/trace-processor.js +42 -116
- package/lighthouse-core/lib/url-shim.js +2 -29
- package/lighthouse-core/report/html/html-report-assets.js +38 -0
- package/{report/README.md → lighthouse-core/report/html/readme.md} +11 -7
- package/{report → lighthouse-core/report/html}/renderer/category-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/crc-details-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/details-renderer.js +1 -1
- package/{report → lighthouse-core/report/html}/renderer/dom.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/element-screenshot-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/i18n.js +1 -1
- package/{report → lighthouse-core/report/html}/renderer/logger.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/performance-category-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/psi.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/pwa-category-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/report-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/report-ui-features.js +3 -3
- package/{report → lighthouse-core/report/html}/renderer/snippet-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/text-encoding.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/util.js +4 -7
- package/{report/assets/styles.css → lighthouse-core/report/html/report-styles.css} +0 -0
- package/{report/assets/standalone-template.html → lighthouse-core/report/html/report-template.html} +41 -1
- package/{report/assets → lighthouse-core/report/html}/templates.html +0 -0
- package/{report → lighthouse-core/report}/report-generator.js +1 -1
- package/lighthouse-core/runner.js +1 -1
- package/package.json +12 -13
- package/readme.md +2 -2
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -3
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -2
- package/third-party/download-content-shell/download-content-shell.js +1 -2
- package/third-party/snyk/snapshot.json +1 -1
- package/tsconfig.json +1 -0
- package/types/artifacts.d.ts +21 -41
- package/types/audit.d.ts +0 -2
- package/types/config.d.ts +2 -16
- package/types/externs.d.ts +0 -1
- package/types/gatherer.d.ts +13 -13
- package/types/html-renderer.d.ts +14 -14
- package/types/i18n.d.ts +1 -1
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -94
- package/lighthouse-core/computed/image-records.js +0 -62
- package/lighthouse-core/computed/metrics/navigation-metric.js +0 -46
- package/lighthouse-core/computed/processed-navigation.js +0 -21
- package/lighthouse-core/computed/processed-trace.js +0 -21
- package/lighthouse-core/gather/gatherers/gather-context.js +0 -25
- package/lighthouse-core/gather/gatherers/host-form-factor.js +0 -31
- package/lighthouse-core/gather/gatherers/host-user-agent.js +0 -29
- package/lighthouse-core/lib/lh-trace-processor.js +0 -46
- package/report/clients/standalone.js +0 -52
- package/report/test/renderer/category-renderer-test.js +0 -488
- package/report/test/renderer/crc-details-renderer-test.js +0 -115
- package/report/test/renderer/details-renderer-test.js +0 -843
- package/report/test/renderer/dom-test.js +0 -157
- package/report/test/renderer/element-screenshot-renderer-test.js +0 -189
- package/report/test/renderer/i18n-test.js +0 -146
- package/report/test/renderer/performance-category-renderer-test.js +0 -332
- package/report/test/renderer/psi-test.js +0 -152
- package/report/test/renderer/pwa-category-renderer-test.js +0 -303
- package/report/test/renderer/report-renderer-test.js +0 -325
- package/report/test/renderer/report-ui-features-test.js +0 -572
- package/report/test/renderer/snippet-renderer-test.js +0 -291
- package/report/test/renderer/text-encoding-test.js +0 -41
- package/report/test/renderer/util-test.js +0 -388
- package/report/test/report-generator-test.js +0 -145
|
@@ -1,572 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2017 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* 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
|
|
4
|
-
* 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.
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
/* eslint-env jest */
|
|
9
|
-
|
|
10
|
-
const assert = require('assert').strict;
|
|
11
|
-
const jsdom = require('jsdom');
|
|
12
|
-
const reportAssets = require('../../report-assets.js');
|
|
13
|
-
const Util = require('../../renderer/util.js');
|
|
14
|
-
const I18n = require('../../renderer/i18n.js');
|
|
15
|
-
const DOM = require('../../renderer/dom.js');
|
|
16
|
-
const DetailsRenderer = require('../../renderer/details-renderer.js');
|
|
17
|
-
const ReportUIFeatures = require('../../renderer/report-ui-features.js');
|
|
18
|
-
const CategoryRenderer = require('../../renderer/category-renderer.js');
|
|
19
|
-
const ElementScreenshotRenderer = require('../../renderer/element-screenshot-renderer.js');
|
|
20
|
-
const RectHelpers = require('../../../lighthouse-core/lib/rect-helpers.js');
|
|
21
|
-
const CriticalRequestChainRenderer = require('../../renderer/crc-details-renderer.js');
|
|
22
|
-
const ReportRenderer = require('../../renderer/report-renderer.js');
|
|
23
|
-
const sampleResultsOrig = require('../../../lighthouse-core/test/results/sample_v2.json');
|
|
24
|
-
|
|
25
|
-
describe('ReportUIFeatures', () => {
|
|
26
|
-
let sampleResults;
|
|
27
|
-
let dom;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @param {LH.JSON} lhr
|
|
31
|
-
* @return {HTMLElement}
|
|
32
|
-
*/
|
|
33
|
-
function render(lhr) {
|
|
34
|
-
const detailsRenderer = new DetailsRenderer(dom);
|
|
35
|
-
const categoryRenderer = new CategoryRenderer(dom, detailsRenderer);
|
|
36
|
-
const renderer = new ReportRenderer(dom, categoryRenderer);
|
|
37
|
-
const reportUIFeatures = new ReportUIFeatures(dom);
|
|
38
|
-
const container = dom.find('main', dom._document);
|
|
39
|
-
renderer.renderReport(lhr, container);
|
|
40
|
-
reportUIFeatures.initFeatures(lhr);
|
|
41
|
-
return container;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
beforeAll(() => {
|
|
45
|
-
global.Util = Util;
|
|
46
|
-
global.I18n = I18n;
|
|
47
|
-
global.ReportUIFeatures = ReportUIFeatures;
|
|
48
|
-
global.CriticalRequestChainRenderer = CriticalRequestChainRenderer;
|
|
49
|
-
global.DetailsRenderer = DetailsRenderer;
|
|
50
|
-
global.CategoryRenderer = CategoryRenderer;
|
|
51
|
-
global.ElementScreenshotRenderer = ElementScreenshotRenderer;
|
|
52
|
-
global.RectHelpers = RectHelpers;
|
|
53
|
-
|
|
54
|
-
// lazy loaded because they depend on CategoryRenderer to be available globally
|
|
55
|
-
global.PerformanceCategoryRenderer =
|
|
56
|
-
require('../../renderer/performance-category-renderer.js');
|
|
57
|
-
global.PwaCategoryRenderer =
|
|
58
|
-
require('../../renderer/pwa-category-renderer.js');
|
|
59
|
-
|
|
60
|
-
// Stub out matchMedia for Node.
|
|
61
|
-
global.matchMedia = function() {
|
|
62
|
-
return {
|
|
63
|
-
addListener: function() {},
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const reportWithTemplates = reportAssets.REPORT_TEMPLATE
|
|
68
|
-
.replace('%%LIGHTHOUSE_TEMPLATES%%', reportAssets.REPORT_TEMPLATES);
|
|
69
|
-
const document = new jsdom.JSDOM(reportWithTemplates);
|
|
70
|
-
global.self = document.window;
|
|
71
|
-
global.self.matchMedia = function() {
|
|
72
|
-
return {
|
|
73
|
-
addListener: function() {},
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
global.HTMLElement = document.window.HTMLElement;
|
|
78
|
-
global.HTMLInputElement = document.window.HTMLInputElement;
|
|
79
|
-
|
|
80
|
-
global.window = document.window;
|
|
81
|
-
global.window.getComputedStyle = function() {
|
|
82
|
-
return {
|
|
83
|
-
marginTop: '10px',
|
|
84
|
-
height: '10px',
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
dom = new DOM(document.window.document);
|
|
89
|
-
sampleResults = Util.prepareReportResult(sampleResultsOrig);
|
|
90
|
-
render(sampleResults);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
afterAll(() => {
|
|
94
|
-
global.self = undefined;
|
|
95
|
-
global.Util = undefined;
|
|
96
|
-
global.I18n = undefined;
|
|
97
|
-
global.ReportUIFeatures = undefined;
|
|
98
|
-
global.matchMedia = undefined;
|
|
99
|
-
global.CriticalRequestChainRenderer = undefined;
|
|
100
|
-
global.DetailsRenderer = undefined;
|
|
101
|
-
global.CategoryRenderer = undefined;
|
|
102
|
-
global.ElementScreenshotRenderer = undefined;
|
|
103
|
-
global.RectHelpers = undefined;
|
|
104
|
-
global.PerformanceCategoryRenderer = undefined;
|
|
105
|
-
global.PwaCategoryRenderer = undefined;
|
|
106
|
-
global.window = undefined;
|
|
107
|
-
global.HTMLElement = undefined;
|
|
108
|
-
global.HTMLInputElement = undefined;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('initFeatures', () => {
|
|
112
|
-
it('should init a report', () => {
|
|
113
|
-
const container = render(sampleResults);
|
|
114
|
-
assert.equal(dom.findAll('.lh-category', container).length, 5);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should init a report with a single category', () => {
|
|
118
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
119
|
-
lhr.categories = {
|
|
120
|
-
performance: lhr.categories.performance,
|
|
121
|
-
};
|
|
122
|
-
const container = render(lhr);
|
|
123
|
-
assert.equal(dom.findAll('.lh-category', container).length, 1);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
describe('third-party filtering', () => {
|
|
127
|
-
let container;
|
|
128
|
-
|
|
129
|
-
beforeAll(() => {
|
|
130
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
131
|
-
lhr.requestedUrl = lhr.finalUrl = 'http://www.example.com';
|
|
132
|
-
const webpAuditItemTemplate = {
|
|
133
|
-
...sampleResults.audits['modern-image-formats'].details.items[0],
|
|
134
|
-
wastedBytes: 8.8 * 1024,
|
|
135
|
-
};
|
|
136
|
-
const renderBlockingAuditItemTemplate =
|
|
137
|
-
sampleResults.audits['render-blocking-resources'].details.items[0];
|
|
138
|
-
const textCompressionAuditItemTemplate =
|
|
139
|
-
sampleResults.audits['uses-text-compression'].details.items[0];
|
|
140
|
-
|
|
141
|
-
// Interleave first/third party URLs to test restoring order.
|
|
142
|
-
lhr.audits['modern-image-formats'].details.items = [
|
|
143
|
-
{
|
|
144
|
-
...webpAuditItemTemplate,
|
|
145
|
-
url: 'http://www.cdn.com/img1.jpg', // Third party, will be filtered.
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
...webpAuditItemTemplate,
|
|
149
|
-
url: 'http://www.example.com/img2.jpg', // First party, not filtered.
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
...webpAuditItemTemplate,
|
|
153
|
-
url: 'http://www.notexample.com/img3.jpg', // Third party, will be filtered.
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
|
|
157
|
-
// Test sub-item rows.
|
|
158
|
-
lhr.audits['unused-javascript'].details.items = [
|
|
159
|
-
{
|
|
160
|
-
...webpAuditItemTemplate,
|
|
161
|
-
url: 'http://www.cdn.com/script1.js', // Third party, will be filtered.
|
|
162
|
-
subItems: {
|
|
163
|
-
type: 'subitems',
|
|
164
|
-
items: [
|
|
165
|
-
{source: '1', sourceBytes: 1, sourceWastedBytes: 1},
|
|
166
|
-
{source: '2', sourceBytes: 2, sourceWastedBytes: 2},
|
|
167
|
-
],
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
...webpAuditItemTemplate,
|
|
172
|
-
url: 'http://www.example.com/script2.js', // First party, not filtered.
|
|
173
|
-
subItems: {
|
|
174
|
-
type: 'subitems',
|
|
175
|
-
items: [
|
|
176
|
-
{source: '3', sourceBytes: 3, sourceWastedBytes: 3},
|
|
177
|
-
{source: '4', sourceBytes: 4, sourceWastedBytes: 4},
|
|
178
|
-
],
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
...webpAuditItemTemplate,
|
|
183
|
-
url: 'http://www.notexample.com/script3.js', // Third party, will be filtered.
|
|
184
|
-
subItems: {
|
|
185
|
-
type: 'subitems',
|
|
186
|
-
items: [
|
|
187
|
-
{source: '5', sourceBytes: 5, sourceWastedBytes: 5},
|
|
188
|
-
{source: '6', sourceBytes: 6, sourceWastedBytes: 6},
|
|
189
|
-
],
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
];
|
|
193
|
-
// Sample json currently doesn't have any results for `unused-javascript`, so
|
|
194
|
-
// headings is empty. Can delete this block of code if that changes.
|
|
195
|
-
expect(lhr.audits['unused-javascript'].details.headings).toHaveLength(0);
|
|
196
|
-
lhr.audits['unused-javascript'].details.headings = [
|
|
197
|
-
/* t-disable max-len */
|
|
198
|
-
{key: 'url', valueType: 'url', subItemsHeading: {key: 'source', valueType: 'code'}},
|
|
199
|
-
{key: 'totalBytes', valueType: 'bytes', subItemsHeading: {key: 'sourceBytes'}},
|
|
200
|
-
{key: 'wastedBytes', valueType: 'bytes', subItemsHeading: {key: 'sourceWastedBytes'}},
|
|
201
|
-
/* eslint-enable max-len */
|
|
202
|
-
];
|
|
203
|
-
|
|
204
|
-
// Only third party URLs to test that checkbox is hidden
|
|
205
|
-
lhr.audits['render-blocking-resources'].details.items = [
|
|
206
|
-
{
|
|
207
|
-
...renderBlockingAuditItemTemplate,
|
|
208
|
-
url: 'http://www.cdn.com/script1.js', // Third party.
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
...renderBlockingAuditItemTemplate,
|
|
212
|
-
url: 'http://www.google.com/script2.js', // Third party.
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
...renderBlockingAuditItemTemplate,
|
|
216
|
-
url: 'http://www.notexample.com/script3.js', // Third party.
|
|
217
|
-
},
|
|
218
|
-
];
|
|
219
|
-
|
|
220
|
-
// Only first party URLs to test that checkbox is hidden
|
|
221
|
-
lhr.audits['uses-text-compression'].details.items = [
|
|
222
|
-
{
|
|
223
|
-
...textCompressionAuditItemTemplate,
|
|
224
|
-
url: 'http://www.example.com/font1.ttf', // First party.
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
...textCompressionAuditItemTemplate,
|
|
228
|
-
url: 'http://www.example.com/font2.ttf', // First party.
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
...textCompressionAuditItemTemplate,
|
|
232
|
-
url: 'http://www.example.com/font3.ttf', // First party.
|
|
233
|
-
},
|
|
234
|
-
];
|
|
235
|
-
|
|
236
|
-
// render a report onto the UIFeature dom
|
|
237
|
-
container = render(lhr);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('filters out third party resources in on click', () => {
|
|
241
|
-
const filterCheckbox = dom.find('#modern-image-formats .lh-3p-filter-input', container);
|
|
242
|
-
|
|
243
|
-
function getUrlsInTable() {
|
|
244
|
-
return dom
|
|
245
|
-
.findAll('#modern-image-formats tr:not(.lh-row--hidden) .lh-text__url a:first-child', container) // eslint-disable-line max-len
|
|
246
|
-
.map(el => el.textContent);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']);
|
|
250
|
-
filterCheckbox.click();
|
|
251
|
-
expect(getUrlsInTable()).toEqual(['/img2.jpg']);
|
|
252
|
-
filterCheckbox.click();
|
|
253
|
-
expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']);
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('filters out sub-item rows of third party resources on click', () => {
|
|
257
|
-
dom.find('#unused-javascript', container);
|
|
258
|
-
const filterCheckbox = dom.find('#unused-javascript .lh-3p-filter-input', container);
|
|
259
|
-
|
|
260
|
-
function getRowIdentifiers() {
|
|
261
|
-
return dom
|
|
262
|
-
.findAll(
|
|
263
|
-
'#unused-javascript tbody tr:not(.lh-row--hidden)', container)
|
|
264
|
-
.map(el => el.textContent);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const initialExpected = [
|
|
268
|
-
'/script1.js(www.cdn.com)24.0 KiB8.8 KiB',
|
|
269
|
-
'10.0 KiB0.0 KiB',
|
|
270
|
-
'20.0 KiB0.0 KiB',
|
|
271
|
-
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
272
|
-
'30.0 KiB0.0 KiB',
|
|
273
|
-
'40.0 KiB0.0 KiB',
|
|
274
|
-
'/script3.js(www.notexample.com)24.0 KiB8.8 KiB',
|
|
275
|
-
'50.0 KiB0.0 KiB',
|
|
276
|
-
'60.0 KiB0.0 KiB',
|
|
277
|
-
];
|
|
278
|
-
|
|
279
|
-
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
280
|
-
filterCheckbox.click();
|
|
281
|
-
expect(getRowIdentifiers()).toEqual([
|
|
282
|
-
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
283
|
-
'30.0 KiB0.0 KiB',
|
|
284
|
-
'40.0 KiB0.0 KiB',
|
|
285
|
-
]);
|
|
286
|
-
filterCheckbox.click();
|
|
287
|
-
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it('adds no filter for audits in thirdPartyFilterAuditExclusions', () => {
|
|
291
|
-
const checkboxClassName = 'lh-3p-filter-input';
|
|
292
|
-
|
|
293
|
-
const yesCheckbox = dom.find(`#modern-image-formats .${checkboxClassName}`, container);
|
|
294
|
-
expect(yesCheckbox).toBeTruthy();
|
|
295
|
-
|
|
296
|
-
expect(() => dom.find(`#uses-rel-preconnect .${checkboxClassName}`, container))
|
|
297
|
-
.toThrowError('query #uses-rel-preconnect .lh-3p-filter-input not found');
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it('filter is disabled and checked for when just third party resources', () => {
|
|
301
|
-
const filterCheckbox =
|
|
302
|
-
dom.find('#render-blocking-resources .lh-3p-filter-input', container);
|
|
303
|
-
expect(filterCheckbox.disabled).toEqual(true);
|
|
304
|
-
expect(filterCheckbox.checked).toEqual(true);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
it('filter is disabled and not checked for just first party resources', () => {
|
|
308
|
-
const filterCheckbox = dom.find('#uses-text-compression .lh-3p-filter-input', container);
|
|
309
|
-
expect(filterCheckbox.disabled).toEqual(true);
|
|
310
|
-
expect(filterCheckbox.checked).toEqual(false);
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
describe('fireworks', () => {
|
|
316
|
-
it('should render an non-all 100 report without fireworks', () => {
|
|
317
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
318
|
-
lhr.categories.performance.score = 0.5;
|
|
319
|
-
const container = render(lhr);
|
|
320
|
-
assert.ok(container.querySelector('.score100') === null, 'has no fireworks treatment');
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
it('should render an all 100 report with fireworks', () => {
|
|
324
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
325
|
-
Object.values(lhr.categories).forEach(element => {
|
|
326
|
-
element.score = 1;
|
|
327
|
-
});
|
|
328
|
-
const container = render(lhr);
|
|
329
|
-
assert.ok(container.querySelector('.score100'), 'has fireworks treatment');
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
it('should show fireworks for all 100s except PWA', () => {
|
|
333
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
334
|
-
Object.values(lhr.categories).forEach(element => {
|
|
335
|
-
element.score = 1;
|
|
336
|
-
});
|
|
337
|
-
lhr.categories.pwa.score = 0;
|
|
338
|
-
|
|
339
|
-
const container = render(lhr);
|
|
340
|
-
assert.ok(container.querySelector('.score100'), 'has fireworks treatment');
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
it('should not render fireworks if all core categories are not present', () => {
|
|
344
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
345
|
-
delete lhr.categories.performance;
|
|
346
|
-
delete lhr.categoryGroups.performace;
|
|
347
|
-
Object.values(lhr.categories).forEach(element => {
|
|
348
|
-
element.score = 1;
|
|
349
|
-
});
|
|
350
|
-
const container = render(lhr);
|
|
351
|
-
assert.ok(container.querySelector('.score100') === null, 'has no fireworks treatment');
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
describe('metric descriptions', () => {
|
|
356
|
-
it('with no errors, hide by default', () => {
|
|
357
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
358
|
-
const container = render(lhr);
|
|
359
|
-
assert.ok(!container.querySelector('.lh-metrics-toggle__input').checked);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it('with error, show by default', () => {
|
|
363
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
364
|
-
lhr.audits['first-contentful-paint'].errorMessage = 'Error.';
|
|
365
|
-
const container = render(lhr);
|
|
366
|
-
assert.ok(container.querySelector('.lh-metrics-toggle__input').checked);
|
|
367
|
-
});
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
describe('tools button', () => {
|
|
371
|
-
let window;
|
|
372
|
-
let dropDown;
|
|
373
|
-
|
|
374
|
-
beforeEach(() => {
|
|
375
|
-
window = dom.document().defaultView;
|
|
376
|
-
const features = new ReportUIFeatures(dom);
|
|
377
|
-
features.initFeatures(sampleResults);
|
|
378
|
-
dropDown = features._dropDown;
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it('click should toggle active class', () => {
|
|
382
|
-
dropDown._toggleEl.click();
|
|
383
|
-
assert.ok(dropDown._toggleEl.classList.contains('active'));
|
|
384
|
-
|
|
385
|
-
dropDown._toggleEl.click();
|
|
386
|
-
assert.ok(!dropDown._toggleEl.classList.contains('active'));
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
it('Escape key removes active class', () => {
|
|
391
|
-
dropDown._toggleEl.click();
|
|
392
|
-
assert.ok(dropDown._toggleEl.classList.contains('active'));
|
|
393
|
-
|
|
394
|
-
const escape = new window.KeyboardEvent('keydown', {keyCode: /* ESC */ 27});
|
|
395
|
-
dom.document().dispatchEvent(escape);
|
|
396
|
-
assert.ok(!dropDown._toggleEl.classList.contains('active'));
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
['ArrowUp', 'ArrowDown', 'Enter', ' '].forEach((code) => {
|
|
400
|
-
it(`'${code}' adds active class`, () => {
|
|
401
|
-
const event = new window.KeyboardEvent('keydown', {code});
|
|
402
|
-
dropDown._toggleEl.dispatchEvent(event);
|
|
403
|
-
assert.ok(dropDown._toggleEl.classList.contains('active'));
|
|
404
|
-
});
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
it('ArrowUp on the first menu element should focus the last element', () => {
|
|
408
|
-
dropDown._toggleEl.click();
|
|
409
|
-
|
|
410
|
-
const arrowUp = new window.KeyboardEvent('keydown', {bubbles: true, code: 'ArrowUp'});
|
|
411
|
-
dropDown._menuEl.firstElementChild.dispatchEvent(arrowUp);
|
|
412
|
-
|
|
413
|
-
assert.strictEqual(dom.document().activeElement, dropDown._menuEl.lastElementChild);
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
it('ArrowDown on the first menu element should focus the second element', () => {
|
|
417
|
-
dropDown._toggleEl.click();
|
|
418
|
-
|
|
419
|
-
const {nextElementSibling} = dropDown._menuEl.firstElementChild;
|
|
420
|
-
const arrowDown = new window.KeyboardEvent('keydown', {bubbles: true, code: 'ArrowDown'});
|
|
421
|
-
dropDown._menuEl.firstElementChild.dispatchEvent(arrowDown);
|
|
422
|
-
|
|
423
|
-
assert.strictEqual(dom.document().activeElement, nextElementSibling);
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it('Home on the last menu element should focus the first element', () => {
|
|
427
|
-
dropDown._toggleEl.click();
|
|
428
|
-
|
|
429
|
-
const {firstElementChild} = dropDown._menuEl;
|
|
430
|
-
const home = new window.KeyboardEvent('keydown', {bubbles: true, code: 'Home'});
|
|
431
|
-
dropDown._menuEl.lastElementChild.dispatchEvent(home);
|
|
432
|
-
|
|
433
|
-
assert.strictEqual(dom.document().activeElement, firstElementChild);
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
it('End on the first menu element should focus the last element', () => {
|
|
437
|
-
dropDown._toggleEl.click();
|
|
438
|
-
|
|
439
|
-
const {lastElementChild} = dropDown._menuEl;
|
|
440
|
-
const end = new window.KeyboardEvent('keydown', {bubbles: true, code: 'End'});
|
|
441
|
-
dropDown._menuEl.firstElementChild.dispatchEvent(end);
|
|
442
|
-
|
|
443
|
-
assert.strictEqual(dom.document().activeElement, lastElementChild);
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
describe('_getNextSelectableNode', () => {
|
|
447
|
-
let createDiv;
|
|
448
|
-
|
|
449
|
-
beforeAll(() => {
|
|
450
|
-
createDiv = () => dom.document().createElement('div');
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
it('should return undefined when nodes is empty', () => {
|
|
454
|
-
const nodes = [];
|
|
455
|
-
|
|
456
|
-
const nextNode = dropDown._getNextSelectableNode(nodes);
|
|
457
|
-
|
|
458
|
-
assert.strictEqual(nextNode, undefined);
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
it('should return the only node when start is defined', () => {
|
|
462
|
-
const node = createDiv();
|
|
463
|
-
|
|
464
|
-
const nextNode = dropDown._getNextSelectableNode([node], node);
|
|
465
|
-
|
|
466
|
-
assert.strictEqual(nextNode, node);
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
it('should return first node when start is undefined', () => {
|
|
470
|
-
const nodes = [createDiv(), createDiv()];
|
|
471
|
-
|
|
472
|
-
const nextNode = dropDown._getNextSelectableNode(nodes);
|
|
473
|
-
|
|
474
|
-
assert.strictEqual(nextNode, nodes[0]);
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
it('should return second node when start is first node', () => {
|
|
478
|
-
const nodes = [createDiv(), createDiv()];
|
|
479
|
-
|
|
480
|
-
const nextNode = dropDown._getNextSelectableNode(nodes, nodes[0]);
|
|
481
|
-
|
|
482
|
-
assert.strictEqual(nextNode, nodes[1]);
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
it('should return first node when start is second node', () => {
|
|
486
|
-
const nodes = [createDiv(), createDiv()];
|
|
487
|
-
|
|
488
|
-
const nextNode = dropDown._getNextSelectableNode(nodes, nodes[1]);
|
|
489
|
-
|
|
490
|
-
assert.strictEqual(nextNode, nodes[0]);
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
it('should skip the undefined node', () => {
|
|
494
|
-
const nodes = [createDiv(), undefined, createDiv()];
|
|
495
|
-
|
|
496
|
-
const nextNode = dropDown._getNextSelectableNode(nodes, nodes[0]);
|
|
497
|
-
|
|
498
|
-
assert.strictEqual(nextNode, nodes[2]);
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
it('should skip the disabled node', () => {
|
|
502
|
-
const disabledNode = createDiv();
|
|
503
|
-
disabledNode.setAttribute('disabled', true);
|
|
504
|
-
const nodes = [createDiv(), disabledNode, createDiv()];
|
|
505
|
-
|
|
506
|
-
const nextNode = dropDown._getNextSelectableNode(nodes, nodes[0]);
|
|
507
|
-
|
|
508
|
-
assert.strictEqual(nextNode, nodes[2]);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
describe('onMenuFocusOut', () => {
|
|
513
|
-
beforeEach(() => {
|
|
514
|
-
dropDown._toggleEl.click();
|
|
515
|
-
assert.ok(dropDown._toggleEl.classList.contains('active'));
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
it('should toggle active class when focus relatedTarget is null', () => {
|
|
519
|
-
const event = new window.FocusEvent('focusout', {relatedTarget: null});
|
|
520
|
-
dropDown.onMenuFocusOut(event);
|
|
521
|
-
|
|
522
|
-
assert.ok(!dropDown._toggleEl.classList.contains('active'));
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
it('should toggle active class when focus relatedTarget is document.body', () => {
|
|
526
|
-
const relatedTarget = dom.document().body;
|
|
527
|
-
const event = new window.FocusEvent('focusout', {relatedTarget});
|
|
528
|
-
dropDown.onMenuFocusOut(event);
|
|
529
|
-
|
|
530
|
-
assert.ok(!dropDown._toggleEl.classList.contains('active'));
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
it('should toggle active class when focus relatedTarget is _toggleEl', () => {
|
|
534
|
-
const relatedTarget = dropDown._toggleEl;
|
|
535
|
-
const event = new window.FocusEvent('focusout', {relatedTarget});
|
|
536
|
-
dropDown.onMenuFocusOut(event);
|
|
537
|
-
|
|
538
|
-
assert.ok(!dropDown._toggleEl.classList.contains('active'));
|
|
539
|
-
});
|
|
540
|
-
|
|
541
|
-
it('should not toggle active class when focus relatedTarget is a menu item', () => {
|
|
542
|
-
const relatedTarget = dropDown._getNextMenuItem();
|
|
543
|
-
const event = new window.FocusEvent('focusout', {relatedTarget});
|
|
544
|
-
dropDown.onMenuFocusOut(event);
|
|
545
|
-
|
|
546
|
-
assert.ok(dropDown._toggleEl.classList.contains('active'));
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
describe('treemap button', () => {
|
|
552
|
-
it('should only show button if treemap data is available', () => {
|
|
553
|
-
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
554
|
-
|
|
555
|
-
expect(lhr.audits['script-treemap-data']).not.toBeUndefined();
|
|
556
|
-
expect(render(lhr).querySelector('.lh-button.report-icon--treemap')).toBeTruthy();
|
|
557
|
-
|
|
558
|
-
delete lhr.audits['script-treemap-data'];
|
|
559
|
-
expect(render(lhr).querySelector('.lh-button.report-icon--treemap')).toBeNull();
|
|
560
|
-
});
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
describe('data-i18n', () => {
|
|
564
|
-
it('should have only valid data-i18n values in template', () => {
|
|
565
|
-
const container = render(sampleResults);
|
|
566
|
-
for (const node of dom.findAll('[data-i18n]', container)) {
|
|
567
|
-
const val = node.getAttribute('data-i18n');
|
|
568
|
-
assert.ok(val in Util.UIStrings, `Invalid data-i18n value of: "${val}" not found.`);
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
});
|