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) {