Skip to content
Open
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
124 changes: 124 additions & 0 deletions tests/trace-processing/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@
import assert from 'node:assert';
import {describe, it} from 'node:test';

import type {
InsightName,
TraceParseError,
TraceResult,
} from '../../src/trace-processing/parse.js';
import {
getInsightOutput,
getTraceSummary,
parseRawTraceBuffer,
traceResultIsSuccess,
} from '../../src/trace-processing/parse.js';

import {loadTraceAsBuffer} from './fixtures/load.js';

async function parseTrace(fileName: string): Promise<TraceResult> {
const rawData = loadTraceAsBuffer(fileName);
const result = await parseRawTraceBuffer(rawData);
if (!traceResultIsSuccess(result)) {
assert.fail(`Unexpected trace parse error: ${result.error}`);
}
Comment on lines +27 to +29

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!traceResultIsSuccess(result)) {
assert.fail(`Unexpected trace parse error: ${result.error}`);
}
assert(traceResultIsSuccess(result), `Unexpected trace parse error: ${result.error}`);

return result;
}

describe('Trace parsing', async () => {
it('can parse a Uint8Array from Tracing.stop())', async () => {
const rawData = loadTraceAsBuffer('basic-trace.json.gz');
Expand Down Expand Up @@ -44,4 +60,112 @@ describe('Trace parsing', async () => {
error: 'No buffer was provided.',
});
});

it('will return a message if the buffer decodes to an empty string', async () => {
const result = await parseRawTraceBuffer(new Uint8Array());
assert.deepEqual(result, {
error: 'Decoding the trace buffer returned an empty string.',
});
});

it('will return a message if the buffer is not valid JSON', async () => {
const result = await parseRawTraceBuffer(
new TextEncoder().encode('this is not valid JSON'),
);
if (traceResultIsSuccess(result)) {
assert.fail('Expected a parse error for invalid JSON input.');
}
assert.match(result.error, /JSON/);
Comment on lines +75 to +78

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (traceResultIsSuccess(result)) {
assert.fail('Expected a parse error for invalid JSON input.');
}
assert.match(result.error, /JSON/);
assert('error' in result);
assert.match(result.error, /JSON/);

});

it('will return a message if the JSON is not a valid trace', async () => {
const result = await parseRawTraceBuffer(
new TextEncoder().encode('{"notATrace": true}'),
);
if (traceResultIsSuccess(result)) {
assert.fail('Expected a parse error for a non-trace JSON input.');
}
assert.ok(result.error.length > 0);
Comment on lines +85 to +88

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (traceResultIsSuccess(result)) {
assert.fail('Expected a parse error for a non-trace JSON input.');
}
assert.ok(result.error.length > 0);
assert('error' in result);
assert.ok(result.error.length > 0);

});
});

describe('traceResultIsSuccess', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this function we should just use a object that mimics the trace, so we can control it.
Also we can't use parseTrace as that itself include it.

it('returns true for the result of a successful parse', async () => {
const rawData = loadTraceAsBuffer('basic-trace.json.gz');
const result = await parseRawTraceBuffer(rawData);
assert.strictEqual(traceResultIsSuccess(result), true);
});

it('returns true for a trace result without insights', async () => {
const result = await parseTrace('basic-trace.json.gz');
const withoutInsights: TraceResult = {
parsedTrace: result.parsedTrace,
insights: null,
};
assert.strictEqual(traceResultIsSuccess(withoutInsights), true);
});

it('returns false for the result of a failed parse', async () => {
const result = await parseRawTraceBuffer(undefined);
assert.strictEqual(traceResultIsSuccess(result), false);
});

it('returns false for a parse error object', () => {
const error: TraceParseError = {error: 'Something went wrong.'};
assert.strictEqual(traceResultIsSuccess(error), false);
});

it('checks for the parsedTrace key, not the error message contents', () => {
const error: TraceParseError = {error: 'parsedTrace'};
assert.strictEqual(traceResultIsSuccess(error), false);
});
Comment on lines +118 to +121

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it('checks for the parsedTrace key, not the error message contents', () => {
const error: TraceParseError = {error: 'parsedTrace'};
assert.strictEqual(traceResultIsSuccess(error), false);
});

});

describe('getInsightOutput', () => {
it('returns the formatted output for a known insight', async () => {
const result = await parseTrace('web-dev-with-commit.json.gz');
const insight = getInsightOutput(result, 'NAVIGATION_0', 'LCPBreakdown');
if ('error' in insight) {
assert.fail(`Unexpected insight error: ${insight.error}`);
}
Comment on lines +128 to +130

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ('error' in insight) {
assert.fail(`Unexpected insight error: ${insight.error}`);
}
assert(!('error' in insight`),Unexpected insight error: ${insight.error}`);

assert.match(insight.output, /Insight Title: LCP breakdown/);
});

it('returns an error if the trace has no insights', async () => {
const result = await parseTrace('web-dev-with-commit.json.gz');
const withoutInsights: TraceResult = {
parsedTrace: result.parsedTrace,
insights: null,
};
const insight = getInsightOutput(
withoutInsights,
'NAVIGATION_0',
'LCPBreakdown',
);
assert.deepEqual(insight, {
error: 'No Performance insights are available for this trace.',
});
});

it('returns an error for an unknown insight set id', async () => {
const result = await parseTrace('web-dev-with-commit.json.gz');
const insight = getInsightOutput(result, 'NOT_A_SET_ID', 'LCPBreakdown');
assert.deepEqual(insight, {
error:
'No Performance Insights for the given insight set id. Only use ids given in the "Available insight sets" list.',
});
});

it('returns an error for an unknown insight name', async () => {
const result = await parseTrace('web-dev-with-commit.json.gz');
const insight = getInsightOutput(
result,
'NAVIGATION_0',
'NotARealInsight' as InsightName,
);
assert.deepEqual(insight, {
error:
'No Insight with the name NotARealInsight found. Double check the name you provided is accurate and try again.',
});
});
});
Loading