Skip to content
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

💥 [RUMF-1589] automatically start recording #2275

Merged
merged 7 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/core/src/domain/telemetry/telemetryEvent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ export type TelemetryConfigurationEvent = CommonTelemetryProperties & {
* The percentage of sessions with Browser RUM & Session Replay pricing tracked
*/
session_replay_sample_rate?: number
/**
* Whether the session replay start is handled manually
*/
start_session_replay_recording_manually?: boolean
/**
* Whether a proxy configured is used
*/
Expand Down
35 changes: 32 additions & 3 deletions packages/rum-core/src/boot/rumPublicApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -829,23 +829,25 @@ describe('rum public api', () => {
let recorderApiOnRumStartSpy: jasmine.Spy<RecorderApi['onRumStart']>
let setupBuilder: TestSetupBuilder
let rumPublicApi: RumPublicApi
let recorderApi: RecorderApi

beforeEach(() => {
recorderApiOnRumStartSpy = jasmine.createSpy('recorderApiOnRumStart')
rumPublicApi = makeRumPublicApi(noopStartRum, { ...noopRecorderApi, onRumStart: recorderApiOnRumStartSpy })
recorderApi = { ...noopRecorderApi, onRumStart: recorderApiOnRumStartSpy }
rumPublicApi = makeRumPublicApi(noopStartRum, recorderApi)
setupBuilder = setup()
})

afterEach(() => {
setupBuilder.cleanup()
})

it('recording is started with the default defaultPrivacyLevel', () => {
it('is started with the default defaultPrivacyLevel', () => {
rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)
expect(recorderApiOnRumStartSpy.calls.mostRecent().args[1].defaultPrivacyLevel).toBe(DefaultPrivacyLevel.MASK)
})

it('recording is started with the configured defaultPrivacyLevel', () => {
it('is started with the configured defaultPrivacyLevel', () => {
rumPublicApi.init({
...DEFAULT_INIT_CONFIGURATION,
defaultPrivacyLevel: DefaultPrivacyLevel.MASK_USER_INPUT,
Expand All @@ -854,6 +856,33 @@ describe('rum public api', () => {
DefaultPrivacyLevel.MASK_USER_INPUT
)
})

it('api calls before init are performed after onRumStart', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice test!

// in order to let recording initial state to be defined by init configuration
const callOrders: string[] = []
spyOn(recorderApi, 'start').and.callFake(() => callOrders.push('start'))
spyOn(recorderApi, 'stop').and.callFake(() => callOrders.push('stop'))
recorderApiOnRumStartSpy.and.callFake(() => callOrders.push('onRumStart'))

rumPublicApi.startSessionReplayRecording()
rumPublicApi.stopSessionReplayRecording()
rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)

expect(callOrders).toEqual(['onRumStart', 'start', 'stop'])
})

it('is started with the default startSessionReplayRecordingManually', () => {
rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)
expect(recorderApiOnRumStartSpy.calls.mostRecent().args[1].startSessionReplayRecordingManually).toBe(false)
})

it('is started with the configured startSessionReplayRecordingManually', () => {
rumPublicApi.init({
...DEFAULT_INIT_CONFIGURATION,
startSessionReplayRecordingManually: true,
})
expect(recorderApiOnRumStartSpy.calls.mostRecent().args[1].startSessionReplayRecordingManually).toBe(true)
})
})

it('should provide sdk version', () => {
Expand Down
16 changes: 13 additions & 3 deletions packages/rum-core/src/boot/rumPublicApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ export function makeRumPublicApi(
bufferApiCalls.add(() => addErrorStrategy(providedError, commonContext))
}

let recorderStartStrategy: typeof recorderApi.start = () => {
bufferApiCalls.add(() => recorderStartStrategy())
}

let recorderStopStrategy: typeof recorderApi.stop = () => {
bufferApiCalls.add(() => recorderStopStrategy())
}

let addFeatureFlagEvaluationStrategy: StartRumResult['addFeatureFlagEvaluation'] = (key: string, value: any) => {
bufferApiCalls.add(() => addFeatureFlagEvaluationStrategy(key, value))
}
Expand Down Expand Up @@ -158,6 +166,8 @@ export function makeRumPublicApi(
)
getSessionReplayLinkStrategy = () =>
recorderApi.getSessionReplayLink(configuration, startRumResults.session, startRumResults.viewContexts)
recorderStartStrategy = recorderApi.start
recorderStopStrategy = recorderApi.stop
;({
startView: startViewStrategy,
addAction: addActionStrategy,
Expand All @@ -167,14 +177,14 @@ export function makeRumPublicApi(
getInternalContext: getInternalContextStrategy,
stopSession: stopSessionStrategy,
} = startRumResults)
bufferApiCalls.drain()

recorderApi.onRumStart(
startRumResults.lifeCycle,
configuration,
startRumResults.session,
startRumResults.viewContexts
)
bufferApiCalls.drain()
}

const startView: {
Expand Down Expand Up @@ -249,8 +259,8 @@ export function makeRumPublicApi(
stopSessionStrategy()
}),

startSessionReplayRecording: monitor(recorderApi.start),
stopSessionReplayRecording: monitor(recorderApi.stop),
startSessionReplayRecording: monitor(() => recorderStartStrategy()),
stopSessionReplayRecording: monitor(() => recorderStopStrategy()),

/**
* This feature is currently in beta. For more information see the full [feature flag tracking guide](https://docs.datadoghq.com/real_user_monitoring/feature_flag_tracking/).
Expand Down
28 changes: 28 additions & 0 deletions packages/rum-core/src/domain/configuration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,34 @@ describe('validateAndBuildRumConfiguration', () => {
})
})

describe('startSessionReplayRecordingManually', () => {
it('defaults to false', () => {
expect(
validateAndBuildRumConfiguration(DEFAULT_INIT_CONFIGURATION)!.startSessionReplayRecordingManually
).toBeFalse()
})

it('is set to provided value', () => {
expect(
validateAndBuildRumConfiguration({ ...DEFAULT_INIT_CONFIGURATION, startSessionReplayRecordingManually: true })!
.startSessionReplayRecordingManually
).toBeTrue()
expect(
validateAndBuildRumConfiguration({ ...DEFAULT_INIT_CONFIGURATION, startSessionReplayRecordingManually: false })!
.startSessionReplayRecordingManually
).toBeFalse()
})

it('the provided value is cast to boolean', () => {
expect(
validateAndBuildRumConfiguration({
...DEFAULT_INIT_CONFIGURATION,
startSessionReplayRecordingManually: 'foo' as any,
})!.startSessionReplayRecordingManually
).toBeTrue()
})
})

describe('actionNameAttribute', () => {
it('defaults to undefined', () => {
expect(validateAndBuildRumConfiguration(DEFAULT_INIT_CONFIGURATION)!.actionNameAttribute).toBeUndefined()
Expand Down
4 changes: 4 additions & 0 deletions packages/rum-core/src/domain/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface RumInitConfiguration extends InitConfiguration {
defaultPrivacyLevel?: DefaultPrivacyLevel | undefined
subdomain?: string
sessionReplaySampleRate?: number | undefined
startSessionReplayRecordingManually?: boolean | undefined

// action options
trackUserInteractions?: boolean | undefined
Expand All @@ -53,6 +54,7 @@ export interface RumConfiguration extends Configuration {
applicationId: string
defaultPrivacyLevel: DefaultPrivacyLevel
sessionReplaySampleRate: number
startSessionReplayRecordingManually: boolean
trackUserInteractions: boolean
trackViewsManually: boolean
trackResources: boolean
Expand Down Expand Up @@ -104,6 +106,7 @@ export function validateAndBuildRumConfiguration(
version: initConfiguration.version,
actionNameAttribute: initConfiguration.actionNameAttribute,
sessionReplaySampleRate: initConfiguration.sessionReplaySampleRate ?? 0,
startSessionReplayRecordingManually: !!initConfiguration.startSessionReplayRecordingManually,
traceSampleRate: initConfiguration.traceSampleRate,
allowedTracingUrls,
excludedActivityUrls: initConfiguration.excludedActivityUrls ?? [],
Expand Down Expand Up @@ -181,6 +184,7 @@ export function serializeRumConfiguration(configuration: RumInitConfiguration):
return assign(
{
session_replay_sample_rate: configuration.sessionReplaySampleRate,
start_session_replay_recording_manually: configuration.startSessionReplayRecordingManually,
trace_sample_rate: configuration.traceSampleRate,
action_name_attribute: configuration.actionNameAttribute,
use_allowed_tracing_urls:
Expand Down
Loading