diff --git a/packages/browser-integration-tests/suites/replay/fileInput/init.js b/packages/browser-integration-tests/suites/replay/fileInput/init.js new file mode 100644 index 000000000000..a09c517b6a92 --- /dev/null +++ b/packages/browser-integration-tests/suites/replay/fileInput/init.js @@ -0,0 +1,19 @@ +import * as Sentry from '@sentry/browser'; +import { Replay } from '@sentry/replay'; + +window.Sentry = Sentry; +window.Replay = new Replay({ + flushMinDelay: 200, + flushMaxDelay: 200, + useCompression: false, + maskAllInputs: false, +}); + +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/browser-integration-tests/suites/replay/fileInput/template.html b/packages/browser-integration-tests/suites/replay/fileInput/template.html new file mode 100644 index 000000000000..eb183083d872 --- /dev/null +++ b/packages/browser-integration-tests/suites/replay/fileInput/template.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/browser-integration-tests/suites/replay/fileInput/test.ts b/packages/browser-integration-tests/suites/replay/fileInput/test.ts new file mode 100644 index 000000000000..685c626ec470 --- /dev/null +++ b/packages/browser-integration-tests/suites/replay/fileInput/test.ts @@ -0,0 +1,58 @@ +import { expect } from '@playwright/test'; +import { IncrementalSource } from '@sentry-internal/rrweb'; +import type { inputData } from '@sentry-internal/rrweb/typings/types'; + +import { sentryTest } from '../../../utils/fixtures'; +import type { IncrementalRecordingSnapshot } from '../../../utils/replayHelpers'; +import { + getIncrementalRecordingSnapshots, + shouldSkipReplayTest, + waitForReplayRequest, +} from '../../../utils/replayHelpers'; + +function isInputMutation( + snap: IncrementalRecordingSnapshot, +): snap is IncrementalRecordingSnapshot & { data: inputData } { + return snap.data.source == IncrementalSource.Input; +} + +sentryTest( + 'should not capture file input mutations', + async ({ forceFlushReplay, getLocalTestPath, page, browserName }) => { + // This seems to be flaky on webkit, so skipping there + if (shouldSkipReplayTest() || browserName === 'webkit') { + sentryTest.skip(); + } + + const reqPromise0 = waitForReplayRequest(page, 0); + const reqPromise1 = waitForReplayRequest(page, 1); + + 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); + + await reqPromise0; + + await page.setInputFiles('#file-input', { + name: 'file.csv', + mimeType: 'text/csv', + buffer: Buffer.from('this,is,test'), + }); + + await forceFlushReplay(); + + const res1 = await reqPromise1; + + const snapshots = getIncrementalRecordingSnapshots(res1).filter(isInputMutation); + + expect(snapshots).toEqual([]); + }, +); diff --git a/packages/replay/src/util/getPrivacyOptions.ts b/packages/replay/src/util/getPrivacyOptions.ts index a8655bdf76af..a2aec1dcdb9d 100644 --- a/packages/replay/src/util/getPrivacyOptions.ts +++ b/packages/replay/src/util/getPrivacyOptions.ts @@ -88,7 +88,7 @@ export function getPrivacyOptions({ blockSelector, ), unblockSelector: getOption(unblock, ['.sentry-unblock', '[data-sentry-unblock]']), - ignoreSelector: getOption(ignore, ['.sentry-ignore', '[data-sentry-ignore]'], ignoreClass), + ignoreSelector: getOption(ignore, ['.sentry-ignore', '[data-sentry-ignore]', 'input[type="file"]'], ignoreClass), }; if (blockClass instanceof RegExp) { diff --git a/packages/replay/test/integration/rrweb.test.ts b/packages/replay/test/integration/rrweb.test.ts index 3e37df5f2910..cc40061b4a3d 100644 --- a/packages/replay/test/integration/rrweb.test.ts +++ b/packages/replay/test/integration/rrweb.test.ts @@ -20,7 +20,7 @@ describe('Integration | rrweb', () => { "blockSelector": ".sentry-block,[data-sentry-block],base[href=\\"/\\"],img,image,svg,video,object,picture,embed,map,audio,link[rel=\\"icon\\"],link[rel=\\"apple-touch-icon\\"]", "collectFonts": true, "emit": [Function], - "ignoreSelector": ".sentry-test-ignore,.sentry-ignore,[data-sentry-ignore]", + "ignoreSelector": ".sentry-test-ignore,.sentry-ignore,[data-sentry-ignore],input[type=\\"file\\"]", "inlineImages": false, "inlineStylesheet": true, "maskAllInputs": true, diff --git a/packages/replay/test/unit/util/getPrivacyOptions.test.ts b/packages/replay/test/unit/util/getPrivacyOptions.test.ts index 3f13f6410a35..27cf839fdd3b 100644 --- a/packages/replay/test/unit/util/getPrivacyOptions.test.ts +++ b/packages/replay/test/unit/util/getPrivacyOptions.test.ts @@ -20,7 +20,7 @@ describe('Unit | util | getPrivacyOptions', () => { ).toMatchInlineSnapshot(` Object { "blockSelector": ".custom-block,.sentry-block,[data-sentry-block],base[href=\\"/\\"]", - "ignoreSelector": ".custom-ignore,.sentry-ignore,[data-sentry-ignore]", + "ignoreSelector": ".custom-ignore,.sentry-ignore,[data-sentry-ignore],input[type=\\"file\\"]", "maskInputSelector": ".custom-mask,.sentry-mask,[data-sentry-mask]", "maskTextSelector": ".custom-mask,.sentry-mask,[data-sentry-mask]", "unblockSelector": ".custom-unblock,.sentry-unblock,[data-sentry-unblock]", @@ -48,7 +48,7 @@ describe('Unit | util | getPrivacyOptions', () => { ).toMatchInlineSnapshot(` Object { "blockSelector": ".custom-block,.deprecated-block-selector,.sentry-block,[data-sentry-block],base[href=\\"/\\"],.deprecated-block-class", - "ignoreSelector": ".custom-ignore,.sentry-ignore,[data-sentry-ignore],.deprecated-ignore-class", + "ignoreSelector": ".custom-ignore,.sentry-ignore,[data-sentry-ignore],input[type=\\"file\\"],.deprecated-ignore-class", "maskInputSelector": ".custom-mask,.deprecated-mask-selector,.sentry-mask,[data-sentry-mask],.deprecated-mask-class", "maskTextSelector": ".custom-mask,.deprecated-mask-selector,.sentry-mask,[data-sentry-mask],.deprecated-mask-class", "unblockSelector": ".custom-unblock,.sentry-unblock,[data-sentry-unblock]", @@ -74,7 +74,7 @@ describe('Unit | util | getPrivacyOptions', () => { Object { "blockClass": /deprecated-block-\\*/, "blockSelector": ".custom-block,.sentry-block,[data-sentry-block],base[href=\\"/\\"]", - "ignoreSelector": ".custom-ignore,.sentry-ignore,[data-sentry-ignore]", + "ignoreSelector": ".custom-ignore,.sentry-ignore,[data-sentry-ignore],input[type=\\"file\\"]", "maskInputSelector": ".custom-mask,.sentry-mask,[data-sentry-mask]", "maskTextClass": /deprecated-mask-\\*/, "maskTextSelector": ".custom-mask,.sentry-mask,[data-sentry-mask]",