Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin-lighthouse): add audit details to lighthouse plugin #684

Merged
merged 104 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 90 commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
f9173b0
refactor(model): add table to audit details
BioPhoton Apr 16, 2024
6ff30b3
refactor: adjust typing
BioPhoton Apr 16, 2024
e53c84a
test(utils): adjust snapshots
BioPhoton Apr 17, 2024
b15ca5e
test(utils): fix tests
BioPhoton Apr 17, 2024
1ee2734
refactor(utils): fix lint
BioPhoton Apr 17, 2024
edebbc6
Update packages/core/src/lib/normalize.ts
BioPhoton Apr 17, 2024
e95a295
Update packages/utils/src/lib/reports/md/table.ts
BioPhoton Apr 17, 2024
056d4f9
feat(utils): don't send table data to portal
BioPhoton Apr 17, 2024
b23d051
refactor(utils): adjust data transform
BioPhoton Apr 17, 2024
e8fc9bd
feat(plugin-lighthouse): add detail support for table, opportunity an…
BioPhoton Apr 17, 2024
fa2f6d2
refactor(utils): format code
BioPhoton Apr 17, 2024
080e3ac
Update packages/models/src/lib/audit-output.ts
BioPhoton Apr 17, 2024
daee456
Update packages/utils/src/lib/reports/generate-md-report.ts
BioPhoton Apr 17, 2024
5fdecdd
Update packages/utils/src/lib/reports/generate-md-report.unit.test.ts
BioPhoton Apr 18, 2024
420622c
Update packages/utils/src/lib/reports/generate-md-report.unit.test.ts
BioPhoton Apr 18, 2024
bd403f2
Update packages/utils/src/lib/reports/generate-md-report.unit.test.ts
BioPhoton Apr 18, 2024
6e00ec8
Update packages/utils/src/lib/reports/generate-md-report.unit.test.ts
BioPhoton Apr 18, 2024
9b34999
Update packages/utils/src/lib/reports/generate-md-report.unit.test.ts
BioPhoton Apr 18, 2024
ad510f8
Update packages/utils/src/lib/reports/generate-md-report.ts
BioPhoton Apr 19, 2024
6dc82df
Update packages/utils/src/lib/reports/generate-md-report.ts
BioPhoton Apr 19, 2024
128d25e
Update packages/models/src/lib/table.ts
BioPhoton Apr 19, 2024
45643db
test(utils): add report tests
BioPhoton Apr 18, 2024
b7c1022
test(utils): adopt line breaks
BioPhoton Apr 19, 2024
028ea6d
refactor(utils): normalize report logic for NEW_LINE in reports
BioPhoton Apr 19, 2024
cb27d5f
test(models): test audit output details for table
BioPhoton Apr 19, 2024
f860ab1
fix(utils): show details only if issues are given
BioPhoton Apr 19, 2024
d548ccb
refactor(utils): format
BioPhoton Apr 19, 2024
ad8a43c
refactor(utils): adjust typing
BioPhoton Apr 19, 2024
d5a3d26
test(utils): adjust snapshots
BioPhoton Apr 19, 2024
b860fb0
test(utils): adjust test data
BioPhoton Apr 20, 2024
57b63b7
refactor(utils): adjust issues handling
BioPhoton Apr 20, 2024
9a71fb3
feat(utils): add section to md formats
BioPhoton Apr 20, 2024
33b5eae
feat(utils): adjust section in md formats
BioPhoton Apr 20, 2024
13fec98
feat(utils): adjust section in md formats
BioPhoton Apr 20, 2024
a01ba05
feat(utils): adjust section in md diff
BioPhoton Apr 20, 2024
026317d
test: update snapshots
BioPhoton Apr 20, 2024
a21267e
refactor: format
BioPhoton Apr 20, 2024
7d14597
Update packages/models/src/lib/table.ts
BioPhoton Apr 20, 2024
ff28d9b
refactor: format
BioPhoton Apr 20, 2024
4a7c685
refactor: format
BioPhoton Apr 20, 2024
ece36dc
refactor: snapshots
BioPhoton Apr 20, 2024
9b24741
refactor: format
BioPhoton Apr 20, 2024
2ea1786
refactor: snapshots update
BioPhoton Apr 20, 2024
4c03200
Merge branch 'main' into add-detail-type-table-to-report
BioPhoton Apr 20, 2024
c957ed0
refactor: snapshots update
BioPhoton Apr 20, 2024
d7c3f9a
refactor: test normalize.ts
BioPhoton Apr 20, 2024
2052dc1
refactor: fix lint
BioPhoton Apr 21, 2024
7d4699c
refactor: fix lint
BioPhoton Apr 21, 2024
e38cb7e
refactor: fix lint
BioPhoton Apr 21, 2024
549062e
refactor: fix lint
BioPhoton Apr 21, 2024
88b5f2a
refactor: tests
BioPhoton Apr 21, 2024
3b13b25
update snapshots
BioPhoton Apr 21, 2024
694c756
update snapshots
BioPhoton Apr 21, 2024
941784b
Merge branch 'add-detail-type-table-to-report' into add-audit-details…
BioPhoton Apr 21, 2024
68a04e8
wip
BioPhoton Apr 22, 2024
09f6605
wip
BioPhoton Apr 22, 2024
95d80d9
refactor(utils): update detail block with new line
BioPhoton Apr 22, 2024
9851c72
Update packages/models/src/index.ts
BioPhoton Apr 22, 2024
e7818cf
refactor(utils): add comments to detail
BioPhoton Apr 22, 2024
b5c8f36
refactor(utils): export table props, remove target deps
BioPhoton Apr 22, 2024
e83b630
Update packages/utils/src/lib/reports/md/table.ts
BioPhoton Apr 22, 2024
a92759c
refactor(utils): update tab
BioPhoton Apr 22, 2024
eeb3988
refactor(utils): update naming
BioPhoton Apr 22, 2024
977a9c5
refactor(core): update comments
BioPhoton Apr 22, 2024
b54765a
refactor(core): adjust tests and cloning logic
BioPhoton Apr 23, 2024
13779e6
refactor(utils): adjust line break in report
BioPhoton Apr 23, 2024
963975c
refactor(utils): fix lint
BioPhoton Apr 23, 2024
0e2238a
refactor(ci): set parallel of e2e temporally to 1
BioPhoton Apr 23, 2024
a0f61a0
Merge branch 'add-detail-type-table-to-report' into add-audit-details…
BioPhoton Apr 23, 2024
b1bd594
Merge branch 'main' into add-audit-details-to-lighthouse-plugin
BioPhoton May 2, 2024
37505b4
Merge branch 'main' into add-audit-details-to-lighthouse-plugin
BioPhoton May 21, 2024
a976408
wip
BioPhoton May 21, 2024
4edbdae
wip 2
BioPhoton May 21, 2024
6c5760a
lint fix
BioPhoton May 21, 2024
670c6ea
remove opportunities
BioPhoton May 28, 2024
2eadfa0
refactor(plugin-lighthouse): fix unit tests
BioPhoton Jun 3, 2024
b5e3794
refactor(plugin-lighthouse): fix tests
BioPhoton Jun 3, 2024
c359110
refactor(plugin-lighthouse): fix e2e tests
BioPhoton Jun 3, 2024
cf344a8
Delete md-to-pdf.config.json
BioPhoton Jun 3, 2024
9d0d23b
Update .github/workflows/ci.yml
BioPhoton Jun 3, 2024
6026375
refactor(plugin-lighthouse): fix structure
BioPhoton Jun 5, 2024
34e40c3
refactor(plugin-lighthouse): add tests
BioPhoton Jun 10, 2024
4b61712
Merge branch 'main' into add-audit-details-to-lighthouse-plugin
BioPhoton Jun 10, 2024
6041c69
refactor(plugin-lighthouse): fix lint
BioPhoton Jun 10, 2024
ccb5bcb
refactor(plugin-lighthouse): fix build
BioPhoton Jun 10, 2024
322a32a
refactor(plugin-lighthouse): format
BioPhoton Jun 10, 2024
e6906a7
Merge branch 'main' into add-audit-details-to-lighthouse-plugin
BioPhoton Jun 12, 2024
8918456
fix(models): add undefined to table row value to make lighthouse pass
BioPhoton Jun 12, 2024
9071a0c
fix(models): add default null to table row value to make lighthouse pass
BioPhoton Jun 12, 2024
14a7a19
test(models): adjust table tests
BioPhoton Jun 12, 2024
e62c756
Update packages/plugin-lighthouse/src/lib/runner/details/details.ts
BioPhoton Jun 13, 2024
52aaced
Update packages/models/src/lib/implementation/schemas.ts
BioPhoton Jun 13, 2024
2ec6587
Update packages/plugin-lighthouse/src/lib/runner/utils.unit.test.ts
BioPhoton Jun 13, 2024
a5c51ca
Update packages/plugin-lighthouse/src/lib/runner/details/item-value.ts
BioPhoton Jun 13, 2024
93f0ad1
Update packages/plugin-lighthouse/src/lib/runner/utils.ts
BioPhoton Jun 13, 2024
5d38b56
fix lint
BioPhoton Jun 13, 2024
5b411a8
add tests
BioPhoton Jun 14, 2024
f55ef09
refactor(utils): adjust logic
BioPhoton Jun 15, 2024
3985b1d
refactor(utils): adjust logic
BioPhoton Jun 15, 2024
18c8b85
refactor(utils): adjust logic
BioPhoton Jun 15, 2024
3d9aab9
Merge branch 'main' into add-audit-details-to-lighthouse-plugin
BioPhoton Jun 20, 2024
05ddd88
merge master
BioPhoton Jun 20, 2024
39ef8d6
fix merge
BioPhoton Jun 20, 2024
ef592b9
Merge branch 'main' into add-audit-details-to-lighthouse-plugin
BioPhoton Jun 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,7 @@ exports[`CLI collect > should run Lighthouse plugin that runs lighthouse CLI and
},
],
"icon": "lighthouse",
"packageName": "@code-pushup/lighthouse-plugin",
"slug": "lighthouse",
"title": "Lighthouse",
},
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/lib/implementation/report-to-gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ export function tableToGQL(table: Table): PortalTable {
}),
rows: table.rows.map((row): PortalTableCell[] =>
Array.isArray(row)
? row.map(content => ({ content: content.toString() }))
? row.map(content => ({ content: content?.toString() ?? '' }))
: Object.entries(row).map(([key, content]) => ({
key,
content: content.toString(),
content: content?.toString() ?? '',
})),
),
};
Expand Down
2 changes: 1 addition & 1 deletion packages/models/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export {
PrimitiveValue,
primitiveValueSchema,
tableCellValueSchema,
} from './lib/implementation/schemas';

export { Audit, auditSchema } from './lib/audit';
Expand Down
6 changes: 4 additions & 2 deletions packages/models/src/lib/implementation/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
} from './limits';
import { filenameRegex, slugRegex } from './utils';

export const primitiveValueSchema = z.union([z.string(), z.number()]);
export type PrimitiveValue = z.infer<typeof primitiveValueSchema>;
export const tableCellValueSchema = z
.union([z.string(), z.number(), z.boolean(), z.null()])
.default(null);
matejchalk marked this conversation as resolved.
Show resolved Hide resolved
export type PrimitiveValue = z.infer<typeof tableCellValueSchema>;
BioPhoton marked this conversation as resolved.
Show resolved Hide resolved

/**
* Schema for execution meta date
Expand Down
6 changes: 3 additions & 3 deletions packages/models/src/lib/implementation/schemas.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { describe, expect, it } from 'vitest';
import { PrimitiveValue, primitiveValueSchema, weightSchema } from './schemas';
import { PrimitiveValue, tableCellValueSchema, weightSchema } from './schemas';

describe('primitiveValueSchema', () => {
it('should accept a valid union', () => {
const value: PrimitiveValue = 'test';
expect(() => primitiveValueSchema.parse(value)).not.toThrow();
expect(() => tableCellValueSchema.parse(value)).not.toThrow();
});

it('should throw for a invalid union', () => {
const value = new Date();
expect(() => primitiveValueSchema.parse(value)).toThrow('invalid_union');
expect(() => tableCellValueSchema.parse(value)).toThrow('invalid_union');
});
});

Expand Down
6 changes: 3 additions & 3 deletions packages/models/src/lib/table.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from 'zod';
import { primitiveValueSchema } from './implementation/schemas';
import { tableCellValueSchema } from './implementation/schemas';

export const tableAlignmentSchema = z.enum(['left', 'center', 'right'], {
description: 'Cell alignment',
Expand All @@ -16,12 +16,12 @@ export const tableColumnObjectSchema = z.object({
});
export type TableColumnObject = z.infer<typeof tableColumnObjectSchema>;

export const tableRowObjectSchema = z.record(primitiveValueSchema, {
export const tableRowObjectSchema = z.record(tableCellValueSchema, {
description: 'Object row',
});
export type TableRowObject = z.infer<typeof tableRowObjectSchema>;

export const tableRowPrimitiveSchema = z.array(primitiveValueSchema, {
export const tableRowPrimitiveSchema = z.array(tableCellValueSchema, {
description: 'Primitive row',
});
export type TableRowPrimitive = z.infer<typeof tableRowPrimitiveSchema>;
Expand Down
9 changes: 8 additions & 1 deletion packages/models/src/lib/table.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,15 @@ describe('tableRowObjectSchema', () => {
expect(() => tableRowObjectSchema.parse(row)).not.toThrow();
});

it('should throw for a invalid object', () => {
it('should default undefined object values to null', () => {
const row = { prop: undefined };
expect(tableRowObjectSchema.parse(row)).toStrictEqual({
prop: null,
});
});

it('should throw for a invalid object', () => {
const row = { prop: [] };
expect(() => tableRowObjectSchema.parse(row)).toThrow('invalid_union');
});
});
Expand Down
3 changes: 3 additions & 0 deletions packages/plugin-lighthouse/src/lib/lighthouse-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { PluginConfig } from '@code-pushup/models';
import { name, version } from '../../package.json';
import { LIGHTHOUSE_PLUGIN_SLUG } from './constants';
import { normalizeFlags } from './normalize-flags';
import {
Expand Down Expand Up @@ -28,6 +29,8 @@ export function lighthousePlugin(

return {
slug: LIGHTHOUSE_PLUGIN_SLUG,
packageName: name,
version,
title: 'Lighthouse',
icon: 'lighthouse',
audits,
Expand Down
83 changes: 83 additions & 0 deletions packages/plugin-lighthouse/src/lib/runner/details/details.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import chalk from 'chalk';

Check failure on line 1 in packages/plugin-lighthouse/src/lib/runner/details/details.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<↗> Code coverage | Branch coverage

1st branch is not taken in any test case.
import type { FormattedIcu } from 'lighthouse';
import type Details from 'lighthouse/types/lhr/audit-details';
import { Result } from 'lighthouse/types/lhr/audit-result';
import { AuditDetails, Table, tableSchema } from '@code-pushup/models';
import { ui } from '@code-pushup/utils';
import { PLUGIN_SLUG } from '../constants';
import { parseTableToAuditDetailsTable } from './table.type';

export function toAuditDetails<T extends FormattedIcu<Details>>(
details: T | undefined,
): AuditDetails | undefined {
if (details == null) {
return undefined;
}

const { type } = details;

if (type !== 'table') {
return undefined;
}

const rawTable: Table | undefined = parseTableToAuditDetailsTable(
details as Details.Table,
);
BioPhoton marked this conversation as resolved.
Show resolved Hide resolved

if (rawTable != null) {
const result = tableSchema().safeParse(rawTable);
if (result.success) {
return {
table: result.data,
};
}

Check failure on line 33 in packages/plugin-lighthouse/src/lib/runner/details/details.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<↗> Code coverage | Branch coverage

1st branch is not taken in any test case.

throw new Error(
`Parsing details ${chalk.bold(
type,
)} failed: \nRaw data:\n ${JSON.stringify(
rawTable,
null,
2,
)}\n${result.error.toString()}`,
);
}

Check warning on line 44 in packages/plugin-lighthouse/src/lib/runner/details/details.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<↗> Code coverage | Line coverage

Lines 34-44 are not covered in any test case.

return undefined;
}

// @TODO implement all details
export const unsupportedDetailTypes = new Set([
'opportunity',
'debugdata',
'treemap-data',
'screenshot',
'filmstrip',
'criticalrequestchain',
]);

export function logUnsupportedDetails(
BioPhoton marked this conversation as resolved.
Show resolved Hide resolved
lhrAudits: Result[],
{ displayCount = 3 }: { displayCount?: number } = {},
) {
const slugsWithDetailParsingErrors = [
...new Set(
lhrAudits
.filter(({ details }) =>
unsupportedDetailTypes.has(details?.type as string),
)
.map(({ details }) => details?.type),
),
];
if (slugsWithDetailParsingErrors.length > 0) {
const postFix = (count: number) =>
count > displayCount ? ` and ${count - displayCount} more.` : '';
ui().logger.debug(
`${chalk.yellow('⚠')} Plugin ${chalk.bold(
PLUGIN_SLUG,
)} skipped parsing of unsupported audit details: ${chalk.bold(
slugsWithDetailParsingErrors.slice(0, displayCount).join(', '),
)}${postFix(slugsWithDetailParsingErrors.length)}`,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import chalk from 'chalk';
import type { FormattedIcu } from 'lighthouse';
import type Details from 'lighthouse/types/lhr/audit-details';
import type { Result } from 'lighthouse/types/lhr/audit-result';
import { describe, expect, it } from 'vitest';
import { getLogMessages } from '@code-pushup/test-utils';
import { ui } from '@code-pushup/utils';
import { logUnsupportedDetails, toAuditDetails } from './details';

describe('logUnsupportedDetails', () => {
it('should log unsupported entries', () => {
logUnsupportedDetails([
{ details: { type: 'screenshot' } },
] as unknown as Result[]);
expect(getLogMessages(ui().logger)).toHaveLength(1);
expect(getLogMessages(ui().logger).at(0)).toBe(
`[ cyan(debug) ] ${chalk.yellow('⚠')} Plugin ${chalk.bold(
'lighthouse',
)} skipped parsing of unsupported audit details: ${chalk.bold(
'screenshot',
)}`,
);
});

it('should log only 3 details of unsupported entries', () => {
logUnsupportedDetails([
{ details: { type: 'table' } },
{ details: { type: 'filmstrip' } },
{ details: { type: 'screenshot' } },
{ details: { type: 'opportunity' } },
{ details: { type: 'debugdata' } },
{ details: { type: 'treemap-data' } },
{ details: { type: 'criticalrequestchain' } },
] as unknown as Result[]);
expect(getLogMessages(ui().logger)).toHaveLength(1);
expect(getLogMessages(ui().logger).at(0)).toBe(
`[ cyan(debug) ] ${chalk.yellow('⚠')} Plugin ${chalk.bold(
'lighthouse',
)} skipped parsing of unsupported audit details: ${chalk.bold(
'filmstrip, screenshot, opportunity',
)} and 3 more.`,
);
});
});

describe('toAuditDetails', () => {
it('should return undefined for missing details', () => {
const outputs = toAuditDetails(undefined);
expect(outputs).toBeUndefined();
});

it('should return undefined for unsupported type', () => {
const outputs = toAuditDetails({ type: 'debugdata' });
expect(outputs).toBeUndefined();
});

it('should return undefined for supported type with empty table', () => {
const outputs = toAuditDetails({
type: 'table',
items: [],
} as unknown as FormattedIcu<Details>);
expect(outputs).toBeUndefined();
});

it('should render audit details of type table', () => {
const outputs = toAuditDetails({
type: 'table',
headings: [
{
key: 'name',
valueType: 'text',
label: 'Name',
},
{
key: 'duration',
valueType: 'ms',
label: 'Duration',
},
],
items: [
{
name: 'Zone',
duration: 0.634,
},
{
name: 'Zone:ZoneAwarePromise',
duration: 0.783,
},
],
});

expect(outputs).toStrictEqual({
table: {
columns: [
{
key: 'name',
label: 'Name',
align: 'left',
},
{
key: 'duration',
label: 'Duration',
align: 'left',
},
],
rows: [
{
name: 'Zone',
duration: '0.634 ms',
},
{
name: 'Zone:ZoneAwarePromise',
duration: '0.783 ms',
},
],
},
});
});

it('should inform that debugdata detail type is not supported yet', () => {
const outputs = toAuditDetails({
type: 'debugdata',
items: [
{
cumulativeLayoutShiftMainFrame: 0.000_350_978_852_728_593_95,
},
],
});

// @TODO add check that cliui.logger is called. Resolve TODO after PR #487 is merged.

expect(outputs).toBeUndefined();
});

it('should inform that filmstrip detail type is not supported yet', () => {
const outputs = toAuditDetails({
type: 'filmstrip',
scale: 3000,
items: [
{
timing: 375,
timestamp: 106_245_424_545,
data: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwY...',
},
],
});

expect(outputs).toBeUndefined();
});

it('should inform that screenshot detail type is not supported yet', () => {
const outputs = toAuditDetails({
type: 'screenshot',
timing: 541,
timestamp: 106_245_590_644,
data: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//2Q==',
});

expect(outputs).toBeUndefined();
});

it('should inform that treemap-data detail type is not supported yet', () => {
const outputs = toAuditDetails({
type: 'treemap-data',
nodes: [],
});

expect(outputs).toBeUndefined();
});

it('should inform that criticalrequestchain detail type is not supported yet', () => {
const outputs = toAuditDetails({
type: 'criticalrequestchain',
chains: {
EED301D300C9A7B634A444E0C6019FC1: {
request: {
url: 'https://example.com/',
startTime: 106_245.050_727,
endTime: 106_245.559_225,
responseReceivedTime: 106_245.559_001,
transferSize: 849,
},
},
},
longestChain: {
duration: 508.498_000_010_848_05,
length: 1,
transferSize: 849,
},
});

expect(outputs).toBeUndefined();
});
});
Loading
Loading