Skip to content

Commit cd0ade9

Browse files
committed
test(replay): Use WINDOW in replay tests
1 parent 741dff9 commit cd0ade9

10 files changed

+71
-61
lines changed

packages/replay/test/unit/flush.test.ts

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { WINDOW } from '@sentry/browser';
12
import * as SentryUtils from '@sentry/utils';
23
import { BASE_TIMESTAMP, mockRrweb, mockSdk } from '@test';
34

@@ -20,7 +21,7 @@ type MockEventBufferFinish = jest.MockedFunction<Exclude<typeof Replay.prototype
2021
type MockFlush = jest.MockedFunction<typeof Replay.prototype.flush>;
2122
type MockRunFlush = jest.MockedFunction<typeof Replay.prototype.runFlush>;
2223

23-
const prevLocation = window.location;
24+
const prevLocation = WINDOW.location;
2425
let domHandler: (args: any) => any;
2526

2627
const { record: mockRecord } = mockRrweb();
@@ -91,9 +92,7 @@ afterEach(async () => {
9192
replay.clearSession();
9293
replay.loadSession({ expiry: SESSION_IDLE_DURATION });
9394
mockRecord.takeFullSnapshot.mockClear();
94-
// @ts-ignore: The operand of a 'delete' operator must be optional.ts(2790)
95-
delete window.location;
96-
Object.defineProperty(window, 'location', {
95+
Object.defineProperty(WINDOW, 'location', {
9796
value: prevLocation,
9897
writable: true,
9998
});
@@ -109,10 +108,10 @@ it('flushes twice after multiple flush() calls)', async () => {
109108
// the following blur events will all call a debounced flush function, which
110109
// should end up queueing a second flush
111110

112-
window.dispatchEvent(new Event('blur'));
113-
window.dispatchEvent(new Event('blur'));
114-
window.dispatchEvent(new Event('blur'));
115-
window.dispatchEvent(new Event('blur'));
111+
WINDOW.dispatchEvent(new Event('blur'));
112+
WINDOW.dispatchEvent(new Event('blur'));
113+
WINDOW.dispatchEvent(new Event('blur'));
114+
WINDOW.dispatchEvent(new Event('blur'));
116115

117116
expect(replay.flush).toHaveBeenCalledTimes(4);
118117

@@ -138,7 +137,7 @@ it('long first flush enqueues following events', async () => {
138137
expect(mockAddPerformanceEntries).not.toHaveBeenCalled();
139138

140139
// flush #1 @ t=0s - due to blur
141-
window.dispatchEvent(new Event('blur'));
140+
WINDOW.dispatchEvent(new Event('blur'));
142141
expect(replay.flush).toHaveBeenCalledTimes(1);
143142
expect(replay.runFlush).toHaveBeenCalledTimes(1);
144143

@@ -152,7 +151,7 @@ it('long first flush enqueues following events', async () => {
152151

153152
await advanceTimers(1000);
154153
// flush #3 @ t=6s - due to blur
155-
window.dispatchEvent(new Event('blur'));
154+
WINDOW.dispatchEvent(new Event('blur'));
156155
expect(replay.flush).toHaveBeenCalledTimes(3);
157156

158157
// NOTE: Blur also adds a breadcrumb which calls `addUpdate`, meaning it will
@@ -161,7 +160,7 @@ it('long first flush enqueues following events', async () => {
161160
expect(replay.flush).toHaveBeenCalledTimes(3);
162161

163162
// flush #4 @ t=14s - due to blur
164-
window.dispatchEvent(new Event('blur'));
163+
WINDOW.dispatchEvent(new Event('blur'));
165164
expect(replay.flush).toHaveBeenCalledTimes(4);
166165

167166
expect(replay.runFlush).toHaveBeenCalledTimes(1);

packages/replay/test/unit/index-errorSampleRate.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
jest.unmock('@sentry/browser');
22

3-
import { captureException } from '@sentry/browser';
3+
import { captureException, WINDOW } from '@sentry/browser';
44
import { BASE_TIMESTAMP, RecordMock } from '@test';
55
import { PerformanceEntryResource } from '@test/fixtures/performanceEntry/resource';
66
import { resetSdkMock } from '@test/mocks';
@@ -317,7 +317,7 @@ describe('Replay (errorSampleRate)', () => {
317317
*/
318318
it('sends a replay after loading the session multiple times', async () => {
319319
// Pretend that a session is already saved before loading replay
320-
window.sessionStorage.setItem(
320+
WINDOW.sessionStorage.setItem(
321321
REPLAY_SESSION_KEY,
322322
`{"segmentId":0,"id":"fd09adfc4117477abc8de643e5a5798a","sampled":"error","started":${BASE_TIMESTAMP},"lastActivity":${BASE_TIMESTAMP}}`,
323323
);

packages/replay/test/unit/index.test.ts

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
jest.mock('./../../src/util/isInternal', () => ({
22
isInternal: jest.fn(() => true),
33
}));
4+
import { WINDOW } from '@sentry/browser';
45
import { BASE_TIMESTAMP, RecordMock } from '@test';
56
import { PerformanceEntryResource } from '@test/fixtures/performanceEntry/resource';
67
import { resetSdkMock } from '@test/mocks';
@@ -23,7 +24,7 @@ describe('Replay', () => {
2324
let mockTransportSend: MockTransportSend;
2425
let domHandler: DomHandler;
2526
let spyCaptureException: jest.MockedFunction<any>;
26-
const prevLocation = window.location;
27+
const prevLocation = WINDOW.location;
2728

2829
type MockSendReplayRequest = jest.MockedFunction<typeof replay.sendReplayRequest>;
2930
let mockSendReplayRequest: MockSendReplayRequest;
@@ -56,9 +57,7 @@ describe('Replay', () => {
5657
afterEach(async () => {
5758
jest.runAllTimers();
5859
await new Promise(process.nextTick);
59-
// @ts-ignore: The operand of a 'delete' operator must be optional.ts(2790)
60-
delete window.location;
61-
Object.defineProperty(window, 'location', {
60+
Object.defineProperty(WINDOW, 'location', {
6261
value: prevLocation,
6362
writable: true,
6463
});
@@ -97,7 +96,7 @@ describe('Replay', () => {
9796

9897
it('clears session', () => {
9998
replay.clearSession();
100-
expect(window.sessionStorage.getItem(REPLAY_SESSION_KEY)).toBe(null);
99+
expect(WINDOW.sessionStorage.getItem(REPLAY_SESSION_KEY)).toBe(null);
101100
expect(replay.session).toBe(undefined);
102101
});
103102

@@ -133,7 +132,7 @@ describe('Replay', () => {
133132

134133
jest.advanceTimersByTime(VISIBILITY_CHANGE_TIMEOUT + 1);
135134

136-
window.dispatchEvent(new Event('focus'));
135+
WINDOW.dispatchEvent(new Event('focus'));
137136

138137
expect(mockRecord.takeFullSnapshot).toHaveBeenLastCalledWith(true);
139138

@@ -169,7 +168,7 @@ describe('Replay', () => {
169168
expect(replay).toHaveSameSession(initialSession);
170169
});
171170

172-
it('uploads a replay event when window is blurred', async () => {
171+
it('uploads a replay event when WINDOW is blurred', async () => {
173172
Object.defineProperty(document, 'visibilityState', {
174173
configurable: true,
175174
get: function () {
@@ -196,7 +195,7 @@ describe('Replay', () => {
196195
};
197196

198197
replay.addEvent(TEST_EVENT);
199-
window.dispatchEvent(new Event('blur'));
198+
WINDOW.dispatchEvent(new Event('blur'));
200199
await new Promise(process.nextTick);
201200
expect(mockRecord.takeFullSnapshot).not.toHaveBeenCalled();
202201
expect(replay).toHaveSentReplay({
@@ -303,7 +302,7 @@ describe('Replay', () => {
303302
);
304303

305304
const url = 'http://dummy/';
306-
Object.defineProperty(window, 'location', {
305+
Object.defineProperty(WINDOW, 'location', {
307306
value: new URL(url),
308307
});
309308

@@ -391,7 +390,7 @@ describe('Replay', () => {
391390
);
392391

393392
const url = 'http://dummy/';
394-
Object.defineProperty(window, 'location', {
393+
Object.defineProperty(WINDOW, 'location', {
395394
value: new URL(url),
396395
});
397396

@@ -419,7 +418,7 @@ describe('Replay', () => {
419418
return true;
420419
});
421420

422-
window.dispatchEvent(new Event('blur'));
421+
WINDOW.dispatchEvent(new Event('blur'));
423422
await advanceTimers(5000);
424423

425424
expect(mockRecord.takeFullSnapshot).not.toHaveBeenCalled();
@@ -639,15 +638,15 @@ describe('Replay', () => {
639638
const TEST_EVENT = { data: {}, timestamp: BASE_TIMESTAMP, type: 2 };
640639

641640
replay.addEvent(TEST_EVENT);
642-
window.dispatchEvent(new Event('blur'));
641+
WINDOW.dispatchEvent(new Event('blur'));
643642
await new Promise(process.nextTick);
644643
expect(replay).toHaveSentReplay({
645644
recordingPayloadHeader: { segment_id: 0 },
646645
});
647646
expect(replay.session?.segmentId).toBe(1);
648647

649648
replay.addEvent(TEST_EVENT);
650-
window.dispatchEvent(new Event('blur'));
649+
WINDOW.dispatchEvent(new Event('blur'));
651650
jest.runAllTimers();
652651
await new Promise(process.nextTick);
653652
expect(replay.session?.segmentId).toBe(2);
@@ -679,7 +678,7 @@ describe('Replay', () => {
679678
};
680679

681680
replay.addEvent(TEST_EVENT);
682-
window.dispatchEvent(new Event('blur'));
681+
WINDOW.dispatchEvent(new Event('blur'));
683682
await new Promise(process.nextTick);
684683

685684
expect(replay).toHaveSentReplay({
@@ -773,7 +772,7 @@ describe('Replay', () => {
773772
type: 5,
774773
});
775774

776-
window.dispatchEvent(new Event('blur'));
775+
WINDOW.dispatchEvent(new Event('blur'));
777776
await new Promise(process.nextTick);
778777
expect(replay).toHaveSentReplay({
779778
replayEventPayload: expect.objectContaining({
@@ -816,7 +815,7 @@ describe('Replay', () => {
816815

817816
replay.addEvent(TEST_EVENT);
818817
// This event will trigger a flush
819-
window.dispatchEvent(new Event('blur'));
818+
WINDOW.dispatchEvent(new Event('blur'));
820819
jest.runAllTimers();
821820
await new Promise(process.nextTick);
822821

packages/replay/test/unit/session/Session.test.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
jest.mock('./../../../src/session/saveSession');
22

33
jest.mock('@sentry/browser', () => {
4+
const originalModule = jest.requireActual('@sentry/browser');
5+
46
return {
7+
...originalModule,
58
getCurrentHub: jest.fn(() => {
69
return {
710
captureEvent: jest.fn(),
@@ -11,24 +14,25 @@ jest.mock('@sentry/browser', () => {
1114
};
1215
});
1316

17+
jest.mock('@sentry/utils', () => {
18+
const originalModule = jest.requireActual('@sentry/utils');
19+
20+
return {
21+
...originalModule,
22+
uuid4: jest.fn(() => 'test_session_id'),
23+
};
24+
});
25+
1426
import * as Sentry from '@sentry/browser';
27+
import { WINDOW } from '@sentry/browser';
1528

1629
import { saveSession } from '../../../src/session/saveSession';
1730
import { Session } from '../../../src/session/Session';
1831

1932
type CaptureEventMockType = jest.MockedFunction<typeof Sentry.captureEvent>;
2033

21-
jest.mock('@sentry/browser');
22-
23-
jest.mock('@sentry/utils', () => {
24-
return {
25-
...(jest.requireActual('@sentry/utils') as { string: unknown }),
26-
uuid4: jest.fn(() => 'test_session_id'),
27-
};
28-
});
29-
3034
beforeEach(() => {
31-
window.sessionStorage.clear();
35+
WINDOW.sessionStorage.clear();
3236
});
3337

3438
afterEach(() => {

packages/replay/test/unit/session/createSession.test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { WINDOW } from '@sentry/browser';
12
import * as Sentry from '@sentry/core';
23

34
import { createSession } from '../../../src/session/createSession';
@@ -17,7 +18,7 @@ type CaptureEventMockType = jest.MockedFunction<typeof Sentry.captureEvent>;
1718
const captureEventMock: CaptureEventMockType = jest.fn();
1819

1920
beforeAll(() => {
20-
window.sessionStorage.clear();
21+
WINDOW.sessionStorage.clear();
2122
jest.spyOn(Sentry, 'getCurrentHub');
2223
(Sentry.getCurrentHub as jest.Mock).mockImplementation(() => ({
2324
captureEvent: captureEventMock,

packages/replay/test/unit/session/deleteSession.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { WINDOW } from '@sentry/browser';
2+
13
import { REPLAY_SESSION_KEY } from '../../../src/session/constants';
24
import { deleteSession } from '../../../src/session/deleteSession';
35

4-
const storageEngine = window.sessionStorage;
6+
const storageEngine = WINDOW.sessionStorage;
57

68
it('deletes a session', function () {
79
storageEngine.setItem(

packages/replay/test/unit/session/fetchSession.test.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1+
import { WINDOW } from '@sentry/browser';
2+
13
import { REPLAY_SESSION_KEY } from '../../../src/session/constants';
24
import { fetchSession } from '../../../src/session/fetchSession';
35

4-
const oldSessionStorage = window.sessionStorage;
6+
const oldSessionStorage = WINDOW.sessionStorage;
57

68
beforeAll(() => {
7-
window.sessionStorage.clear();
9+
WINDOW.sessionStorage.clear();
810
});
911

1012
afterEach(() => {
11-
Object.defineProperty(window, 'sessionStorage', {
13+
Object.defineProperty(WINDOW, 'sessionStorage', {
1214
writable: true,
1315
value: oldSessionStorage,
1416
});
15-
window.sessionStorage.clear();
17+
WINDOW.sessionStorage.clear();
1618
});
1719

1820
const SAMPLE_RATES = {
@@ -21,7 +23,7 @@ const SAMPLE_RATES = {
2123
};
2224

2325
it('fetches a valid and sampled session', function () {
24-
window.sessionStorage.setItem(
26+
WINDOW.sessionStorage.setItem(
2527
REPLAY_SESSION_KEY,
2628
'{"id":"fd09adfc4117477abc8de643e5a5798a","sampled": true,"started":1648827162630,"lastActivity":1648827162658}',
2729
);
@@ -40,13 +42,13 @@ it('fetches a session that does not exist', function () {
4042
});
4143

4244
it('fetches an invalid session', function () {
43-
window.sessionStorage.setItem(REPLAY_SESSION_KEY, '{"id":"fd09adfc4117477abc8de643e5a5798a",');
45+
WINDOW.sessionStorage.setItem(REPLAY_SESSION_KEY, '{"id":"fd09adfc4117477abc8de643e5a5798a",');
4446

4547
expect(fetchSession(SAMPLE_RATES)).toBe(null);
4648
});
4749

4850
it('safely attempts to fetch session when Session Storage is disabled', function () {
49-
Object.defineProperty(window, 'sessionStorage', {
51+
Object.defineProperty(WINDOW, 'sessionStorage', {
5052
writable: true,
5153
value: {
5254
getItem: () => {

packages/replay/test/unit/session/getSession.test.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { WINDOW } from '@sentry/browser';
2+
13
import * as CreateSession from '../../../src/session/createSession';
24
import * as FetchSession from '../../../src/session/fetchSession';
35
import { getSession } from '../../../src/session/getSession';
@@ -32,11 +34,11 @@ function createMockSession(when: number = new Date().getTime()) {
3234
beforeAll(() => {
3335
jest.spyOn(CreateSession, 'createSession');
3436
jest.spyOn(FetchSession, 'fetchSession');
35-
window.sessionStorage.clear();
37+
WINDOW.sessionStorage.clear();
3638
});
3739

3840
afterEach(() => {
39-
window.sessionStorage.clear();
41+
WINDOW.sessionStorage.clear();
4042
(CreateSession.createSession as jest.MockedFunction<typeof CreateSession.createSession>).mockClear();
4143
(FetchSession.fetchSession as jest.MockedFunction<typeof FetchSession.fetchSession>).mockClear();
4244
});

packages/replay/test/unit/session/saveSession.test.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
import { WINDOW } from '@sentry/browser';
2+
13
import { REPLAY_SESSION_KEY } from '../../../src/session/constants';
24
import { saveSession } from '../../../src/session/saveSession';
35
import { Session } from '../../../src/session/Session';
46

57
beforeAll(() => {
6-
window.sessionStorage.clear();
8+
WINDOW.sessionStorage.clear();
79
});
810

911
afterEach(() => {
10-
window.sessionStorage.clear();
12+
WINDOW.sessionStorage.clear();
1113
});
1214

1315
it('saves a valid session', function () {
@@ -23,5 +25,5 @@ it('saves a valid session', function () {
2325
);
2426
saveSession(session);
2527

26-
expect(window.sessionStorage.getItem(REPLAY_SESSION_KEY)).toEqual(JSON.stringify(session));
28+
expect(WINDOW.sessionStorage.getItem(REPLAY_SESSION_KEY)).toEqual(JSON.stringify(session));
2729
});

0 commit comments

Comments
 (0)