Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
327 changes: 222 additions & 105 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"lighthouse-logger": "2.0.1",
"multi-progress-bars": "^5.0.3",
"nx": "21.4.1",
"ora": "^9.0.0",
"parse-lcov": "^1.0.4",
"rimraf": "^6.0.1",
"semver": "^7.6.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ exports[`parseCriticalRequestChainToAuditDetails > should convert chains to basi
{
"name": "https://fonts.gstatic.com/s/googlesans/v62/4UasrENHsxJlGDuGo1OIlJfC6l_24rlCK1Yo_Iqcsih3SAyH6cAwhX9RPjIUvbQoi-E.woff2",
"values": {
"duration": "48.083 ms",
"duration": "48 ms",
"transferSize": "35.89 kB",
},
},
{
"name": "https://fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0me8iUI0.woff2",
"values": {
"duration": "63.943 ms",
"duration": "64 ms",
"transferSize": "22.31 kB",
},
},
],
"name": "https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap",
"values": {
"duration": "50.656 ms",
"duration": "51 ms",
"transferSize": "3.68 kB",
},
},
Expand All @@ -33,42 +33,42 @@ exports[`parseCriticalRequestChainToAuditDetails > should convert chains to basi
{
"name": "https://fonts.gstatic.com/s/materialicons/v143/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2",
"values": {
"duration": "86.765 ms",
"duration": "87 ms",
"transferSize": "125.78 kB",
},
},
],
"name": "https://fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block",
"values": {
"duration": "55.102 ms",
"duration": "55 ms",
"transferSize": "615 B",
},
},
{
"name": "https://www.gstatic.com/devrel-devsite/prod/ve761bca974e16662f27aa8810df6d144acde5bdbeeca0dfd50e25f86621eaa19/chrome/css/app.css",
"values": {
"duration": "70.050 ms",
"duration": "70 ms",
"transferSize": "133.58 kB",
},
},
{
"name": "https://www.gstatic.com/devrel-devsite/prod/ve761bca974e16662f27aa8810df6d144acde5bdbeeca0dfd50e25f86621eaa19/chrome/css/dark-theme.css",
"values": {
"duration": "69.755 ms",
"duration": "70 ms",
"transferSize": "3.98 kB",
},
},
{
"name": "https://developer.chrome.com/extras.css",
"values": {
"duration": "199.327 ms",
"duration": "199 ms",
"transferSize": "109 B",
},
},
],
"name": "https://developer.chrome.com/docs/lighthouse/performance/critical-request-chains",
"values": {
"duration": "472.304 ms",
"duration": "472 ms",
"transferSize": "18.66 kB",
},
},
Expand Down Expand Up @@ -98,7 +98,7 @@ exports[`parseCriticalRequestChainToAuditDetails > should convert longest chain
],
"rows": [
{
"duration": "757.072 ms",
"duration": "757 ms",
"length": 3,
"transferSize": "125.78 kB",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe('toAuditDetails', () => {
},
{
name: 'Zone:ZoneAwarePromise',
duration: 0.783,
duration: 1.783,
},
],
});
Expand All @@ -104,11 +104,11 @@ describe('toAuditDetails', () => {
rows: [
{
name: 'Zone',
duration: '0.634 ms',
duration: '1 ms',
},
{
name: 'Zone:ZoneAwarePromise',
duration: '0.783 ms',
duration: '2 ms',
},
],
},
Expand Down Expand Up @@ -360,7 +360,7 @@ describe('toAuditDetails', () => {
root: {
name: 'https://example.com/',
values: {
duration: '508.498 ms',
duration: '508 ms',
transferSize: '849 B',
},
},
Expand All @@ -375,7 +375,7 @@ describe('toAuditDetails', () => {
],
rows: [
{
duration: '508.498 ms',
duration: '508 ms',
transferSize: '849 B',
length: 1,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
formatBytes,
formatDuration,
html,
roundDecimals,
truncateText,
ui,
} from '@code-pushup/utils';
Expand Down Expand Up @@ -72,17 +73,14 @@ export function formatTableItemPropertyValue(
return html.link(url);
case 'timespanMs':
case 'ms':
return formatDuration(Number(parsedItemValue));
return formatDuration(Number(parsedItemValue), 3);
case 'node':
return parseNodeValue(itemValue as Details.NodeValue);
case 'source-location':
return truncateText(String(parsedItemValue), 200);
case 'numeric':
const num = Number(parsedItemValue);
if (num.toFixed(3).toString().endsWith('.000')) {
return String(num);
}
return String(num.toFixed(3));
return roundDecimals(num, 3).toString();
case 'text':
return truncateText(String(parsedItemValue), 500);
case 'multi': // @TODO
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,13 @@ describe('formatTableItemPropertyValue', () => {
{ type: 'numeric', value: 2142 },
'timespanMs',
),
).toBe('2.14 s');
).toBe('2.142 s');
});

it('should format value based on itemValueFormat "ms"', () => {
expect(
formatTableItemPropertyValue({ type: 'numeric', value: 2142 }, 'ms'),
).toBe('2.14 s');
).toBe('2.142 s');
});

it('should format value based on itemValueFormat "node"', () => {
Expand Down Expand Up @@ -318,7 +318,7 @@ describe('formatTableItemPropertyValue', () => {
{ type: 'numeric', value: 42.1 } as Details.ItemValue,
'numeric',
),
).toBe('42.100');
).toBe('42.1');
});

it('should format value based on itemValueFormat "numeric" as int if float has only 0 post comma', () => {
Expand Down
91 changes: 91 additions & 0 deletions packages/utils/mocks/logger-demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import ansis from 'ansis';
import { logger } from '../src/index.js';

async function sleep(delay: number) {
return new Promise(resolve => {
setTimeout(resolve, delay);
});
}

logger.setVerbose(process.argv.includes('--verbose'));

const errorStage = process.argv
.find(arg => arg.startsWith('--error='))
?.split('=')[1];

try {
logger.info(ansis.bold.blue('Code PushUp CLI v0.80.1'));
logger.newline();

await logger.task('Importing code-pushup.config.ts', async () => {
await sleep(500);

return 'Loaded configuration from code-pushup.config.ts';
});
logger.debug('2 plugins:');
logger.debug('• ESLint');
logger.debug('• Lighthouse');

await logger.group(
`Running plugin "ESLint" ${ansis.gray('[1/2]')}`,
async () => {
const bin = 'npx eslint . --format=json';
await logger.command(bin, async () => {
await sleep(3000);
if (errorStage === 'plugin') {
logger.info('Configuration file not found.');
throw new Error(`Command ${ansis.bold(bin)} exited with code 1`);
}
logger.debug('All files pass linting.');
});

logger.info('Found 0 lint problems');

logger.warn(
'Metadata not found for rule @angular-eslint/template/eqeqeq',
);

return 'Completed "ESLint" plugin execution';
},
);

await logger.group(
`Running plugin "Lighthouse" ${ansis.gray('[2/2]')}`,
async () => {
await logger.task(
`Executing ${ansis.bold('runLighthouse')} function`,
async () => {
await sleep(8000);
return `Executed ${ansis.bold('runLighthouse')} function`;
},
);

logger.debug('Lighthouse category scores:');
logger.debug('• Accessibility: 100');
logger.debug('• SEO: 84');

return 'Completed "Lighthouse" plugin execution';
},
);

logger.info(ansis.bold('Collected report'));
logger.newline();

await logger.task(ansis.bold('Uploading report to portal'), async () => {
logger.debug(
'Sent GraphQL mutation to https://api.code-pushup.example.com/graphql (organization: "example", project: "website")',
);
await sleep(2000);
if (errorStage === 'core') {
throw new Error('GraphQL error');
}
return ansis.bold('Uploaded report to portal');
});
} catch (error) {
logger.newline();
console.error(error);
logger.newline();
logger.error(ansis.bold(`Code PushUp CLI failed (see error above)`));
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit
process.exit(1);
}
3 changes: 2 additions & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"multi-progress-bars": "^5.0.3",
"semver": "^7.6.0",
"simple-git": "^3.20.0",
"zod": "^4.0.5"
"zod": "^4.0.5",
"ora": "^9.0.0"
},
"files": [
"src",
Expand Down
24 changes: 23 additions & 1 deletion packages/utils/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,29 @@
}
},
"unit-test": {},
"int-test": {}
"int-test": {},
"demo-logger": {
"executor": "nx:run-commands",
"options": {
"command": "npx tsx --tsconfig=tsconfig.base.json packages/utils/mocks/logger-demo.ts"
},
"configurations": {
"ci": {
"env": {
"CI": "true"
}
},
"verbose": {
"args": ["--verbose"]
},
"error-core": {
"args": ["--error=core"]
},
"error-plugin": {
"args": ["--error=plugin"]
}
}
}
},
"tags": ["scope:shared", "type:util", "publishable"]
}
11 changes: 10 additions & 1 deletion packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export {
} from './lib/case-conversions.js';
export { filesCoverageToTree, type FileCoverage } from './lib/coverage-tree.js';
export { createRunnerFiles } from './lib/create-runner-files.js';
export { dateToUnixTimestamp } from './lib/dates.js';
export { comparePairs, matchArrayItemsByKey, type Diff } from './lib/diff.js';
export {
coerceBooleanValue,
Expand Down Expand Up @@ -51,9 +52,12 @@ export { filterItemRefsBy } from './lib/filter.js';
export {
formatBytes,
formatDuration,
indentLines,
pluralize,
pluralizeToken,
roundDecimals,
slugify,
transformLines,
truncateDescription,
truncateIssueMessage,
truncateText,
Expand Down Expand Up @@ -81,10 +85,15 @@ export {
} from './lib/guards.js';
export { interpolate } from './lib/interpolate.js';
export { logMultipleResults } from './lib/log-results.js';
export { Logger, logger } from './lib/logger.js';
export { link, ui, type CliUi, type Column } from './lib/logging.js';
export { mergeConfigs } from './lib/merge-configs.js';
export { getProgressBar, type ProgressBar } from './lib/progress.js';
export { asyncSequential, groupByStatus } from './lib/promises.js';
export {
asyncSequential,
groupByStatus,
settlePromise,
} from './lib/promises.js';
export { generateRandomId } from './lib/random.js';
export {
CODE_PUSHUP_DOMAIN,
Expand Down
3 changes: 3 additions & 0 deletions packages/utils/src/lib/dates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function dateToUnixTimestamp(date: Date): number {
return Math.round(date.getTime() / 1000);
}
9 changes: 9 additions & 0 deletions packages/utils/src/lib/dates.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { dateToUnixTimestamp } from './dates.js';

describe('dateToUnixTimestamp', () => {
it('should convert date to number of seconds since epoch', () => {
expect(dateToUnixTimestamp(new Date('1970-01-01T01:00:04.567Z'))).toBe(
3605, // 1 hour is 3600 seconds + 4.567 seconds is rounded up to 5 seconds
);
});
});
Loading