fix(trace viewer): library-only trace should not merge actions (#31768)

Without `wallTime`, actions are matched by `actionName:undefined` and
all actions with the same are merged.

Fixes #31764.
This commit is contained in:
Dmitry Gozman 2024-07-19 11:18:22 -07:00 committed by GitHub
parent b8546eb35e
commit b535139b32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 5 deletions

View File

@ -183,8 +183,8 @@ function mergeActionsAndUpdateTiming(contexts: ContextEntry[]) {
if (traceFileToContexts.size > 1)
makeCallIdsUniqueAcrossTraceFiles(contexts, ++traceFileId);
// Align action times across runner and library contexts within each trace file.
const map = mergeActionsAndUpdateTimingSameTrace(contexts);
result.push(...map.values());
const actions = mergeActionsAndUpdateTimingSameTrace(contexts);
result.push(...actions);
}
result.sort((a1, a2) => {
if (a2.parentId === a1.callId)
@ -211,19 +211,26 @@ function makeCallIdsUniqueAcrossTraceFiles(contexts: ContextEntry[], traceFileId
}
}
function mergeActionsAndUpdateTimingSameTrace(contexts: ContextEntry[]) {
function mergeActionsAndUpdateTimingSameTrace(contexts: ContextEntry[]): ActionTraceEventInContext[] {
const map = new Map<string, ActionTraceEventInContext>();
const libraryContexts = contexts.filter(context => context.origin === 'library');
const testRunnerContexts = contexts.filter(context => context.origin === 'testRunner');
// With library-only or test-runner-only traces there is nothing to match.
if (!testRunnerContexts.length || !libraryContexts.length) {
return contexts.map(context => {
return context.actions.map(action => ({ ...action, context }));
}).flat();
}
// Library actions are replaced with corresponding test runner steps. Matching with
// the test runner steps enables us to find parent steps.
// - In the newer versions the actions are matched by explicit step id stored in the
// library context actions.
// - In the older versions the step id is not stored and the match is perfomed based on
// action name and wallTime.
const matchByStepId = !libraryContexts.length || libraryContexts.some(c => c.actions.some(a => !!a.stepId));
const matchByStepId = libraryContexts.some(c => c.actions.some(a => !!a.stepId));
for (const context of libraryContexts) {
for (const action of context.actions) {
@ -264,7 +271,7 @@ function mergeActionsAndUpdateTimingSameTrace(contexts: ContextEntry[]) {
map.set(key, { ...action, context });
}
}
return map;
return [...map.values()];
}
function adjustMonotonicTime(contexts: ContextEntry[], monotonicTimeDelta: number) {

Binary file not shown.

View File

@ -1282,6 +1282,17 @@ test('should open snapshot in new browser context', async ({ browser, page, runA
await newPage.close();
});
test('should show similar actions from library-only trace', async ({ showTraceViewer, asset }) => {
const traceViewer = await showTraceViewer([asset('trace-library-1.46.zip')]);
await expect(traceViewer.actionTitles).toHaveText([
/page.setContent/,
/locator.getAttributelocator\('div'\)/,
/locator.isVisiblelocator\('div'\)/,
/locator.getAttributelocator\('div'\)/,
/locator.isVisiblelocator\('div'\)/,
]);
});
function parseMillis(s: string): number {
const matchMs = s.match(/(\d+)ms/);
if (matchMs)