[go: nahoru, domu]

Revert "[RPP] Use the new engine in the Timings track"

This reverts commit 27d82aef6155cd7510c4cd339e97449f2445634a.

Reason for revert: Breaking CQ bots

Original change's description:
> [RPP] Use the new engine in the Timings track
>
> NOTE: This has to be landed *after* the new engine has been reenabled
>
> The first track appender is introduced to add the Timings track into the flame chart data (TimingsTrackAppender).
>
> This appender consists of the bits previously in the TimelineFlameChartDataProvider that were in charge of appending the data of the track along with the bits that provided extra feature for events in the track (like stylings and display names).
>
> All these parts are moved to a common place to handle the details of the track together in the same module, but separate from other tracks. The source of data used by the track appender is the output of the new engine
>
> In the future further test coverage will be added using dedicated screenshot tests.
>
> Bug: 1409044
> Change-Id: I007d5ffd93e310cba26546fa09829e02e3cc581c
> Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4295982
> Commit-Queue: Andres Olivares <andoli@chromium.org>
> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>

Bug: 1409044
Change-Id: Ie9dd0d16351beb996de5d70dba2107c99296b4dc
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4315943
Commit-Queue: Andres Olivares <andoli@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
diff --git a/config/gni/devtools_grd_files.gni b/config/gni/devtools_grd_files.gni
index 8a30203..f1acb8d 100644
--- a/config/gni/devtools_grd_files.gni
+++ b/config/gni/devtools_grd_files.gni
@@ -1380,7 +1380,6 @@
   "front_end/panels/timeline/TimelinePanel.js",
   "front_end/panels/timeline/TimelineTreeView.js",
   "front_end/panels/timeline/TimelineUIUtils.js",
-  "front_end/panels/timeline/TimingsTrackAppender.js",
   "front_end/panels/timeline/UIDevtoolsController.js",
   "front_end/panels/timeline/UIDevtoolsUtils.js",
   "front_end/panels/timeline/WebVitalsTimelineUtils.js",
diff --git a/front_end/models/timeline_model/BUILD.gn b/front_end/models/timeline_model/BUILD.gn
index 3311181..9524c96 100644
--- a/front_end/models/timeline_model/BUILD.gn
+++ b/front_end/models/timeline_model/BUILD.gn
@@ -33,7 +33,10 @@
 
   visibility = [
     ":*",
-    "../../../test/unittests/*",
+    "../../../test/unittests/front_end/helpers",
+    "../../../test/unittests/front_end/models/timeline_model/*",
+    "../../../test/unittests/front_end/panels/timeline:*",
+    "../../../test/unittests/front_end/panels/timeline/components/*",
     "../../panels/timeline/*",
 
     # TODO(crbug.com/1202788): Remove invalid dependents
diff --git a/front_end/models/timeline_model/TimelineModel.ts b/front_end/models/timeline_model/TimelineModel.ts
index 916348c..4eee37a 100644
--- a/front_end/models/timeline_model/TimelineModel.ts
+++ b/front_end/models/timeline_model/TimelineModel.ts
@@ -421,11 +421,6 @@
    * into Timings so they can be appended to the performance UI.
    * Performance.mark() are a part of the "blink.user_timing" category alongside
    * Navigation and Resource Timing events, so we must filter them out before pushing.
-   *
-   * Note: Although this looks like a duplicate of the timings appending at the
-   * TimingsTrackAppender, this is still necessary for compatibility with features
-   * outside the flame chart that rely on the definition and construction of the legacy
-   * TimelineModel.Track version of the timings track (f.e. the details pane).
    */
   private buildTimings(): void {
     const timingsTrack = this.tracksInternal.find(track => track.type === TrackType.Timings);
diff --git a/front_end/models/trace/handlers/PageLoadMetricsHandler.ts b/front_end/models/trace/handlers/PageLoadMetricsHandler.ts
index e9761f6..3c5d709 100644
--- a/front_end/models/trace/handlers/PageLoadMetricsHandler.ts
+++ b/front_end/models/trace/handlers/PageLoadMetricsHandler.ts
@@ -587,20 +587,17 @@
 }
 
 export const enum MetricName {
-  // First Contentful Paint
   FCP = 'FCP',
   // First Paint
   FP = 'FP',
   // MarkLoad
   L = 'L',
   LCP = 'LCP',
-  // Mark DOM Content
   DCL = 'DCL',
   // Time To Interactive
   TTI = 'TTI',
   // Total Blocking Time
   TBT = 'TBT',
-  // Cumulative Layout Shift
   CLS = 'CLS',
 }
 
diff --git a/front_end/models/trace/handlers/UserTimings.md b/front_end/models/trace/handlers/UserTimings.md
index 22341d2..dde6bfb 100644
--- a/front_end/models/trace/handlers/UserTimings.md
+++ b/front_end/models/trace/handlers/UserTimings.md
@@ -5,7 +5,9 @@
 ### 1. Injected timings
 Chrome will inject some timings that have this category. These align with the Performance Navigation Timing API [https://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming] and the Resource Timing API [https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming].
 
-When working with user timings we have to be careful to filter out any events that aren't actually user timings generated by calls to `performance.mark` or `performance.measure`. This filtering happens at the UserTimingsHandler level.
+You can see how the legacy data layer filters these out in `TimelineFlameChartDataProvider.ts` [https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/panels/timeline/TimelineFlameChartDataProvider.ts;l=851?q=timelineflamechartdataprov&ss=chromium].
+
+When working with user timings we have to be careful to filter out any events that aren't actually user timings generated by calls to `performance.mark` or `performance.measure`.
 
 ### 2. Performance mark calls
 If the user has code such as `const foo = performance.mark('foo')`, that will generate a single event in the trace file. We use this to give us a list of all marks that were created.
diff --git a/front_end/panels/timeline/BUILD.gn b/front_end/panels/timeline/BUILD.gn
index 73b6c14..e976ea6 100644
--- a/front_end/panels/timeline/BUILD.gn
+++ b/front_end/panels/timeline/BUILD.gn
@@ -41,7 +41,6 @@
     "TimelinePanel.ts",
     "TimelineTreeView.ts",
     "TimelineUIUtils.ts",
-    "TimingsTrackAppender.ts",
     "UIDevtoolsController.ts",
     "UIDevtoolsUtils.ts",
     "WebVitalsTimelineUtils.ts",
diff --git a/front_end/panels/timeline/CompatibilityTracksAppender.ts b/front_end/panels/timeline/CompatibilityTracksAppender.ts
index 70d7d99..48769a8 100644
--- a/front_end/panels/timeline/CompatibilityTracksAppender.ts
+++ b/front_end/panels/timeline/CompatibilityTracksAppender.ts
@@ -5,9 +5,7 @@
 import type * as TraceEngine from '../../models/trace/trace.js';
 import type * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
 import * as SDK from '../../core/sdk/sdk.js';
-import * as TimelineModel from '../../models/timeline_model/timeline_model.js';
-import {type TimelineFlameChartEntry, type EntryType} from './TimelineFlameChartDataProvider.js';
-import {TimingsTrackAppender} from './TimingsTrackAppender.js';
+import type * as TimelineModel from '../../models/timeline_model/timeline_model.js';
 
 export type HighlightedEntryInfo = {
   title: string,
@@ -41,16 +39,20 @@
    * The position relative to other tracks that an appender's track should
    * be rendered on.
    **/
-  appenderName: TrackAppenderName;
-
+  weight: number;
   /**
    * Appends into the flame chart data the data corresponding to a track.
    * @param level the horizontal level of the flame chart events where the
    * track's events will start being appended.
+   * @param flameChartData the data used by the flame chart renderer on
+   * which the track data will be appended.
+   * @param traceParsedData the trace parsing engines output.
    * @returns the first available level to append more data after having
    * appended the track's events.
    */
-  appendTrackAtLevel(level: number): number;
+  appendTrackAtLevel(
+      level: number, flameChartData: PerfUI.FlameChart.TimelineData,
+      traceParsedData: TraceEngine.Handlers.Types.TraceParseData): number;
   /**
    * Returns the color an event is shown with in the timeline.
    */
@@ -65,52 +67,18 @@
   highlightedEntryInfo(event: TraceEngine.Types.TraceEvents.TraceEventData): HighlightedEntryInfo;
 }
 
-export const TrackNames = ['Timings'] as const;
-export type TrackAppenderName = typeof TrackNames[number];
-
 export class CompatibilityTracksAppender {
   #trackForLevel = new Map<number, TrackAppender>();
-  #flameChartData: PerfUI.FlameChart.TimelineData;
-  #traceParsedData: TraceEngine.Handlers.Types.TraceParseData;
-  #entryData: TimelineFlameChartEntry[];
   // TODO(crbug.com/1416533)
-  // These are used only for compatibility with the legacy flame chart
-  // architecture of the panel. Once all tracks have been migrated to
+  // This is used only for compatibility with the legacy flame chart
+  // architechture of the panel. Once all tracks have been migrated to
   // use the new engine and flame chart architecture, the reference can
   // be removed.
   #legacyTimelineModel: TimelineModel.TimelineModel.TimelineModelImpl;
-  #legacyEntryTypeByLevel: EntryType[];
-  #timingsTrackAppender: TimingsTrackAppender;
 
-  /**
-   * @param flameChartData the data used by the flame chart renderer on
-   * which the track data will be appended.
-   * @param traceParsedData the trace parsing engines output.
-   * @param entryData the array containing all event to be rendered in
-   * the flamechart.
-   * @param legacyEntryTypeByLevel an array containing the type of
-   * each entry in the entryData array. Indexed by the position the
-   * corresponding entry occupies in the entryData array. This reference
-   * is needed only for compatibility with the legacy flamechart
-   * architecture and should be removed once all tracks use the new
-   * system.
-   */
-  constructor(
-      flameChartData: PerfUI.FlameChart.TimelineData, traceParsedData: TraceEngine.Handlers.Types.TraceParseData,
-      entryData: TimelineFlameChartEntry[], legacyEntryTypeByLevel: EntryType[],
-      legacyTimelineModel: TimelineModel.TimelineModel.TimelineModelImpl) {
-    this.#flameChartData = flameChartData;
-    this.#traceParsedData = traceParsedData;
-    this.#entryData = entryData;
-    this.#legacyEntryTypeByLevel = legacyEntryTypeByLevel;
+  constructor(legacyTimelineModel: TimelineModel.TimelineModel.TimelineModelImpl) {
     this.#legacyTimelineModel = legacyTimelineModel;
-    const timings =
-        this.#legacyTimelineModel.tracks().find(track => track.type === TimelineModel.TimelineModel.TrackType.Timings);
-    this.#timingsTrackAppender = new TimingsTrackAppender(
-        this, 'Timings', this.#flameChartData, this.#traceParsedData, this.#entryData, this.#legacyEntryTypeByLevel,
-        timings);
   }
-
   /**
    * Given a trace event returns instantiates a legacy SDK.Event. This should
    * be used for compatibility purposes only.
@@ -124,17 +92,9 @@
     return SDK.TracingModel.PayloadEvent.fromPayload(event as unknown as SDK.TracingManager.EventPayload, thread);
   }
 
-  timingsTrackAppender(): TimingsTrackAppender {
-    return this.#timingsTrackAppender;
-  }
-
-  registerTrackForLevel(level: number, appender: TrackAppender): void {
-    this.#trackForLevel.set(level, appender);
-  }
-
   allTrackAppenders(): TrackAppender[] {
     // TODO(crbug.com/1409044) Return appenders for all tracks
-    return [this.#timingsTrackAppender];
+    return [];
   }
   /**
    * Returns the color an event is shown with in the timeline.
diff --git a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts
index 62d8cf0..c8deb32 100644
--- a/front_end/panels/timeline/TimelineFlameChartDataProvider.ts
+++ b/front_end/panels/timeline/TimelineFlameChartDataProvider.ts
@@ -41,13 +41,11 @@
 import * as UI from '../../ui/legacy/legacy.js';
 import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
 
-import {CompatibilityTracksAppender, type TrackAppenderName} from './CompatibilityTracksAppender.js';
-
+import {CompatibilityTracksAppender} from './CompatibilityTracksAppender.js';
 import timelineFlamechartPopoverStyles from './timelineFlamechartPopover.css.js';
 
 import {type PerformanceModel} from './PerformanceModel.js';
-
-import {FlameChartStyle, Selection, type TimelineFlameChartMarker} from './TimelineFlameChartView.js';
+import {FlameChartStyle, Selection, TimelineFlameChartMarker} from './TimelineFlameChartView.js';
 import {TimelineSelection} from './TimelinePanel.js';
 
 import {TimelineUIUtils, type TimelineCategory} from './TimelineUIUtils.js';
@@ -66,6 +64,10 @@
    */
   userInteractions: 'Interactions',
   /**
+   *@description Text in Timeline Flame Chart Data Provider of the Performance panel
+   */
+  timings: 'Timings',
+  /**
    *@description Title of the Console tool
    */
   console: 'Console',
@@ -335,6 +337,9 @@
       if (eventToDisallowRoot.get(event)) {
         return i18nString(UIStrings.onIgnoreList);
       }
+      if (this.legacyPerformanceModel && this.legacyPerformanceModel.timelineModel().isMarkerEvent(event)) {
+        return TimelineUIUtils.markerShortTitle(event);
+      }
       return TimelineUIUtils.eventTitle(event);
     }
     if (entryType === entryTypes.ExtensionEvent) {
@@ -401,10 +406,8 @@
         this.legacyTimelineModel.maximumRecordTime() - this.minimumBoundaryInternal;
     this.currentLevel = 0;
 
-    if (this.traceEngineData) {
-      this.compatibilityTracksAppender = new CompatibilityTracksAppender(
-          this.timelineDataInternal, this.traceEngineData, this.entryData, this.entryTypeByLevel,
-          this.legacyTimelineModel);
+    if (this.traceEngineData && this.timelineDataInternal) {
+      this.compatibilityTracksAppender = new CompatibilityTracksAppender(this.legacyTimelineModel);
     }
     if (this.legacyTimelineModel.isGenericTrace()) {
       this.processGenericTrace();
@@ -452,19 +455,15 @@
   private processInspectorTrace(): void {
     this.appendFrames();
 
-    const weight = (track: {type?: string, forMainFrame?: boolean, appenderName?: TrackAppenderName}): number => {
-      if (track.appenderName !== undefined) {
-        switch (track.appenderName) {
-          case 'Timings':
-            return 1;
-          default:
-            return -1;
-        }
+    const weight = (track: {type?: string, forMainFrame?: boolean, weight?: number}): number => {
+      if (track.weight !== undefined) {
+        return track.weight;
       }
-
       switch (track.type) {
         case TimelineModel.TimelineModel.TrackType.Animation:
           return 0;
+        case TimelineModel.TimelineModel.TrackType.Timings:
+          return 1;
         case TimelineModel.TimelineModel.TrackType.UserInteractions:
           return 2;
         case TimelineModel.TimelineModel.TrackType.Console:
@@ -507,7 +506,8 @@
       if (!this.traceEngineData) {
         continue;
       }
-      this.currentLevel = trackOrAppender.appendTrackAtLevel(this.currentLevel);
+      this.currentLevel =
+          trackOrAppender.appendTrackAtLevel(this.currentLevel, this.timelineData(), this.traceEngineData);
     }
     if (this.timelineDataInternal && this.timelineDataInternal.selectedGroup) {
       this.timelineDataInternal.selectedGroup.expanded = true;
@@ -518,6 +518,11 @@
     }
 
     this.flowEventIndexById.clear();
+
+    this.markers.sort((a, b) => a.startTime() - b.startTime());
+    if (this.timelineDataInternal) {
+      this.timelineDataInternal.markers = this.markers;
+    }
   }
 
   private appendLegacyTrackData(track: TimelineModel.TimelineModel.Track): void {
@@ -536,6 +541,18 @@
         break;
       }
 
+      case TimelineModel.TimelineModel.TrackType.Timings: {
+        const style = track.asyncEvents.length > 0 ? this.collapsibleTimingsHeader : this.timingsHeader;
+        const group = this.appendHeader(i18nString(UIStrings.timings), style, true /* selectable */);
+        group.track = track;
+        this.appendPageMetrics();
+        // Leave some space in between page load marks and user timings.
+        this.currentLevel++;
+        this.appendSyncEvents(track, track.events, null, null, eventEntryType, true /* selectable */);
+        this.appendAsyncEventsGroup(track, null, track.asyncEvents, null, eventEntryType, true /* selectable */);
+        break;
+      }
+
       case TimelineModel.TimelineModel.TrackType.Console: {
         this.appendAsyncEventsGroup(
             track, i18nString(UIStrings.console), track.asyncEvents, this.headerLevel1, eventEntryType,
@@ -655,23 +672,9 @@
         result.push(i);
       }
     }
-    result.sort((a, b) => {
-      let firstEvent: TimelineFlameChartEntry|null = this.entryData[a];
-      let secondEvent: TimelineFlameChartEntry|null = this.entryData[b];
-      if (!this.isEntryRegularEvent(firstEvent) || !this.isEntryRegularEvent(secondEvent)) {
-        return 0;
-      }
-      firstEvent = firstEvent instanceof SDK.TracingModel.Event ?
-          firstEvent :
-          (this.compatibilityTracksAppender?.getLegacyEvent(firstEvent) || null);
-      secondEvent = secondEvent instanceof SDK.TracingModel.Event ?
-          secondEvent :
-          (this.compatibilityTracksAppender?.getLegacyEvent(secondEvent) || null);
-      if (!firstEvent || !secondEvent) {
-        return 0;
-      }
-      return SDK.TracingModel.Event.compareStartTime(firstEvent, secondEvent);
-    });
+    result.sort(
+        (a, b) => SDK.TracingModel.Event.compareStartTime(
+            (this.entryData[a] as SDK.TracingModel.Event), (this.entryData[b] as SDK.TracingModel.Event)));
     return result;
   }
 
@@ -729,6 +732,12 @@
           e.setEndTime(frame.endTime);
         }
       }
+
+      if (!isExtension && this.legacyPerformanceModel.timelineModel().isMarkerEvent(e)) {
+        this.markers.push(new TimelineFlameChartMarker(
+            e.startTime, e.startTime - this.legacyTimelineModel.minimumRecordTime(),
+            TimelineUIUtils.markerStyleForEvent(e)));
+      }
       if (!SDK.TracingModel.TracingModel.isFlowPhase(e.phase)) {
         if (!e.endTime && e.phase !== TraceEngine.Types.TraceEvents.Phase.INSTANT) {
           continue;
@@ -767,6 +776,10 @@
       if (openEvents.length) {
         this.entryParent[index] = (openEvents[openEvents.length - 1] as SDK.TracingModel.Event);
       }
+      if (!isExtension && this.legacyPerformanceModel.timelineModel().isMarkerEvent(e)) {
+        // @ts-ignore This is invalid code, but we should keep it for now
+        this.timelineDataInternal.entryTotalTimes[this.entryData.length] = undefined;
+      }
 
       maxStackDepth = Math.max(maxStackDepth, openEvents.length + 1);
       if (e.endTime) {
@@ -824,6 +837,64 @@
     return group;
   }
 
+  private appendPageMetrics(): void {
+    this.entryTypeByLevel[this.currentLevel] = EntryType.Event;
+
+    if (!this.legacyPerformanceModel || !this.legacyTimelineModel) {
+      return;
+    }
+
+    const metricEvents: SDK.TracingModel.Event[] = [];
+    const lcpEvents = [];
+    const timelineModel = this.legacyPerformanceModel.timelineModel();
+    for (const track of this.legacyTimelineModel.tracks()) {
+      for (const event of track.events) {
+        if (!SDK.TracingModel.eventHasPayload(event)) {
+          continue;
+        }
+        if (!timelineModel.isMarkerEvent(event)) {
+          continue;
+        }
+        if (timelineModel.isLCPCandidateEvent(event) || timelineModel.isLCPInvalidateEvent(event)) {
+          lcpEvents.push(event);
+        } else {
+          metricEvents.push(event);
+        }
+      }
+    }
+
+    // Only the LCP event with the largest candidate index is relevant.
+    // Do not record an LCP event if it is an invalidate event.
+    if (lcpEvents.length > 0) {
+      const lcpEventsByNavigationId = new Map<string, SDK.TracingModel.Event>();
+      for (const e of lcpEvents) {
+        const key = e.args['data']['navigationId'];
+        const previousLastEvent = lcpEventsByNavigationId.get(key);
+
+        if (!previousLastEvent || previousLastEvent.args['data']['candidateIndex'] < e.args['data']['candidateIndex']) {
+          lcpEventsByNavigationId.set(key, e);
+        }
+      }
+
+      const latestCandidates = Array.from(lcpEventsByNavigationId.values());
+      const latestEvents =
+          latestCandidates.filter(e => SDK.TracingModel.eventHasPayload(e) && timelineModel.isLCPCandidateEvent(e));
+
+      metricEvents.push(...latestEvents);
+    }
+
+    metricEvents.sort(SDK.TracingModel.Event.compareStartTime);
+    if (this.timelineDataInternal) {
+      const totalTimes = this.timelineDataInternal.entryTotalTimes;
+      for (const event of metricEvents) {
+        this.appendEvent(event, this.currentLevel);
+        totalTimes[totalTimes.length - 1] = Number.NaN;
+      }
+    }
+
+    ++this.currentLevel;
+  }
+
   private appendFrames(): void {
     if (!this.legacyPerformanceModel || !this.timelineDataInternal || !this.legacyTimelineModel) {
       return;
@@ -991,7 +1062,8 @@
       if (this.legacyTimelineModel.isEventTimingInteractionEvent(event)) {
         return this.consoleColorGenerator.colorForID(event.args.data.type + ':' + event.args.data.interactionId);
       }
-      if (event.hasCategory(TimelineModel.TimelineModel.TimelineModelImpl.Category.Console)) {
+      if (event.hasCategory(TimelineModel.TimelineModel.TimelineModelImpl.Category.Console) ||
+          event.hasCategory(TimelineModel.TimelineModel.TimelineModelImpl.Category.UserTiming)) {
         return this.consoleColorGenerator.colorForID(event.name);
       }
       const category = TimelineUIUtils.eventStyle(event).category;
diff --git a/front_end/panels/timeline/TimelinePanel.ts b/front_end/panels/timeline/TimelinePanel.ts
index d558a85..0875838 100644
--- a/front_end/panels/timeline/TimelinePanel.ts
+++ b/front_end/panels/timeline/TimelinePanel.ts
@@ -1263,7 +1263,6 @@
       this.historyManager.addRecording(this.performanceModel, traceParsedData);
     } catch (error) {
       this.recordingFailed(error.message);
-      console.error(error);
     }
   }
 
diff --git a/front_end/panels/timeline/TimingsTrackAppender.ts b/front_end/panels/timeline/TimingsTrackAppender.ts
deleted file mode 100644
index 4811949..0000000
--- a/front_end/panels/timeline/TimingsTrackAppender.ts
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright 2023 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-import * as TraceEngine from '../../models/trace/trace.js';
-import type * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
-
-import {
-  FONT,
-  EntryType,
-  InstantEventVisibleDurationMs,
-  type TimelineFlameChartEntry,
-} from './TimelineFlameChartDataProvider.js';
-import {
-  type CompatibilityTracksAppender,
-  type TrackAppender,
-  type HighlightedEntryInfo,
-  type TrackAppenderName,
-} from './CompatibilityTracksAppender.js';
-import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
-import * as i18n from '../../core/i18n/i18n.js';
-import {TimelineFlameChartMarker} from './TimelineFlameChartView.js';
-import {type TimelineMarkerStyle, TimelineUIUtils} from './TimelineUIUtils.js';
-import * as Common from '../../core/common/common.js';
-import * as TimelineModel from '../../models/timeline_model/timeline_model.js';
-
-const UIStrings = {
-  /**
-   *@description Text in Timeline Flame Chart Data Provider of the Performance panel
-   */
-  timings: 'Timings',
-  /**
-   * @description Text in the Performance panel to show how long was spent in a particular part of the code.
-   * The first placeholder is the total time taken for this node and all children, the second is the self time
-   * (time taken in this node, without children included).
-   *@example {10ms} PH1
-   *@example {10ms} PH2
-   */
-  sSelfS: '{PH1} (self {PH2})',
-};
-
-const str_ = i18n.i18n.registerUIStrings('panels/timeline/TimingsTrackAppender.ts', UIStrings);
-const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
-
-export class TimingsTrackAppender implements TrackAppender {
-  readonly appenderName: TrackAppenderName;
-
-  #colorGenerator: Common.Color.Generator;
-  #compatibilityBuilder: CompatibilityTracksAppender;
-  #flameChartData: PerfUI.FlameChart.TimelineData;
-  #traceParsedData: Readonly<TraceEngine.Handlers.Types.TraceParseData>;
-  #entryData: TimelineFlameChartEntry[];
-  // TODO(crbug.com/1416533)
-  // These are used only for compatibility with the legacy flame chart
-  // architecture of the panel. Once all tracks have been migrated to
-  // use the new engine and flame chart architecture, the reference can
-  // be removed.
-  #legacyEntryTypeByLevel: EntryType[];
-  #legacyTrack: TimelineModel.TimelineModel.Track|null;
-
-  constructor(
-      compatibilityBuilder: CompatibilityTracksAppender, appenderName: TrackAppenderName,
-      flameChartData: PerfUI.FlameChart.TimelineData, traceParsedData: TraceEngine.Handlers.Types.TraceParseData,
-      entryData: TimelineFlameChartEntry[], legacyEntryTypeByLevel: EntryType[],
-      legacyTrack?: TimelineModel.TimelineModel.Track) {
-    this.appenderName = appenderName;
-    this.#compatibilityBuilder = compatibilityBuilder;
-    this.#colorGenerator = new Common.Color.Generator(
-        {
-          min: 30,
-          max: 55,
-          count: undefined,
-        },
-        {min: 70, max: 100, count: 6}, 50, 0.7);
-    this.#flameChartData = flameChartData;
-    this.#traceParsedData = traceParsedData;
-    this.#entryData = entryData;
-    this.#legacyEntryTypeByLevel = legacyEntryTypeByLevel;
-    this.#legacyTrack = legacyTrack || null;
-  }
-
-  /**
-   * Appends into the flame chart data the data corresponding to the
-   * timings track.
-   * @param level the horizontal level of the flame chart events where
-   * the track's events will start being appended.
-   * @returns the first available level to append more data after having
-   * appended the track's events.
-   */
-  appendTrackAtLevel(currentLevel: number): number {
-    this.#appendTrackHeaderAtLevel(currentLevel);
-    const newLevel = this.#appendMarkersAtLevel(currentLevel);
-    // Add some vertical space between page load markers and user
-    // timings by appending timings 2 levels after the markers' level.
-    return this.#appendUserTimingsAtLevel(newLevel + 1);
-  }
-
-  /**
-   * Adds into the flame chart data the header corresponding to the
-   * timings track. A header is added in the shape of a group in the
-   * flame chart data. A group has a predefined style and a reference
-   * to the definition of the legacy track (which should be removed
-   * in the future).
-   * @param currentLevel the flame chart level at which the header is
-   * appended.
-   */
-  #appendTrackHeaderAtLevel(currentLevel: number): void {
-    const trackIsCollapsible = this.#traceParsedData.UserTimings.performanceMeasures.length > 0;
-
-    const style: PerfUI.FlameChart.GroupStyle = {
-      padding: 4,
-      height: 17,
-      collapsible: trackIsCollapsible,
-      color: ThemeSupport.ThemeSupport.instance().getComputedValue('--color-text-primary'),
-      backgroundColor: ThemeSupport.ThemeSupport.instance().getComputedValue('--color-background'),
-      font: FONT,
-      nestingLevel: 0,
-      shareHeaderLine: true,
-      useFirstLineForOverview: true,
-    };
-    const group =
-        ({startLevel: currentLevel, name: i18nString(UIStrings.timings), style: style, selectable: true} as
-         PerfUI.FlameChart.Group);
-    this.#flameChartData.groups.push(group);
-    group.track = this.#legacyTrack;
-  }
-
-  /**
-   * Adds into the flame chart data the trace events corresponding
-   * to page load markers (LCP, FCP, L, etc.). These are taken straight
-   * from the PageLoadMetrics handler.
-   * @param currentLevel the flame chart level from which markers will
-   * be appended.
-   * @returns the next level after the last occupied by the appended
-   * page load markers (the first available level to append more data).
-   */
-  #appendMarkersAtLevel(currentLevel: number): number {
-    const totalTimes = this.#flameChartData.entryTotalTimes;
-    const markers = this.#traceParsedData.PageLoadMetrics.allMarkerEvents;
-    markers.forEach(marker => {
-      const index = this.#appendEventAtLevel(marker, currentLevel);
-      totalTimes[index] = Number.NaN;
-    });
-    const minTimeMs = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(this.#traceParsedData.Meta.traceBounds.min);
-    const flameChartMarkers = markers.map(marker => {
-      const startTimeMs = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(marker.ts);
-      return new TimelineFlameChartMarker(startTimeMs, startTimeMs - minTimeMs, this.markerStyleForEvent(marker));
-    });
-    this.#flameChartData.markers.push(...flameChartMarkers);
-    return ++currentLevel;
-  }
-
-  /**
-   * Adds into the flame chart data the trace events corresponding to
-   * user timings (performance.measure and performance.mark). These are
-   * taken straight from the UserTimings handler.
-   * @param currentLevel the flame chart level from which user timings will
-   * be appended.
-   * @returns the next level after the last occupied by the appended
-   * timings (the first available level to append more data).
-   */
-  #appendUserTimingsAtLevel(currentLevel: number): number {
-    let newLevel = currentLevel;
-
-    for (const userMark of this.#traceParsedData.UserTimings.performanceMarks) {
-      this.#appendEventAtLevel(userMark, newLevel);
-    }
-    newLevel++;
-    newLevel = this.#appendTimingsAtLevel(newLevel);
-    return newLevel;
-  }
-
-  /**
-   * Adds into the flame chart data the trace events dispatched by the
-   * performace.measure API. These events are taken from the UserTimings
-   * handler.
-   * @param currentLevel the flame chart level from which timings will
-   * be appended.
-   * @returns the next level after the last occupied by the appended
-   * timings (the first available level to append more data).
-   */
-
-  #appendTimingsAtLevel(currentLevel: number): number {
-    const timings = this.#traceParsedData.UserTimings.performanceMeasures;
-    const lastUsedTimeByLevel: number[] = [];
-    for (let i = 0; i < timings.length; ++i) {
-      const event = timings[i];
-      const eventAsLegacy = this.#compatibilityBuilder.getLegacyEvent(event);
-      // Default styles are globally defined for each event name. Some
-      // events are hidden by default.
-      const visibleNames = new Set(TimelineUIUtils.visibleTypes());
-      const eventIsVisible = eventAsLegacy &&
-          visibleNames.has(TimelineModel.TimelineModelFilter.TimelineVisibleEventsFilter.eventType(eventAsLegacy));
-      if (!eventIsVisible) {
-        continue;
-      }
-      const startTime = event.ts;
-      let level;
-      // look vertically for the first level where this event fits,
-      // that is, where it wouldn't overlap with other events.
-      for (level = 0; level < lastUsedTimeByLevel.length && lastUsedTimeByLevel[level] > startTime; ++level) {
-      }
-      this.#appendEventAtLevel(event, currentLevel + level);
-      const endTime = event.ts + (event.dur || 0);
-      lastUsedTimeByLevel[level] = endTime;
-    }
-    this.#legacyEntryTypeByLevel.length = currentLevel + lastUsedTimeByLevel.length;
-    // Set the entry type to TrackAppender for all the levels occupied by the appended timings.
-    this.#legacyEntryTypeByLevel.fill(EntryType.TrackAppender, currentLevel);
-    return currentLevel + lastUsedTimeByLevel.length;
-  }
-
-  /**
-   * Adds an event to the flame chart data at a defined level.
-   * @returns the position occupied by the new event in the entryData
-   * array, which contains all the events in the timeline.
-   */
-  #appendEventAtLevel(event: TraceEngine.Types.TraceEvents.TraceEventData, level: number): number {
-    this.#compatibilityBuilder.registerTrackForLevel(level, this);
-    const index = this.#entryData.length;
-    this.#entryData.push(event);
-    this.#legacyEntryTypeByLevel[level] = EntryType.TrackAppender;
-    this.#flameChartData.entryLevels[index] = level;
-    this.#flameChartData.entryStartTimes[index] = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(event.ts);
-    const msDuration = event.dur ||
-        TraceEngine.Helpers.Timing.millisecondsToMicroseconds(
-            InstantEventVisibleDurationMs as TraceEngine.Types.Timing.MilliSeconds);
-    this.#flameChartData.entryTotalTimes[index] = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(msDuration);
-    return index;
-  }
-
-  /*
-    ------------------------------------------------------------------------------------
-     The following methods  are invoked by the flame chart renderer to query features about
-     events on rendering.
-    ------------------------------------------------------------------------------------
-  */
-
-  /**
-   * Gets the style for a page load marker event.
-   */
-  markerStyleForEvent(markerEvent: TraceEngine.Types.TraceEvents.PageLoadEvent): TimelineMarkerStyle {
-    const tallMarkerDashStyle = [6, 4];
-    let title = '';
-    let color = 'grey';
-    if (TraceEngine.Types.TraceEvents.isTraceEventMarkDOMContent(markerEvent)) {
-      color = '#0867CB';
-      title = TraceEngine.Handlers.ModelHandlers.PageLoadMetrics.MetricName.DCL;
-    }
-    if (TraceEngine.Types.TraceEvents.isTraceEventMarkLoad(markerEvent)) {
-      color = '#B31412';
-      title = TraceEngine.Handlers.ModelHandlers.PageLoadMetrics.MetricName.L;
-    }
-    if (TraceEngine.Types.TraceEvents.isTraceEventFirstPaint(markerEvent)) {
-      color = '#228847';
-      title = TraceEngine.Handlers.ModelHandlers.PageLoadMetrics.MetricName.FP;
-    }
-    if (TraceEngine.Types.TraceEvents.isTraceEventFirstContentfulPaint(markerEvent)) {
-      color = '#1A6937';
-      title = TraceEngine.Handlers.ModelHandlers.PageLoadMetrics.MetricName.FCP;
-    }
-    if (TraceEngine.Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(markerEvent)) {
-      color = '#1A3422';
-      title = TraceEngine.Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP;
-    }
-    return {
-      title: title,
-      dashStyle: tallMarkerDashStyle,
-      lineWidth: 0.5,
-      color: color,
-      tall: true,
-      lowPriority: false,
-    };
-  }
-
-  /**
-   * Gets the color an event added by this appender should be rendered with.
-   */
-  colorForEvent(event: TraceEngine.Types.TraceEvents.TraceEventData): string {
-    if (TraceEngine.Handlers.ModelHandlers.PageLoadMetrics.eventIsPageLoadEvent(event)) {
-      return this.markerStyleForEvent(event).color;
-    }
-    // User timings.
-    return this.#colorGenerator.colorForID(event.name);
-  }
-
-  /**
-   * Gets the title an event added by this appender should be rendered with.
-   */
-  titleForEvent(event: TraceEngine.Types.TraceEvents.TraceEventData): string {
-    const metricsHandler = TraceEngine.Handlers.ModelHandlers.PageLoadMetrics;
-    if (metricsHandler.eventIsPageLoadEvent(event)) {
-      switch (event.name) {
-        case 'MarkDOMContent':
-          return metricsHandler.MetricName.DCL;
-        case 'MarkLoad':
-          return metricsHandler.MetricName.L;
-        case 'firstContentfulPaint':
-          return metricsHandler.MetricName.FCP;
-        case 'firstPaint':
-          return metricsHandler.MetricName.FP;
-        case 'largestContentfulPaint::Candidate':
-          return metricsHandler.MetricName.LCP;
-        default:
-          return event.name;
-      }
-    }
-    return event.name;
-  }
-
-  /**
-   * Returns the info shown when an event added by this appender
-   * is hovered in the timeline.
-   */
-  highlightedEntryInfo(event: TraceEngine.Types.TraceEvents.TraceEventData): HighlightedEntryInfo {
-    const title = this.titleForEvent(event);
-    const totalTime = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(
-        (event.dur || 0) as TraceEngine.Types.Timing.MicroSeconds);
-    const selfTime = totalTime;
-    if (totalTime === TraceEngine.Types.Timing.MilliSeconds(0)) {
-      return {title, formattedTime: ''};
-    }
-    const minSelfTimeSignificance = 1e-6;
-    const time = Math.abs(totalTime - selfTime) > minSelfTimeSignificance && selfTime > minSelfTimeSignificance ?
-        i18nString(UIStrings.sSelfS, {
-          PH1: i18n.TimeUtilities.millisToString(totalTime, true),
-          PH2: i18n.TimeUtilities.millisToString(selfTime, true),
-        }) :
-        i18n.TimeUtilities.millisToString(totalTime, true);
-    return {title, formattedTime: time};
-  }
-}
diff --git a/front_end/panels/timeline/timeline.ts b/front_end/panels/timeline/timeline.ts
index b1a50dc..b33d43d 100644
--- a/front_end/panels/timeline/timeline.ts
+++ b/front_end/panels/timeline/timeline.ts
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 import * as CLSLinkifier from './CLSLinkifier.js';
-import * as CompatibilityTracksAppender from './CompatibilityTracksAppender.js';
 import * as CountersGraph from './CountersGraph.js';
 import * as EventsTimelineTreeView from './EventsTimelineTreeView.js';
 import * as ExtensionTracingSession from './ExtensionTracingSession.js';
@@ -22,13 +21,11 @@
 import * as TimelinePanel from './TimelinePanel.js';
 import * as TimelineTreeView from './TimelineTreeView.js';
 import * as TimelineUIUtils from './TimelineUIUtils.js';
-import * as TimingsTrackAppender from './TimingsTrackAppender.js';
 import * as UIDevtoolsController from './UIDevtoolsController.js';
 import * as UIDevtoolsUtils from './UIDevtoolsUtils.js';
 
 export {
   CLSLinkifier,
-  CompatibilityTracksAppender,
   CountersGraph,
   EventsTimelineTreeView,
   ExtensionTracingSession,
@@ -47,7 +44,6 @@
   TimelinePanel,
   TimelineTreeView,
   TimelineUIUtils,
-  TimingsTrackAppender,
   UIDevtoolsController,
   UIDevtoolsUtils,
 };
diff --git a/front_end/ui/legacy/components/perf_ui/BUILD.gn b/front_end/ui/legacy/components/perf_ui/BUILD.gn
index 91f5db5..c80e3da 100644
--- a/front_end/ui/legacy/components/perf_ui/BUILD.gn
+++ b/front_end/ui/legacy/components/perf_ui/BUILD.gn
@@ -73,7 +73,7 @@
 
   visibility = [
     ":*",
-    "../../../../../test/unittests/*",
+    "../../../../../test/unittests/front_end/ui/legacy/components/perf_ui/*",
     "../../../../panels/layer_viewer/*",
     "../../../../panels/media/*",
     "../../../../panels/network/*",
diff --git a/test/unittests/fixtures/traces/BUILD.gn b/test/unittests/fixtures/traces/BUILD.gn
index 23238d6..670eca7 100644
--- a/test/unittests/fixtures/traces/BUILD.gn
+++ b/test/unittests/fixtures/traces/BUILD.gn
@@ -39,7 +39,6 @@
     "style-invalidation-change-attribute.json.gz",
     "style-invalidation-change-id.json.gz",
     "threejs-gpu.json.gz",
-    "timings-track.json.gz",
     "user-timings-complex.json.gz",
     "user-timings.json.gz",
     "web-dev.json.gz",
diff --git a/test/unittests/fixtures/traces/timings-track.json.gz b/test/unittests/fixtures/traces/timings-track.json.gz
deleted file mode 100644
index fe1c54e..0000000
--- a/test/unittests/fixtures/traces/timings-track.json.gz
+++ /dev/null
Binary files differ
diff --git a/test/unittests/front_end/panels/timeline/BUILD.gn b/test/unittests/front_end/panels/timeline/BUILD.gn
index 5268d39..eb5d9a4 100644
--- a/test/unittests/front_end/panels/timeline/BUILD.gn
+++ b/test/unittests/front_end/panels/timeline/BUILD.gn
@@ -19,6 +19,5 @@
     "../../../../../front_end/models/trace:bundle",
     "../../../../../front_end/panels/timeline:bundle",
     "../../helpers",
-    "./track_appenders",
   ]
 }
diff --git a/test/unittests/front_end/panels/timeline/track_appenders/BUILD.gn b/test/unittests/front_end/panels/timeline/track_appenders/BUILD.gn
deleted file mode 100644
index a7fb949..0000000
--- a/test/unittests/front_end/panels/timeline/track_appenders/BUILD.gn
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2023 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("../../../../../../third_party/typescript/typescript.gni")
-
-ts_library("track_appenders") {
-  testonly = true
-  sources = [ "TimingsTrackAppender_test.ts" ]
-
-  deps = [
-    "../../../../../../front_end/core/sdk:bundle",
-    "../../../../../../front_end/models/timeline_model:bundle",
-    "../../../../../../front_end/panels/timeline:bundle",
-    "../../../../../../front_end/ui/legacy/components/perf_ui:bundle",
-    "../../../helpers",
-  ]
-}
diff --git a/test/unittests/front_end/panels/timeline/track_appenders/TimingsTrackAppender_test.ts b/test/unittests/front_end/panels/timeline/track_appenders/TimingsTrackAppender_test.ts
deleted file mode 100644
index 987fc0e..0000000
--- a/test/unittests/front_end/panels/timeline/track_appenders/TimingsTrackAppender_test.ts
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2023 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import * as TraceModel from '../../../../../../front_end/models/trace/trace.js';
-import * as Timeline from '../../../../../../front_end/panels/timeline/timeline.js';
-import * as PerfUI from '../../../../../../front_end/ui/legacy/components/perf_ui/perf_ui.js';
-import {describeWithEnvironment} from '../../../helpers/EnvironmentHelpers.js';
-import {traceModelFromTraceFile} from '../../../helpers/TimelineHelpers.js';
-import {loadModelDataFromTraceFile} from '../../../helpers/TraceHelpers.js';
-
-import type * as TimelineModel from '../../../../../../front_end/models/timeline_model/timeline_model.js';
-
-const {assert} = chai;
-
-function initTrackAppender(
-    flameChartData: PerfUI.FlameChart.TimelineData, traceParsedData: TraceModel.Handlers.Types.TraceParseData,
-    entryData: Timeline.TimelineFlameChartDataProvider.TimelineFlameChartEntry[],
-    entryTypeByLevel: Timeline.TimelineFlameChartDataProvider.EntryType[],
-    timelineModel: TimelineModel.TimelineModel.TimelineModelImpl): Timeline.TimingsTrackAppender.TimingsTrackAppender {
-  const compatibilityTracksAppender = new Timeline.CompatibilityTracksAppender.CompatibilityTracksAppender(
-      flameChartData, traceParsedData, entryData, entryTypeByLevel, timelineModel);
-  return compatibilityTracksAppender.timingsTrackAppender();
-}
-
-describeWithEnvironment('TimingTrackAppender', () => {
-  let traceParsedData: TraceModel.Handlers.Types.TraceParseData;
-  let timelineModel: TimelineModel.TimelineModel.TimelineModelImpl;
-  let timingsTrackAppender: Timeline.TimingsTrackAppender.TimingsTrackAppender;
-  let entryData: Timeline.TimelineFlameChartDataProvider.TimelineFlameChartEntry[] = [];
-  let flameChartData = new PerfUI.FlameChart.TimelineData([], [], [], []);
-  let entryTypeByLevel: Timeline.TimelineFlameChartDataProvider.EntryType[] = [];
-  beforeEach(async () => {
-    traceParsedData = await loadModelDataFromTraceFile('timings-track.json.gz');
-    timelineModel = (await traceModelFromTraceFile('timings-track.json.gz')).timelineModel;
-    timingsTrackAppender =
-        initTrackAppender(flameChartData, traceParsedData, entryData, entryTypeByLevel, timelineModel);
-    timingsTrackAppender.appendTrackAtLevel(0);
-  });
-  afterEach(() => {
-    entryData = [];
-    flameChartData = new PerfUI.FlameChart.TimelineData([], [], [], []);
-    entryTypeByLevel = [];
-  });
-
-  describe('appendTrackAtLevel', () => {
-    it('marks all levels used by the track with the `TrackAppender` type', () => {
-      // Five levels should be taken: 1 for page load marks, 1 added for spacing
-      // between page load marks and user timings and 3 used by user timings.
-      const levelCount = 5;
-      assert.strictEqual(entryTypeByLevel.length, levelCount);
-      const allEntriesAreTrackAppender =
-          entryTypeByLevel.every(type => type === Timeline.TimelineFlameChartDataProvider.EntryType.TrackAppender);
-      assert.isTrue(allEntriesAreTrackAppender);
-    });
-    it('creates a flamechart group for the timings track', () => {
-      assert.strictEqual(flameChartData.groups.length, 1);
-      assert.strictEqual(flameChartData.groups[0].name, 'Timings');
-    });
-    it('populates the markers array in ascendent order', () => {
-      const traceMarkers = traceParsedData.PageLoadMetrics.allMarkerEvents;
-      assert.strictEqual(flameChartData.markers.length, traceMarkers.length);
-      for (let i = 1; i < flameChartData.markers.length; i++) {
-        assert.isAtLeast(flameChartData.markers[i].startTime(), flameChartData.markers[i - 1].startTime());
-      }
-    });
-    it('creates a TimelineFlameChartMarker for each page load marker event in a trace', () => {
-      const traceMarkers = traceParsedData.PageLoadMetrics.allMarkerEvents;
-      assert.strictEqual(flameChartData.markers.length, traceMarkers.length);
-      for (const traceMarker of traceMarkers) {
-        const markerTimeMs = TraceModel.Helpers.Timing.microSecondsToMilliseconds(traceMarker.ts);
-        const flameChartMarker =
-            flameChartData.markers.find(flameChartMarker => flameChartMarker.startTime() === markerTimeMs);
-        assert.isDefined(flameChartMarker);
-      }
-      assert.strictEqual(flameChartData.markers.length, traceMarkers.length);
-    });
-    it('adds start times correctly', () => {
-      const traceMarkers = traceParsedData.PageLoadMetrics.allMarkerEvents;
-      const performanceMarks = traceParsedData.UserTimings.performanceMarks;
-      const performanceMeasures = traceParsedData.UserTimings.performanceMeasures;
-      for (const event of [...traceMarkers, ...performanceMarks, ...performanceMeasures]) {
-        const markerIndex = entryData.indexOf(event);
-        assert.isDefined(markerIndex);
-        assert.strictEqual(
-            flameChartData.entryStartTimes[markerIndex],
-            TraceModel.Helpers.Timing.microSecondsToMilliseconds(event.ts));
-      }
-    });
-    it('adds total times correctly', () => {
-      const traceMarkers = traceParsedData.PageLoadMetrics.allMarkerEvents;
-      const performanceMarks = traceParsedData.UserTimings.performanceMarks;
-      const performanceMeasures = traceParsedData.UserTimings.performanceMeasures;
-      for (const event of [...traceMarkers, ...performanceMarks, ...performanceMeasures]) {
-        const markerIndex = entryData.indexOf(event);
-        assert.isDefined(markerIndex);
-        if (TraceModel.Handlers.ModelHandlers.PageLoadMetrics.isTraceEventMarkerEvent(event)) {
-          assert.isNaN(flameChartData.entryTotalTimes[markerIndex]);
-          continue;
-        }
-        const expectedTotalTimeForEvent = event.dur ?
-            TraceModel.Helpers.Timing.microSecondsToMilliseconds(event.dur as TraceModel.Types.Timing.MicroSeconds) :
-            Timeline.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs;
-        assert.strictEqual(flameChartData.entryTotalTimes[markerIndex], expectedTotalTimeForEvent);
-      }
-    });
-  });
-
-  describe('colorForEvent and titleForEvent', () => {
-    it('returns the correct color and title for page load markers', () => {
-      const traceMarkers = traceParsedData.PageLoadMetrics.allMarkerEvents;
-      const firstContentfulPaint = traceMarkers.find(marker => marker.name === 'firstContentfulPaint');
-      const markLoad = traceMarkers.find(marker => marker.name === 'MarkLoad');
-      const markDOMContent = traceMarkers.find(marker => marker.name === 'MarkDOMContent');
-      const firstPaint = traceMarkers.find(marker => marker.name === 'firstPaint');
-      const largestContentfulPaint = traceMarkers.find(marker => marker.name === 'largestContentfulPaint::Candidate');
-
-      if (firstContentfulPaint === undefined || markLoad === undefined || markDOMContent === undefined ||
-          firstPaint === undefined || largestContentfulPaint === undefined) {
-        throw new Error('A metric was not found');
-      }
-
-      assert.strictEqual(timingsTrackAppender.colorForEvent(firstContentfulPaint), '#1A6937');
-      assert.strictEqual(
-          timingsTrackAppender.titleForEvent(firstContentfulPaint),
-          TraceModel.Handlers.ModelHandlers.PageLoadMetrics.MetricName.FCP);
-
-      assert.strictEqual(timingsTrackAppender.colorForEvent(markLoad), '#B31412');
-      assert.strictEqual(
-          timingsTrackAppender.titleForEvent(markLoad), TraceModel.Handlers.ModelHandlers.PageLoadMetrics.MetricName.L);
-
-      assert.strictEqual(timingsTrackAppender.colorForEvent(markDOMContent), '#0867CB');
-      assert.strictEqual(
-          timingsTrackAppender.titleForEvent(markDOMContent),
-          TraceModel.Handlers.ModelHandlers.PageLoadMetrics.MetricName.DCL);
-
-      assert.strictEqual(timingsTrackAppender.colorForEvent(firstPaint), '#228847');
-      assert.strictEqual(
-          timingsTrackAppender.titleForEvent(firstPaint),
-          TraceModel.Handlers.ModelHandlers.PageLoadMetrics.MetricName.FP);
-
-      assert.strictEqual(timingsTrackAppender.colorForEvent(largestContentfulPaint), '#1A3422');
-      assert.strictEqual(
-          timingsTrackAppender.titleForEvent(largestContentfulPaint),
-          TraceModel.Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP);
-    });
-
-    it('returns the correct title for user timings', () => {
-      const traceMarkers = traceParsedData.UserTimings.performanceMarks;
-      for (const mark of traceMarkers) {
-        assert.strictEqual(timingsTrackAppender.titleForEvent(mark), mark.name);
-      }
-    });
-  });
-  describe('highlightedEntryInfo', () => {
-    it('returns the info for a entries with no duration correctly', () => {
-      const traceMarkers = traceParsedData.PageLoadMetrics.allMarkerEvents;
-      const performanceMarks = traceParsedData.UserTimings.performanceMarks;
-      const allTrackEvents = [...traceMarkers, ...performanceMarks];
-      for (const event of allTrackEvents) {
-        const highlightedEntryInfo = timingsTrackAppender.highlightedEntryInfo(event);
-        if (TraceModel.Handlers.ModelHandlers.PageLoadMetrics.isTraceEventMarkerEvent(event)) {
-          assert.strictEqual(highlightedEntryInfo.formattedTime, '');
-        }
-      }
-    });
-    it('returns the info for a performance.measure calls correctly', () => {
-      const performanceMeasures = traceParsedData.UserTimings.performanceMeasures;
-      const highlightedEntryInfo = timingsTrackAppender.highlightedEntryInfo(performanceMeasures[0]);
-      // The i18n encondes spaces using the u00A0 unicode character.
-      assert.strictEqual(highlightedEntryInfo.formattedTime, ('500.00\u00A0ms'));
-    });
-  });
-});