Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 0 additions & 2 deletions packages/core/src/tools/experimentalFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { objectHasValue } from './utils/objectUtils'
export enum ExperimentalFeature {
TRACK_INTAKE_REQUESTS = 'track_intake_requests',
FEATURE_OPERATION_VITAL = 'feature_operation_vital',
START_STOP_ACTION = 'start_stop_action',
START_STOP_RESOURCE = 'start_stop_resource',
TOO_MANY_REQUESTS_INVESTIGATION = 'too_many_requests_investigation',
SESSION_RENEWAL_DEBUG_CONTEXT = 'session_renewal_debug_context',
}
Expand Down
4 changes: 0 additions & 4 deletions packages/rum-core/src/boot/preStartRum.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import {
TrackingConsent,
createTrackingConsentState,
DefaultPrivacyLevel,
ExperimentalFeature,
startTelemetry,
addExperimentalFeatures,
startSessionManager,
} from '@datadog/browser-core'
import type { Clock } from '@datadog/browser-core/test'
Expand Down Expand Up @@ -918,8 +916,6 @@ describe('preStartRum', () => {
})

it('startAction / stopAction', async () => {
addExperimentalFeatures([ExperimentalFeature.START_STOP_ACTION])

const startActionSpy = jasmine.createSpy()
const stopActionSpy = jasmine.createSpy()
doStartRumSpy.and.returnValue({
Expand Down
46 changes: 0 additions & 46 deletions packages/rum-core/src/boot/rumPublicApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import {
display,
DefaultPrivacyLevel,
timeStampToClocks,
ExperimentalFeature,
ResourceType,
startTelemetry,
addExperimentalFeatures,
startSessionManager,
getTimeStamp,
} from '@datadog/browser-core'
Expand Down Expand Up @@ -852,7 +850,6 @@ describe('rum public api', () => {
describe('startAction / stopAction', () => {
it('should call startAction and stopAction on the strategy', async () => {
const clock = mockClock()
addExperimentalFeatures([ExperimentalFeature.START_STOP_ACTION])

const startActionSpy = jasmine.createSpy('startAction')
const stopActionSpy = jasmine.createSpy('stopAction')
Expand Down Expand Up @@ -894,8 +891,6 @@ describe('rum public api', () => {
})

it('should sanitize startAction and stopAction inputs', async () => {
addExperimentalFeatures([ExperimentalFeature.START_STOP_ACTION])

const startActionSpy = jasmine.createSpy()
const { rumPublicApi } = makeRumPublicApiWithDefaults({
startRumResult: {
Expand All @@ -920,31 +915,11 @@ describe('rum public api', () => {
})
)
})

it('should not call startAction/stopAction when feature flag is disabled', async () => {
const startActionSpy = jasmine.createSpy()
const stopActionSpy = jasmine.createSpy()
const { rumPublicApi, startRumSpy } = makeRumPublicApiWithDefaults({
startRumResult: {
startAction: startActionSpy,
stopAction: stopActionSpy,
},
})

rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)
rumPublicApi.startAction('purchase', { type: ActionType.CUSTOM })
rumPublicApi.stopAction('purchase')
await collectAsyncCalls(startRumSpy, 1)

expect(startActionSpy).not.toHaveBeenCalled()
expect(stopActionSpy).not.toHaveBeenCalled()
})
})

describe('startResource / stopResource', () => {
it('should call startResource and stopResource on the strategy', async () => {
const clock = mockClock()
addExperimentalFeatures([ExperimentalFeature.START_STOP_RESOURCE])

const startResourceSpy = jasmine.createSpy('startResource')
const stopResourceSpy = jasmine.createSpy('stopResource')
Expand Down Expand Up @@ -993,8 +968,6 @@ describe('rum public api', () => {
})

it('should sanitize startResource and stopResource inputs', async () => {
addExperimentalFeatures([ExperimentalFeature.START_STOP_RESOURCE])

const startResourceSpy = jasmine.createSpy()
const { rumPublicApi } = makeRumPublicApiWithDefaults({
startRumResult: {
Expand All @@ -1020,25 +993,6 @@ describe('rum public api', () => {
})
)
})

it('should not call startResource/stopResource when feature flag is disabled', async () => {
const startResourceSpy = jasmine.createSpy()
const stopResourceSpy = jasmine.createSpy()
const { rumPublicApi, startRumSpy } = makeRumPublicApiWithDefaults({
startRumResult: {
startResource: startResourceSpy,
stopResource: stopResourceSpy,
},
})

rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)
rumPublicApi.startResource('https://api.example.com/data', { type: ResourceType.FETCH })
rumPublicApi.stopResource('https://api.example.com/data')
await collectAsyncCalls(startRumSpy, 1)

expect(startResourceSpy).not.toHaveBeenCalled()
expect(stopResourceSpy).not.toHaveBeenCalled()
})
})

describe('addDurationVital', () => {
Expand Down
57 changes: 33 additions & 24 deletions packages/rum-core/src/boot/rumPublicApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ import {
CustomerContextKey,
defineContextMethod,
startBufferingData,
isExperimentalFeatureEnabled,
ExperimentalFeature,
mockable,
generateUUID,
timeStampNow,
Expand Down Expand Up @@ -176,16 +174,29 @@ export interface RumPublicApi extends PublicApi {
addAction: (name: string, context?: object) => void

/**
* [Experimental] Start an action, stored in `@action`
* Start tracking a custom action.
*
* Call {@link stopAction} with the same name (and optional `actionKey`) to send a RUM action event
* with the elapsed duration. Errors and resources triggered between start and stop are associated
* with the action.
*
* @category Data Collection
* @param name - Name of the action
* @param options - Options of the action (@default type: 'custom')
* @example
* ```ts
* datadogRum.startAction('checkout', { context: { cartId: 'abc' } })
* // ... user completes checkout
* datadogRum.stopAction('checkout')
* ```
*/
startAction: (name: string, options?: ActionOptions) => void

/**
* [Experimental] Stop an action, stored in `@action`
* Stop tracking a custom action started with {@link startAction}.
*
* Sends a RUM action event with the elapsed duration since the matching start call. Context from
* start and stop calls is merged into the event.
*
* @category Data Collection
* @param name - Name of the action
Expand All @@ -194,16 +205,28 @@ export interface RumPublicApi extends PublicApi {
stopAction: (name: string, options?: ActionOptions) => void

/**
* [Experimental] Start tracking a resource, stored in `@resource`
* Start tracking a resource manually.
*
* Use this for network activity that the SDK cannot automatically instrument. Call {@link stopResource}
* with the same URL (and optional `resourceKey`) to send a RUM resource event with the elapsed duration.
*
* @category Data Collection
* @param url - URL of the resource
* @param options - Options of the resource (@default type: 'other')
* @example
* ```ts
* datadogRum.startResource('https://api.example.com/users', { type: 'fetch', method: 'POST' })
* // ... perform the request
* datadogRum.stopResource('https://api.example.com/users', { statusCode: 201 })
* ```
*/
startResource: (url: string, options?: ResourceOptions) => void

/**
* [Experimental] Stop tracking a resource, stored in `@resource`
* Stop tracking a resource started with {@link startResource}.
*
* Sends a RUM resource event with the elapsed duration since the matching start call. Context from
* start and stop calls is merged into the event.
*
* @category Data Collection
* @param url - URL of the resource
Expand Down Expand Up @@ -727,11 +750,7 @@ export function makeRumPublicApi(
},

startAction: monitor((name, options) => {
// Check feature flag only after init; pre-init calls should be buffered
if (strategy.initConfiguration && !isExperimentalFeatureEnabled(ExperimentalFeature.START_STOP_ACTION)) {
return
}
// addTelemetryUsage({ feature: 'start-action' })
addTelemetryUsage({ feature: 'start-action' })
strategy.startAction(sanitize(name)!, {
type: sanitize(options && options.type) as ActionType | undefined,
context: sanitize(options && options.context) as Context,
Expand All @@ -740,10 +759,7 @@ export function makeRumPublicApi(
}),

stopAction: monitor((name, options) => {
if (strategy.initConfiguration && !isExperimentalFeatureEnabled(ExperimentalFeature.START_STOP_ACTION)) {
return
}
// addTelemetryUsage({ feature: 'stop-action' })
addTelemetryUsage({ feature: 'stop-action' })
strategy.stopAction(sanitize(name)!, {
type: sanitize(options && options.type) as ActionType | undefined,
context: sanitize(options && options.context) as Context,
Expand All @@ -752,11 +768,7 @@ export function makeRumPublicApi(
}),

startResource: monitor((url, options) => {
// Check feature flag only after init; pre-init calls should be buffered
if (strategy.initConfiguration && !isExperimentalFeatureEnabled(ExperimentalFeature.START_STOP_RESOURCE)) {
return
}
// addTelemetryUsage({ feature: 'start-resource' })
addTelemetryUsage({ feature: 'start-resource' })
strategy.startResource(sanitize(url)!, {
type: sanitize(options && options.type) as ResourceType | undefined,
method: sanitize(options && options.method) as string | undefined,
Expand All @@ -766,10 +778,7 @@ export function makeRumPublicApi(
}),

stopResource: monitor((url, options) => {
if (strategy.initConfiguration && !isExperimentalFeatureEnabled(ExperimentalFeature.START_STOP_RESOURCE)) {
return
}
// addTelemetryUsage({ feature: 'stop-resource' })
addTelemetryUsage({ feature: 'stop-resource' })
strategy.stopResource(sanitize(url)!, {
type: sanitize(options && options.type) as ResourceType | undefined,
statusCode: options && options.statusCode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Duration, ServerDuration } from '@datadog/browser-core'
import { addExperimentalFeatures, ExperimentalFeature, Observable } from '@datadog/browser-core'
import { Observable } from '@datadog/browser-core'
import type { Clock } from '@datadog/browser-core/test'
import { mockClock, registerCleanupTask } from '@datadog/browser-core/test'
import { collectAndValidateRawRumEvents, mockRumConfiguration } from '../../../test'
Expand All @@ -21,7 +21,6 @@ describe('trackManualActions', () => {

beforeEach(() => {
clock = mockClock()
addExperimentalFeatures([ExperimentalFeature.START_STOP_ACTION])

const domMutationObservable = new Observable<RumMutationRecord[]>()
const windowOpenObservable = new Observable<void>()
Expand Down
14 changes: 7 additions & 7 deletions test/e2e/scenario/rum/actions.scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ test.describe('action collection with shadow DOM', () => {

test.describe('custom actions with startAction/stopAction', () => {
createTest('track a custom action with startAction/stopAction')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startAction('checkout')
Expand All @@ -623,7 +623,7 @@ test.describe('custom actions with startAction/stopAction', () => {
})

createTest('associate an error to a custom action')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startAction('checkout')
Expand All @@ -646,7 +646,7 @@ test.describe('custom actions with startAction/stopAction', () => {
})

createTest('associate a resource to a custom action')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startAction('load-data')
Expand All @@ -671,7 +671,7 @@ test.describe('custom actions with startAction/stopAction', () => {
})

createTest('track multiple concurrent custom actions with actionKey')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startAction('click', { actionKey: 'button1' })
Expand All @@ -687,7 +687,7 @@ test.describe('custom actions with startAction/stopAction', () => {
})

createTest('merge contexts from start and stop')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startAction('purchase', { context: { cart_id: 'abc123' } })
Expand All @@ -706,7 +706,7 @@ test.describe('custom actions with startAction/stopAction', () => {
})

createTest('preserve timing when startAction is called before init')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.withRumInit((configuration) => {
window.DD_RUM!.startAction('pre_init_action')

Expand All @@ -725,7 +725,7 @@ test.describe('custom actions with startAction/stopAction', () => {
})

createTest('attribute errors and resources to action started before init')
.withRum({ enableExperimentalFeatures: ['start_stop_action'] })
.withRum()
.withRumInit((configuration) => {
window.DD_RUM!.startAction('pre_init_action')

Expand Down
10 changes: 5 additions & 5 deletions test/e2e/scenario/rum/resources.scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ test.describe('resource headers with trackResourceHeaders', () => {

test.describe('manual resources with startResource/stopResource', () => {
createTest('track a manual resource with startResource/stopResource')
.withRum({ enableExperimentalFeatures: ['start_stop_resource'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startResource('https://api.example.com/data')
Expand All @@ -524,7 +524,7 @@ test.describe('manual resources with startResource/stopResource', () => {
})

createTest('track a manual resource with type and method')
.withRum({ enableExperimentalFeatures: ['start_stop_resource'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startResource('https://api.example.com/users', {
Expand All @@ -547,7 +547,7 @@ test.describe('manual resources with startResource/stopResource', () => {
})

createTest('track multiple concurrent manual resources with resourceKey')
.withRum({ enableExperimentalFeatures: ['start_stop_resource'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startResource('https://api.example.com/data', { resourceKey: 'request1' })
Expand All @@ -565,7 +565,7 @@ test.describe('manual resources with startResource/stopResource', () => {
})

createTest('merge contexts from start and stop')
.withRum({ enableExperimentalFeatures: ['start_stop_resource'] })
.withRum()
.run(async ({ intakeRegistry, flushEvents, page }) => {
await page.evaluate(() => {
window.DD_RUM!.startResource('https://api.example.com/data', {
Expand All @@ -590,7 +590,7 @@ test.describe('manual resources with startResource/stopResource', () => {
})

createTest('preserve timing when startResource is called before init')
.withRum({ enableExperimentalFeatures: ['start_stop_resource'] })
.withRum()
.withRumInit((configuration) => {
window.DD_RUM!.startResource('https://api.example.com/early')

Expand Down
Loading