|
@@ -1,24 +1,17 @@
|
|
|
import {
|
|
|
countColumns,
|
|
|
divide,
|
|
|
- flattenSpans,
|
|
|
+ flattenFrames,
|
|
|
formatTime,
|
|
|
getCrumbsByColumn,
|
|
|
relativeTimeInMs,
|
|
|
showPlayerTime,
|
|
|
} from 'sentry/components/replays/utils';
|
|
|
import {BreadcrumbLevelType, BreadcrumbType, Crumb} from 'sentry/types/breadcrumbs';
|
|
|
-import type {ReplaySpan} from 'sentry/views/replays/types';
|
|
|
+import hydrateSpans from 'sentry/utils/replays/hydrateSpans';
|
|
|
|
|
|
const SECOND = 1000;
|
|
|
|
|
|
-function createSpan(span: Partial<ReplaySpan>): ReplaySpan {
|
|
|
- return {
|
|
|
- data: {},
|
|
|
- ...span,
|
|
|
- } as ReplaySpan;
|
|
|
-}
|
|
|
-
|
|
|
function createCrumb({timestamp}: Pick<Crumb, 'timestamp'>): Crumb {
|
|
|
return {
|
|
|
timestamp,
|
|
@@ -151,106 +144,113 @@ describe('getCrumbsByColumn', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-describe('flattenSpans', () => {
|
|
|
+describe('flattenFrames', () => {
|
|
|
it('should return an empty array if there ar eno spans', () => {
|
|
|
- expect(flattenSpans([])).toStrictEqual([]);
|
|
|
+ expect(flattenFrames([])).toStrictEqual([]);
|
|
|
});
|
|
|
|
|
|
it('should return the FlattenedSpanRange for a single span', () => {
|
|
|
- const span = createSpan({
|
|
|
- op: 'span',
|
|
|
- startTimestamp: 10,
|
|
|
- endTimestamp: 30,
|
|
|
- });
|
|
|
- expect(flattenSpans([span])).toStrictEqual([
|
|
|
+ const frames = hydrateSpans(TestStubs.ReplayRecord(), [
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(10000),
|
|
|
+ endTimestamp: new Date(30000),
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
+ expect(flattenFrames(frames)).toStrictEqual([
|
|
|
{
|
|
|
duration: 20000,
|
|
|
endTimestamp: 30000,
|
|
|
- spanCount: 1,
|
|
|
+ frameCount: 1,
|
|
|
startTimestamp: 10000,
|
|
|
},
|
|
|
]);
|
|
|
});
|
|
|
|
|
|
it('should return two non-overlapping spans', () => {
|
|
|
- const span1 = createSpan({
|
|
|
- op: 'span1',
|
|
|
- startTimestamp: 10,
|
|
|
- endTimestamp: 30,
|
|
|
- });
|
|
|
- const span2 = createSpan({
|
|
|
- op: 'span2',
|
|
|
- startTimestamp: 60,
|
|
|
- endTimestamp: 90,
|
|
|
- });
|
|
|
+ const frames = hydrateSpans(TestStubs.ReplayRecord(), [
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(10000),
|
|
|
+ endTimestamp: new Date(30000),
|
|
|
+ }),
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(60000),
|
|
|
+ endTimestamp: new Date(90000),
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
|
|
|
- expect(flattenSpans([span1, span2])).toStrictEqual([
|
|
|
+ expect(flattenFrames(frames)).toStrictEqual([
|
|
|
{
|
|
|
duration: 20000,
|
|
|
endTimestamp: 30000,
|
|
|
- spanCount: 1,
|
|
|
+ frameCount: 1,
|
|
|
startTimestamp: 10000,
|
|
|
},
|
|
|
{
|
|
|
duration: 30000,
|
|
|
endTimestamp: 90000,
|
|
|
- spanCount: 1,
|
|
|
+ frameCount: 1,
|
|
|
startTimestamp: 60000,
|
|
|
},
|
|
|
]);
|
|
|
});
|
|
|
|
|
|
it('should merge two overlapping spans', () => {
|
|
|
- const span1 = createSpan({
|
|
|
- op: 'span1',
|
|
|
- data: {},
|
|
|
- startTimestamp: 10,
|
|
|
- endTimestamp: 30,
|
|
|
- });
|
|
|
- const span2 = createSpan({
|
|
|
- op: 'span2',
|
|
|
- startTimestamp: 20,
|
|
|
- endTimestamp: 40,
|
|
|
- });
|
|
|
+ const frames = hydrateSpans(TestStubs.ReplayRecord(), [
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(10000),
|
|
|
+ endTimestamp: new Date(30000),
|
|
|
+ }),
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(20000),
|
|
|
+ endTimestamp: new Date(40000),
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
|
|
|
- expect(flattenSpans([span1, span2])).toStrictEqual([
|
|
|
+ expect(flattenFrames(frames)).toStrictEqual([
|
|
|
{
|
|
|
duration: 30000,
|
|
|
endTimestamp: 40000,
|
|
|
- spanCount: 2,
|
|
|
+ frameCount: 2,
|
|
|
startTimestamp: 10000,
|
|
|
},
|
|
|
]);
|
|
|
});
|
|
|
|
|
|
it('should merge overlapping spans that are not first in the list', () => {
|
|
|
- const span0 = createSpan({
|
|
|
- op: 'span0',
|
|
|
- startTimestamp: 0,
|
|
|
- endTimestamp: 1,
|
|
|
- });
|
|
|
- const span1 = createSpan({
|
|
|
- op: 'span1',
|
|
|
- startTimestamp: 10,
|
|
|
- endTimestamp: 30,
|
|
|
- });
|
|
|
- const span2 = createSpan({
|
|
|
- op: 'span2',
|
|
|
- startTimestamp: 20,
|
|
|
- endTimestamp: 40,
|
|
|
- });
|
|
|
+ const frames = hydrateSpans(TestStubs.ReplayRecord(), [
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(0),
|
|
|
+ endTimestamp: new Date(1000),
|
|
|
+ }),
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(10000),
|
|
|
+ endTimestamp: new Date(30000),
|
|
|
+ }),
|
|
|
+ TestStubs.Replay.RequestFrame({
|
|
|
+ op: 'resource.fetch',
|
|
|
+ startTimestamp: new Date(20000),
|
|
|
+ endTimestamp: new Date(40000),
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
|
|
|
- expect(flattenSpans([span0, span1, span2])).toStrictEqual([
|
|
|
+ expect(flattenFrames(frames)).toStrictEqual([
|
|
|
{
|
|
|
duration: 1000,
|
|
|
endTimestamp: 1000,
|
|
|
- spanCount: 1,
|
|
|
+ frameCount: 1,
|
|
|
startTimestamp: 0,
|
|
|
},
|
|
|
{
|
|
|
duration: 30000,
|
|
|
endTimestamp: 40000,
|
|
|
- spanCount: 2,
|
|
|
+ frameCount: 2,
|
|
|
startTimestamp: 10000,
|
|
|
},
|
|
|
]);
|