diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a0ce21803..99e6b4f337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - Skips development server spans ([#4271](https://github.com/getsentry/sentry-react-native/pull/4271)) - Execute `DebugSymbolicator` after `RewriteFrames` to avoid overwrites by default ([#4285](https://github.com/getsentry/sentry-react-native/pull/4285)) - If custom `RewriteFrames` is provided the order changes +- `browserReplayIntegration` is no longer included by default on React Native Web ([#4270](https://github.com/getsentry/sentry-react-native/pull/4270)) ### Dependencies diff --git a/packages/core/src/js/integrations/default.ts b/packages/core/src/js/integrations/default.ts index 483d1f6f3f..0f32ba6b16 100644 --- a/packages/core/src/js/integrations/default.ts +++ b/packages/core/src/js/integrations/default.ts @@ -4,14 +4,13 @@ import type { Integration } from '@sentry/types'; import type { ReactNativeClientOptions } from '../options'; import { reactNativeTracingIntegration } from '../tracing'; -import { isExpoGo, notWeb } from '../utils/environment'; +import { isExpoGo, isWeb, notWeb } from '../utils/environment'; import { appStartIntegration, breadcrumbsIntegration, browserApiErrorsIntegration, browserGlobalHandlersIntegration, browserLinkedErrorsIntegration, - browserReplayIntegration, createNativeFramesIntegrations, createReactNativeRewriteFrames, debugSymbolicatorIntegration, @@ -132,10 +131,13 @@ export function getDefaultIntegrations(options: ReactNativeClientOptions): Integ (options._experiments && typeof options._experiments.replaysOnErrorSampleRate === 'number') || (options._experiments && typeof options._experiments.replaysSessionSampleRate === 'number') ) { - integrations.push(notWeb() ? mobileReplayIntegration() : browserReplayIntegration()); - if (!notWeb()) { + if (isWeb()) { + // We can't create and add browserReplayIntegration as it overrides the users supplied one + // The browser replay integration works differently than the rest of default integrations (options as BrowserOptions).replaysOnErrorSampleRate = options._experiments.replaysOnErrorSampleRate; (options as BrowserOptions).replaysSessionSampleRate = options._experiments.replaysSessionSampleRate; + } else { + integrations.push(mobileReplayIntegration()); } } diff --git a/packages/core/test/sdk.test.ts b/packages/core/test/sdk.test.ts index 2f9f6e4e69..c78774edea 100644 --- a/packages/core/test/sdk.test.ts +++ b/packages/core/test/sdk.test.ts @@ -15,7 +15,7 @@ import { init, withScope } from '../src/js/sdk'; import type { ReactNativeTracingIntegration } from '../src/js/tracing'; import { REACT_NATIVE_TRACING_INTEGRATION_NAME, reactNativeTracingIntegration } from '../src/js/tracing'; import { makeNativeTransport } from '../src/js/transports/native'; -import { getDefaultEnvironment, isExpoGo, notWeb } from '../src/js/utils/environment'; +import { getDefaultEnvironment, isExpoGo, isWeb, notWeb } from '../src/js/utils/environment'; import { NATIVE } from './mockWrapper'; import { firstArg, secondArg } from './testutils'; @@ -854,6 +854,84 @@ describe('Tests the SDK functionality', () => { expectIntegration('ExpoContext'); }); + + it('adds mobile replay integration when _experiments.replaysOnErrorSampleRate is set', () => { + init({ + _experiments: { + replaysOnErrorSampleRate: 1.0, + }, + }); + + expectIntegration('MobileReplay'); + }); + + it('adds mobile replay integration when _experiments.replaysSessionSampleRate is set', () => { + init({ + _experiments: { + replaysSessionSampleRate: 1.0, + }, + }); + + expectIntegration('MobileReplay'); + }); + + it('does not add mobile replay integration when no replay sample rates are set', () => { + init({ + _experiments: {}, + }); + + expectNotIntegration('MobileReplay'); + }); + + it('does not add any replay integration when on web even with on error sample rate', () => { + (isWeb as jest.Mock).mockImplementation(() => true); + init({ + _experiments: { + replaysOnErrorSampleRate: 1.0, + }, + }); + + expectNotIntegration('Replay'); + expectNotIntegration('MobileReplay'); + }); + + it('does not add any replay integration when on web even with session sample rate', () => { + (isWeb as jest.Mock).mockImplementation(() => true); + init({ + _experiments: { + replaysSessionSampleRate: 1.0, + }, + }); + + expectNotIntegration('Replay'); + expectNotIntegration('MobileReplay'); + }); + + it('does not add any replay integration when on web', () => { + (isWeb as jest.Mock).mockImplementation(() => true); + init({}); + + expectNotIntegration('Replay'); + expectNotIntegration('MobileReplay'); + }); + + it('converts experimental replay options to standard web options when on web', () => { + (isWeb as jest.Mock).mockImplementation(() => true); + init({ + _experiments: { + replaysOnErrorSampleRate: 0.5, + replaysSessionSampleRate: 0.1, + }, + }); + + const actualOptions = usedOptions(); + expect(actualOptions).toEqual( + expect.objectContaining({ + replaysOnErrorSampleRate: 0.5, + replaysSessionSampleRate: 0.1, + }), + ); + }); }); function expectIntegration(name: string): void {