diff --git a/packages/integration-tests/.gitignore b/packages/integration-tests/.gitignore
new file mode 100644
index 000000000000..87364a273f79
--- /dev/null
+++ b/packages/integration-tests/.gitignore
@@ -0,0 +1 @@
+test-results
diff --git a/packages/integration-tests/suites/replay/privacyBlock/init.js b/packages/integration-tests/suites/replay/privacyBlock/init.js
new file mode 100644
index 000000000000..31d8a00ed0fd
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/init.js
@@ -0,0 +1,20 @@
+import * as Sentry from '@sentry/browser';
+import { Replay } from '@sentry/replay';
+
+window.Sentry = Sentry;
+window.Replay = new Replay({
+ flushMinDelay: 200,
+ flushMaxDelay: 200,
+ useCompression: false,
+ blockAllMedia: false,
+ block: ['link[rel="icon"]', 'video', '.nested-hide'],
+});
+
+Sentry.init({
+ dsn: 'https://public@dsn.ingest.sentry.io/1337',
+ sampleRate: 0,
+ replaysSessionSampleRate: 1.0,
+ replaysOnErrorSampleRate: 0.0,
+
+ integrations: [window.Replay],
+});
diff --git a/packages/integration-tests/suites/replay/privacyBlock/template.html b/packages/integration-tests/suites/replay/privacyBlock/template.html
new file mode 100644
index 000000000000..1742e26f18f1
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/template.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+ This should be masked by default
+ This should be unmasked due to data attribute
+
+ Title should be masked
+
+
+
+
+
+
+
This should be hidden.
+
+
+
diff --git a/packages/integration-tests/suites/replay/privacyBlock/test.ts b/packages/integration-tests/suites/replay/privacyBlock/test.ts
new file mode 100644
index 000000000000..8b000b07e461
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/test.ts
@@ -0,0 +1,35 @@
+import { expect } from '@playwright/test';
+
+import { sentryTest } from '../../../utils/fixtures';
+import {
+ getFullRecordingSnapshots,
+ normalize,
+ shouldSkipReplayTest,
+ waitForReplayRequest,
+} from '../../../utils/replayHelpers';
+
+sentryTest('should allow to manually block elements', async ({ getLocalTestPath, page }) => {
+ if (shouldSkipReplayTest()) {
+ sentryTest.skip();
+ }
+
+ const reqPromise0 = waitForReplayRequest(page, 0);
+
+ await page.route('https://dsn.ingest.sentry.io/**/*', route => {
+ return route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({ id: 'test-id' }),
+ });
+ });
+
+ const url = await getLocalTestPath({ testDir: __dirname });
+
+ await page.goto(url);
+ const snapshots = getFullRecordingSnapshots(await reqPromise0);
+ expect(snapshots.length).toEqual(1);
+
+ const stringifiedSnapshot = normalize(snapshots[0], { normalizeNumberAttributes: ['rr_width', 'rr_height'] });
+
+ expect(stringifiedSnapshot).toMatchSnapshot('privacy.json');
+});
diff --git a/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-chromium.json b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-chromium.json
new file mode 100644
index 000000000000..a120d5e44a5e
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-chromium.json
@@ -0,0 +1,319 @@
+{
+ "node": {
+ "type": 0,
+ "childNodes": [
+ {
+ "type": 1,
+ "name": "html",
+ "publicId": "",
+ "systemId": "",
+ "id": 2
+ },
+ {
+ "type": 2,
+ "tagName": "html",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "head",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "meta",
+ "attributes": {
+ "charset": "utf-8"
+ },
+ "childNodes": [],
+ "id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 6
+ }
+ ],
+ "id": 4
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 7
+ },
+ {
+ "type": 2,
+ "tagName": "body",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 9
+ },
+ {
+ "type": 2,
+ "tagName": "button",
+ "attributes": {
+ "aria-label": "***** **",
+ "onclick": "console.log('Test log')"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** **",
+ "id": 11
+ }
+ ],
+ "id": 10
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 12
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "**** ****** ** ****** ** *******",
+ "id": 14
+ }
+ ],
+ "id": 13
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 15
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "data-sentry-unmask": ""
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "This should be unmasked due to data attribute",
+ "id": 17
+ }
+ ],
+ "id": 16
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 18
+ },
+ {
+ "type": 2,
+ "tagName": "input",
+ "attributes": {
+ "placeholder": "*********** ****** ** ******"
+ },
+ "childNodes": [],
+ "id": 19
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 20
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "title": "***** ****** ** ******"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** ****** ** ******",
+ "id": 22
+ }
+ ],
+ "id": 21
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 23
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80"
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 25
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 26
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 27
+ }
+ ],
+ "isSVG": true,
+ "id": 24
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 28
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80",
+ "data-sentry-unblock": ""
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 30
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 31
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 32
+ }
+ ],
+ "isSVG": true,
+ "id": 29
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 33
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 34
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 35
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "data-sentry-unblock": "",
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 36
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 37
+ },
+ {
+ "type": 2,
+ "tagName": "video",
+ "attributes": {
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 38
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 39
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "class": "nested-hide",
+ "rr_width": "[1250-1300]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 40
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 41
+ },
+ {
+ "type": 3,
+ "textContent": "\n\n",
+ "id": 42
+ }
+ ],
+ "id": 8
+ }
+ ],
+ "id": 3
+ }
+ ],
+ "id": 1
+ },
+ "initialOffset": {
+ "left": 0,
+ "top": 0
+ }
+}
\ No newline at end of file
diff --git a/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-firefox.json b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-firefox.json
new file mode 100644
index 000000000000..a120d5e44a5e
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-firefox.json
@@ -0,0 +1,319 @@
+{
+ "node": {
+ "type": 0,
+ "childNodes": [
+ {
+ "type": 1,
+ "name": "html",
+ "publicId": "",
+ "systemId": "",
+ "id": 2
+ },
+ {
+ "type": 2,
+ "tagName": "html",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "head",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "meta",
+ "attributes": {
+ "charset": "utf-8"
+ },
+ "childNodes": [],
+ "id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 6
+ }
+ ],
+ "id": 4
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 7
+ },
+ {
+ "type": 2,
+ "tagName": "body",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 9
+ },
+ {
+ "type": 2,
+ "tagName": "button",
+ "attributes": {
+ "aria-label": "***** **",
+ "onclick": "console.log('Test log')"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** **",
+ "id": 11
+ }
+ ],
+ "id": 10
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 12
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "**** ****** ** ****** ** *******",
+ "id": 14
+ }
+ ],
+ "id": 13
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 15
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "data-sentry-unmask": ""
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "This should be unmasked due to data attribute",
+ "id": 17
+ }
+ ],
+ "id": 16
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 18
+ },
+ {
+ "type": 2,
+ "tagName": "input",
+ "attributes": {
+ "placeholder": "*********** ****** ** ******"
+ },
+ "childNodes": [],
+ "id": 19
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 20
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "title": "***** ****** ** ******"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** ****** ** ******",
+ "id": 22
+ }
+ ],
+ "id": 21
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 23
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80"
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 25
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 26
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 27
+ }
+ ],
+ "isSVG": true,
+ "id": 24
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 28
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80",
+ "data-sentry-unblock": ""
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 30
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 31
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 32
+ }
+ ],
+ "isSVG": true,
+ "id": 29
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 33
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 34
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 35
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "data-sentry-unblock": "",
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 36
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 37
+ },
+ {
+ "type": 2,
+ "tagName": "video",
+ "attributes": {
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 38
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 39
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "class": "nested-hide",
+ "rr_width": "[1250-1300]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 40
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 41
+ },
+ {
+ "type": 3,
+ "textContent": "\n\n",
+ "id": 42
+ }
+ ],
+ "id": 8
+ }
+ ],
+ "id": 3
+ }
+ ],
+ "id": 1
+ },
+ "initialOffset": {
+ "left": 0,
+ "top": 0
+ }
+}
\ No newline at end of file
diff --git a/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-webkit.json b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-webkit.json
new file mode 100644
index 000000000000..a120d5e44a5e
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-webkit.json
@@ -0,0 +1,319 @@
+{
+ "node": {
+ "type": 0,
+ "childNodes": [
+ {
+ "type": 1,
+ "name": "html",
+ "publicId": "",
+ "systemId": "",
+ "id": 2
+ },
+ {
+ "type": 2,
+ "tagName": "html",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "head",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "meta",
+ "attributes": {
+ "charset": "utf-8"
+ },
+ "childNodes": [],
+ "id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 6
+ }
+ ],
+ "id": 4
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 7
+ },
+ {
+ "type": 2,
+ "tagName": "body",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 9
+ },
+ {
+ "type": 2,
+ "tagName": "button",
+ "attributes": {
+ "aria-label": "***** **",
+ "onclick": "console.log('Test log')"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** **",
+ "id": 11
+ }
+ ],
+ "id": 10
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 12
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "**** ****** ** ****** ** *******",
+ "id": 14
+ }
+ ],
+ "id": 13
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 15
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "data-sentry-unmask": ""
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "This should be unmasked due to data attribute",
+ "id": 17
+ }
+ ],
+ "id": 16
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 18
+ },
+ {
+ "type": 2,
+ "tagName": "input",
+ "attributes": {
+ "placeholder": "*********** ****** ** ******"
+ },
+ "childNodes": [],
+ "id": 19
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 20
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "title": "***** ****** ** ******"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** ****** ** ******",
+ "id": 22
+ }
+ ],
+ "id": 21
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 23
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80"
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 25
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 26
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 27
+ }
+ ],
+ "isSVG": true,
+ "id": 24
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 28
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80",
+ "data-sentry-unblock": ""
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 30
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 31
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 32
+ }
+ ],
+ "isSVG": true,
+ "id": 29
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 33
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 34
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 35
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "data-sentry-unblock": "",
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 36
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 37
+ },
+ {
+ "type": 2,
+ "tagName": "video",
+ "attributes": {
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 38
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 39
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "class": "nested-hide",
+ "rr_width": "[1250-1300]px",
+ "rr_height": "[0-50]px"
+ },
+ "childNodes": [],
+ "id": 40
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 41
+ },
+ {
+ "type": 3,
+ "textContent": "\n\n",
+ "id": 42
+ }
+ ],
+ "id": 8
+ }
+ ],
+ "id": 3
+ }
+ ],
+ "id": 1
+ },
+ "initialOffset": {
+ "left": 0,
+ "top": 0
+ }
+}
\ No newline at end of file
diff --git a/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy.json b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy.json
new file mode 100644
index 000000000000..4b08d64a07b3
--- /dev/null
+++ b/packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy.json
@@ -0,0 +1,319 @@
+{
+ "node": {
+ "type": 0,
+ "childNodes": [
+ {
+ "type": 1,
+ "name": "html",
+ "publicId": "",
+ "systemId": "",
+ "id": 2
+ },
+ {
+ "type": 2,
+ "tagName": "html",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "head",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "meta",
+ "attributes": {
+ "charset": "utf-8"
+ },
+ "childNodes": [],
+ "id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rr_width": "0px",
+ "rr_height": "0px"
+ },
+ "childNodes": [],
+ "id": 6
+ }
+ ],
+ "id": 4
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 7
+ },
+ {
+ "type": 2,
+ "tagName": "body",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 9
+ },
+ {
+ "type": 2,
+ "tagName": "button",
+ "attributes": {
+ "aria-label": "***** **",
+ "onclick": "console.log('Test log')"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** **",
+ "id": 11
+ }
+ ],
+ "id": 10
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 12
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {},
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "**** ****** ** ****** ** *******",
+ "id": 14
+ }
+ ],
+ "id": 13
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 15
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "data-sentry-unmask": ""
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "This should be unmasked due to data attribute",
+ "id": 17
+ }
+ ],
+ "id": 16
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 18
+ },
+ {
+ "type": 2,
+ "tagName": "input",
+ "attributes": {
+ "placeholder": "*********** ****** ** ******"
+ },
+ "childNodes": [],
+ "id": 19
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 20
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "title": "***** ****** ** ******"
+ },
+ "childNodes": [
+ {
+ "type": 3,
+ "textContent": "***** ****** ** ******",
+ "id": 22
+ }
+ ],
+ "id": 21
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 23
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80"
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 25
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 26
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 27
+ }
+ ],
+ "isSVG": true,
+ "id": 24
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 28
+ },
+ {
+ "type": 2,
+ "tagName": "svg",
+ "attributes": {
+ "style": "width:200px;height:200px",
+ "viewBox": "0 0 80 80",
+ "data-sentry-unblock": ""
+ },
+ "childNodes": [
+ {
+ "type": 2,
+ "tagName": "path",
+ "attributes": {
+ "d": ""
+ },
+ "childNodes": [],
+ "isSVG": true,
+ "id": 30
+ },
+ {
+ "type": 2,
+ "tagName": "area",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 31
+ },
+ {
+ "type": 2,
+ "tagName": "rect",
+ "attributes": {},
+ "childNodes": [],
+ "isSVG": true,
+ "id": 32
+ }
+ ],
+ "isSVG": true,
+ "id": 29
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 33
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 34
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 35
+ },
+ {
+ "type": 2,
+ "tagName": "img",
+ "attributes": {
+ "data-sentry-unblock": "",
+ "style": "width:100px;height:100px",
+ "src": "file:///none.png"
+ },
+ "childNodes": [],
+ "id": 36
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 37
+ },
+ {
+ "type": 2,
+ "tagName": "video",
+ "attributes": {
+ "rr_width": "30px",
+ "rr_height": "30px"
+ },
+ "childNodes": [],
+ "id": 38
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 39
+ },
+ {
+ "type": 2,
+ "tagName": "div",
+ "attributes": {
+ "class": "nested-hide",
+ "rr_width": "1264px",
+ "rr_height": "18px"
+ },
+ "childNodes": [],
+ "id": 40
+ },
+ {
+ "type": 3,
+ "textContent": "\n ",
+ "id": 41
+ },
+ {
+ "type": 3,
+ "textContent": "\n\n",
+ "id": 42
+ }
+ ],
+ "id": 8
+ }
+ ],
+ "id": 3
+ }
+ ],
+ "id": 1
+ },
+ "initialOffset": {
+ "left": 0,
+ "top": 0
+ }
+}
\ No newline at end of file
diff --git a/packages/integration-tests/suites/replay/privacy/init.js b/packages/integration-tests/suites/replay/privacyDefault/init.js
similarity index 100%
rename from packages/integration-tests/suites/replay/privacy/init.js
rename to packages/integration-tests/suites/replay/privacyDefault/init.js
diff --git a/packages/integration-tests/suites/replay/privacy/template.html b/packages/integration-tests/suites/replay/privacyDefault/template.html
similarity index 86%
rename from packages/integration-tests/suites/replay/privacy/template.html
rename to packages/integration-tests/suites/replay/privacyDefault/template.html
index 2eb0f8df7b37..a8279dad4d17 100644
--- a/packages/integration-tests/suites/replay/privacy/template.html
+++ b/packages/integration-tests/suites/replay/privacyDefault/template.html
@@ -1,6 +1,9 @@
-
+
+
+
+
This should be masked by default
diff --git a/packages/integration-tests/suites/replay/privacy/test.ts b/packages/integration-tests/suites/replay/privacyDefault/test.ts
similarity index 53%
rename from packages/integration-tests/suites/replay/privacy/test.ts
rename to packages/integration-tests/suites/replay/privacyDefault/test.ts
index a6315d5d1e66..713431ca3063 100644
--- a/packages/integration-tests/suites/replay/privacy/test.ts
+++ b/packages/integration-tests/suites/replay/privacyDefault/test.ts
@@ -1,10 +1,12 @@
import { expect } from '@playwright/test';
-import { EventType } from '@sentry-internal/rrweb';
-import type { RecordingEvent } from '@sentry/replay/build/npm/types/types';
import { sentryTest } from '../../../utils/fixtures';
-import { envelopeRequestParser } from '../../../utils/helpers';
-import { shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers';
+import {
+ getFullRecordingSnapshots,
+ normalize,
+ shouldSkipReplayTest,
+ waitForReplayRequest,
+} from '../../../utils/replayHelpers';
sentryTest('should have the correct default privacy settings', async ({ getLocalTestPath, page }) => {
if (shouldSkipReplayTest()) {
@@ -24,8 +26,11 @@ sentryTest('should have the correct default privacy settings', async ({ getLocal
const url = await getLocalTestPath({ testDir: __dirname });
await page.goto(url);
- const replayPayload = envelopeRequestParser(await reqPromise0, 5);
- const checkoutEvent = replayPayload.find(({ type }) => type === EventType.FullSnapshot);
- expect(JSON.stringify(checkoutEvent?.data, null, 2)).toMatchSnapshot('privacy.json');
+ const snapshots = getFullRecordingSnapshots(await reqPromise0);
+ expect(snapshots.length).toEqual(1);
+
+ const stringifiedSnapshot = normalize(snapshots[0], { normalizeNumberAttributes: ['rr_width', 'rr_height'] });
+
+ expect(stringifiedSnapshot).toMatchSnapshot('privacy.json');
});
diff --git a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-chromium.json b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-chromium.json
similarity index 87%
rename from packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-chromium.json
rename to packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-chromium.json
index d0cb968d61ff..f31f8b967d12 100644
--- a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-chromium.json
+++ b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-chromium.json
@@ -27,6 +27,17 @@
},
"childNodes": [],
"id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rel": "icon",
+ "type": "image/png",
+ "href": "file://assets/icon/favicon.png"
+ },
+ "childNodes": [],
+ "id": 6
}
],
"id": 4
@@ -34,7 +45,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 6
+ "id": 7
},
{
"type": 2,
@@ -44,7 +55,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 8
+ "id": 9
},
{
"type": 2,
@@ -57,15 +68,15 @@
{
"type": 3,
"textContent": "***** **",
- "id": 10
+ "id": 11
}
],
- "id": 9
+ "id": 10
},
{
"type": 3,
"textContent": "\n ",
- "id": 11
+ "id": 12
},
{
"type": 2,
@@ -75,15 +86,15 @@
{
"type": 3,
"textContent": "**** ****** ** ****** ** *******",
- "id": 13
+ "id": 14
}
],
- "id": 12
+ "id": 13
},
{
"type": 3,
"textContent": "\n ",
- "id": 14
+ "id": 15
},
{
"type": 2,
@@ -95,15 +106,15 @@
{
"type": 3,
"textContent": "This should be unmasked due to data attribute",
- "id": 16
+ "id": 17
}
],
- "id": 15
+ "id": 16
},
{
"type": 3,
"textContent": "\n ",
- "id": 17
+ "id": 18
},
{
"type": 2,
@@ -112,12 +123,12 @@
"placeholder": "*********** ****** ** ******"
},
"childNodes": [],
- "id": 18
+ "id": 19
},
{
"type": 3,
"textContent": "\n ",
- "id": 19
+ "id": 20
},
{
"type": 2,
@@ -129,31 +140,31 @@
{
"type": 3,
"textContent": "***** ****** ** ******",
- "id": 21
+ "id": 22
}
],
- "id": 20
+ "id": 21
},
{
"type": 3,
"textContent": "\n ",
- "id": 22
+ "id": 23
},
{
"type": 2,
"tagName": "svg",
"attributes": {
- "rr_width": "200px",
- "rr_height": "200px"
+ "rr_width": "[200-250]px",
+ "rr_height": "[200-250]px"
},
"childNodes": [],
"isSVG": true,
- "id": 23
+ "id": 24
},
{
"type": 3,
"textContent": "\n ",
- "id": 24
+ "id": 25
},
{
"type": 2,
@@ -172,7 +183,7 @@
},
"childNodes": [],
"isSVG": true,
- "id": 26
+ "id": 27
},
{
"type": 2,
@@ -180,7 +191,7 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 27
+ "id": 28
},
{
"type": 2,
@@ -188,31 +199,31 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 28
+ "id": 29
}
],
"isSVG": true,
- "id": 25
+ "id": 26
},
{
"type": 3,
"textContent": "\n ",
- "id": 29
+ "id": 30
},
{
"type": 2,
"tagName": "img",
"attributes": {
- "rr_width": "100px",
- "rr_height": "100px"
+ "rr_width": "[100-150]px",
+ "rr_height": "[100-150]px"
},
"childNodes": [],
- "id": 30
+ "id": 31
},
{
"type": 3,
"textContent": "\n ",
- "id": 31
+ "id": 32
},
{
"type": 2,
@@ -223,35 +234,35 @@
"src": "file:///none.png"
},
"childNodes": [],
- "id": 32
+ "id": 33
},
{
"type": 3,
"textContent": "\n ",
- "id": 33
+ "id": 34
},
{
"type": 2,
"tagName": "video",
"attributes": {
- "rr_width": "30px",
- "rr_height": "30px"
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
},
"childNodes": [],
- "id": 34
+ "id": 35
},
{
"type": 3,
"textContent": "\n ",
- "id": 35
+ "id": 36
},
{
"type": 3,
"textContent": "\n\n",
- "id": 36
+ "id": 37
}
],
- "id": 7
+ "id": 8
}
],
"id": 3
diff --git a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-firefox.json b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-firefox.json
similarity index 87%
rename from packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-firefox.json
rename to packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-firefox.json
index d0cb968d61ff..d33a2d86b730 100644
--- a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-firefox.json
+++ b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-firefox.json
@@ -27,6 +27,17 @@
},
"childNodes": [],
"id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rel": "icon",
+ "type": "image/png",
+ "href": "file:///icon/favicon.png"
+ },
+ "childNodes": [],
+ "id": 6
}
],
"id": 4
@@ -34,7 +45,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 6
+ "id": 7
},
{
"type": 2,
@@ -44,7 +55,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 8
+ "id": 9
},
{
"type": 2,
@@ -57,15 +68,15 @@
{
"type": 3,
"textContent": "***** **",
- "id": 10
+ "id": 11
}
],
- "id": 9
+ "id": 10
},
{
"type": 3,
"textContent": "\n ",
- "id": 11
+ "id": 12
},
{
"type": 2,
@@ -75,15 +86,15 @@
{
"type": 3,
"textContent": "**** ****** ** ****** ** *******",
- "id": 13
+ "id": 14
}
],
- "id": 12
+ "id": 13
},
{
"type": 3,
"textContent": "\n ",
- "id": 14
+ "id": 15
},
{
"type": 2,
@@ -95,15 +106,15 @@
{
"type": 3,
"textContent": "This should be unmasked due to data attribute",
- "id": 16
+ "id": 17
}
],
- "id": 15
+ "id": 16
},
{
"type": 3,
"textContent": "\n ",
- "id": 17
+ "id": 18
},
{
"type": 2,
@@ -112,12 +123,12 @@
"placeholder": "*********** ****** ** ******"
},
"childNodes": [],
- "id": 18
+ "id": 19
},
{
"type": 3,
"textContent": "\n ",
- "id": 19
+ "id": 20
},
{
"type": 2,
@@ -129,31 +140,31 @@
{
"type": 3,
"textContent": "***** ****** ** ******",
- "id": 21
+ "id": 22
}
],
- "id": 20
+ "id": 21
},
{
"type": 3,
"textContent": "\n ",
- "id": 22
+ "id": 23
},
{
"type": 2,
"tagName": "svg",
"attributes": {
- "rr_width": "200px",
- "rr_height": "200px"
+ "rr_width": "[200-250]px",
+ "rr_height": "[200-250]px"
},
"childNodes": [],
"isSVG": true,
- "id": 23
+ "id": 24
},
{
"type": 3,
"textContent": "\n ",
- "id": 24
+ "id": 25
},
{
"type": 2,
@@ -172,7 +183,7 @@
},
"childNodes": [],
"isSVG": true,
- "id": 26
+ "id": 27
},
{
"type": 2,
@@ -180,7 +191,7 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 27
+ "id": 28
},
{
"type": 2,
@@ -188,31 +199,31 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 28
+ "id": 29
}
],
"isSVG": true,
- "id": 25
+ "id": 26
},
{
"type": 3,
"textContent": "\n ",
- "id": 29
+ "id": 30
},
{
"type": 2,
"tagName": "img",
"attributes": {
- "rr_width": "100px",
- "rr_height": "100px"
+ "rr_width": "[100-150]px",
+ "rr_height": "[100-150]px"
},
"childNodes": [],
- "id": 30
+ "id": 31
},
{
"type": 3,
"textContent": "\n ",
- "id": 31
+ "id": 32
},
{
"type": 2,
@@ -223,35 +234,35 @@
"src": "file:///none.png"
},
"childNodes": [],
- "id": 32
+ "id": 33
},
{
"type": 3,
"textContent": "\n ",
- "id": 33
+ "id": 34
},
{
"type": 2,
"tagName": "video",
"attributes": {
- "rr_width": "30px",
- "rr_height": "30px"
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
},
"childNodes": [],
- "id": 34
+ "id": 35
},
{
"type": 3,
"textContent": "\n ",
- "id": 35
+ "id": 36
},
{
"type": 3,
"textContent": "\n\n",
- "id": 36
+ "id": 37
}
],
- "id": 7
+ "id": 8
}
],
"id": 3
diff --git a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-webkit.json b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-webkit.json
similarity index 87%
rename from packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-webkit.json
rename to packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-webkit.json
index d0cb968d61ff..f31f8b967d12 100644
--- a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy-webkit.json
+++ b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy-webkit.json
@@ -27,6 +27,17 @@
},
"childNodes": [],
"id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rel": "icon",
+ "type": "image/png",
+ "href": "file://assets/icon/favicon.png"
+ },
+ "childNodes": [],
+ "id": 6
}
],
"id": 4
@@ -34,7 +45,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 6
+ "id": 7
},
{
"type": 2,
@@ -44,7 +55,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 8
+ "id": 9
},
{
"type": 2,
@@ -57,15 +68,15 @@
{
"type": 3,
"textContent": "***** **",
- "id": 10
+ "id": 11
}
],
- "id": 9
+ "id": 10
},
{
"type": 3,
"textContent": "\n ",
- "id": 11
+ "id": 12
},
{
"type": 2,
@@ -75,15 +86,15 @@
{
"type": 3,
"textContent": "**** ****** ** ****** ** *******",
- "id": 13
+ "id": 14
}
],
- "id": 12
+ "id": 13
},
{
"type": 3,
"textContent": "\n ",
- "id": 14
+ "id": 15
},
{
"type": 2,
@@ -95,15 +106,15 @@
{
"type": 3,
"textContent": "This should be unmasked due to data attribute",
- "id": 16
+ "id": 17
}
],
- "id": 15
+ "id": 16
},
{
"type": 3,
"textContent": "\n ",
- "id": 17
+ "id": 18
},
{
"type": 2,
@@ -112,12 +123,12 @@
"placeholder": "*********** ****** ** ******"
},
"childNodes": [],
- "id": 18
+ "id": 19
},
{
"type": 3,
"textContent": "\n ",
- "id": 19
+ "id": 20
},
{
"type": 2,
@@ -129,31 +140,31 @@
{
"type": 3,
"textContent": "***** ****** ** ******",
- "id": 21
+ "id": 22
}
],
- "id": 20
+ "id": 21
},
{
"type": 3,
"textContent": "\n ",
- "id": 22
+ "id": 23
},
{
"type": 2,
"tagName": "svg",
"attributes": {
- "rr_width": "200px",
- "rr_height": "200px"
+ "rr_width": "[200-250]px",
+ "rr_height": "[200-250]px"
},
"childNodes": [],
"isSVG": true,
- "id": 23
+ "id": 24
},
{
"type": 3,
"textContent": "\n ",
- "id": 24
+ "id": 25
},
{
"type": 2,
@@ -172,7 +183,7 @@
},
"childNodes": [],
"isSVG": true,
- "id": 26
+ "id": 27
},
{
"type": 2,
@@ -180,7 +191,7 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 27
+ "id": 28
},
{
"type": 2,
@@ -188,31 +199,31 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 28
+ "id": 29
}
],
"isSVG": true,
- "id": 25
+ "id": 26
},
{
"type": 3,
"textContent": "\n ",
- "id": 29
+ "id": 30
},
{
"type": 2,
"tagName": "img",
"attributes": {
- "rr_width": "100px",
- "rr_height": "100px"
+ "rr_width": "[100-150]px",
+ "rr_height": "[100-150]px"
},
"childNodes": [],
- "id": 30
+ "id": 31
},
{
"type": 3,
"textContent": "\n ",
- "id": 31
+ "id": 32
},
{
"type": 2,
@@ -223,35 +234,35 @@
"src": "file:///none.png"
},
"childNodes": [],
- "id": 32
+ "id": 33
},
{
"type": 3,
"textContent": "\n ",
- "id": 33
+ "id": 34
},
{
"type": 2,
"tagName": "video",
"attributes": {
- "rr_width": "30px",
- "rr_height": "30px"
+ "rr_width": "[0-50]px",
+ "rr_height": "[0-50]px"
},
"childNodes": [],
- "id": 34
+ "id": 35
},
{
"type": 3,
"textContent": "\n ",
- "id": 35
+ "id": 36
},
{
"type": 3,
"textContent": "\n\n",
- "id": 36
+ "id": 37
}
],
- "id": 7
+ "id": 8
}
],
"id": 3
diff --git a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy.json b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy.json
similarity index 91%
rename from packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy.json
rename to packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy.json
index d0cb968d61ff..f29f31d2eb75 100644
--- a/packages/integration-tests/suites/replay/privacy/test.ts-snapshots/privacy.json
+++ b/packages/integration-tests/suites/replay/privacyDefault/test.ts-snapshots/privacy.json
@@ -27,6 +27,17 @@
},
"childNodes": [],
"id": 5
+ },
+ {
+ "type": 2,
+ "tagName": "link",
+ "attributes": {
+ "rel": "icon",
+ "type": "image/png",
+ "href": "file://assets/icon/favicon.png"
+ },
+ "childNodes": [],
+ "id": 6
}
],
"id": 4
@@ -34,7 +45,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 6
+ "id": 7
},
{
"type": 2,
@@ -44,7 +55,7 @@
{
"type": 3,
"textContent": "\n ",
- "id": 8
+ "id": 9
},
{
"type": 2,
@@ -57,15 +68,15 @@
{
"type": 3,
"textContent": "***** **",
- "id": 10
+ "id": 11
}
],
- "id": 9
+ "id": 10
},
{
"type": 3,
"textContent": "\n ",
- "id": 11
+ "id": 12
},
{
"type": 2,
@@ -75,15 +86,15 @@
{
"type": 3,
"textContent": "**** ****** ** ****** ** *******",
- "id": 13
+ "id": 14
}
],
- "id": 12
+ "id": 13
},
{
"type": 3,
"textContent": "\n ",
- "id": 14
+ "id": 15
},
{
"type": 2,
@@ -95,15 +106,15 @@
{
"type": 3,
"textContent": "This should be unmasked due to data attribute",
- "id": 16
+ "id": 17
}
],
- "id": 15
+ "id": 16
},
{
"type": 3,
"textContent": "\n ",
- "id": 17
+ "id": 18
},
{
"type": 2,
@@ -112,12 +123,12 @@
"placeholder": "*********** ****** ** ******"
},
"childNodes": [],
- "id": 18
+ "id": 19
},
{
"type": 3,
"textContent": "\n ",
- "id": 19
+ "id": 20
},
{
"type": 2,
@@ -129,15 +140,15 @@
{
"type": 3,
"textContent": "***** ****** ** ******",
- "id": 21
+ "id": 22
}
],
- "id": 20
+ "id": 21
},
{
"type": 3,
"textContent": "\n ",
- "id": 22
+ "id": 23
},
{
"type": 2,
@@ -148,12 +159,12 @@
},
"childNodes": [],
"isSVG": true,
- "id": 23
+ "id": 24
},
{
"type": 3,
"textContent": "\n ",
- "id": 24
+ "id": 25
},
{
"type": 2,
@@ -172,7 +183,7 @@
},
"childNodes": [],
"isSVG": true,
- "id": 26
+ "id": 27
},
{
"type": 2,
@@ -180,7 +191,7 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 27
+ "id": 28
},
{
"type": 2,
@@ -188,16 +199,16 @@
"attributes": {},
"childNodes": [],
"isSVG": true,
- "id": 28
+ "id": 29
}
],
"isSVG": true,
- "id": 25
+ "id": 26
},
{
"type": 3,
"textContent": "\n ",
- "id": 29
+ "id": 30
},
{
"type": 2,
@@ -207,12 +218,12 @@
"rr_height": "100px"
},
"childNodes": [],
- "id": 30
+ "id": 31
},
{
"type": 3,
"textContent": "\n ",
- "id": 31
+ "id": 32
},
{
"type": 2,
@@ -223,12 +234,12 @@
"src": "file:///none.png"
},
"childNodes": [],
- "id": 32
+ "id": 33
},
{
"type": 3,
"textContent": "\n ",
- "id": 33
+ "id": 34
},
{
"type": 2,
@@ -238,20 +249,20 @@
"rr_height": "30px"
},
"childNodes": [],
- "id": 34
+ "id": 35
},
{
"type": 3,
"textContent": "\n ",
- "id": 35
+ "id": 36
},
{
"type": 3,
"textContent": "\n\n",
- "id": 36
+ "id": 37
}
],
- "id": 7
+ "id": 8
}
],
"id": 3
diff --git a/packages/integration-tests/utils/replayHelpers.ts b/packages/integration-tests/utils/replayHelpers.ts
index a35520e0a799..8238e986b0cb 100644
--- a/packages/integration-tests/utils/replayHelpers.ts
+++ b/packages/integration-tests/utils/replayHelpers.ts
@@ -133,7 +133,7 @@ export function getFullRecordingSnapshots(replayRequest: Request): RecordingSnap
return events.filter(event => event.type === 2).map(event => event.data as RecordingSnapshot);
}
-function getincrementalRecordingSnapshots(replayRequest: Request): RecordingSnapshot[] {
+function getIncrementalRecordingSnapshots(replayRequest: Request): RecordingSnapshot[] {
const events = getDecompressedRecordingEvents(replayRequest) as RecordingEvent[];
return events.filter(event => event.type === 3).map(event => event.data as RecordingSnapshot);
}
@@ -144,7 +144,7 @@ function getDecompressedRecordingEvents(replayRequest: Request): RecordingEvent[
export function getReplayRecordingContent(replayRequest: Request): RecordingContent {
const fullSnapshots = getFullRecordingSnapshots(replayRequest);
- const incrementalSnapshots = getincrementalRecordingSnapshots(replayRequest);
+ const incrementalSnapshots = getIncrementalRecordingSnapshots(replayRequest);
const customEvents = getCustomRecordingEvents(replayRequest);
return { fullSnapshots, incrementalSnapshots, ...customEvents };
@@ -216,10 +216,42 @@ export function shouldSkipReplayTest(): boolean {
* files which break the tests on different machines.
* Also, we need to normalize any time offsets as they can vary and cause flakes.
*/
-export function normalize(obj: unknown): string {
+export function normalize(
+ obj: unknown,
+ { normalizeNumberAttributes }: { normalizeNumberAttributes?: string[] } = {},
+): string {
const rawString = JSON.stringify(obj, null, 2);
- const normalizedString = rawString
+ let normalizedString = rawString
.replace(/"file:\/\/.+(\/.*\.html)"/gm, '"$1"')
.replace(/"timeOffset":\s*-?\d+/gm, '"timeOffset": [timeOffset]');
+
+ if (normalizeNumberAttributes?.length) {
+ // We look for: "attr": "123px", "123", "123%", "123em", "123rem"
+ const regex = new RegExp(
+ `"(${normalizeNumberAttributes
+ .map(attr => `(?:${attr})`)
+ .join('|')})":\\s*"([\\d\\.]+)((?:px)|%|(?:em)(?:rem))?"`,
+ 'gm',
+ );
+
+ normalizedString = normalizedString.replace(regex, (_, attr, num, unit) => {
+ // Remove floating points here, to ensure this is a bit less flaky
+ const integer = parseInt(num, 10);
+ const normalizedNum = normalizeNumberAttribute(integer);
+
+ return `"${attr}": "${normalizedNum}${unit || ''}"`;
+ });
+ }
+
return normalizedString;
}
+
+/**
+ * Map e.g. 16 to [0-50] or 123 to [100-150].
+ */
+function normalizeNumberAttribute(num: number): string {
+ const step = 50;
+ const stepCount = Math.floor(num / step);
+
+ return `[${stepCount * step}-${(stepCount + 1) * step}]`;
+}