diff --git a/test/e2e/scenario/recorder/recorder.scenario.ts b/test/e2e/scenario/recorder/recorder.scenario.ts index 0fdae3ba91..e73e2ef105 100644 --- a/test/e2e/scenario/recorder/recorder.scenario.ts +++ b/test/e2e/scenario/recorder/recorder.scenario.ts @@ -1,4 +1,10 @@ -import type { InputData, StyleSheetRuleData, CreationReason, BrowserSegment } from '@datadog/browser-rum/src/types' +import type { + InputData, + StyleSheetRuleData, + CreationReason, + BrowserSegment, + ScrollData, +} from '@datadog/browser-rum/src/types' import { NodeType, IncrementalSource, RecordType, MouseInteractionType } from '@datadog/browser-rum/src/types' import type { RumInitConfiguration } from '@datadog/browser-rum-core' @@ -16,11 +22,12 @@ import { createMutationPayloadValidatorFromSegment, findAllFrustrationRecords, findMouseInteractionRecords, + findElementWithTagName, } from '@datadog/browser-rum/test/utils' import { renewSession } from '../../lib/helpers/session' import type { EventRegistry } from '../../lib/framework' import { flushEvents, createTest, bundleSetup, html } from '../../lib/framework' -import { browserExecute } from '../../lib/helpers/browser' +import { browserExecute, browserExecuteAsync } from '../../lib/helpers/browser' const INTEGER_RE = /^\d+$/ const TIMESTAMP_RE = /^\d{13}$/ @@ -721,6 +728,85 @@ describe('recorder', () => { }) }) }) + + describe('scroll positions', () => { + createTest('should be recorded across navigation') + .withRum() + .withSetup(bundleSetup) + .withBody( + html` + +
+
I'm bigger than the container
+
+
+ ` + ) + .run(async ({ serverEvents }) => { + await browserExecute(() => { + // initial scroll positions + window.scrollTo(0, 100) + document.getElementById('container')!.scrollTo(10, 0) + + window.DD_RUM!.startSessionReplayRecording() + }) + + await browserExecuteAsync((done) => + // wait for recording to be properly started + setTimeout(() => { + // update scroll positions + window.scrollTo(0, 150) + document.getElementById('container')!.scrollTo(20, 0) + + done(undefined) + }, 200) + ) + + await browserExecuteAsync((done) => { + setTimeout(() => { + // trigger new full snapshot + window.DD_RUM!.startView() + + done(undefined) + }, 200) + }) + + await flushEvents() + + expect(serverEvents.sessionReplay.length).toBe(2, 'number of segments') + const firstSegment = getFirstSegment(serverEvents) + + const firstFullSnapshot = findFullSnapshot(firstSegment)! + let htmlElement = findElementWithTagName(firstFullSnapshot.data.node, 'html')! + expect(htmlElement.attributes.rr_scrollTop).toBe(100) + let containerElement = findElementWithIdAttribute(firstFullSnapshot.data.node, 'container')! + expect(containerElement.attributes.rr_scrollLeft).toBe(10) + + const scrollRecords = findAllIncrementalSnapshots(firstSegment, IncrementalSource.Scroll) + expect(scrollRecords.length).toBe(2, 'number of scroll records') + const [windowScrollData, containerScrollData] = scrollRecords.map((record) => record.data as ScrollData) + expect(windowScrollData.y).toEqual(150) + expect(containerScrollData.x).toEqual(20) + + const secondFullSnapshot = findFullSnapshot(getLastSegment(serverEvents))! + htmlElement = findElementWithTagName(secondFullSnapshot.data.node, 'html')! + expect(htmlElement.attributes.rr_scrollTop).toBe(150) + containerElement = findElementWithIdAttribute(secondFullSnapshot.data.node, 'container')! + expect(containerElement.attributes.rr_scrollLeft).toBe(20) + }) + }) }) function getFirstSegment(events: EventRegistry) {