-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(replay): Use vitest
instead of jest
#11899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0c2c609
a33ce01
091bf94
ac4de92
c0d4cfa
83162b6
ceca10e
cde0779
1864c67
2b2ea3d
6ec58f6
a42012e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,10 +51,12 @@ | |
"build:tarball": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", | ||
"circularDepCheck": "madge --circular src/index.ts", | ||
"clean": "rimraf build sentry-replay-*.tgz", | ||
"fix": "eslint . --format stylish --fix", | ||
"fix": "run-s fix:biome fix:eslint", | ||
"fix:eslint": "eslint . --format stylish --fix", | ||
"fix:biome": "biome check --apply .", | ||
"lint": "eslint . --format stylish", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test": "vitest", | ||
"test:watch": "vitest --watch", | ||
"yalc:publish": "ts-node ../../scripts/prepack.ts --bundles && yalc publish ./build/npm --push --sig" | ||
}, | ||
"repository": { | ||
|
@@ -73,6 +75,7 @@ | |
"@sentry-internal/rrweb": "2.15.0", | ||
"@sentry-internal/rrweb-snapshot": "2.15.0", | ||
"fflate": "^0.8.1", | ||
"jest-matcher-utils": "^29.0.0", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our custom matchers use a util fn from this lib to pretty print diffs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we can possibly refactor this later to avoid this dependency, but all good for now! |
||
"jsdom-worker": "^0.2.1" | ||
}, | ||
"dependencies": { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,17 @@ | ||
import { TextEncoder } from 'util'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
import { printDiffOrStringify } from 'jest-matcher-utils'; | ||
import { vi } from 'vitest'; | ||
import type { Mocked, MockedFunction } from 'vitest'; | ||
|
||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */ | ||
import { getClient } from '@sentry/core'; | ||
import type { ReplayRecordingData, Transport } from '@sentry/types'; | ||
import * as SentryUtils from '@sentry/utils'; | ||
|
||
import type { ReplayContainer, Session } from './src/types'; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
(global as any).TextEncoder = TextEncoder; | ||
|
||
type MockTransport = jest.MockedFunction<Transport['send']>; | ||
type MockTransport = MockedFunction<Transport['send']>; | ||
|
||
jest.spyOn(SentryUtils, 'isBrowser').mockImplementation(() => true); | ||
vi.spyOn(SentryUtils, 'isBrowser').mockImplementation(() => true); | ||
|
||
type EnvelopeHeader = { | ||
event_id: string; | ||
|
@@ -36,7 +36,7 @@ type SentReplayExpected = { | |
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
const toHaveSameSession = function (received: jest.Mocked<ReplayContainer>, expected: undefined | Session) { | ||
const toHaveSameSession = function (received: Mocked<ReplayContainer>, expected: undefined | Session) { | ||
const pass = this.equals(received.session?.id, expected?.id) as boolean; | ||
|
||
const options = { | ||
|
@@ -47,12 +47,12 @@ const toHaveSameSession = function (received: jest.Mocked<ReplayContainer>, expe | |
return { | ||
pass, | ||
message: () => | ||
`${this.utils.matcherHint( | ||
'toHaveSameSession', | ||
undefined, | ||
undefined, | ||
options, | ||
)}\n\n${this.utils.printDiffOrStringify(expected, received.session, 'Expected', 'Received')}`, | ||
`${this.utils.matcherHint('toHaveSameSession', undefined, undefined, options)}\n\n${printDiffOrStringify( | ||
expected, | ||
received.session, | ||
'Expected', | ||
'Received', | ||
)}`, | ||
}; | ||
}; | ||
|
||
|
@@ -101,6 +101,7 @@ function checkCallForSentReplay( | |
: (expected as SentReplayExpected); | ||
|
||
if (isObjectContaining) { | ||
// eslint-disable-next-line no-console | ||
console.warn('`expect.objectContaining` is unnecessary when using the `toHaveSentReplay` matcher'); | ||
} | ||
|
||
|
@@ -152,7 +153,7 @@ function getReplayCalls(calls: any[][][]): any[][][] { | |
*/ | ||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
const toHaveSentReplay = function ( | ||
_received: jest.Mocked<ReplayContainer>, | ||
_received: Mocked<ReplayContainer>, | ||
expected?: SentReplayExpected | { sample: SentReplayExpected; inverse: boolean }, | ||
) { | ||
const { calls } = (getClient()?.getTransport()?.send as MockTransport).mock; | ||
|
@@ -194,12 +195,7 @@ const toHaveSentReplay = function ( | |
: 'Expected Replay to have been sent, but a request was not attempted' | ||
: `${this.utils.matcherHint('toHaveSentReplay', undefined, undefined, options)}\n\n${results | ||
.map(({ key, expectedVal, actualVal }: Result) => | ||
this.utils.printDiffOrStringify( | ||
expectedVal, | ||
actualVal, | ||
`Expected (key: ${key})`, | ||
`Received (key: ${key})`, | ||
), | ||
printDiffOrStringify(expectedVal, actualVal, `Expected (key: ${key})`, `Received (key: ${key})`), | ||
) | ||
.join('\n')}`, | ||
}; | ||
|
@@ -211,7 +207,7 @@ const toHaveSentReplay = function ( | |
*/ | ||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
const toHaveLastSentReplay = function ( | ||
_received: jest.Mocked<ReplayContainer>, | ||
_received: Mocked<ReplayContainer>, | ||
expected?: SentReplayExpected | { sample: SentReplayExpected; inverse: boolean }, | ||
) { | ||
const { calls } = (getClient()?.getTransport()?.send as MockTransport).mock; | ||
|
@@ -235,12 +231,7 @@ const toHaveLastSentReplay = function ( | |
: 'Expected Replay to have last been sent, but a request was not attempted' | ||
: `${this.utils.matcherHint('toHaveSentReplay', undefined, undefined, options)}\n\n${results | ||
.map(({ key, expectedVal, actualVal }: Result) => | ||
this.utils.printDiffOrStringify( | ||
expectedVal, | ||
actualVal, | ||
`Expected (key: ${key})`, | ||
`Received (key: ${key})`, | ||
), | ||
printDiffOrStringify(expectedVal, actualVal, `Expected (key: ${key})`, `Received (key: ${key})`), | ||
) | ||
.join('\n')}`, | ||
}; | ||
|
@@ -252,18 +243,13 @@ expect.extend({ | |
toHaveLastSentReplay, | ||
}); | ||
|
||
declare global { | ||
// eslint-disable-next-line @typescript-eslint/no-namespace | ||
namespace jest { | ||
interface AsymmetricMatchers { | ||
toHaveSentReplay(expected?: SentReplayExpected): void; | ||
toHaveLastSentReplay(expected?: SentReplayExpected): void; | ||
toHaveSameSession(expected: undefined | Session): void; | ||
} | ||
interface Matchers<R> { | ||
toHaveSentReplay(expected?: SentReplayExpected): R; | ||
toHaveLastSentReplay(expected?: SentReplayExpected): R; | ||
toHaveSameSession(expected: undefined | Session): R; | ||
} | ||
} | ||
interface CustomMatchers<R = unknown> { | ||
toHaveSentReplay(expected?: SentReplayExpected): R; | ||
toHaveLastSentReplay(expected?: SentReplayExpected): R; | ||
toHaveSameSession(expected: undefined | Session): R; | ||
} | ||
|
||
declare module 'vitest' { | ||
type Assertion<T = any> = CustomMatchers<T>; | ||
type AsymmetricMatchersContaining = CustomMatchers; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,42 @@ | ||
import { vi } from 'vitest'; | ||
|
||
import { EventType } from '@sentry-internal/rrweb'; | ||
|
||
import { saveSession } from '../../src/session/saveSession'; | ||
import type { RecordingEvent } from '../../src/types'; | ||
import { addEvent } from '../../src/util/addEvent'; | ||
import { resetSdkMock } from '../mocks/resetSdkMock'; | ||
import { useFakeTimers } from '../utils/use-fake-timers'; | ||
|
||
useFakeTimers(); | ||
|
||
vi.mock('../../src/session/saveSession', () => { | ||
return { | ||
saveSession: vi.fn(), | ||
}; | ||
}); | ||
|
||
describe('Integration | autoSaveSession', () => { | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
test.each([ | ||
['with stickySession=true', true, 1], | ||
['with stickySession=false', false, 0], | ||
])('%s', async (_: string, stickySession: boolean, addSummand: number) => { | ||
const saveSessionSpy = jest.fn(); | ||
|
||
jest.mock('../../src/session/saveSession', () => { | ||
return { | ||
saveSession: saveSessionSpy, | ||
}; | ||
}); | ||
|
||
Comment on lines
-19
to
-26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This gets hoisted and yells at you for using vars outside of scope |
||
const { replay } = await resetSdkMock({ | ||
replayOptions: { | ||
stickySession, | ||
}, | ||
}); | ||
|
||
// Initially called up to three times: once for start, then once for replay.updateSessionActivity & once for segmentId increase | ||
expect(saveSessionSpy).toHaveBeenCalledTimes(addSummand * 3); | ||
expect(saveSession).toHaveBeenCalledTimes(addSummand * 3); | ||
|
||
replay['_updateSessionActivity'](); | ||
|
||
expect(saveSessionSpy).toHaveBeenCalledTimes(addSummand * 4); | ||
expect(saveSession).toHaveBeenCalledTimes(addSummand * 4); | ||
|
||
// In order for runFlush to actually do something, we need to add an event | ||
const event = { | ||
|
@@ -48,8 +49,8 @@ describe('Integration | autoSaveSession', () => { | |
|
||
addEvent(replay, event); | ||
|
||
await replay['_runFlush'](); | ||
await Promise.all([replay['_runFlush'](), vi.runAllTimersAsync()]); | ||
|
||
expect(saveSessionSpy).toHaveBeenCalledTimes(addSummand * 5); | ||
expect(saveSession).toHaveBeenCalledTimes(addSummand * 5); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this, kept running into lint errors because I only want to
yarn fix
this package.