diff --git a/src/__tests__/extensions/replay/sessionrecording.test.ts b/src/__tests__/extensions/replay/sessionrecording.test.ts index c74dd883f..79e23290f 100644 --- a/src/__tests__/extensions/replay/sessionrecording.test.ts +++ b/src/__tests__/extensions/replay/sessionrecording.test.ts @@ -42,6 +42,7 @@ function makeDecideResponse(partialResponse: Partial) { } describe('SessionRecording', () => { + const _addCustomEvent = jest.fn() let _emit: any let posthog: PostHog let sessionRecording: SessionRecording @@ -54,6 +55,8 @@ describe('SessionRecording', () => { beforeEach(() => { assignableWindow.rrwebRecord = jest.fn() + _addCustomEvent.mockClear() + assignableWindow.rrwebRecord = _addCustomEvent assignableWindow.rrwebConsoleRecord = { getRecordConsolePlugin: jest.fn(), } @@ -283,6 +286,7 @@ describe('SessionRecording', () => { return () => {} }) assignableWindow.rrwebRecord.takeFullSnapshot = mockFullSnapshot + assignableWindow.rrwebRecord.addCustomEvent = _addCustomEvent ;(loadScript as any).mockImplementation((_path: any, callback: any) => callback()) }) @@ -369,7 +373,7 @@ describe('SessionRecording', () => { expect(sessionRecording['sessionId']).not.toBe(lastSessionId) lastSessionId = sessionRecording['sessionId'] - emitValues.push(sessionRecording.status) + emitValues.push(sessionRecording['status']) } // the random number generator won't always be exactly 0.5, but it should be close @@ -998,6 +1002,11 @@ describe('SessionRecording', () => { timestamp: lastActivityTimestamp + RECORDING_IDLE_ACTIVITY_TIMEOUT_MS + 1000, }) expect(sessionRecording['isIdle']).toEqual(true) + expect(_addCustomEvent).toHaveBeenCalledWith('sessionIdle', { + reason: 'user inactivity', + threshold: 300000, + timeSinceLastActive: 300900, + }) expect(sessionRecording['_lastActivityTimestamp']).toEqual(lastActivityTimestamp + 100) expect(assignableWindow.rrwebRecord.takeFullSnapshot).toHaveBeenCalledTimes(1) @@ -1011,6 +1020,10 @@ describe('SessionRecording', () => { timestamp: lastActivityTimestamp + RECORDING_IDLE_ACTIVITY_TIMEOUT_MS + 2000, }) expect(sessionRecording['isIdle']).toEqual(false) + expect(_addCustomEvent).toHaveBeenCalledWith('sessionNoLongerIdle', { + reason: 'user activity', + type: INCREMENTAL_SNAPSHOT_EVENT_TYPE, + }) expect(sessionRecording['_lastActivityTimestamp']).toEqual( lastActivityTimestamp + RECORDING_IDLE_ACTIVITY_TIMEOUT_MS + 2000 ) diff --git a/src/extensions/replay/sessionrecording.ts b/src/extensions/replay/sessionrecording.ts index 5718cb1fa..f8d770554 100644 --- a/src/extensions/replay/sessionrecording.ts +++ b/src/extensions/replay/sessionrecording.ts @@ -389,6 +389,11 @@ export class SessionRecording { // We check if the lastActivityTimestamp is old enough to go idle if (event.timestamp - this._lastActivityTimestamp > RECORDING_IDLE_ACTIVITY_TIMEOUT_MS) { this.isIdle = true + this.rrwebRecord?.addCustomEvent('sessionIdle', { + reason: 'user inactivity', + timeSinceLastActive: event.timestamp - this._lastActivityTimestamp, + threshold: RECORDING_IDLE_ACTIVITY_TIMEOUT_MS, + }) } } @@ -397,6 +402,10 @@ export class SessionRecording { if (this.isIdle) { // Remove the idle state if set and trigger a full snapshot as we will have ignored previous mutations this.isIdle = false + this.rrwebRecord?.addCustomEvent('sessionNoLongerIdle', { + reason: 'user activity', + type: event.type, + }) this._tryTakeFullSnapshot() } }