diff --git a/package.json b/package.json index 04cff3238e..99d06eb1fc 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,6 @@ }, "dependencies": { "mitt": "^1.1.3", - "rrweb-snapshot": "^0.6.8" + "rrweb-snapshot": "^0.6.10" } } diff --git a/src/record/observer.ts b/src/record/observer.ts index 778be3aa15..cf1569b19d 100644 --- a/src/record/observer.ts +++ b/src/record/observer.ts @@ -291,6 +291,7 @@ const HOOK_PROPERTIES: Array<[HTMLElement, string]> = [ [HTMLSelectElement.prototype, 'value'], [HTMLTextAreaElement.prototype, 'value'], ]; +const IGNORE_CLASS = 'rr-ignore'; const lastInputValueMap: WeakMap = new WeakMap(); function initInputObserver(cb: inputCallback): listenerHandler { function eventHandler(event: Event) { @@ -303,6 +304,12 @@ function initInputObserver(cb: inputCallback): listenerHandler { return; } const type: string | undefined = (target as HTMLInputElement).type; + if ( + type === 'password' || + (target as HTMLElement).classList.contains(IGNORE_CLASS) + ) { + return; + } const text = (target as HTMLInputElement).value; let isChecked = false; if (type === 'radio' || type === 'checkbox') { diff --git a/src/replay/styles/inject-style.ts b/src/replay/styles/inject-style.ts index ff311580d1..2fafbd4b04 100644 --- a/src/replay/styles/inject-style.ts +++ b/src/replay/styles/inject-style.ts @@ -1,5 +1,5 @@ const rules: string[] = [ - 'iframe { background: #ccc }', + 'iframe, .rr-block { background: #ccc }', 'noscript { display: none !important; }', ]; diff --git a/test/__snapshots__/integration.test.ts.snap b/test/__snapshots__/integration.test.ts.snap index b3e177bbb5..7d9ebb6e1d 100644 --- a/test/__snapshots__/integration.test.ts.snap +++ b/test/__snapshots__/integration.test.ts.snap @@ -1200,6 +1200,288 @@ exports[`form 1`] = ` ]" `; +exports[`ignore 1`] = ` +"[ + { + \\"type\\": 0, + \\"data\\": {}, + \\"timestamp\\": 1542268800000 + }, + { + \\"type\\": 1, + \\"data\\": {}, + \\"timestamp\\": 1542268800000 + }, + { + \\"type\\": 4, + \\"data\\": { + \\"href\\": \\"about:blank\\", + \\"width\\": 1920, + \\"height\\": 1080 + }, + \\"timestamp\\": 1542268800000 + }, + { + \\"type\\": 2, + \\"data\\": { + \\"node\\": { + \\"type\\": 0, + \\"childNodes\\": [ + { + \\"type\\": 1, + \\"name\\": \\"html\\", + \\"publicId\\": \\"\\", + \\"systemId\\": \\"\\", + \\"id\\": 2 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"html\\", + \\"attributes\\": { + \\"lang\\": \\"en\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 2, + \\"tagName\\": \\"head\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 5 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"charset\\": \\"UTF-8\\" + }, + \\"childNodes\\": [], + \\"id\\": 6 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 7 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"name\\": \\"viewport\\", + \\"content\\": \\"width=device-width, initial-scale=1.0\\" + }, + \\"childNodes\\": [], + \\"id\\": 8 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 9 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"http-equiv\\": \\"X-UA-Compatible\\", + \\"content\\": \\"ie=edge\\" + }, + \\"childNodes\\": [], + \\"id\\": 10 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 11 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"title\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"ignore fields\\", + \\"id\\": 13 + } + ], + \\"id\\": 12 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 14 + } + ], + \\"id\\": 4 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n\\\\n \\", + \\"id\\": 15 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"body\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 17 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"form\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 19 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"password\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 21 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"password\\" + }, + \\"childNodes\\": [], + \\"id\\": 22 + }, + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 23 + } + ], + \\"id\\": 20 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 24 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"ignore text\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 26 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"text\\", + \\"class\\": \\"rr-ignore\\" + }, + \\"childNodes\\": [], + \\"id\\": 27 + }, + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 28 + } + ], + \\"id\\": 25 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 29 + } + ], + \\"id\\": 18 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\\\n \\", + \\"id\\": 30 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"script\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", + \\"id\\": 32 + } + ], + \\"id\\": 31 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", + \\"id\\": 33 + } + ], + \\"id\\": 16 + } + ], + \\"id\\": 3 + } + ], + \\"id\\": 1 + }, + \\"initialOffset\\": { + \\"left\\": 0, + \\"top\\": 0 + } + }, + \\"timestamp\\": 1542268800000 + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 22 + }, + \\"timestamp\\": 1542268800000 + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 6, + \\"id\\": 22 + }, + \\"timestamp\\": 1542268800000 + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 27 + }, + \\"timestamp\\": 1542268800000 + } +]" +`; + exports[`select2 1`] = ` "[ { diff --git a/test/html/ignore.html b/test/html/ignore.html new file mode 100644 index 0000000000..91e0652d9e --- /dev/null +++ b/test/html/ignore.html @@ -0,0 +1,16 @@ + + + + + + + ignore fields + + + +
+ + +
+ + diff --git a/test/integration.test.ts b/test/integration.test.ts index b84e818ab1..1bb6c4ccdf 100644 --- a/test/integration.test.ts +++ b/test/integration.test.ts @@ -230,4 +230,21 @@ describe('record integration tests', () => { ); assert(result.pass, result.pass ? '' : result.report()); }).timeout(10000); + + it('should not record input events on ignored elements', async () => { + const page: puppeteer.Page = await this.browser.newPage(); + await page.goto('about:blank'); + await page.setContent(getHtml.call(this, 'ignore.html')); + + await page.type('input[type="password"]', 'password'); + await page.type('.rr-ignore', 'secret'); + + const snapshots = await page.evaluate('window.snapshots'); + const result = matchSnapshot( + stringifySnapshots(snapshots), + __filename, + 'ignore', + ); + assert(result.pass, result.pass ? '' : result.report()); + }); });