chrome-devtools-frontend
Version:
Chrome DevTools UI
185 lines (166 loc) • 7.31 kB
text/typescript
// Copyright 2024 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 {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
import {microsecondsTraceWindow} from '../../testing/TraceHelpers.js';
import type * as Overlays from './overlays/overlays.js';
import * as Timeline from './timeline.js';
const {
getAnnotationEntries,
getAnnotationWindow,
} = Timeline.AnnotationHelpers;
describe('AnnotationHelpers', () => {
describe('getAnnotationEntries', () => {
const FAKE_ENTRY_1 = {} as unknown as Trace.Types.Events.Event;
const FAKE_ENTRY_2 = {} as unknown as Trace.Types.Events.Event;
it('returns the entry for an ENTRY_LABEL', async () => {
const annotation: Trace.Types.File.EntryLabelAnnotation = {
entry: FAKE_ENTRY_1,
label: 'Hello world',
type: 'ENTRY_LABEL',
};
assert.deepEqual(getAnnotationEntries(annotation), [FAKE_ENTRY_1]);
});
it('returns an empty array for a range', async () => {
const annotation: Trace.Types.File.TimeRangeAnnotation = {
bounds: Trace.Helpers.Timing.traceWindowFromMicroSeconds(
Trace.Types.Timing.Micro(0),
Trace.Types.Timing.Micro(10),
),
type: 'TIME_RANGE',
label: 'Hello world',
};
assert.lengthOf(getAnnotationEntries(annotation), 0);
});
it('returns both entries for a link', async () => {
const annotation: Trace.Types.File.EntriesLinkAnnotation = {
type: 'ENTRIES_LINK',
state: Trace.Types.File.EntriesLinkState.CONNECTED,
entryFrom: FAKE_ENTRY_1,
entryTo: FAKE_ENTRY_2,
};
assert.deepEqual(getAnnotationEntries(annotation), [FAKE_ENTRY_1, FAKE_ENTRY_2]);
});
});
describe('getAnnotationWindow', () => {
const FAKE_ENTRY_1 = {
ts: 1,
dur: 10,
} as unknown as Trace.Types.Events.Event;
const FAKE_ENTRY_2 = {
ts: 20,
dur: 5,
} as unknown as Trace.Types.Events.Event;
it('returns the entry window for an ENTRY_LABEL', async () => {
const annotation: Trace.Types.File.EntryLabelAnnotation = {
entry: FAKE_ENTRY_1,
label: 'Hello world',
type: 'ENTRY_LABEL',
};
assert.deepEqual(getAnnotationWindow(annotation), {
min: 1,
max: 11,
range: 10,
});
});
it('returns the bounds for a TIME_RANGE', async () => {
const annotation: Trace.Types.File.TimeRangeAnnotation = {
bounds: Trace.Helpers.Timing.traceWindowFromMicroSeconds(
Trace.Types.Timing.Micro(0),
Trace.Types.Timing.Micro(10),
),
type: 'TIME_RANGE',
label: 'Hello world',
};
assert.deepEqual(getAnnotationWindow(annotation), {
min: 0,
max: 10,
range: 10,
});
});
it('returns the bounds based on the start and end entry for an ENTRIES_LINK', async () => {
const annotation: Trace.Types.File.EntriesLinkAnnotation = {
type: 'ENTRIES_LINK',
state: Trace.Types.File.EntriesLinkState.CONNECTED,
entryFrom: FAKE_ENTRY_1,
entryTo: FAKE_ENTRY_2,
};
assert.deepEqual(getAnnotationWindow(annotation), {
min: 1,
max: 25,
range: 24,
});
});
});
describeWithEnvironment('Aria Announcement', () => {
const {ariaAnnouncementForModifiedEvent} = Timeline.AnnotationHelpers;
const FAKE_ENTRY_1 = {
name: 'fake-one',
ts: 1,
dur: 10,
} as unknown as Trace.Types.Events.Event;
const FAKE_ENTRY_2 = {
name: 'fake-two',
ts: 10,
dur: 10,
} as unknown as Trace.Types.Events.Event;
it('returns text for an annotation being removed', () => {
const overlay: Overlays.Overlays.EntryLabel = {type: 'ENTRY_LABEL', entry: FAKE_ENTRY_1, label: 'Hello world'};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(overlay, 'Remove');
const text = ariaAnnouncementForModifiedEvent(event);
assert.strictEqual(text, 'The entry label annotation has been removed');
});
it('returns text for entering the edit state on a label', () => {
const overlay: Overlays.Overlays.EntryLabel = {type: 'ENTRY_LABEL', entry: FAKE_ENTRY_1, label: 'Hello world'};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(overlay, 'EnterLabelEditState');
const text = ariaAnnouncementForModifiedEvent(event);
assert.strictEqual(text, 'Editing the annotation label text');
});
it('returns text for an annotation being added', async () => {
const overlay: Overlays.Overlays.EntryLabel = {type: 'ENTRY_LABEL', entry: FAKE_ENTRY_1, label: 'Hello world'};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(overlay, 'Add');
const text = ariaAnnouncementForModifiedEvent(event);
assert.strictEqual(text, 'The entry label annotation has been added');
});
it('does not return an announcement for new empty labels', async () => {
const overlay: Overlays.Overlays.EntryLabel = {type: 'ENTRY_LABEL', entry: FAKE_ENTRY_1, label: ''};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(overlay, 'Add');
const text = ariaAnnouncementForModifiedEvent(event);
assert.isNull(text);
});
it('returns text for an annotation having its label updated', async () => {
const overlay: Overlays.Overlays.EntryLabel = {type: 'ENTRY_LABEL', entry: FAKE_ENTRY_1, label: 'Hello world'};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(overlay, 'UpdateLabel');
const text = ariaAnnouncementForModifiedEvent(event);
assert.strictEqual(text, 'Label updated to Hello world');
});
it('returns text for a time range having its bounds updated', async () => {
TraceBounds.TraceBounds.BoundsManager.instance({forceNew: true})
.resetWithNewBounds(
microsecondsTraceWindow(0, 10_000),
);
const timeRange: Overlays.Overlays.TimeRangeLabel = {
type: 'TIME_RANGE',
bounds: microsecondsTraceWindow(0, 5_000),
label: 'hello',
showDuration: true,
};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(timeRange, 'UpdateTimeRange');
const text = ariaAnnouncementForModifiedEvent(event);
assert.strictEqual(text, 'Time range updated, starting at 0 ms and ending at 5 ms');
});
it('returns text when an entries link has its entries connected', async () => {
const link: Overlays.Overlays.EntriesLink = {
type: 'ENTRIES_LINK',
state: Trace.Types.File.EntriesLinkState.CONNECTED,
entryFrom: FAKE_ENTRY_1,
entryTo: FAKE_ENTRY_2,
};
const event = new Timeline.ModificationsManager.AnnotationModifiedEvent(link, 'UpdateLinkToEntry');
const text = ariaAnnouncementForModifiedEvent(event);
assert.strictEqual(text, 'The connected entries annotation now links from fake-one to fake-two');
});
});
});