Skip to content

Commit a5e7b7e

Browse files
fix: remove open report getter
2 parents 997054b + e773a42 commit a5e7b7e

File tree

12 files changed

+145
-70
lines changed

12 files changed

+145
-70
lines changed

packages/cli/src/lib/commands/collect/command-impl.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ import { run } from '../../core/processing/behaviors';
55
import { collectRcJson } from '../init/processes/collect-rc-json';
66
import { startServerIfNeededAndExecute } from './utils/serve-command';
77
import { collectReports } from './processes/collect-reports';
8-
import { CollectOptions } from './options';
8+
import { CollectCommandOptions } from './options';
99

10-
export async function runCollectCommand(argv: CollectOptions): Promise<void> {
10+
export async function runCollectCommand(argv: CollectCommandOptions): Promise<void> {
1111
const cfg = getCollectCommandOptionsFromArgv(argv);
1212
logVerbose('Collect options: ', cfg);
1313
await run([
1414
collectRcJson,
1515
(cfg: RcJson) =>
16-
startServerIfNeededAndExecute(() => collectReports(cfg)
17-
.then()
18-
, cfg.collect)
16+
startServerIfNeededAndExecute(
17+
() => collectReports(cfg, argv),
18+
cfg.collect
19+
)
1920
])(cfg);
2021
}

packages/cli/src/lib/commands/collect/options/dryRun.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,3 @@ export const dryRun = {
88
default: getEnvPreset().dryRun as boolean
99
} satisfies Options;
1010

11-
export function get(): boolean {
12-
const { dryRun } = argv as any as { dryRun: boolean };
13-
return dryRun;
14-
}

packages/cli/src/lib/commands/collect/options/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { awaitServeStdout } from './awaitServeStdout';
1010
import { dryRun } from './dryRun';
1111
import { assertOptions } from '../../assert/options';
1212
import { config } from './config';
13+
import { GlobalCliOptions } from '../../../global/options';
1314

1415
export const persistOptions = {
1516
outPath,
@@ -29,3 +30,4 @@ export const collectOptions = {
2930
...assertOptions
3031
} satisfies Record<string, Options>;
3132
export type CollectOptions = InferredOptionTypes<typeof collectOptions>;
33+
export type CollectCommandOptions = CollectOptions & GlobalCliOptions;
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
import { argv, Options } from 'yargs';
1+
import { Options } from 'yargs';
22
import { getEnvPreset } from '../../../pre-set';
33

44
export const openReport = {
55
alias: 'e',
66
type: 'boolean',
77
description: 'Opens browser automatically after the user-flow is collected. (true by default)',
8-
default: getEnvPreset().openReport as boolean,
8+
default: getEnvPreset().openReport,
99
requiresArg: true
1010
} satisfies Options;
11-
12-
export function get(): boolean {
13-
const { openReport } = argv as any as { openReport: boolean };
14-
return openReport;
15-
}

packages/cli/src/lib/commands/collect/processes/collect-reports.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
1-
import { UserFlowProvider } from '../utils/user-flow/types';
21
import { concat } from '../../../core/processing/behaviors';
3-
import { get as dryRun } from '../../../commands/collect/options/dryRun';
42
import { collectFlow, loadFlow } from '../utils/user-flow';
53
import { persistFlow } from '../utils/persist/persist-flow';
6-
import { openFlowReport } from '../utils/persist/open-report';
4+
import { handleOpenFlowReports } from '../utils/persist/open-report';
75
import { RcJson } from '../../../types';
6+
import { CollectCommandOptions } from '../options';
87

9-
export async function collectReports(cfg: RcJson): Promise<RcJson> {
8+
export async function collectReports(cfg: RcJson, argv: CollectCommandOptions): Promise<RcJson> {
109

1110
const { collect, persist, assert } = cfg;
1211

13-
let userFlows = [] as ({ exports: UserFlowProvider, path: string })[];
14-
// Load and run user-flows in sequential
15-
userFlows = loadFlow(collect);
12+
const userFlows = loadFlow(collect);
1613
await concat(userFlows.map(({ exports: provider, path }) =>
1714
(_: any) => {
18-
return collectFlow({
19-
...collect, ...persist, ...assert, dryRun: dryRun()
20-
}, { ...provider, path })
15+
return collectFlow({ ...collect, ...persist, ...assert }, { ...provider, path }, argv)
2116
.then((flow) => persistFlow(flow, { ...persist, ...collect }))
22-
.then(openFlowReport)
17+
.then(handleOpenFlowReports(argv))
2318
.then(_ => cfg);
2419
})
2520
)(cfg);
Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
1-
import { get as dryRun } from '../../../../commands/collect/options/dryRun';
2-
import { get as openReport } from '../../options/openReport';
3-
import { get as interactive } from '../../../../global/options/interactive';
1+
import * as openReport from 'open';
42
import { logVerbose } from '../../../../core/loggin';
5-
import * as openFileInBrowser from 'open';
3+
import { CollectCommandOptions } from '../../options';
64

7-
export async function openFlowReport(fileNames: string[]): Promise<void> {
8-
// open report if requested and not in executed in CI
9-
if (!dryRun() && openReport() && interactive()) {
10-
11-
const htmlReport = fileNames.find(i => i.includes('.html'));
12-
if (htmlReport) {
13-
logVerbose('open HTML report in browser');
14-
await openFileInBrowser(htmlReport, { wait: false });
15-
return Promise.resolve(void 0);
16-
}
5+
export async function openFlowReports(fileNames: string[]): Promise<void> {
6+
const htmlReport = fileNames.find(i => i.includes('.html'));
7+
if (htmlReport) {
8+
logVerbose('open HTML report in browser');
9+
await openReport(htmlReport, { wait: false });
10+
return Promise.resolve(void 0);
11+
}
1712

18-
const mdReport = fileNames.find(i => i.includes('.md'));
19-
if (mdReport) {
20-
logVerbose('open Markdown report in browser');
21-
await openFileInBrowser(mdReport, { wait: false });
22-
return Promise.resolve(void 0);
23-
}
13+
const mdReport = fileNames.find(i => i.includes('.md'));
14+
if (mdReport) {
15+
logVerbose('open Markdown report in browser');
16+
await openReport(mdReport, { wait: false });
17+
return Promise.resolve(void 0);
18+
}
2419

25-
const jsonReport = fileNames.find(i => i.includes('.json'));
26-
if (jsonReport) {
27-
logVerbose('open JSON report in browser');
28-
// @TODO if JSON is given open the file in https://googlechrome.github.io/lighthouse/viewer/
29-
await openFileInBrowser(jsonReport, { wait: false });
30-
}
20+
const jsonReport = fileNames.find(i => i.includes('.json'));
21+
if (jsonReport) {
22+
logVerbose('open JSON report in browser');
23+
// @TODO if JSON is given open the file in https://googlechrome.github.io/lighthouse/viewer/
24+
await openReport(jsonReport, { wait: false });
3125
}
3226
return Promise.resolve(void 0);
3327
}
28+
29+
export function handleOpenFlowReports({ dryRun, openReport, interactive}: CollectCommandOptions) {
30+
if (dryRun || !openReport || !interactive) {
31+
return;
32+
}
33+
return openFlowReports;
34+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import * as openReport from 'open';
2+
import { handleOpenFlowReports, openFlowReports } from './open-report';
3+
import { logVerbose } from '../../../../core/loggin';
4+
import { CollectCommandOptions } from '../../options';
5+
6+
jest.mock('open');
7+
jest.mock('../../../../core/loggin');
8+
9+
describe('handleOpenFlowReport', () => {
10+
11+
beforeEach(() => {
12+
jest.clearAllMocks();
13+
})
14+
15+
it('should return the openFlowReport function if openReport, interactive and not dryRun', async () => {
16+
const openReportsProcess = handleOpenFlowReports({
17+
openReport: true,
18+
interactive: true,
19+
dryRun: false,
20+
} as CollectCommandOptions);
21+
expect(openReportsProcess).toEqual(expect.any(Function));
22+
});
23+
24+
it('should return undefined if openReport is false', () => {
25+
const openReportsProcess = handleOpenFlowReports({
26+
openReport: false,
27+
interactive: true,
28+
dryRun: false,
29+
} as CollectCommandOptions);
30+
expect(openReportsProcess).toBeUndefined();
31+
});
32+
33+
it('should return undefined if dryRun is true', () => {
34+
const openReportsProcess = handleOpenFlowReports({
35+
openReport: true,
36+
interactive: true,
37+
dryRun: true,
38+
} as CollectCommandOptions);
39+
expect(openReportsProcess).toBeUndefined();
40+
});
41+
42+
it('should return undefined if interactive is false', () => {
43+
const openReportsProcess = handleOpenFlowReports({
44+
openReport: true,
45+
interactive: false,
46+
dryRun: false,
47+
} as CollectCommandOptions);
48+
expect(openReportsProcess).toBeUndefined();
49+
});
50+
});
51+
52+
describe('openReports', () => {
53+
54+
beforeEach(() => {
55+
jest.clearAllMocks();
56+
});
57+
58+
it('should not open the report if no file name is passed', async () => {
59+
await openFlowReports([]);
60+
expect(openReport).not.toHaveBeenCalled();
61+
});
62+
63+
it.each(['html', 'json', 'md'])('should open the %s report', async (format) => {
64+
await openFlowReports([`example.${format}`]);
65+
expect(openReport).toHaveBeenCalled();
66+
});
67+
68+
it('should not logVerbose if no file name is passed', async () => {
69+
await openFlowReports([]);
70+
expect(logVerbose).not.toHaveBeenCalled();
71+
});
72+
73+
it('should only open 1 time report if multiple report formats are passed', async () => {
74+
await openFlowReports(['example.html', 'example.json', 'example.md']);
75+
expect(openReport).toHaveBeenCalledTimes(1);
76+
});
77+
});

packages/cli/src/lib/commands/collect/utils/user-flow/collect-flow.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ import { Browser, LaunchOptions, Page } from 'puppeteer';
55
import { normalize } from 'path';
66
// @ts-ignore
77
import { startFlow, UserFlow } from 'lighthouse/lighthouse-core/fraggle-rock/api';
8-
import { get as dryRun } from '../../../../commands/collect/options/dryRun';
98
import { UserFlowMock } from './user-flow.mock';
10-
import { detectCliMode } from '../../../../global/cli-mode/cli-mode';
9+
import { detectCliMode } from '../../../../global/cli-mode';
1110
import { CollectArgvOptions } from '../../options/types';
1211
import { getLhConfigFromArgv, mergeLhConfig } from '../config';
1312
import { PersistArgvOptions } from '../../options/types';
1413
import { AssertRcOptions } from '../../../assert/options';
14+
import { CollectCommandOptions } from '../../options';
1515

1616
export async function collectFlow(
1717
cliOption: CollectArgvOptions & PersistArgvOptions & AssertRcOptions,
18-
userFlowProvider: UserFlowProvider & { path: string }
18+
userFlowProvider: UserFlowProvider & { path: string },
19+
argv: CollectCommandOptions
1920
) {
2021
let {
2122
path,
@@ -37,7 +38,7 @@ export async function collectFlow(
3738
logVerbose(`User-flow path: ${normalize(path)}`);
3839
let start = Date.now();
3940

40-
const flow: UserFlow = !dryRun() ? await startFlow(page, flowOptions) : new UserFlowMock(page, flowOptions);
41+
const flow: UserFlow = !argv.dryRun ? await startFlow(page, flowOptions) : new UserFlowMock(page, flowOptions);
4142

4243
// run custom interactions
4344
await interactions({ flow, page, browser, collectOptions: cliOption });

packages/cli/src/lib/commands/init/utils.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
import { CollectRcOptions, PersistRcOptions } from '../collect/options/types';
1+
import { CollectRcOptions, PersistRcOptions, ReportFormat } from '../collect/options/types';
22
import { InitOptions } from './options';
33
import { AssertRcOptions } from '../assert/options';
4+
import { REPORT_FORMAT_VALUES } from '../collect/constants';
5+
6+
const isValidFormat = (value: any): value is ReportFormat => REPORT_FORMAT_VALUES.includes(value);
7+
8+
function sanitizedFormats(formats: string[]) {
9+
const validatedFormats: ReportFormat[] = formats.filter(isValidFormat);
10+
if (validatedFormats.length !== formats.length) {
11+
throw new Error(`${formats} contains invalid format options`);
12+
}
13+
return validatedFormats;
14+
}
415

516
export function getInitCommandOptionsFromArgv(argv: InitOptions) {
617
let {
@@ -18,7 +29,7 @@ export function getInitCommandOptionsFromArgv(argv: InitOptions) {
1829

1930
let persist = {} as PersistRcOptions;
2031
outPath && (persist.outPath = outPath);
21-
format && (persist.format = format);
32+
format && (persist.format = sanitizedFormats(format));
2233

2334
let assert = {} as AssertRcOptions;
2435
budgetPath && (assert.budgetPath = budgetPath);

packages/cli/src/lib/global/options/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
import { InferredOptionTypes, Options } from 'yargs';
2+
13
import { verbose, get as getVerbose } from './verbose';
24
import { rcPath, get as getRcPath } from '../rc-json/options/rc';
35
import { interactive, get as getInteractive } from './interactive';
4-
import { Options } from 'yargs';
56

67
export const GLOBAL_OPTIONS_YARGS_CFG = {
78
verbose,
89
rcPath,
910
interactive
1011
} satisfies Record<string, Options>;
12+
export type GlobalCliOptions = InferredOptionTypes<typeof GLOBAL_OPTIONS_YARGS_CFG>;
1113

1214
export const globalOptions = {
1315
getVerbose,

0 commit comments

Comments
 (0)