Skip to content
Merged
1 change: 1 addition & 0 deletions packages/browser-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export * from './tools/utils/numberUtils'
export * from './tools/utils/byteUtils'
export * from './tools/utils/objectUtils'
export * from './tools/utils/functionUtils'
export * from './tools/queueMicrotask'
export * from './tools/serialisation/jsonStringify'
export * from './tools/serialisation/stringify'
export * from './tools/utils/stringUtils'
Expand Down
12 changes: 11 additions & 1 deletion packages/browser-core/test/emulate/mockClock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { TimeStamp, RelativeTime } from '@datadog/js-core/time'
import { queueMicrotask } from '../../src/tools/queueMicrotask'
import { registerCleanupTask } from '../registerCleanupTask'
import { replaceMockable } from '../replaceMockable'

export type Clock = ReturnType<typeof mockClock>

Expand All @@ -15,6 +17,11 @@ export function mockClock() {

registerCleanupTask(() => jasmine.clock().uninstall())

const pendingMicroTasks: Array<() => void> = []
replaceMockable(queueMicrotask, (callback) => {
pendingMicroTasks.push(callback)
})

return {
/**
* Returns a RelativeTime representing the time it was X milliseconds after the `mockClock()`
Expand All @@ -26,7 +33,10 @@ export function mockClock() {
* invokation (the start of the test).
*/
timeStamp: (duration: number) => (timeStampStart + duration) as TimeStamp,
tick: (ms: number) => jasmine.clock().tick(ms),
tick: (ms: number) => {
Comment thread
BenoitZugmeyer marked this conversation as resolved.
pendingMicroTasks.splice(0).forEach((task) => task())
jasmine.clock().tick(ms)
},
setDate: (date: Date) => jasmine.clock().mockDate(date),
}
}
24 changes: 14 additions & 10 deletions packages/browser-rum-core/src/boot/startRum.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ describe('session expiration lifecycle', () => {

describe('rum session', () => {
let serverRumEvents: RumEvent[]
let clock: Clock
let lifeCycle: LifeCycle
let sessionManager: SessionManagerMock

beforeEach(() => {
lifeCycle = new LifeCycle()
clock = mockClock()
sessionManager = createSessionManagerMock().setId('42')

serverRumEvents = collectServerEvents(lifeCycle)
Expand All @@ -106,22 +108,24 @@ describe('rum session', () => {
})

it('when the session is renewed, a new view event should be sent', () => {
expect(serverRumEvents.length).toEqual(1)
expect(serverRumEvents[0].type).toEqual('view')
expect(serverRumEvents[0].session.id).toEqual('42')
const getViewEvents = () =>
serverRumEvents.filter((event): event is RumViewEvent => event.type === RumEventType.VIEW)

clock.tick(0)
expect(getViewEvents().length).toEqual(1)
expect(getViewEvents()[0].session.id).toEqual('42')

lifeCycle.notify(LifeCycleEventType.SESSION_EXPIRED, { endClocks: relativeToClocks(relativeNow()) })
expect(serverRumEvents.length).toEqual(2)
expect(getViewEvents().length).toEqual(2)

sessionManager.setId('43')
lifeCycle.notify(LifeCycleEventType.SESSION_RENEWED)
clock.tick(0)

expect(serverRumEvents.length).toEqual(3)

// New view event
expect(serverRumEvents[2].type).toEqual('view')
expect(serverRumEvents[2].session.id).toEqual('43')
expect(serverRumEvents[2].view.id).not.toEqual(serverRumEvents[0].view.id)
const viewEvents = getViewEvents()
expect(viewEvents.length).toEqual(3)
expect(viewEvents[2].session.id).toEqual('43')
expect(viewEvents[2].view.id).not.toEqual(viewEvents[0].view.id)
})
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import { Observable } from '@datadog/browser-core'
import { deepClone } from '@datadog/js-core/util'
import { registerCleanupTask } from '@datadog/browser-core/test'
import { mockRumConfiguration, setupLocationObserver } from '../../../test'
import type { LifeCycle } from '../lifeCycle'
import { LifeCycleEventType } from '../lifeCycle'
import { LifeCycle, LifeCycleEventType } from '../lifeCycle'
import type { RumConfiguration } from '../configuration'
import type { RumMutationRecord } from '../../browser/domMutationObservable'
import type { ViewCreatedEvent, ViewEvent, ViewOptions, ViewEndedEvent } from './trackViews'
import { trackViews } from './trackViews'

export type ViewTest = ReturnType<typeof setupViewTest>

interface ViewTrackingContext {
lifeCycle: LifeCycle
interface ViewTestOptions {
initialLocation?: string
partialConfig?: Partial<RumConfiguration>
initialViewOptions?: ViewOptions
}

export function setupViewTest(
{ lifeCycle, initialLocation, partialConfig }: ViewTrackingContext,
initialViewOptions?: ViewOptions
) {
export function setupViewTest({ initialLocation, partialConfig, initialViewOptions }: ViewTestOptions = {}) {
const lifeCycle = new LifeCycle()
const domMutationObservable = new Observable<RumMutationRecord[]>()
const windowOpenObservable = new Observable<void>()
const configuration = mockRumConfiguration(partialConfig)
Expand Down Expand Up @@ -64,8 +62,11 @@ export function setupViewTest(
!configuration.trackViewsManually,
initialViewOptions
)

registerCleanupTask(stop)

return {
stop,
lifeCycle,
startView,
setViewContext,
setViewContextProperty,
Expand All @@ -80,9 +81,6 @@ export function setupViewTest(
getViewCreateCount,
getViewEnd,
getViewEndCount,
getLatestViewContext: () => ({
id: getViewCreate(getViewCreateCount() - 1).id,
}),
}
}

Expand Down
Loading
Loading