lighthouse 8.5.1-dev.20211012 → 8.5.1
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/dist/report/flow.js +149 -0
- package/dist/report/standalone.js +228 -0
- package/flow-report/assets/styles.css +9 -272
- package/flow-report/jest.config.js +1 -1
- package/flow-report/src/app.tsx +9 -31
- package/flow-report/src/common.tsx +7 -86
- package/flow-report/src/icons.tsx +3 -20
- package/flow-report/src/sidebar/sidebar.tsx +16 -11
- package/flow-report/src/summary/category.tsx +24 -42
- package/flow-report/src/summary/summary.tsx +29 -32
- package/flow-report/src/topbar.tsx +4 -54
- package/flow-report/src/util.ts +1 -26
- package/flow-report/src/wrappers/report-renderer.tsx +1 -1
- package/flow-report/src/wrappers/report.tsx +21 -6
- package/flow-report/test/app-test.tsx +13 -17
- package/flow-report/test/setup/env-setup.ts +0 -1
- package/flow-report/test/sidebar/flow-test.tsx +12 -6
- package/flow-report/test/sidebar/sidebar-test.tsx +13 -7
- package/flow-report/test/summary/category-test.tsx +34 -79
- package/flow-report/test/summary/summary-test.tsx +17 -11
- package/flow-report/test/util-test.tsx +12 -1
- package/flow-report/tsconfig.json +0 -1
- package/flow-report/types/flow-report.d.ts +1 -2
- package/jest.config.js +15 -1
- package/lighthouse-cli/bin.js +0 -5
- package/lighthouse-cli/cli-flags.js +3 -10
- package/lighthouse-cli/commands/commands.js +0 -1
- package/lighthouse-cli/run.js +2 -2
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +0 -0
- package/lighthouse-cli/test/smokehouse/report-assert.js +4 -20
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -1
- package/lighthouse-core/audits/seo/crawlable-anchors.js +12 -10
- package/lighthouse-core/computed/js-bundles.js +2 -1
- package/lighthouse-core/computed/unused-javascript-summary.js +3 -3
- package/lighthouse-core/config/config.js +2 -2
- package/lighthouse-core/config/default-config.js +0 -5
- package/lighthouse-core/fraggle-rock/api.js +0 -10
- package/lighthouse-core/fraggle-rock/config/filters.js +3 -22
- package/lighthouse-core/fraggle-rock/gather/driver.js +0 -4
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +2 -2
- package/lighthouse-core/fraggle-rock/user-flow.js +6 -35
- package/lighthouse-core/gather/driver/navigation.js +0 -5
- package/lighthouse-core/gather/driver/prepare.js +0 -14
- package/lighthouse-core/gather/driver/storage.js +0 -5
- package/lighthouse-core/gather/gather-runner.js +2 -2
- package/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +1 -5
- package/lighthouse-core/gather/gatherers/full-page-screenshot.js +24 -30
- package/{shared/localization/i18n-module.js → lighthouse-core/lib/cdt/Common.js} +8 -3
- package/lighthouse-core/lib/cdt/SDK.js +123 -3
- package/lighthouse-core/lib/cdt/generated/SourceMap.js +312 -148
- package/lighthouse-core/lib/csp-evaluator.js +1 -2
- package/lighthouse-core/lib/i18n/README.md +6 -6
- package/lighthouse-core/lib/i18n/i18n.js +342 -9
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ar-XB.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ar.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/bg.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ca.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/cs.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/da.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/de.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/el.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-GB.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-US.json +0 -111
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-XA.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-XL.json +0 -111
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/es-419.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/es.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/fi.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/fil.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/fr.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/he.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/hi.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/hr.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/hu.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/id.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/it.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ja.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ko.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/lt.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/lv.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/nl.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/no.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/pl.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/pt-PT.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/pt.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ro.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ru.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/sk.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/sl.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/sr-Latn.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/sr.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/sv.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/ta.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/te.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/th.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/tr.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/uk.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/vi.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/zh-HK.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/zh-TW.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales/zh.json +0 -0
- package/{shared/localization → lighthouse-core/lib/i18n}/locales.js +1 -2
- package/{shared/localization → lighthouse-core/lib/i18n}/swap-locale.js +7 -9
- package/lighthouse-core/lib/page-functions.js +4 -4
- package/lighthouse-core/lib/stack-packs.js +13 -1
- package/{shared → lighthouse-core/lib}/type-verifiers.js +0 -0
- package/lighthouse-core/runner.js +6 -6
- package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -4
- package/lighthouse-core/util-commonjs.js +4 -20
- package/package.json +16 -19
- package/readme.md +1 -1
- package/report/assets/standalone-template.html +1 -0
- package/report/assets/styles.css +41 -16
- package/report/assets/templates.html +4 -42
- package/report/clients/psi.js +0 -1
- package/report/clients/standalone.js +2 -1
- package/report/generator/file-namer.js +8 -17
- package/report/generator/report-generator.js +1 -0
- package/report/renderer/category-renderer.js +16 -4
- package/report/renderer/components.js +71 -107
- package/report/renderer/dom.js +0 -19
- package/report/renderer/logger.js +2 -35
- package/report/renderer/performance-category-renderer.js +21 -23
- package/report/renderer/pwa-category-renderer.js +2 -1
- package/report/renderer/report-renderer.js +0 -21
- package/report/renderer/report-ui-features.js +19 -7
- package/report/renderer/util.js +4 -20
- package/report/test/clients/psi-test.js +4 -0
- package/report/test/generator/file-namer-test.js +2 -2
- package/report/test/renderer/category-renderer-test.js +1 -1
- package/report/test/renderer/performance-category-renderer-test.js +0 -12
- package/report/test/renderer/report-renderer-test.js +55 -0
- package/report/test/renderer/util-test.js +8 -68
- package/report/test-assets/faux-psi-template.html +1 -0
- package/report/tsconfig.json +1 -2
- package/report/types/html-renderer.d.ts +1 -2
- package/root.js +0 -18
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +3 -5
- package/third-party/chromium-synchronization/installability-errors-test.js +1 -2
- package/tsconfig-all.json +0 -1
- package/tsconfig-base.json +1 -1
- package/tsconfig.json +3 -2
- package/types/config.d.ts +0 -1
- package/types/externs.d.ts +0 -2
- package/types/lhr/flow.d.ts +0 -7
- package/types/lhr/i18n.d.ts +3 -0
- package/changelog.md +0 -5395
- package/flow-report/.eslintrc.cjs +0 -49
- package/flow-report/package.json +0 -4
- package/flow-report/src/header.tsx +0 -88
- package/flow-report/src/help-dialog.tsx +0 -120
- package/flow-report/src/i18n/i18n.tsx +0 -44
- package/flow-report/src/i18n/localized-strings.js +0 -11
- package/flow-report/src/i18n/ui-strings.js +0 -86
- package/flow-report/test/common-test.tsx +0 -89
- package/flow-report/test/header-test.tsx +0 -55
- package/flow-report/test/sample-flow.ts +0 -17
- package/flow-report/test/topbar-test.tsx +0 -68
- package/lighthouse-cli/commands/list-locales.js +0 -16
- package/lighthouse-core/lib/cdt/Platform.js +0 -55
- package/lighthouse-core/scripts/package.json +0 -4
- package/report/renderer/swap-locale-feature.js +0 -82
- package/report/test/renderer/report-renderer-axe-test.js +0 -86
- package/shared/localization/format.js +0 -422
- package/shared/localization/swap-flow-locale.js +0 -20
- package/shared/test/localization/format-test.js +0 -377
- package/shared/test/localization/locales-test.js +0 -47
- package/shared/test/localization/swap-locale-test.js +0 -140
- package/shared/tsconfig.json +0 -22
- package/shared/types/shared.d.ts +0 -24
- package/types/es-main.d.ts +0 -18
|
@@ -4,110 +4,65 @@
|
|
|
4
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
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import {dirname} from 'path';
|
|
9
|
+
import {fileURLToPath} from 'url';
|
|
10
|
+
|
|
8
11
|
import {render} from '@testing-library/preact';
|
|
9
12
|
|
|
10
13
|
import {SummaryTooltip} from '../../src/summary/category';
|
|
11
|
-
import {
|
|
12
|
-
import {I18nProvider} from '../../src/i18n/i18n';
|
|
13
|
-
import {FlowResultContext} from '../../src/util';
|
|
14
|
-
|
|
15
|
-
let wrapper: FunctionComponent;
|
|
14
|
+
import {Util} from '../../../report/renderer/util';
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
</FlowResultContext.Provider>
|
|
25
|
-
);
|
|
26
|
-
});
|
|
16
|
+
const flowResult: LH.FlowResult = JSON.parse(
|
|
17
|
+
fs.readFileSync(
|
|
18
|
+
// eslint-disable-next-line max-len
|
|
19
|
+
`${dirname(fileURLToPath(import.meta.url))}/../../../lighthouse-core/test/fixtures/fraggle-rock/reports/sample-lhrs.json`,
|
|
20
|
+
'utf-8'
|
|
21
|
+
)
|
|
22
|
+
);
|
|
27
23
|
|
|
28
24
|
describe('SummaryTooltip', () => {
|
|
29
25
|
it('renders tooltip with rating', async () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
auditRefs: [
|
|
34
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
35
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
36
|
-
{result: {score: 0, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
37
|
-
],
|
|
38
|
-
};
|
|
26
|
+
// Snapshot SEO
|
|
27
|
+
const reportResult = Util.prepareReportResult(flowResult.steps[2].lhr);
|
|
28
|
+
const category = reportResult.categories['seo'];
|
|
39
29
|
|
|
40
30
|
const root = render(
|
|
41
|
-
<SummaryTooltip category={category} gatherMode=
|
|
42
|
-
{wrapper}
|
|
31
|
+
<SummaryTooltip category={category} gatherMode={reportResult.gatherMode}/>
|
|
43
32
|
);
|
|
44
33
|
|
|
45
|
-
|
|
46
|
-
expect(
|
|
47
|
-
|
|
34
|
+
const rating = root.getByTestId('SummaryTooltip__rating');
|
|
35
|
+
expect(rating.classList).toContain('SummaryTooltip__rating--average');
|
|
36
|
+
|
|
37
|
+
expect(root.getByText('9 audits passed / 11 audits run')).toBeTruthy();
|
|
48
38
|
});
|
|
49
39
|
|
|
50
40
|
it('renders tooltip without rating', async () => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
auditRefs: [
|
|
55
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 0, group: 'diagnostics'},
|
|
56
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 0, group: 'diagnostics'},
|
|
57
|
-
{result: {score: 0, scoreDisplayMode: 'binary'}, weight: 0, group: 'diagnostics'},
|
|
58
|
-
],
|
|
59
|
-
};
|
|
41
|
+
// Snapshot performance
|
|
42
|
+
const reportResult = Util.prepareReportResult(flowResult.steps[2].lhr);
|
|
43
|
+
const category = reportResult.categories['performance'];
|
|
60
44
|
|
|
61
45
|
const root = render(
|
|
62
|
-
<SummaryTooltip category={category} gatherMode=
|
|
63
|
-
{wrapper}
|
|
46
|
+
<SummaryTooltip category={category} gatherMode={reportResult.gatherMode}/>
|
|
64
47
|
);
|
|
65
48
|
|
|
66
|
-
expect(() => root.
|
|
67
|
-
expect(
|
|
68
|
-
expect(root.getByText('2 audits passed / 3 passable audits')).toBeTruthy();
|
|
49
|
+
expect(() => root.getByTestId('SummaryTooltip__rating')).toThrow();
|
|
50
|
+
expect(root.getByText('2 audits passed / 4 audits run')).toBeTruthy();
|
|
69
51
|
});
|
|
70
52
|
|
|
71
53
|
it('renders scored category tooltip with score', async () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
auditRefs: [
|
|
76
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
77
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
78
|
-
{result: {score: 0, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
54
|
+
// Navigation performance
|
|
55
|
+
const reportResult = Util.prepareReportResult(flowResult.steps[0].lhr);
|
|
56
|
+
const category = reportResult.categories['performance'];
|
|
81
57
|
|
|
82
58
|
const root = render(
|
|
83
|
-
<SummaryTooltip category={category} gatherMode=
|
|
84
|
-
{wrapper}
|
|
59
|
+
<SummaryTooltip category={category} gatherMode={reportResult.gatherMode}/>
|
|
85
60
|
);
|
|
86
61
|
|
|
87
|
-
|
|
88
|
-
expect(
|
|
89
|
-
expect(
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('renders informative audit count if any', async () => {
|
|
93
|
-
const category: any = {
|
|
94
|
-
id: 'performance',
|
|
95
|
-
score: 1,
|
|
96
|
-
auditRefs: [
|
|
97
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
98
|
-
{result: {score: 1, scoreDisplayMode: 'binary'}, weight: 1, group: 'diagnostics'},
|
|
99
|
-
{result: {score: 0, scoreDisplayMode: 'informative'}, weight: 1, group: 'diagnostics'},
|
|
100
|
-
],
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const root = render(
|
|
104
|
-
<SummaryTooltip category={category} gatherMode="navigation"/>,
|
|
105
|
-
{wrapper}
|
|
106
|
-
);
|
|
62
|
+
const rating = root.getByTestId('SummaryTooltip__rating');
|
|
63
|
+
expect(rating.classList).toContain('SummaryTooltip__rating--pass');
|
|
64
|
+
expect(rating.textContent).toEqual('Good · 94');
|
|
107
65
|
|
|
108
|
-
expect(root.getByText('
|
|
109
|
-
expect(root.getByText('100')).toBeTruthy();
|
|
110
|
-
expect(root.getByText('2 audits passed / 2 passable audits')).toBeTruthy();
|
|
111
|
-
expect(root.getByText('1 informative audits')).toBeTruthy();
|
|
66
|
+
expect(root.getByText('41 audits passed / 58 audits run')).toBeTruthy();
|
|
112
67
|
});
|
|
113
68
|
});
|
|
@@ -4,14 +4,24 @@
|
|
|
4
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
5
|
*/
|
|
6
6
|
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import {dirname} from 'path';
|
|
9
|
+
import {fileURLToPath} from 'url';
|
|
10
|
+
|
|
7
11
|
import {render} from '@testing-library/preact';
|
|
8
12
|
import {FunctionComponent} from 'preact';
|
|
9
13
|
|
|
10
|
-
import {I18nProvider} from '../../src/i18n/i18n';
|
|
11
14
|
import {SummaryHeader, SummaryFlowStep} from '../../src/summary/summary';
|
|
12
15
|
import {FlowResultContext} from '../../src/util';
|
|
13
16
|
import {ReportRendererProvider} from '../../src/wrappers/report-renderer';
|
|
14
|
-
|
|
17
|
+
|
|
18
|
+
const flowResult: LH.FlowResult = JSON.parse(
|
|
19
|
+
fs.readFileSync(
|
|
20
|
+
// eslint-disable-next-line max-len
|
|
21
|
+
`${dirname(fileURLToPath(import.meta.url))}/../../../lighthouse-core/test/fixtures/fraggle-rock/reports/sample-lhrs.json`,
|
|
22
|
+
'utf-8'
|
|
23
|
+
)
|
|
24
|
+
);
|
|
15
25
|
|
|
16
26
|
let wrapper: FunctionComponent;
|
|
17
27
|
|
|
@@ -19,9 +29,7 @@ beforeEach(() => {
|
|
|
19
29
|
wrapper = ({children}) => (
|
|
20
30
|
<FlowResultContext.Provider value={flowResult}>
|
|
21
31
|
<ReportRendererProvider>
|
|
22
|
-
|
|
23
|
-
{children}
|
|
24
|
-
</I18nProvider>
|
|
32
|
+
{children}
|
|
25
33
|
</ReportRendererProvider>
|
|
26
34
|
</FlowResultContext.Provider>
|
|
27
35
|
);
|
|
@@ -51,8 +59,7 @@ describe('SummaryFlowStep', () => {
|
|
|
51
59
|
|
|
52
60
|
expect(root.getByText('Navigation (1)')).toBeTruthy();
|
|
53
61
|
|
|
54
|
-
const screenshot =
|
|
55
|
-
root.getByAltText('Screenshot of a page tested by Lighthouse') as HTMLImageElement;
|
|
62
|
+
const screenshot = root.getByTestId('SummaryFlowStep__screenshot') as HTMLImageElement;
|
|
56
63
|
expect(screenshot.src).toMatch(/data:image\/jpeg;base64/);
|
|
57
64
|
|
|
58
65
|
const gauges = root.getAllByTestId('CategoryScore');
|
|
@@ -60,7 +67,6 @@ describe('SummaryFlowStep', () => {
|
|
|
60
67
|
|
|
61
68
|
const links = root.getAllByRole('link') as HTMLAnchorElement[];
|
|
62
69
|
expect(links.map(a => a.href)).toEqual([
|
|
63
|
-
'https://www.mikescerealshack.co/',
|
|
64
70
|
'file:///Users/example/report.html/#index=0',
|
|
65
71
|
'file:///Users/example/report.html/#index=0&anchor=performance',
|
|
66
72
|
'file:///Users/example/report.html/#index=0&anchor=accessibility',
|
|
@@ -80,7 +86,8 @@ describe('SummaryFlowStep', () => {
|
|
|
80
86
|
|
|
81
87
|
expect(root.getByText('Timespan (1)')).toBeTruthy();
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
const screenshot = root.getByTestId('SummaryFlowStep__screenshot') as HTMLImageElement;
|
|
90
|
+
expect(screenshot.src).toBeFalsy();
|
|
84
91
|
|
|
85
92
|
// Accessibility and SEO are missing in timespan.
|
|
86
93
|
const nullCategories = root.getAllByTestId('SummaryCategory__null');
|
|
@@ -108,8 +115,7 @@ describe('SummaryFlowStep', () => {
|
|
|
108
115
|
|
|
109
116
|
expect(root.getByText('Snapshot (1)')).toBeTruthy();
|
|
110
117
|
|
|
111
|
-
const screenshot =
|
|
112
|
-
root.getByAltText('Screenshot of a page tested by Lighthouse') as HTMLImageElement;
|
|
118
|
+
const screenshot = root.getByTestId('SummaryFlowStep__screenshot') as HTMLImageElement;
|
|
113
119
|
expect(screenshot.src).toMatch(/data:image\/jpeg;base64/);
|
|
114
120
|
|
|
115
121
|
const gauges = root.getAllByTestId('CategoryScore');
|
|
@@ -4,13 +4,24 @@
|
|
|
4
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
5
|
*/
|
|
6
6
|
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import {dirname} from 'path';
|
|
9
|
+
import {fileURLToPath} from 'url';
|
|
10
|
+
|
|
7
11
|
import {jest} from '@jest/globals';
|
|
8
12
|
import {renderHook} from '@testing-library/preact-hooks';
|
|
9
13
|
import {FunctionComponent} from 'preact';
|
|
10
14
|
import {act} from 'preact/test-utils';
|
|
11
15
|
|
|
12
16
|
import {FlowResultContext, useCurrentLhr} from '../src/util';
|
|
13
|
-
|
|
17
|
+
|
|
18
|
+
const flowResult: LH.FlowResult = JSON.parse(
|
|
19
|
+
fs.readFileSync(
|
|
20
|
+
// eslint-disable-next-line max-len
|
|
21
|
+
`${dirname(fileURLToPath(import.meta.url))}/../../lighthouse-core/test/fixtures/fraggle-rock/reports/sample-lhrs.json`,
|
|
22
|
+
'utf-8'
|
|
23
|
+
)
|
|
24
|
+
);
|
|
14
25
|
|
|
15
26
|
let wrapper: FunctionComponent;
|
|
16
27
|
|
package/jest.config.js
CHANGED
|
@@ -6,6 +6,18 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
module.exports = {
|
|
9
|
+
collectCoverage: false,
|
|
10
|
+
coverageReporters: ['none'],
|
|
11
|
+
collectCoverageFrom: [
|
|
12
|
+
'**/lighthouse-core/**/*.js',
|
|
13
|
+
'**/lighthouse-cli/**/*.js',
|
|
14
|
+
'**/report/**/*.js',
|
|
15
|
+
'**/lighthouse-viewer/**/*.js',
|
|
16
|
+
],
|
|
17
|
+
coveragePathIgnorePatterns: [
|
|
18
|
+
'/test/',
|
|
19
|
+
'/scripts/',
|
|
20
|
+
],
|
|
9
21
|
setupFilesAfterEnv: ['./lighthouse-core/test/test-utils.js'],
|
|
10
22
|
testEnvironment: 'node',
|
|
11
23
|
testMatch: [
|
|
@@ -14,10 +26,12 @@ module.exports = {
|
|
|
14
26
|
'**/report/**/*-test.js',
|
|
15
27
|
'**/lighthouse-core/test/fraggle-rock/**/*-test-pptr.js',
|
|
16
28
|
'**/lighthouse-treemap/**/*-test.js',
|
|
29
|
+
'**/lighthouse-treemap/**/*-test-pptr.js',
|
|
17
30
|
'**/lighthouse-viewer/**/*-test.js',
|
|
31
|
+
'**/lighthouse-viewer/**/*-test-pptr.js',
|
|
18
32
|
'**/third-party/**/*-test.js',
|
|
19
33
|
'**/clients/test/**/*-test.js',
|
|
20
|
-
'**/
|
|
34
|
+
'**/docs/**/*.test.js',
|
|
21
35
|
],
|
|
22
36
|
transform: {},
|
|
23
37
|
prettierPath: null,
|
package/lighthouse-cli/bin.js
CHANGED
|
@@ -61,11 +61,6 @@ async function begin() {
|
|
|
61
61
|
commands.listAudits();
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// Process terminating command
|
|
65
|
-
if (cliFlags.listLocales) {
|
|
66
|
-
commands.listLocales();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
64
|
// Process terminating command
|
|
70
65
|
if (cliFlags.listTraceCategories) {
|
|
71
66
|
commands.listTraceCategories();
|
|
@@ -12,8 +12,7 @@ import fs from 'fs';
|
|
|
12
12
|
import yargs from 'yargs';
|
|
13
13
|
import * as yargsHelpers from 'yargs/helpers';
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
import {isObjectOfUnknownValues} from '../shared/type-verifiers.js';
|
|
15
|
+
import {isObjectOfUnknownValues} from '../lighthouse-core/lib/type-verifiers.js';
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* @param {string=} manualArgv
|
|
@@ -27,7 +26,6 @@ function getFlags(manualArgv, options = {}) {
|
|
|
27
26
|
yargs(yargsHelpers.hideBin(process.argv));
|
|
28
27
|
|
|
29
28
|
let parser = y.help('help')
|
|
30
|
-
.version(JSON.parse(fs.readFileSync(`${LH_ROOT}/package.json`, 'utf-8')).version)
|
|
31
29
|
.showHelpOnFail(false, 'Specify --help for available options')
|
|
32
30
|
|
|
33
31
|
.usage('lighthouse <url> <options>')
|
|
@@ -105,11 +103,6 @@ function getFlags(manualArgv, options = {}) {
|
|
|
105
103
|
default: false,
|
|
106
104
|
describe: 'Prints a list of all available audits and exits',
|
|
107
105
|
},
|
|
108
|
-
'list-locales': {
|
|
109
|
-
type: 'boolean',
|
|
110
|
-
default: false,
|
|
111
|
-
describe: 'Prints a list of all supported locales and exits',
|
|
112
|
-
},
|
|
113
106
|
'list-trace-categories': {
|
|
114
107
|
type: 'boolean',
|
|
115
108
|
default: false,
|
|
@@ -215,7 +208,7 @@ function getFlags(manualArgv, options = {}) {
|
|
|
215
208
|
},
|
|
216
209
|
})
|
|
217
210
|
.group([
|
|
218
|
-
'save-assets', 'list-all-audits', 'list-
|
|
211
|
+
'save-assets', 'list-all-audits', 'list-trace-categories', 'print-config', 'additional-trace-categories',
|
|
219
212
|
'config-path', 'preset', 'chrome-flags', 'port', 'hostname', 'form-factor', 'screenEmulation', 'emulatedUserAgent',
|
|
220
213
|
'max-wait-for-load', 'enable-error-reporting', 'gather-mode', 'audit-mode',
|
|
221
214
|
'only-audits', 'only-categories', 'skip-audits', 'budget-path',
|
|
@@ -319,7 +312,7 @@ function getFlags(manualArgv, options = {}) {
|
|
|
319
312
|
// - We're just printing the config.
|
|
320
313
|
// - We're in auditMode (and we have artifacts already)
|
|
321
314
|
// If one of these don't apply, if no URL, stop the program and ask for one.
|
|
322
|
-
const isPrintSomethingMode = argv.listAllAudits || argv.
|
|
315
|
+
const isPrintSomethingMode = argv.listAllAudits || argv.listTraceCategories || argv.printConfig;
|
|
323
316
|
const isOnlyAuditMode = !!argv.auditMode && !argv.gatherMode;
|
|
324
317
|
if (isPrintSomethingMode || isOnlyAuditMode) {
|
|
325
318
|
return true;
|
package/lighthouse-cli/run.js
CHANGED
|
@@ -17,7 +17,7 @@ import open from 'open';
|
|
|
17
17
|
|
|
18
18
|
import * as Printer from './printer.js';
|
|
19
19
|
import lighthouse from '../lighthouse-core/index.js';
|
|
20
|
-
import {
|
|
20
|
+
import {getFilenamePrefix} from '../report/generator/file-namer.js';
|
|
21
21
|
import * as assetSaver from '../lighthouse-core/lib/asset-saver.js';
|
|
22
22
|
import URL from '../lighthouse-core/lib/url-shim.js';
|
|
23
23
|
|
|
@@ -137,7 +137,7 @@ async function saveResults(runnerResult, flags) {
|
|
|
137
137
|
// Use the output path as the prefix for all generated files.
|
|
138
138
|
// If no output path is set, generate a file prefix using the URL and date.
|
|
139
139
|
const configuredPath = !flags.outputPath || flags.outputPath === 'stdout' ?
|
|
140
|
-
|
|
140
|
+
getFilenamePrefix(lhr) :
|
|
141
141
|
flags.outputPath.replace(/\.\w{2,4}$/, '');
|
|
142
142
|
const resolvedPath = path.resolve(cwd, configuredPath);
|
|
143
143
|
|
|
File without changes
|
|
@@ -200,42 +200,26 @@ function pruneExpectations(localConsole, lhr, expected, reportOptions) {
|
|
|
200
200
|
JSON.stringify(value, null, 2),
|
|
201
201
|
`Actual Chromium version: ${getChromeVersion()}`,
|
|
202
202
|
].join(' '));
|
|
203
|
-
|
|
204
|
-
obj.splice(Number(key), 1);
|
|
205
|
-
} else {
|
|
206
|
-
delete obj[key];
|
|
207
|
-
}
|
|
203
|
+
delete obj[key];
|
|
208
204
|
} else if (value._legacyOnly && isFraggleRock) {
|
|
209
205
|
localConsole.log([
|
|
210
206
|
`[${key}] marked legacy only but run is Fraggle Rock, pruning expectation:`,
|
|
211
207
|
JSON.stringify(value, null, 2),
|
|
212
208
|
].join(' '));
|
|
213
|
-
|
|
214
|
-
obj.splice(Number(key), 1);
|
|
215
|
-
} else {
|
|
216
|
-
delete obj[key];
|
|
217
|
-
}
|
|
209
|
+
delete obj[key];
|
|
218
210
|
} else if (value._fraggleRockOnly && !isFraggleRock) {
|
|
219
211
|
localConsole.log([
|
|
220
212
|
`[${key}] marked Fraggle Rock only but run is legacy, pruning expectation:`,
|
|
221
213
|
JSON.stringify(value, null, 2),
|
|
222
214
|
`Actual channel: ${lhr.configSettings.channel}`,
|
|
223
215
|
].join(' '));
|
|
224
|
-
|
|
225
|
-
obj.splice(Number(key), 1);
|
|
226
|
-
} else {
|
|
227
|
-
delete obj[key];
|
|
228
|
-
}
|
|
216
|
+
delete obj[key];
|
|
229
217
|
} else if (value._skipInBundled && !isBundled) {
|
|
230
218
|
localConsole.log([
|
|
231
219
|
`[${key}] marked as skip in bundled and runner is bundled, pruning expectation:`,
|
|
232
220
|
JSON.stringify(value, null, 2),
|
|
233
221
|
].join(' '));
|
|
234
|
-
|
|
235
|
-
obj.splice(Number(key), 1);
|
|
236
|
-
} else {
|
|
237
|
-
delete obj[key];
|
|
238
|
-
}
|
|
222
|
+
delete obj[key];
|
|
239
223
|
} else {
|
|
240
224
|
pruneRecursively(value);
|
|
241
225
|
}
|
|
@@ -115,12 +115,11 @@ class UnusedBytes extends Audit {
|
|
|
115
115
|
settings,
|
|
116
116
|
};
|
|
117
117
|
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
118
|
-
const hasContentfulRecords = networkRecords.some(record => record.transferSize);
|
|
119
118
|
|
|
120
119
|
// Requesting load simulator requires non-empty network records.
|
|
121
120
|
// Timespans are not guaranteed to have any network activity.
|
|
122
121
|
// There are no bytes to be saved if no bytes were downloaded, so mark N/A if empty.
|
|
123
|
-
if (!
|
|
122
|
+
if (!networkRecords.length && gatherContext.gatherMode === 'timespan') {
|
|
124
123
|
return {
|
|
125
124
|
score: 1,
|
|
126
125
|
notApplicable: true,
|
|
@@ -128,7 +128,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
|
|
|
128
128
|
})
|
|
129
129
|
.filter(d => d.unused >= bundleSourceUnusedThreshold);
|
|
130
130
|
|
|
131
|
-
const commonSourcePrefix = commonPrefix([...bundle.map.
|
|
131
|
+
const commonSourcePrefix = commonPrefix([...bundle.map._sourceInfos.keys()]);
|
|
132
132
|
item.subItems = {
|
|
133
133
|
type: 'subitems',
|
|
134
134
|
items: topUnusedSourceSizes.map(({source, unused, total}) => {
|
|
@@ -31,7 +31,7 @@ class CrawlableAnchors extends Audit {
|
|
|
31
31
|
title: str_(UIStrings.title),
|
|
32
32
|
failureTitle: str_(UIStrings.failureTitle),
|
|
33
33
|
description: str_(UIStrings.description),
|
|
34
|
-
requiredArtifacts: ['AnchorElements'
|
|
34
|
+
requiredArtifacts: ['AnchorElements'],
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -39,12 +39,15 @@ class CrawlableAnchors extends Audit {
|
|
|
39
39
|
* @param {LH.Artifacts} artifacts
|
|
40
40
|
* @return {LH.Audit.Product}
|
|
41
41
|
*/
|
|
42
|
-
static audit({AnchorElements: anchorElements
|
|
42
|
+
static audit({AnchorElements: anchorElements}) {
|
|
43
43
|
const failingAnchors = anchorElements.filter(({
|
|
44
44
|
rawHref,
|
|
45
|
+
listeners = [],
|
|
46
|
+
onclick = '',
|
|
45
47
|
name = '',
|
|
46
48
|
role = '',
|
|
47
49
|
}) => {
|
|
50
|
+
onclick = onclick.replace( /\s/g, '');
|
|
48
51
|
rawHref = rawHref.replace( /\s/g, '');
|
|
49
52
|
name = name.trim();
|
|
50
53
|
role = role.trim();
|
|
@@ -53,20 +56,19 @@ class CrawlableAnchors extends Audit {
|
|
|
53
56
|
// Ignore mailto links even if they use one of the failing patterns. See https://github.com/GoogleChrome/lighthouse/issues/11443#issuecomment-694898412
|
|
54
57
|
if (rawHref.startsWith('mailto:')) return;
|
|
55
58
|
|
|
59
|
+
const windowLocationRegExp = /window\.location=/;
|
|
60
|
+
const windowOpenRegExp = /window\.open\(/;
|
|
56
61
|
const javaScriptVoidRegExp = /javascript:void(\(|)0(\)|)/;
|
|
57
62
|
|
|
58
63
|
if (rawHref.startsWith('file:')) return true;
|
|
59
|
-
if (
|
|
64
|
+
if (windowLocationRegExp.test(onclick)) return true;
|
|
65
|
+
if (windowOpenRegExp.test(onclick)) return true;
|
|
66
|
+
|
|
67
|
+
const hasClickHandler = listeners.some(({type}) => type === 'click');
|
|
68
|
+
if (hasClickHandler || name.length > 0) return;
|
|
60
69
|
|
|
61
70
|
if (rawHref === '') return true;
|
|
62
71
|
if (javaScriptVoidRegExp.test(rawHref)) return true;
|
|
63
|
-
|
|
64
|
-
// checking if rawHref is a valid
|
|
65
|
-
try {
|
|
66
|
-
new URL(rawHref, url.finalUrl);
|
|
67
|
-
} catch (e) {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
72
|
});
|
|
71
73
|
|
|
72
74
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
@@ -29,7 +29,8 @@ function computeGeneratedFileSizes(map, content) {
|
|
|
29
29
|
const source = mapping.sourceURL;
|
|
30
30
|
const lineNum = mapping.lineNumber;
|
|
31
31
|
const colNum = mapping.columnNumber;
|
|
32
|
-
|
|
32
|
+
// @ts-expect-error: `lastColumnNumber` is not on types yet. This will eventually be added to CDT.
|
|
33
|
+
const lastColNum = /** @type {number=} */ (mapping.lastColumnNumber);
|
|
33
34
|
|
|
34
35
|
// Webpack sometimes emits null mappings.
|
|
35
36
|
// https://github.com/mozilla/source-map/pull/303
|
|
@@ -127,9 +127,9 @@ class UnusedJavascriptSummary {
|
|
|
127
127
|
let offset = lineOffsets[mapping.lineNumber];
|
|
128
128
|
|
|
129
129
|
offset += mapping.columnNumber;
|
|
130
|
-
const lastColumnOfMapping =
|
|
131
|
-
|
|
132
|
-
lineLengths[mapping.lineNumber];
|
|
130
|
+
const lastColumnOfMapping =
|
|
131
|
+
// @ts-expect-error: We will upstream lastColumnNumber to CDT eventually.
|
|
132
|
+
(mapping.lastColumnNumber - 1) || lineLengths[mapping.lineNumber];
|
|
133
133
|
for (let i = mapping.columnNumber; i <= lastColumnOfMapping; i++) {
|
|
134
134
|
if (wasteData.every(data => data.unusedByIndex[offset] === 1)) {
|
|
135
135
|
const key = mapping.sourceURL || '(unmapped)';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
const defaultConfigPath = './default-config.js';
|
|
9
9
|
const defaultConfig = require('./default-config.js');
|
|
10
10
|
const constants = require('./constants.js');
|
|
11
|
-
const
|
|
11
|
+
const i18n = require('./../lib/i18n/i18n.js');
|
|
12
12
|
const validation = require('./../fraggle-rock/config/validation.js');
|
|
13
13
|
|
|
14
14
|
const log = require('lighthouse-logger');
|
|
@@ -248,7 +248,7 @@ class Config {
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
// Printed config is more useful with localized strings.
|
|
251
|
-
|
|
251
|
+
i18n.replaceIcuMessages(jsonConfig, jsonConfig.settings.locale);
|
|
252
252
|
|
|
253
253
|
return JSON.stringify(jsonConfig, null, 2);
|
|
254
254
|
}
|
|
@@ -421,7 +421,6 @@ const defaultConfig = {
|
|
|
421
421
|
categories: {
|
|
422
422
|
'performance': {
|
|
423
423
|
title: str_(UIStrings.performanceCategoryTitle),
|
|
424
|
-
supportedModes: ['navigation', 'timespan', 'snapshot'],
|
|
425
424
|
auditRefs: [
|
|
426
425
|
{id: 'first-contentful-paint', weight: 10, group: 'metrics', acronym: 'FCP', relevantAudits: m2a.fcpRelevantAudits},
|
|
427
426
|
{id: 'speed-index', weight: 10, group: 'metrics', acronym: 'SI'},
|
|
@@ -491,7 +490,6 @@ const defaultConfig = {
|
|
|
491
490
|
title: str_(UIStrings.a11yCategoryTitle),
|
|
492
491
|
description: str_(UIStrings.a11yCategoryDescription),
|
|
493
492
|
manualDescription: str_(UIStrings.a11yCategoryManualDescription),
|
|
494
|
-
supportedModes: ['navigation', 'snapshot'],
|
|
495
493
|
// Audit weights are meant to match the aXe scoring system of
|
|
496
494
|
// minor, moderate, serious, and critical.
|
|
497
495
|
// See the audits listed at dequeuniversity.com/rules/axe/4.1.
|
|
@@ -556,7 +554,6 @@ const defaultConfig = {
|
|
|
556
554
|
},
|
|
557
555
|
'best-practices': {
|
|
558
556
|
title: str_(UIStrings.bestPracticesCategoryTitle),
|
|
559
|
-
supportedModes: ['navigation', 'timespan', 'snapshot'],
|
|
560
557
|
auditRefs: [
|
|
561
558
|
// Trust & Safety
|
|
562
559
|
{id: 'is-on-https', weight: 1, group: 'best-practices-trust-safety'},
|
|
@@ -587,7 +584,6 @@ const defaultConfig = {
|
|
|
587
584
|
title: str_(UIStrings.seoCategoryTitle),
|
|
588
585
|
description: str_(UIStrings.seoCategoryDescription),
|
|
589
586
|
manualDescription: str_(UIStrings.seoCategoryManualDescription),
|
|
590
|
-
supportedModes: ['navigation', 'snapshot'],
|
|
591
587
|
auditRefs: [
|
|
592
588
|
{id: 'viewport', weight: 1, group: 'seo-mobile'},
|
|
593
589
|
{id: 'document-title', weight: 1, group: 'seo-content'},
|
|
@@ -611,7 +607,6 @@ const defaultConfig = {
|
|
|
611
607
|
title: str_(UIStrings.pwaCategoryTitle),
|
|
612
608
|
description: str_(UIStrings.pwaCategoryDescription),
|
|
613
609
|
manualDescription: str_(UIStrings.pwaCategoryManualDescription),
|
|
614
|
-
supportedModes: ['navigation'],
|
|
615
610
|
auditRefs: [
|
|
616
611
|
// Installable
|
|
617
612
|
{id: 'installable-manifest', weight: 2, group: 'pwa-installable'},
|
|
@@ -8,19 +8,9 @@
|
|
|
8
8
|
const {snapshot} = require('./gather/snapshot-runner.js');
|
|
9
9
|
const {startTimespan} = require('./gather/timespan-runner.js');
|
|
10
10
|
const {navigation} = require('./gather/navigation-runner.js');
|
|
11
|
-
const UserFlow = require('./user-flow.js');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @param {import('puppeteer').Page} page
|
|
15
|
-
* @param {UserFlow.UserFlowOptions} [options]
|
|
16
|
-
*/
|
|
17
|
-
async function startFlow(page, options) {
|
|
18
|
-
return new UserFlow(page, options);
|
|
19
|
-
}
|
|
20
11
|
|
|
21
12
|
module.exports = {
|
|
22
13
|
snapshot,
|
|
23
14
|
startTimespan,
|
|
24
15
|
navigation,
|
|
25
|
-
startFlow,
|
|
26
16
|
};
|