Skip to content

Commit 1ee0e2b

Browse files
committed
test(replay): Rename & streamline replay test modules
1 parent cf5a4b2 commit 1ee0e2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2100
-2032
lines changed

packages/replay/src/coreHandlers/handleFetch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { ReplayPerformanceEntry } from '../createPerformanceEntry';
21
import type { ReplayContainer } from '../types';
2+
import type { ReplayPerformanceEntry } from '../util/createPerformanceEntry';
33
import { createPerformanceSpans } from '../util/createPerformanceSpans';
44
import { shouldFilterRequest } from '../util/shouldFilterRequest';
55

packages/replay/src/coreHandlers/handleHistory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ReplayPerformanceEntry } from '../createPerformanceEntry';
21
import type { ReplayContainer } from '../types';
2+
import { ReplayPerformanceEntry } from '../util/createPerformanceEntry';
33
import { createPerformanceSpans } from '../util/createPerformanceSpans';
44

55
interface HistoryHandlerData {

packages/replay/src/coreHandlers/handleXhr.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ReplayPerformanceEntry } from '../createPerformanceEntry';
21
import type { ReplayContainer } from '../types';
2+
import { ReplayPerformanceEntry } from '../util/createPerformanceEntry';
33
import { createPerformanceSpans } from '../util/createPerformanceSpans';
44
import { shouldFilterRequest } from '../util/shouldFilterRequest';
55

packages/replay/src/replay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { handleGlobalEventListener } from './coreHandlers/handleGlobalEvent';
1818
import { handleHistorySpanListener } from './coreHandlers/handleHistory';
1919
import { handleXhrSpanListener } from './coreHandlers/handleXhr';
2020
import { setupPerformanceObserver } from './coreHandlers/performanceObserver';
21-
import { createPerformanceEntries } from './createPerformanceEntry';
2221
import { createEventBuffer } from './eventBuffer';
2322
import { deleteSession } from './session/deleteSession';
2423
import { getSession } from './session/getSession';
@@ -42,6 +41,7 @@ import { addEvent } from './util/addEvent';
4241
import { addMemoryEntry } from './util/addMemoryEntry';
4342
import { createBreadcrumb } from './util/createBreadcrumb';
4443
import { createPayload } from './util/createPayload';
44+
import { createPerformanceEntries } from './util/createPerformanceEntry';
4545
import { createPerformanceSpans } from './util/createPerformanceSpans';
4646
import { createReplayEnvelope } from './util/createReplayEnvelope';
4747
import { debounce } from './util/debounce';

packages/replay/src/createPerformanceEntry.ts renamed to packages/replay/src/util/createPerformanceEntry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { browserPerformanceTimeOrigin } from '@sentry/utils';
22
import { record } from 'rrweb';
33

4-
import { WINDOW } from './constants';
5-
import type { AllPerformanceEntry, PerformanceNavigationTiming, PerformancePaintTiming } from './types';
4+
import { WINDOW } from '../constants';
5+
import type { AllPerformanceEntry, PerformanceNavigationTiming, PerformancePaintTiming } from '../types';
66

77
export interface ReplayPerformanceEntry {
88
/**

packages/replay/src/util/createPerformanceSpans.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { EventType } from 'rrweb';
22

3-
import { ReplayPerformanceEntry } from '../createPerformanceEntry';
43
import type { ReplayContainer } from '../types';
54
import { addEvent } from './addEvent';
5+
import { ReplayPerformanceEntry } from './createPerformanceEntry';
66

77
/**
88
* Create a "span" for each performance entry. The parent transaction is `this.replayEvent`.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { EventType } from 'rrweb';
2+
3+
import type { RecordingEvent } from '../../src/types';
4+
import { addEvent } from '../../src/util/addEvent';
5+
import { resetSdkMock } from '../mocks/resetSdkMock';
6+
import { useFakeTimers } from '../utils/use-fake-timers';
7+
8+
useFakeTimers();
9+
10+
describe('Integration | autoSaveSession', () => {
11+
afterEach(() => {
12+
jest.clearAllMocks();
13+
});
14+
15+
test.each([
16+
['with stickySession=true', true, 1],
17+
['with stickySession=false', false, 0],
18+
])('%s', async (_: string, stickySession: boolean, addSummand: number) => {
19+
let saveSessionSpy;
20+
21+
jest.mock('../../src/session/saveSession', () => {
22+
saveSessionSpy = jest.fn();
23+
24+
return {
25+
saveSession: saveSessionSpy,
26+
};
27+
});
28+
29+
const { replay } = await resetSdkMock({
30+
replayOptions: {
31+
stickySession,
32+
},
33+
});
34+
35+
// Initially called up to three times: once for start, then once for replay.updateSessionActivity & once for segmentId increase
36+
expect(saveSessionSpy).toHaveBeenCalledTimes(addSummand * 3);
37+
38+
replay.updateSessionActivity();
39+
40+
expect(saveSessionSpy).toHaveBeenCalledTimes(addSummand * 4);
41+
42+
// In order for runFlush to actually do something, we need to add an event
43+
const event = {
44+
type: EventType.Custom,
45+
data: {
46+
tag: 'test custom',
47+
},
48+
timestamp: new Date().valueOf(),
49+
} as RecordingEvent;
50+
51+
addEvent(replay, event);
52+
53+
await replay.runFlush();
54+
55+
expect(saveSessionSpy).toHaveBeenCalledTimes(addSummand * 5);
56+
});
57+
});

packages/replay/test/integration/coreHandlers/handleGlobalEvent.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { useFakeTimers } from '../../utils/use-fake-timers';
1616
useFakeTimers();
1717
let replay: ReplayContainer;
1818

19-
describe('handleGlobalEvent', () => {
19+
describe('Integration | coreHandlers | handleGlobalEvent', () => {
2020
beforeEach(async () => {
2121
({ replay } = await resetSdkMock({
2222
replayOptions: {

packages/replay/test/integration/coreHandlers/handleScope.test.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,27 @@ import { getCurrentHub } from '@sentry/core';
33
import * as HandleScope from '../../../src/coreHandlers/handleScope';
44
import { mockSdk } from './../../index';
55

6-
let mockHandleScope: jest.MockedFunction<typeof HandleScope.handleScope>;
7-
86
jest.useFakeTimers();
97

10-
beforeAll(async function () {
11-
await mockSdk();
12-
jest.spyOn(HandleScope, 'handleScope');
13-
mockHandleScope = HandleScope.handleScope as jest.MockedFunction<typeof HandleScope.handleScope>;
14-
15-
jest.runAllTimers();
16-
});
8+
describe('Integration | coreHandlers | handleScope', () => {
9+
beforeAll(async function () {
10+
await mockSdk();
11+
jest.runAllTimers();
12+
});
1713

18-
it('returns a breadcrumb only if last breadcrumb has changed (integration)', function () {
19-
getCurrentHub().getScope()?.addBreadcrumb({ message: 'testing' });
14+
it('returns a breadcrumb only if last breadcrumb has changed', function () {
15+
const mockHandleScope = jest.spyOn(HandleScope, 'handleScope');
16+
getCurrentHub().getScope()?.addBreadcrumb({ message: 'testing' });
2017

21-
expect(mockHandleScope).toHaveBeenCalledTimes(1);
22-
expect(mockHandleScope).toHaveReturnedWith(expect.objectContaining({ message: 'testing' }));
18+
expect(mockHandleScope).toHaveBeenCalledTimes(1);
19+
expect(mockHandleScope).toHaveReturnedWith(expect.objectContaining({ message: 'testing' }));
2320

24-
mockHandleScope.mockClear();
21+
mockHandleScope.mockClear();
2522

26-
// This will trigger breadcrumb/scope listener, but handleScope should return
27-
// null because breadcrumbs has not changed
28-
getCurrentHub().getScope()?.setUser({ email: '[email protected]' });
29-
expect(mockHandleScope).toHaveBeenCalledTimes(1);
30-
expect(mockHandleScope).toHaveReturnedWith(null);
23+
// This will trigger breadcrumb/scope listener, but handleScope should return
24+
// null because breadcrumbs has not changed
25+
getCurrentHub().getScope()?.setUser({ email: '[email protected]' });
26+
expect(mockHandleScope).toHaveBeenCalledTimes(1);
27+
expect(mockHandleScope).toHaveReturnedWith(null);
28+
});
3129
});

packages/replay/test/integration/errorSampleRate.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async function advanceTimers(time: number) {
1616
await new Promise(process.nextTick);
1717
}
1818

19-
describe('Replay (errorSampleRate)', () => {
19+
describe('Integration | errorSampleRate', () => {
2020
let replay: ReplayContainer;
2121
let mockRecord: RecordMock;
2222
let domHandler: DomHandler;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { getCurrentHub } from '@sentry/core';
2+
import { Event, Hub, Scope } from '@sentry/types';
3+
4+
import { BASE_TIMESTAMP } from '..';
5+
import { resetSdkMock } from '../mocks/resetSdkMock';
6+
import { useFakeTimers } from '../utils/use-fake-timers';
7+
8+
useFakeTimers();
9+
10+
describe('Integration | eventProcessors', () => {
11+
let hub: Hub;
12+
let scope: Scope;
13+
14+
beforeEach(() => {
15+
hub = getCurrentHub();
16+
scope = hub.pushScope();
17+
});
18+
19+
afterEach(() => {
20+
hub.popScope();
21+
jest.resetAllMocks();
22+
});
23+
24+
it('handles event processors properly', async () => {
25+
const MUTATED_TIMESTAMP = BASE_TIMESTAMP + 3000;
26+
27+
const { mockRecord } = await resetSdkMock({
28+
replayOptions: {
29+
stickySession: false,
30+
},
31+
});
32+
33+
const client = hub.getClient()!;
34+
35+
jest.runAllTimers();
36+
const mockTransportSend = jest.spyOn(client.getTransport()!, 'send');
37+
mockTransportSend.mockReset();
38+
39+
const handler1 = jest.fn((event: Event): Event | null => {
40+
event.timestamp = MUTATED_TIMESTAMP;
41+
42+
return event;
43+
});
44+
45+
const handler2 = jest.fn((): Event | null => {
46+
return null;
47+
});
48+
49+
scope.addEventProcessor(handler1);
50+
51+
const TEST_EVENT = { data: {}, timestamp: BASE_TIMESTAMP, type: 3 };
52+
53+
mockRecord._emitter(TEST_EVENT);
54+
jest.runAllTimers();
55+
jest.advanceTimersByTime(1);
56+
await new Promise(process.nextTick);
57+
58+
expect(mockTransportSend).toHaveBeenCalledTimes(1);
59+
60+
scope.addEventProcessor(handler2);
61+
62+
const TEST_EVENT2 = { data: {}, timestamp: BASE_TIMESTAMP, type: 3 };
63+
64+
mockRecord._emitter(TEST_EVENT2);
65+
jest.runAllTimers();
66+
jest.advanceTimersByTime(1);
67+
await new Promise(process.nextTick);
68+
69+
expect(mockTransportSend).toHaveBeenCalledTimes(1);
70+
71+
expect(handler1).toHaveBeenCalledTimes(2);
72+
expect(handler2).toHaveBeenCalledTimes(1);
73+
74+
// This receives an envelope, which is a deeply nested array
75+
// We only care about the fact that the timestamp was mutated
76+
expect(mockTransportSend).toHaveBeenCalledWith(
77+
expect.arrayContaining([
78+
expect.arrayContaining([expect.arrayContaining([expect.objectContaining({ timestamp: MUTATED_TIMESTAMP })])]),
79+
]),
80+
);
81+
});
82+
});

0 commit comments

Comments
 (0)