UNPKG

chrome-devtools-frontend

Version:
282 lines (223 loc) • 11.1 kB
// 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 Trace from '../../models/trace/trace.js'; import * as TraceBounds from '../../services/trace_bounds/trace_bounds.js'; import * as TimelineComponents from './components/components.js'; function nestedBreadcrumbs(): { initialBreadcrumb: Trace.Types.File.Breadcrumb, breadcrumb1: Trace.Types.File.Breadcrumb, breadcrumb2: Trace.Types.File.Breadcrumb, } { const initialTraceWindow: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(1000), max: Trace.Types.Timing.Micro(10000), range: Trace.Types.Timing.Micro(9000), }; const traceWindow1: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(3000), max: Trace.Types.Timing.Micro(9000), range: Trace.Types.Timing.Micro(6000), }; const traceWindow2: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(4000), max: Trace.Types.Timing.Micro(6000), range: Trace.Types.Timing.Micro(2000), }; const breadcrumb2: Trace.Types.File.Breadcrumb = { window: traceWindow2, child: null, }; const breadcrumb1: Trace.Types.File.Breadcrumb = { window: traceWindow1, child: breadcrumb2, }; const initialBreadcrumb: Trace.Types.File.Breadcrumb = { window: initialTraceWindow, child: breadcrumb1, }; return { initialBreadcrumb, breadcrumb1, breadcrumb2, }; } describe('Timeline breadcrumbs', () => { it('can create breadcrumbs', () => { const {initialBreadcrumb, breadcrumb1, breadcrumb2} = nestedBreadcrumbs(); TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); crumbs.add(breadcrumb1.window); crumbs.add(breadcrumb2.window); assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1, breadcrumb2]); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb2); }); it('can activate breadcrumbs', () => { const {initialBreadcrumb, breadcrumb1, breadcrumb2} = nestedBreadcrumbs(); TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); crumbs.add(breadcrumb1.window); crumbs.add(breadcrumb2.window); // Last added breadcrumb should be active assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb2); // Make sure breadcrumb 1 can be actived crumbs.setActiveBreadcrumb(breadcrumb1, { removeChildBreadcrumbs: false, updateVisibleWindow: true, }); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb1); // Make sure initial breadcrumb can be actived crumbs.setActiveBreadcrumb(initialBreadcrumb, { removeChildBreadcrumbs: false, updateVisibleWindow: true, }); assert.deepEqual(crumbs.activeBreadcrumb, initialBreadcrumb); // No breadcrumb were removed assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1, breadcrumb2]); }); it('can overwrite child breadcrumbs when a new one is added', () => { const {initialBreadcrumb, breadcrumb1, breadcrumb2} = nestedBreadcrumbs(); TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); crumbs.add(breadcrumb1.window); crumbs.add(breadcrumb2.window); // Last added breadcrumb should be active assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb2); // Currently, breadcrumbs structure is: // initialBreadcrumb -> breadcrumb1 -> breadcrumb2(activated) assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1, breadcrumb2]); // In this test we want to check if the children of the activated breadcrumb will be overwrritten if a new one is added // Make the initial breadcrumb active: // initialBreadcrumb(activated) -> breadcrumb1 -> breadcrumb2 crumbs.setActiveBreadcrumb(initialBreadcrumb, { removeChildBreadcrumbs: false, updateVisibleWindow: true, }); assert.deepEqual(crumbs.activeBreadcrumb, initialBreadcrumb); // Add a new breadcrumb const traceWindow4: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(2000), max: Trace.Types.Timing.Micro(5000), range: Trace.Types.Timing.Micro(3000), }; const breadcrumb4: Trace.Types.File.Breadcrumb = { window: traceWindow4, child: null, }; crumbs.add(traceWindow4); // Breadcrumbs should look like this: // initialBreadcrumb -> breadcrumb4 assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb4]); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb4); }); it('can remove breadcrumbs', () => { const {initialBreadcrumb, breadcrumb1, breadcrumb2} = nestedBreadcrumbs(); TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); crumbs.add(breadcrumb1.window); crumbs.add(breadcrumb2.window); assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1, breadcrumb2]); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb2); crumbs.setActiveBreadcrumb(breadcrumb1, { removeChildBreadcrumbs: true, updateVisibleWindow: true, }); assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1]); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb1); }); it('can not create a breadcrumb equal to the parent breadcrumb', () => { const {initialBreadcrumb} = nestedBreadcrumbs(); assert.throws(() => { TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); const equalTraceWindow: Trace.Types.Timing.TraceWindowMicro = { min: initialBreadcrumb.window.min, max: initialBreadcrumb.window.max, range: initialBreadcrumb.window.range, }; crumbs.add(equalTraceWindow); }, 'Can not add a breadcrumb that is equal to or is outside of the parent breadcrumb TimeWindow'); }); it('can create breadcrumbs with equal start or end as the parent breadcrumb', () => { const initialTraceWindow: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(1000), max: Trace.Types.Timing.Micro(10000), range: Trace.Types.Timing.Micro(9000), }; TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialTraceWindow); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialTraceWindow); const traceWindow1: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(1000), max: Trace.Types.Timing.Micro(9000), range: Trace.Types.Timing.Micro(8000), }; const traceWindow2: Trace.Types.Timing.TraceWindowMicro = { min: Trace.Types.Timing.Micro(3000), max: Trace.Types.Timing.Micro(9000), range: Trace.Types.Timing.Micro(6000), }; crumbs.add(traceWindow1); crumbs.add(traceWindow2); const breadcrumb2: Trace.Types.File.Breadcrumb = { window: traceWindow2, child: null, }; const breadcrumb1: Trace.Types.File.Breadcrumb = { window: traceWindow1, child: breadcrumb2, }; const initialBreadcrumb: Trace.Types.File.Breadcrumb = { window: initialTraceWindow, child: breadcrumb1, }; assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1, breadcrumb2]); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb2); }); it('correctly sets the last breadrumb and trace bound window when a new initial breadcrumb is provided', () => { const {initialBreadcrumb, breadcrumb1, breadcrumb2} = nestedBreadcrumbs(); TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); crumbs.setInitialBreadcrumbFromLoadedModifications(initialBreadcrumb); assert.deepEqual( TimelineComponents.Breadcrumbs.flattenBreadcrumbs(initialBreadcrumb), [initialBreadcrumb, breadcrumb1, breadcrumb2]); assert.deepEqual(crumbs.activeBreadcrumb, breadcrumb2); // Make sure the trace bounds were correctly set to the last breadcrumb bounds assert.deepEqual( TraceBounds.TraceBounds.BoundsManager.instance().state()?.micro.minimapTraceBounds, breadcrumb2.window); // Make sure the TimelineVisibleWindow was correctly set to the last breadcrumb bounds assert.deepEqual( TraceBounds.TraceBounds.BoundsManager.instance().state()?.micro.minimapTraceBounds, breadcrumb2.window); }); it('it will not update the trace window when activating a breadcrumb if the option is set to false', () => { const {initialBreadcrumb, breadcrumb1, breadcrumb2} = nestedBreadcrumbs(); TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true}).resetWithNewBounds(initialBreadcrumb.window); const crumbs = new TimelineComponents.Breadcrumbs.Breadcrumbs(initialBreadcrumb.window); crumbs.setInitialBreadcrumbFromLoadedModifications(initialBreadcrumb); // Make sure the trace bounds were correctly set to the last breadcrumb bounds assert.deepEqual( TraceBounds.TraceBounds.BoundsManager.instance().state()?.micro.minimapTraceBounds, breadcrumb2.window); // Now activate breadcrumb1, but tell it not to update the bounds crumbs.setActiveBreadcrumb(breadcrumb1, {removeChildBreadcrumbs: false, updateVisibleWindow: false}); // The visible window is still breadcrumb2. assert.deepEqual( TraceBounds.TraceBounds.BoundsManager.instance().state()?.micro.timelineTraceWindow, breadcrumb2.window); // Now activate breadcrumb1, but ask it to update the bounds this time crumbs.setActiveBreadcrumb(breadcrumb1, {removeChildBreadcrumbs: false, updateVisibleWindow: true}); // Now the window has changed. assert.deepEqual( TraceBounds.TraceBounds.BoundsManager.instance().state()?.micro.timelineTraceWindow, breadcrumb1.window); }); });