diff --git a/packages/replay-internal/src/integration.ts b/packages/replay-internal/src/integration.ts index c3c448a3c6f2..1f690f9af88a 100644 --- a/packages/replay-internal/src/integration.ts +++ b/packages/replay-internal/src/integration.ts @@ -1,5 +1,11 @@ import { parseSampleRate } from '@sentry/core'; -import type { BrowserClientReplayOptions, Client, Integration, IntegrationFn } from '@sentry/types'; +import type { + BrowserClientReplayOptions, + Client, + Integration, + IntegrationFn, + ReplayRecordingMode, +} from '@sentry/types'; import { consoleSandbox, dropUndefinedKeys, isBrowser } from '@sentry/utils'; import { @@ -297,6 +303,22 @@ export class Replay implements Integration { return this._replay.getSessionId(); } + /** + * Get the current recording mode. This can be either `session` or `buffer`. + * + * `session`: Recording the whole session, sending it continuously + * `buffer`: Always keeping the last 60s of recording, requires: + * - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs + * - or calling `flush()` to send the replay + */ + public getRecordingMode(): ReplayRecordingMode | undefined { + if (!this._replay || !this._replay.isEnabled()) { + return; + } + + return this._replay.recordingMode; + } + /** * Initializes replay. */ diff --git a/packages/replay-internal/src/replay.ts b/packages/replay-internal/src/replay.ts index cfd8a2a45c33..0976b7d57870 100644 --- a/packages/replay-internal/src/replay.ts +++ b/packages/replay-internal/src/replay.ts @@ -74,7 +74,7 @@ export class ReplayContainer implements ReplayContainerInterface { public clickDetector: ClickDetector | undefined; /** - * Recording can happen in one of three modes: + * Recording can happen in one of two modes: * - session: Record the whole session, sending it continuously * - buffer: Always keep the last 60s of recording, requires: * - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs diff --git a/packages/replay-internal/test/integration/recordingMode.test.ts b/packages/replay-internal/test/integration/recordingMode.test.ts new file mode 100644 index 000000000000..400a9ffd47b1 --- /dev/null +++ b/packages/replay-internal/test/integration/recordingMode.test.ts @@ -0,0 +1,83 @@ +/** + * @vitest-environment jsdom + */ + +import { describe, expect, test } from 'vitest'; +import { resetSdkMock } from '../mocks/resetSdkMock'; +import { useFakeTimers } from '../utils/use-fake-timers'; + +useFakeTimers(); + +describe('Integration | getRecordingMode()', () => { + test('returns "session" when session sampling is enabled', async () => { + const { integration } = await resetSdkMock({ + replayOptions: { + stickySession: false, + }, + sentryOptions: { + replaysSessionSampleRate: 1.0, + }, + }); + expect(integration.getRecordingMode()).toBe('session'); + }); + + test('returns "buffer" when buffering is enabled', async () => { + const { integration, replay } = await resetSdkMock({ + replayOptions: { + stickySession: false, + }, + sentryOptions: { + replaysSessionSampleRate: 1.0, + }, + }); + replay.stop(); + replay.startBuffering(); + expect(integration.getRecordingMode()).toBe('buffer'); + }); + + test('returns undefined when replay is stopped', async () => { + const { integration, replay } = await resetSdkMock({ + replayOptions: { + stickySession: false, + }, + sentryOptions: { + replaysSessionSampleRate: 1.0, + }, + }); + replay.stop(); + expect(integration.getRecordingMode()).toBeUndefined(); + }); + + test('returns undefined when session sampling is disabled', async () => { + const { integration } = await resetSdkMock({ + replayOptions: { stickySession: false }, + sentryOptions: { + replaysSessionSampleRate: 0.0, + replaysOnErrorSampleRate: 0.0, + }, + }); + expect(integration.getRecordingMode()).toBeUndefined(); + }); + + test('returns "buffer" when session rate is 0 and onError rate is 1', async () => { + const { integration } = await resetSdkMock({ + replayOptions: { stickySession: false }, + sentryOptions: { + replaysSessionSampleRate: 0.0, + replaysOnErrorSampleRate: 1.0, + }, + }); + expect(integration.getRecordingMode()).toBe('buffer'); + }); + + test('returns "session" when both sampling rates are 1', async () => { + const { integration } = await resetSdkMock({ + replayOptions: { stickySession: false }, + sentryOptions: { + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 1.0, + }, + }); + expect(integration.getRecordingMode()).toBe('session'); + }); +});