diff --git a/packages/rum/src/domain/record/mutationObserver.ts b/packages/rum/src/domain/record/mutationObserver.ts index d3ff3acda3..cb81b5e699 100644 --- a/packages/rum/src/domain/record/mutationObserver.ts +++ b/packages/rum/src/domain/record/mutationObserver.ts @@ -211,6 +211,7 @@ function processChildListMutations( document, serializedNodeIds, parentNodePrivacyLevel, + serializationContext: 'mutation', }) if (!serializedNode) { continue diff --git a/packages/rum/src/domain/record/serialize.spec.ts b/packages/rum/src/domain/record/serialize.spec.ts index 541987d0e3..f0f5953cf5 100644 --- a/packages/rum/src/domain/record/serialize.spec.ts +++ b/packages/rum/src/domain/record/serialize.spec.ts @@ -17,7 +17,7 @@ import { import type { ElementNode, SerializedNodeWithId, TextNode } from '../../types' import { NodeType } from '../../types' import { hasSerializedNode } from './serializationUtils' -import type { SerializeOptions } from './serialize' +import type { SerializeOptions, SerializationContext } from './serialize' import { serializeDocument, serializeNodeWithId, @@ -30,6 +30,7 @@ import { MAX_ATTRIBUTE_VALUE_CHAR_LENGTH } from './privacy' const DEFAULT_OPTIONS: SerializeOptions = { document, parentNodePrivacyLevel: NodePrivacyLevel.ALLOW, + serializationContext: 'full-snapshot', } describe('serializeNodeWithId', () => { @@ -113,22 +114,41 @@ describe('serializeNodeWithId', () => { style: 'width: 10px;', }) }) - - it('serializes scroll position', () => { - const element = document.createElement('div') - Object.assign(element.style, { width: '100px', height: '100px', overflow: 'scroll' }) - const inner = document.createElement('div') - Object.assign(inner.style, { width: '200px', height: '200px' }) - element.appendChild(inner) - sandbox.appendChild(element) - element.scrollBy(10, 20) - - expect((serializeNodeWithId(element, DEFAULT_OPTIONS)! as ElementNode).attributes).toEqual( - jasmine.objectContaining({ + ;[ + { + description: 'serializes scroll position during full snapshot', + serializationContext: 'full-snapshot' as SerializationContext, + shouldSerializeScroll: true, + }, + { + description: 'does not serialize scroll position during mutation', + serializationContext: 'mutation' as SerializationContext, + shouldSerializeScroll: false, + }, + ].forEach(({ description, serializationContext, shouldSerializeScroll }) => { + it(description, () => { + const element = document.createElement('div') + Object.assign(element.style, { width: '100px', height: '100px', overflow: 'scroll' }) + const inner = document.createElement('div') + Object.assign(inner.style, { width: '200px', height: '200px' }) + element.appendChild(inner) + sandbox.appendChild(element) + element.scrollBy(10, 20) + + const serializedAttributes = ( + serializeNodeWithId(element, { ...DEFAULT_OPTIONS, serializationContext })! as ElementNode + ).attributes + const attributesWithScrollPositions = jasmine.objectContaining({ rr_scrollTop: 20, rr_scrollLeft: 10, }) - ) + + if (shouldSerializeScroll) { + expect(serializedAttributes).toEqual(attributesWithScrollPositions) + } else { + expect(serializedAttributes).not.toEqual(attributesWithScrollPositions) + } + }) }) it('ignores white space in
', () => { @@ -480,9 +500,10 @@ describe('serializeDocumentNode handles', function testAllowDomTree() { }) it('a masked DOM Document itself is still serialized ', () => { - const serializeOptionsMask = { + const serializeOptionsMask: SerializeOptions = { document, parentNodePrivacyLevel: NodePrivacyLevel.MASK, + serializationContext: 'full-snapshot', } expect(serializeDocumentNode(document, serializeOptionsMask)).toEqual({ type: NodeType.Document, diff --git a/packages/rum/src/domain/record/serialize.ts b/packages/rum/src/domain/record/serialize.ts index 1bc6d80ce8..aecfb2130d 100644 --- a/packages/rum/src/domain/record/serialize.ts +++ b/packages/rum/src/domain/record/serialize.ts @@ -34,11 +34,14 @@ type ParentNodePrivacyLevel = | typeof NodePrivacyLevel.MASK | typeof NodePrivacyLevel.MASK_USER_INPUT +export type SerializationContext = 'full-snapshot' | 'mutation' + export interface SerializeOptions { document: Document serializedNodeIds?: Set