Fix a code path where masking could be skipped on textareas (#1599)
* Fixes #1596
This commit is contained in:
5
.changeset/textarea-inner-html.md
Normal file
5
.changeset/textarea-inner-html.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"rrweb": patch
|
||||
---
|
||||
|
||||
#1596 Add masking for innerText mutations on textarea elements
|
||||
@@ -533,10 +533,18 @@ export default class MutationBuffer {
|
||||
this.attributes.push(item);
|
||||
this.attributeMap.set(textarea, item);
|
||||
}
|
||||
item.attributes.value = Array.from(
|
||||
const value = Array.from(
|
||||
dom.childNodes(textarea),
|
||||
(cn) => dom.textContent(cn) || '',
|
||||
).join('');
|
||||
item.attributes.value = maskInputValue({
|
||||
element: textarea,
|
||||
maskInputOptions: this.maskInputOptions,
|
||||
tagName: textarea.tagName,
|
||||
type: getInputType(textarea),
|
||||
value,
|
||||
maskInputFn: this.maskInputFn,
|
||||
});
|
||||
};
|
||||
|
||||
private processMutation = (m: mutationRecord) => {
|
||||
|
||||
@@ -9964,6 +9964,21 @@ exports[`record integration tests > should not record input values if dynamicall
|
||||
{
|
||||
\\"parentId\\": 14,
|
||||
\\"nextId\\": 16,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"textarea\\",
|
||||
\\"attributes\\": {
|
||||
\\"id\\": \\"textarea\\",
|
||||
\\"size\\": \\"50\\",
|
||||
\\"value\\": \\"*************************\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 21
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 14,
|
||||
\\"nextId\\": 21,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"input\\",
|
||||
@@ -9973,7 +9988,7 @@ exports[`record integration tests > should not record input values if dynamicall
|
||||
\\"value\\": \\"**********************\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 21
|
||||
\\"id\\": 22
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -9985,9 +10000,61 @@ exports[`record integration tests > should not record input values if dynamicall
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"**********************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"*************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 21
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 2,
|
||||
\\"type\\": 5,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"***********************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"*************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 2,
|
||||
\\"type\\": 6,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
@@ -10000,7 +10067,7 @@ exports[`record integration tests > should not record input values if dynamicall
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"***********************\\",
|
||||
\\"text\\": \\"**************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 21
|
||||
}
|
||||
@@ -10009,7 +10076,7 @@ exports[`record integration tests > should not record input values if dynamicall
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"************************\\",
|
||||
\\"text\\": \\"***************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 21
|
||||
}
|
||||
@@ -10018,10 +10085,68 @@ exports[`record integration tests > should not record input values if dynamicall
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"*************************\\",
|
||||
\\"text\\": \\"****************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 21
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"**********************************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 5,
|
||||
\\"text\\": \\"*************************************************\\",
|
||||
\\"isChecked\\": false,
|
||||
\\"id\\": 21
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [
|
||||
{
|
||||
\\"id\\": 22,
|
||||
\\"attributes\\": {
|
||||
\\"value\\": \\"**********************************************************************************************\\"
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"id\\": 21,
|
||||
\\"attributes\\": {
|
||||
\\"value\\": \\"*************************************************************************************************\\"
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"adds\\": []
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [
|
||||
{
|
||||
\\"id\\": 21,
|
||||
\\"attributes\\": {
|
||||
\\"value\\": \\"****************************************************************\\"
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"adds\\": []
|
||||
}
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
@@ -783,9 +783,46 @@ describe('record integration tests', function (this: ISuite) {
|
||||
|
||||
const nextElement = document.querySelector('#one')!;
|
||||
nextElement.parentNode!.insertBefore(el, nextElement);
|
||||
|
||||
const ta = document.createElement('textarea');
|
||||
ta.size = 50;
|
||||
ta.id = 'textarea';
|
||||
ta.setAttribute('size', '50');
|
||||
ta.value = 'textarea should be masked';
|
||||
|
||||
nextElement.parentNode!.insertBefore(ta, nextElement);
|
||||
});
|
||||
|
||||
await page.type('#input', 'moo');
|
||||
await page.type('#textarea', 'boo');
|
||||
|
||||
await page.evaluate(() => {
|
||||
const el = document.querySelector('input');
|
||||
el.value = 'input attribute mutation should also be masked';
|
||||
|
||||
const ta = document.querySelector('textarea');
|
||||
ta.value = 'textarea attribute mutation should also be masked';
|
||||
});
|
||||
|
||||
await page.evaluate(() => {
|
||||
const el = document.querySelector('input');
|
||||
el.setAttribute(
|
||||
'value',
|
||||
"input attribute mutation should also be masked (even though the new value doesn't take effect)",
|
||||
);
|
||||
|
||||
const ta = document.querySelector('textarea');
|
||||
ta.setAttribute(
|
||||
'value',
|
||||
"textarea attribute mutation should also be masked (even though the new value doesn't take effect)",
|
||||
);
|
||||
});
|
||||
|
||||
await page.evaluate(() => {
|
||||
const ta = document.querySelector('textarea');
|
||||
ta.innerText =
|
||||
'textarea attribute mutation via innerText should also be masked ';
|
||||
});
|
||||
|
||||
await assertSnapshot(page);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user