diff --git a/packages/rum/src/domain/record/record.spec.ts b/packages/rum/src/domain/record/record.spec.ts index f94f007b1b..9a27282c12 100644 --- a/packages/rum/src/domain/record/record.spec.ts +++ b/packages/rum/src/domain/record/record.spec.ts @@ -311,6 +311,22 @@ describe('record', () => { expect(innerMutationData.isChecked).toBe(true) }) + it('should record the change event inside a shadow root only once, regardless if the DOM is serialized multiple times', () => { + const radio = appendElement('', createShadow()) as HTMLInputElement + startRecording() + + recordApi.takeSubsequentFullSnapshot() + + radio.checked = true + radio.dispatchEvent(createNewEvent('change', { target: radio, composed: false })) + + const inputRecords = getEmittedRecords().filter( + (record) => record.type === RecordType.IncrementalSnapshot && record.data.source === IncrementalSource.Input + ) + + expect(inputRecords.length).toBe(1) + }) + it('should clean the state once the shadow dom is removed to avoid memory leak', () => { const shadowRoot = createShadow() appendElement('
', shadowRoot) diff --git a/packages/rum/src/domain/record/shadowRootsController.ts b/packages/rum/src/domain/record/shadowRootsController.ts index db2a5c98c3..11bb2e346b 100644 --- a/packages/rum/src/domain/record/shadowRootsController.ts +++ b/packages/rum/src/domain/record/shadowRootsController.ts @@ -30,6 +30,9 @@ export const initShadowRootsController = ( const shadowRootsController: ShadowRootsController = { addShadowRoot: (shadowRoot: ShadowRoot) => { + if (controllerByShadowRoot.has(shadowRoot)) { + return + } const { stop: stopMutationObserver, flush } = initMutationObserver( mutationCb, configuration,