filter text and attributes mutations which target tot a removed node
This commit is contained in:
@@ -154,14 +154,20 @@ function initMutationObserver(cb: mutationCallBack): MutationObserver {
|
||||
});
|
||||
|
||||
cb({
|
||||
texts: texts.map(text => ({
|
||||
id: mirror.getId(text.node as INode),
|
||||
value: text.value,
|
||||
})),
|
||||
attributes: attributes.map(attribute => ({
|
||||
id: mirror.getId(attribute.node as INode),
|
||||
attributes: attribute.attributes,
|
||||
})),
|
||||
texts: texts
|
||||
.map(text => ({
|
||||
id: mirror.getId(text.node as INode),
|
||||
value: text.value,
|
||||
}))
|
||||
// text mutation without ID means the target node has been removed
|
||||
.filter(text => text.id),
|
||||
attributes: attributes
|
||||
.map(attribute => ({
|
||||
id: mirror.getId(attribute.node as INode),
|
||||
attributes: attribute.attributes,
|
||||
}))
|
||||
// attribute mutation without ID means the target node has been removed
|
||||
.filter(attribute => attribute.id),
|
||||
removes,
|
||||
adds,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,317 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`attributes 1`] = `
|
||||
"[
|
||||
{
|
||||
\\"type\\": 0,
|
||||
\\"data\\": {},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"data\\": {},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 4,
|
||||
\\"data\\": {
|
||||
\\"href\\": \\"about:blank\\",
|
||||
\\"width\\": 800,
|
||||
\\"height\\": 600
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"data\\": {
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 3
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 5
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"p\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"mutation observer\\",
|
||||
\\"id\\": 7
|
||||
}
|
||||
],
|
||||
\\"id\\": 6
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 8
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"ul\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 10
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 11
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 12
|
||||
}
|
||||
],
|
||||
\\"id\\": 9
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n\\\\n \\",
|
||||
\\"id\\": 13
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"script\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||
\\"id\\": 15
|
||||
}
|
||||
],
|
||||
\\"id\\": 14
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n \\",
|
||||
\\"id\\": 16
|
||||
}
|
||||
],
|
||||
\\"id\\": 4
|
||||
}
|
||||
],
|
||||
\\"id\\": 2
|
||||
}
|
||||
],
|
||||
\\"id\\": 1
|
||||
},
|
||||
\\"initialOffset\\": {
|
||||
\\"left\\": 0,
|
||||
\\"top\\": 0
|
||||
}
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [
|
||||
{
|
||||
\\"id\\": 4,
|
||||
\\"attributes\\": {
|
||||
\\"test\\": \\"true\\"
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"id\\": 9
|
||||
}
|
||||
],
|
||||
\\"adds\\": []
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`character-data 1`] = `
|
||||
"[
|
||||
{
|
||||
\\"type\\": 0,
|
||||
\\"data\\": {},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"data\\": {},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 4,
|
||||
\\"data\\": {
|
||||
\\"href\\": \\"about:blank\\",
|
||||
\\"width\\": 800,
|
||||
\\"height\\": 600
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"data\\": {
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 3
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 5
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"p\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"mutation observer\\",
|
||||
\\"id\\": 7
|
||||
}
|
||||
],
|
||||
\\"id\\": 6
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 8
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"ul\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 10
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 11
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 12
|
||||
}
|
||||
],
|
||||
\\"id\\": 9
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n\\\\n \\",
|
||||
\\"id\\": 13
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"script\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||
\\"id\\": 15
|
||||
}
|
||||
],
|
||||
\\"id\\": 14
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n \\",
|
||||
\\"id\\": 16
|
||||
}
|
||||
],
|
||||
\\"id\\": 4
|
||||
}
|
||||
],
|
||||
\\"id\\": 2
|
||||
}
|
||||
],
|
||||
\\"id\\": 1
|
||||
},
|
||||
\\"initialOffset\\": {
|
||||
\\"left\\": 0,
|
||||
\\"top\\": 0
|
||||
}
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [
|
||||
{
|
||||
\\"id\\": 7,
|
||||
\\"value\\": \\"mutated\\"
|
||||
}
|
||||
],
|
||||
\\"attributes\\": [],
|
||||
\\"removes\\": [
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"id\\": 9
|
||||
}
|
||||
],
|
||||
\\"adds\\": []
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`child-list 1`] = `
|
||||
"[
|
||||
{
|
||||
@@ -51,33 +363,51 @@ exports[`child-list 1`] = `
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"ul\\",
|
||||
\\"tagName\\": \\"p\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"textContent\\": \\"mutation observer\\",
|
||||
\\"id\\": 7
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 8
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 9
|
||||
}
|
||||
],
|
||||
\\"id\\": 6
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 8
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"ul\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 10
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 11
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 12
|
||||
}
|
||||
],
|
||||
\\"id\\": 9
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n\\\\n \\",
|
||||
\\"id\\": 10
|
||||
\\"id\\": 13
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
@@ -87,15 +417,15 @@ exports[`child-list 1`] = `
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||
\\"id\\": 12
|
||||
\\"id\\": 15
|
||||
}
|
||||
],
|
||||
\\"id\\": 11
|
||||
\\"id\\": 14
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n \\",
|
||||
\\"id\\": 13
|
||||
\\"id\\": 16
|
||||
}
|
||||
],
|
||||
\\"id\\": 4
|
||||
@@ -122,10 +452,23 @@ exports[`child-list 1`] = `
|
||||
\\"removes\\": [
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"id\\": 6
|
||||
\\"id\\": 9
|
||||
}
|
||||
],
|
||||
\\"adds\\": []
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 6,
|
||||
\\"previousId\\": 7,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"span\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 17
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
}
|
||||
@@ -586,20 +929,6 @@ exports[`form 1`] = `
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 1,
|
||||
\\"positions\\": [
|
||||
{
|
||||
\\"x\\": 204,
|
||||
\\"y\\": 117,
|
||||
\\"timeOffset\\": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
\\"timestamp\\": 1542268800000
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<body>
|
||||
<p>mutation observer</p>
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul>
|
||||
@@ -6,6 +6,7 @@ import * as rollup from 'rollup';
|
||||
import typescript = require('rollup-plugin-typescript');
|
||||
import resolve = require('rollup-plugin-node-resolve');
|
||||
import { SnapshotState, toMatchSnapshot } from 'jest-snapshot';
|
||||
import { incrementalSnapshotEvent } from '../src/types';
|
||||
|
||||
function matchSnapshot(actual: string, testFile: string, testTitle: string) {
|
||||
const snapshotState = new SnapshotState(testFile, {
|
||||
@@ -21,6 +22,24 @@ function matchSnapshot(actual: string, testFile: string, testTitle: string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puppeteer may cast random mouse move which make our tests flaky.
|
||||
* So we only do snapshot test with filtered events.
|
||||
* @param snapshots incrementalSnapshotEvent[]
|
||||
*/
|
||||
function stringifySnapshots(snapshots: incrementalSnapshotEvent[]): string {
|
||||
return JSON.stringify(
|
||||
snapshots.filter(s => {
|
||||
if (s.type === 3 && s.data.source === 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
describe('record integration tests', () => {
|
||||
function getHtml(fileName: string): string {
|
||||
const filePath = path.resolve(__dirname, `./html/${fileName}`);
|
||||
@@ -78,7 +97,7 @@ describe('record integration tests', () => {
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
const result = matchSnapshot(
|
||||
JSON.stringify(snapshots, null, 2),
|
||||
stringifySnapshots(snapshots),
|
||||
__filename,
|
||||
'form',
|
||||
);
|
||||
@@ -88,21 +107,71 @@ describe('record integration tests', () => {
|
||||
it('can record childList mutations', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
await page.goto('about:blank');
|
||||
await page.setContent(getHtml.call(this, 'child-list.html'));
|
||||
await page.setContent(getHtml.call(this, 'mutation-observer.html'));
|
||||
|
||||
await page.evaluate(() => {
|
||||
const li = document.createElement('li');
|
||||
const ul = document.querySelector('ul') as HTMLUListElement;
|
||||
ul.appendChild(li);
|
||||
document.body.removeChild(ul);
|
||||
const p = document.querySelector('p') as HTMLParagraphElement;
|
||||
p.appendChild(document.createElement('span'));
|
||||
});
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
const result = matchSnapshot(
|
||||
JSON.stringify(snapshots, null, 2),
|
||||
stringifySnapshots(snapshots),
|
||||
__filename,
|
||||
'child-list',
|
||||
);
|
||||
assert(result.pass, result.pass ? '' : result.report());
|
||||
}).timeout(5000);
|
||||
|
||||
it('can record character data muatations', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
await page.goto('about:blank');
|
||||
await page.setContent(getHtml.call(this, 'mutation-observer.html'));
|
||||
|
||||
await page.evaluate(() => {
|
||||
const li = document.createElement('li');
|
||||
const ul = document.querySelector('ul') as HTMLUListElement;
|
||||
ul.appendChild(li);
|
||||
li.innerText = 'new list item';
|
||||
li.innerText = 'new list item edit';
|
||||
document.body.removeChild(ul);
|
||||
const p = document.querySelector('p') as HTMLParagraphElement;
|
||||
p.innerText = 'mutated';
|
||||
});
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
const result = matchSnapshot(
|
||||
stringifySnapshots(snapshots),
|
||||
__filename,
|
||||
'character-data',
|
||||
);
|
||||
assert(result.pass, result.pass ? '' : result.report());
|
||||
});
|
||||
|
||||
it('can record attribute mutation', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
await page.goto('about:blank');
|
||||
await page.setContent(getHtml.call(this, 'mutation-observer.html'));
|
||||
|
||||
await page.evaluate(() => {
|
||||
const li = document.createElement('li');
|
||||
const ul = document.querySelector('ul') as HTMLUListElement;
|
||||
ul.appendChild(li);
|
||||
li.setAttribute('foo', 'bar');
|
||||
document.body.removeChild(ul);
|
||||
document.body.setAttribute('test', 'true');
|
||||
});
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
const result = matchSnapshot(
|
||||
stringifySnapshots(snapshots),
|
||||
__filename,
|
||||
'attributes',
|
||||
);
|
||||
assert(result.pass, result.pass ? '' : result.report());
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user