chore(trace-viewer): more clear classification of trace contexts (#30737)

This commit is contained in:
Yury Semikhatsky 2024-05-09 17:28:39 -07:00 committed by GitHub
parent a50cd30519
commit 00bf7ea815
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 22 deletions

View file

@ -19,7 +19,7 @@ import type { ResourceSnapshot } from '@trace/snapshot';
import type * as trace from '@trace/trace';
export type ContextEntry = {
isPrimary: boolean;
origin: 'testRunner'|'library';
traceUrl: string;
startTime: number;
endTime: number;
@ -55,7 +55,7 @@ export type ActionEntry = trace.ActionTraceEvent & {
export function createEmptyContext(): ContextEntry {
return {
isPrimary: false,
origin: 'testRunner',
traceUrl: '',
startTime: Number.MAX_SAFE_INTEGER,
endTime: 0,

View file

@ -71,7 +71,7 @@ export class TraceModernizer {
switch (event.type) {
case 'context-options': {
this._version = event.version;
contextEntry.isPrimary = true;
contextEntry.origin = 'library';
contextEntry.browserName = event.browserName;
contextEntry.channel = event.channel;
contextEntry.title = event.title;

View file

@ -80,16 +80,16 @@ export class MultiTraceModel {
constructor(contexts: ContextEntry[]) {
contexts.forEach(contextEntry => indexModel(contextEntry));
const primaryContext = contexts.find(context => context.isPrimary);
const libraryContext = contexts.find(context => context.origin === 'library');
this.browserName = primaryContext?.browserName || '';
this.sdkLanguage = primaryContext?.sdkLanguage;
this.channel = primaryContext?.channel;
this.testIdAttributeName = primaryContext?.testIdAttributeName;
this.platform = primaryContext?.platform || '';
this.title = primaryContext?.title || '';
this.options = primaryContext?.options || {};
// Next call updates all timestamps for all events in non-primary contexts, so it must be done first.
this.browserName = libraryContext?.browserName || '';
this.sdkLanguage = libraryContext?.sdkLanguage;
this.channel = libraryContext?.channel;
this.testIdAttributeName = libraryContext?.testIdAttributeName;
this.platform = libraryContext?.platform || '';
this.title = libraryContext?.title || '';
this.options = libraryContext?.options || {};
// Next call updates all timestamps for all events in library contexts, so it must be done first.
this.actions = mergeActionsAndUpdateTiming(contexts);
this.pages = ([] as PageEntry[]).concat(...contexts.map(c => c.pages));
this.wallTime = contexts.map(c => c.wallTime).reduce((prev, cur) => Math.min(prev || Number.MAX_VALUE, cur!), Number.MAX_VALUE);
@ -99,7 +99,7 @@ export class MultiTraceModel {
this.stdio = ([] as trace.StdioTraceEvent[]).concat(...contexts.map(c => c.stdio));
this.errors = ([] as trace.ErrorTraceEvent[]).concat(...contexts.map(c => c.errors));
this.hasSource = contexts.some(c => c.hasSource);
this.hasStepData = contexts.some(context => !context.isPrimary);
this.hasStepData = contexts.some(context => context.origin === 'testRunner');
this.resources = [...contexts.map(c => c.resources)].flat();
this.events.sort((a1, a2) => a1.time - a2.time);
@ -212,24 +212,24 @@ function makeCallIdsUniqueAcrossTraceFiles(contexts: ContextEntry[], traceFileId
function mergeActionsAndUpdateTimingSameTrace(contexts: ContextEntry[]) {
const map = new Map<string, ActionTraceEventInContext>();
const primaryContexts = contexts.filter(context => context.isPrimary);
const nonPrimaryContexts = contexts.filter(context => !context.isPrimary);
const libraryContexts = contexts.filter(context => context.origin === 'library');
const testRunnerContexts = contexts.filter(context => context.origin === 'testRunner');
for (const context of primaryContexts) {
for (const context of libraryContexts) {
for (const action of context.actions)
map.set(`${action.apiName}@${action.wallTime}`, { ...action, context });
}
// Protocol call aka isPrimary contexts have startTime/endTime as server-side times.
// Step aka non-isPrimary contexts have startTime/endTime are client-side times.
// Adjust startTime/endTime on the primary contexts to align them with the test
// Protocol call aka library contexts have startTime/endTime as server-side times.
// Step aka test runner contexts have startTime/endTime as client-side times.
// Adjust startTime/endTime on the library contexts to align them with the test
// runner steps.
const delta = monotonicTimeDeltaBetweenLibraryAndRunner(nonPrimaryContexts, map);
const delta = monotonicTimeDeltaBetweenLibraryAndRunner(testRunnerContexts, map);
if (delta)
adjustMonotonicTime(primaryContexts, delta);
adjustMonotonicTime(libraryContexts, delta);
const nonPrimaryIdToPrimaryId = new Map<string, string>();
for (const context of nonPrimaryContexts) {
for (const context of testRunnerContexts) {
for (const action of context.actions) {
const key = `${action.apiName}@${action.wallTime}`;
const existing = map.get(key);