Skip to content

Commit

Permalink
Add a feature detection to start recording when a compatible bridge i…
Browse files Browse the repository at this point in the history
…s present
  • Loading branch information
amortemousque committed Jan 31, 2024
1 parent 179840f commit 8df8521
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export {
Payload,
createHttpRequest,
canUseEventBridge,
isBridgeForRecordsSupported,
getEventBridge,
startBatchWithReplica,
createFlushController,
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/transport/eventBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export function getEventBridge<T, E>() {
}
}

export function isBridgeForRecordsSupported(): boolean {
const bridge = getEventBridgeGlobal()
return !!bridge && 'getPrivacyLevel' in bridge
}

export function canUseEventBridge(currentHost = getGlobalObject<Window>().location?.hostname): boolean {
const bridge = getEventBridge()
return (
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/transport/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export { HttpRequest, createHttpRequest, Payload, RetryInfo } from './httpRequest'
export { canUseEventBridge, getEventBridge, BrowserWindowWithEventBridge } from './eventBridge'
export {
canUseEventBridge,
isBridgeForRecordsSupported,
getEventBridge,
BrowserWindowWithEventBridge,
DatadogEventBridge,
} from './eventBridge'
export { startBatchWithReplica } from './startBatchWithReplica'
export { createFlushController, FlushController, FlushEvent, FlushReason } from './flushController'
12 changes: 8 additions & 4 deletions packages/core/test/emulate/eventBridge.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { DefaultPrivacyLevel } from '../../src/domain/configuration'
import type { BrowserWindowWithEventBridge } from '../../src/transport'
import type { BrowserWindowWithEventBridge, DatadogEventBridge } from '../../src/transport'
import { registerCleanupTask } from '../registerCleanupTask'

export function initEventBridgeStub({
allowedWebViewHosts = [window.location.hostname],
privacyLevel = DefaultPrivacyLevel.MASK,
}: { allowedWebViewHosts?: string[]; privacyLevel?: DefaultPrivacyLevel } = {}) {
const eventBridgeStub = {
bridgeForRecordsSupported = true,
}: { allowedWebViewHosts?: string[]; privacyLevel?: DefaultPrivacyLevel; bridgeForRecordsSupported?: boolean } = {}) {
const eventBridgeStub: DatadogEventBridge = {
send: (_msg: string) => undefined,
getAllowedWebViewHosts: () => JSON.stringify(allowedWebViewHosts),
getPrivacyLevel: () => privacyLevel,
}
if (bridgeForRecordsSupported) {
eventBridgeStub.getPrivacyLevel = () => privacyLevel
}

;(window as BrowserWindowWithEventBridge).DatadogEventBridge = eventBridgeStub

registerCleanupTask(() => {
Expand Down
1 change: 0 additions & 1 deletion packages/rum-core/src/domain/assembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ export function startRumAssembly(

const syntheticsContext = getSyntheticsContext()
const ciTestContext = getCiTestContext()

lifeCycle.subscribe(
LifeCycleEventType.RAW_RUM_EVENT_COLLECTED,
({ startTime, rawRumEvent, domainContext, savedCommonContext, customerContext }) => {
Expand Down
21 changes: 19 additions & 2 deletions packages/rum-core/src/domain/rumSessionManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ import {
DOM_EVENT,
} from '@datadog/browser-core'
import type { Clock } from '@datadog/browser-core/test'
import { createNewEvent, mockClock } from '@datadog/browser-core/test'
import { createNewEvent, initEventBridgeStub, mockClock } from '@datadog/browser-core/test'
import type { RumConfiguration } from './configuration'
import { validateAndBuildRumConfiguration } from './configuration'

import { LifeCycle, LifeCycleEventType } from './lifeCycle'
import { RUM_SESSION_KEY, RumTrackingType, startRumSessionManager } from './rumSessionManager'
import {
RUM_SESSION_KEY,
RumTrackingType,
startRumSessionManager,
startRumSessionManagerStub,
} from './rumSessionManager'

describe('rum session manager', () => {
const DURATION = 123456
Expand Down Expand Up @@ -221,3 +226,15 @@ describe('rum session manager', () => {
)
})
})

describe('rum session manager stub', () => {
it('should return a tracked session with replay allowed when the event bridge support records', () => {
initEventBridgeStub({ bridgeForRecordsSupported: true })
expect(startRumSessionManagerStub().findTrackedSession()!.sessionReplayAllowed).toEqual(true)
})

it('should return a tracked session without replay allowed when the event bridge support records', () => {
initEventBridgeStub({ bridgeForRecordsSupported: false })
expect(startRumSessionManagerStub().findTrackedSession()!.sessionReplayAllowed).toEqual(false)
})
})
4 changes: 2 additions & 2 deletions packages/rum-core/src/domain/rumSessionManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { RelativeTime } from '@datadog/browser-core'
import { Observable, noop, performDraw, startSessionManager } from '@datadog/browser-core'
import { Observable, isBridgeForRecordsSupported, noop, performDraw, startSessionManager } from '@datadog/browser-core'
import type { RumConfiguration } from './configuration'
import type { LifeCycle } from './lifeCycle'
import { LifeCycleEventType } from './lifeCycle'
Expand Down Expand Up @@ -58,7 +58,7 @@ export function startRumSessionManager(configuration: RumConfiguration, lifeCycl
export function startRumSessionManagerStub(): RumSessionManager {
const session: RumSession = {
id: '00000000-aaaa-0000-aaaa-000000000000',
sessionReplayAllowed: true,
sessionReplayAllowed: isBridgeForRecordsSupported(),
}
return {
findTrackedSession: () => session,
Expand Down
15 changes: 11 additions & 4 deletions packages/rum/src/boot/recorderApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,21 @@ describe('makeRecorderApi', () => {
})

describe('if event bridge present', () => {
beforeEach(() => {
initEventBridgeStub()
})
it('should start recording when the bridge supports records', () => {
initEventBridgeStub({ bridgeForRecordsSupported: true })

it('does not start recording', () => {
setupBuilder.build()
rumInit()
recorderApi.start()
expect(startRecordingSpy).toHaveBeenCalled()
})

it('should not start recording when the bridge does not support records', () => {
initEventBridgeStub({ bridgeForRecordsSupported: false })

setupBuilder.build()
rumInit()
recorderApi.start()
expect(startRecordingSpy).not.toHaveBeenCalled()
})
})
Expand Down
10 changes: 8 additions & 2 deletions packages/rum/src/boot/recorderApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { DeflateEncoder } from '@datadog/browser-core'
import { DeflateEncoderStreamId, noop, runOnReadyState } from '@datadog/browser-core'
import {
DeflateEncoderStreamId,
canUseEventBridge,
isBridgeForRecordsSupported,
noop,
runOnReadyState,
} from '@datadog/browser-core'
import type {
LifeCycle,
ViewContexts,
Expand Down Expand Up @@ -53,7 +59,7 @@ export function makeRecorderApi(
startRecordingImpl: StartRecording,
createDeflateWorkerImpl?: CreateDeflateWorker
): RecorderApi {
if (!isBrowserSupported()) {
if ((canUseEventBridge() && !isBridgeForRecordsSupported()) || !isBrowserSupported()) {
return {
start: noop,
stop: noop,
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/lib/framework/pageSetups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ function setupEventBridge(servers: Servers) {
return html`
<script type="text/javascript">
window.DatadogEventBridge = {
getPrivacyLevel() {
return 'mask'
},
getAllowedWebViewHosts() {
return '["${baseHostname}"]'
},
Expand Down

0 comments on commit 8df8521

Please sign in to comment.