Skip to content

Commit

Permalink
Merge pull request #232 from push-based/improve-report-details
Browse files Browse the repository at this point in the history
  • Loading branch information
BioPhoton authored Apr 20, 2023
2 parents b70ad52 + ca11245 commit 141cc49
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 44 deletions.
3 changes: 2 additions & 1 deletion packages/cli/src/lib/commands/assert/utils/md-report.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ describe('md-table', () => {
it('should return a Md table if getBudgetTable is passed a baseline report', () => {
const reducedLhr9 = createReducedReport(lhr9budgets);
const mdTable = getBudgetTable(reducedLhr9);
expect(mdTable).toContain('| Resource Type | Requests | Transfer Size |');
expect(mdTable).toContain('| Resource Type | Transfer Size | Over Budget |');
expect(mdTable).toContain('| Resource Type | Requests | Over Budget |');
expect(mdTable).toContain('| Metric | Measurement | Over Budget |');
});
});
137 changes: 98 additions & 39 deletions packages/cli/src/lib/commands/assert/utils/md-report.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { FractionResults, GatherMode, ReducedFlowStep, ReducedReport } from '../../collect/utils/report/types';
import { enrichReducedReportWithBaseline } from '../../collect/utils/report/utils';
import { Alignment, table } from '../../../core/md/table';
import { style } from '../../../core/md/font-style';
import { headline, Hierarchy } from '../../../core/md/headline';
import { NEW_LINE } from '../../../core/md/constants';
import { details } from '../../../core/md/details';
import {FractionResults, GatherMode, ReducedFlowStep, ReducedReport} from '../../collect/utils/report/types';
import {enrichReducedReportWithBaseline} from '../../collect/utils/report/utils';
import {Alignment, table} from '../../../core/md/table';
import {style} from '../../../core/md/font-style';
import {headline, Hierarchy} from '../../../core/md/headline';
import {NEW_LINE} from '../../../core/md/constants';
import {details} from '../../../core/md/details';
import Budget from "lighthouse/types/lhr/budget";
import TimingBudget = Budget.TimingBudget;
import Details from "lighthouse/types/lhr/audit-details";
import Table = Details.Table;

const budgetsSymbol = '🔒'

Expand All @@ -19,7 +23,7 @@ ${stepsTable}${NEW_LINE}
`;

const budgetsTable = getBudgetTable(flowResult);
if(budgetsTable !== '') {
if (budgetsTable !== '') {
md += details(`${budgetsSymbol} Budgets`, budgetsTable) + NEW_LINE;
}

Expand All @@ -42,48 +46,103 @@ ${stepsTable}${NEW_LINE}
* | Time to Interactive | 4745 | - |
*
*/
export function getBudgetTable(reducedReport: ReducedReport, options: {heading: Hierarchy} = {heading: 3}): string {

export function getBudgetTable(reducedReport: ReducedReport, options: { heading: Hierarchy } = {heading: 3}): string {
const performanceBudgets = reducedReport.steps
.filter(({ resultsPerformanceBudget, resultsTimingBudget }) => resultsPerformanceBudget || resultsTimingBudget)
.map(({ name, resultsPerformanceBudget, resultsTimingBudget }) => ({
.filter(({resourceCountsBudget, resourceSizesBudget, timingsBudget}) => resourceCountsBudget || resourceSizesBudget || timingsBudget)
.map(({name, resourceCountsBudget, resourceSizesBudget, timingsBudget}) => ({
name,
resultsPerformanceBudget: resultsPerformanceBudget !== undefined ? [
resultsPerformanceBudget.headings
.map((h) => h.text as string),
...resultsPerformanceBudget.items.map(
({label, transferSize, requestCount, sizeOverBudget, countOverBudget}) =>
[
label,
requestCount,
formatBytes(transferSize as number),
sizeOverBudget ? formatBytes(sizeOverBudget as number) : '-',
countOverBudget || '-'
] as (string|number)[]) || []
] : [],
resultsTimingBudget: resultsTimingBudget !== undefined ? [
resultsTimingBudget.headings.map(h => h.text as string),
...resultsTimingBudget.items.map(({label, measurement, overBudget}) =>
[label,
typeof measurement === 'object' ? (measurement as any).value : measurement + ' ms'
, overBudget !== undefined ? `${overBudget} ms` : '-']) || []
] : []
resultsSizeBudget: getResourceSizes(resourceSizesBudget),
resultsCountBudget: getResourceCounts(resourceCountsBudget),
resultsTimingBudget: getTimings(timingsBudget)
})
);
return performanceBudgets.length ? performanceBudgets.map(b => {
let md = headline(b.name, options.heading) + NEW_LINE + NEW_LINE;
if(b.resultsPerformanceBudget !== undefined) {
md += style('Resource Budget') + NEW_LINE+ NEW_LINE;
md += table(b.resultsPerformanceBudget) + NEW_LINE + NEW_LINE
if (b.resultsSizeBudget !== undefined) {
md += style('Resource Size Budget') + NEW_LINE + NEW_LINE;
md += table(b.resultsSizeBudget) + NEW_LINE + NEW_LINE
}
if(b.resultsTimingBudget !== undefined) {
md += style('Timing Budget') + NEW_LINE+ NEW_LINE;
md += (b.resultsPerformanceBudget ? NEW_LINE : '') + table(b.resultsTimingBudget) + NEW_LINE;
if (b.resultsCountBudget !== undefined) {
md += style('Resource Count Budget') + NEW_LINE + NEW_LINE;
md += table(b.resultsCountBudget) + NEW_LINE + NEW_LINE
}
if (b.resultsTimingBudget !== undefined) {
md += style('Timing Budget') + NEW_LINE + NEW_LINE;
md += table(b.resultsTimingBudget) + NEW_LINE + NEW_LINE
}
return md;
}).join(NEW_LINE) : '';
}


function getTimings(resultsTimingBudget: Table | undefined): undefined | string[][] {
if (resultsTimingBudget === undefined) {
return undefined
} else {
return [
// [ {text: string, ...props } ]
resultsTimingBudget.headings.map((h: any) => h.text as string),
...resultsTimingBudget.items.map(({label, measurement, overBudget}: any) => {
const row = [];
if(label === 'Cumulative Layout Shift') {
return [label + '',
measurement === undefined ? '-' : parseFloat(measurement.value).toFixed(2),
overBudget === undefined ? '-' : parseFloat(overBudget).toFixed(2),
]
} else {
return [label + '',
measurement === undefined ? '-' : measurement + ' ms',
overBudget === undefined ? '-' : overBudget + ' ms'
]
}
})
]
}
};

function getResourceSizes(resourceSizesBudget: Table | undefined): undefined | string[][] {
if (resourceSizesBudget === undefined) {
return undefined
} else {
return [
resourceSizesBudget.headings
.filter((i: any) => ['label', 'transferSize', 'sizeOverBudget'].includes(i.key))
.map((h: any) => h.text as string),
...resourceSizesBudget.items
.map(
({label, transferSize, sizeOverBudget}: any) =>
[
label+'',
formatBytes(transferSize),
sizeOverBudget ? formatBytes(sizeOverBudget) : '-'
])
]
}
}

function getResourceCounts(resourceCountsBudget: Table | undefined): undefined | string[][] {
if (resourceCountsBudget === undefined) {
return undefined
} else {
return [
resourceCountsBudget.headings
.filter((i: any) => ['label', 'requestCount', 'countOverBudget'].includes(i.key))
.map((h: any) => h.key === 'countOverBudget' ? 'Over Budget' : h.text as string),
...resourceCountsBudget.items
.map(
({label, requestCount, countOverBudget}: any) =>
[
label+'',
requestCount+'',
countOverBudget ? countOverBudget : '-'
])
]
}
}



/**
* | Step Name | Gather Mode |Performance | Accessibility | BestPractices | Seo | PWA |
* | --------------- | ----------- | ------------- | ------------- | ---- | --- |
Expand All @@ -110,7 +169,7 @@ function formatStepsForMdTable(reportCategories: string[], reducedReport: Reduce
return reducedReport.steps.map((step) => {
const results = reportCategories.map(category => extractResultsValue(step.results[category]));
// add `budgetsSymbol` to gatherMode to indicate budgets
step.resultsPerformanceBudget && (step.gatherMode = step.gatherMode + ` ${budgetsSymbol}` as GatherMode);
step.resourceCountsBudget && (step.gatherMode = step.gatherMode + ` ${budgetsSymbol}` as GatherMode);
return [step.name, step.gatherMode].concat(results);
});
}
Expand Down Expand Up @@ -139,7 +198,7 @@ function extractTableHead(reportCategories: string[]): string[] {
}

function extractFractionalResultValue(fractionResults: FractionResults): string {
const { totalWeight, numPassed, numPassableAudits } = fractionResults;
const {totalWeight, numPassed, numPassableAudits} = fractionResults;
const value = numPassed + '/' + numPassableAudits;
return totalWeight === 0 ? 'Ø ' + value : value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ export function parseSteps(steps: FlowResult.Step[]): ReducedFlowStep[] {
results
};
if(step.lhr.audits['performance-budget']) {
reducedStep.resultsPerformanceBudget = step.lhr.audits['performance-budget'].details as any
reducedStep.resourceCountsBudget = step.lhr.audits['performance-budget'].details as any
reducedStep.resourceSizesBudget = step.lhr.audits['performance-budget'].details as any
}
if(step.lhr.audits['timing-budget']) {
reducedStep.resultsTimingBudget = step.lhr.audits['timing-budget'].details as any
reducedStep.timingsBudget = step.lhr.audits['timing-budget'].details as any
}
return reducedStep;
});
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/src/lib/commands/collect/utils/report/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ export type ReducedFlowStep =
name: string;
fetchTime: string;
results: ReducedFlowStepResult;
resultsPerformanceBudget?: Details.Table,
resultsTimingBudget?: Details.Table,
resourceCountsBudget?: Details.Table,
resourceSizesBudget?: Details.Table,
timingsBudget?: Details.Table,
baseline?: ReducedFlowStepResult;
};

Expand Down

0 comments on commit 141cc49

Please sign in to comment.