mutation observer v2 (#206)
There are some long-term issues in rrweb's mutation observer. A scenario cause problem: A list of DOM node: n1, n2, n3, n4, n5 Steps of modifying the nodes: 1. remove n1, n2, n3, n4 sequentially 2. append n4, n3, n2, n1 after n5 sequentially Then we got the added node data like this: (id: n4, prev: null, next: n3 ) (id: n3, prev: n4, next: n2 ) (id: n2, prev: n3, next: n1 ) (id: n1, prev: n2, next: null) The problem comes when we try to replay the first add node datum. Since its prev node is null, we rely on its next sibling n3. But n3 was not present at this moment, and in previous code, we fallback to append n4 to the last of its parent node. The solution is to defer the append of elements that missing siblings. But it is also hard to tell which node is the first one that needs to be appended. Take a step back and rethink the design of the mutation observer, we've found there are two implementations make things complicated. 1. We set the id to -1 when we seeing some nodes are not serialized yet. 2. We record both previous sibling and next sibling to determine the position of the node. But we can do better! First, we can put nodes with un-serialized siblings to a queue, and try to add it again later. Then we can just record the next sibling as 'the single truth' so we can be sure which node is the last one of its parent. This patch has implemented the new observer strategy. Data recorded with the new observer should no longer have any node with id -1. But for compatibility consideration, we still keep some replayer code that helps solve legacy data.
This commit is contained in:
@@ -479,7 +479,6 @@ exports[`character-data 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 6,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -635,7 +634,6 @@ exports[`child-list 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 6,
|
||||
\\"previousId\\": 7,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2480,7 +2478,6 @@ exports[`move-node-1 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 6,
|
||||
\\"previousId\\": 9,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2492,7 +2489,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 11,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 13,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2502,7 +2498,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 11,
|
||||
\\"previousId\\": 12,
|
||||
\\"nextId\\": 18,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2514,7 +2509,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 13,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 15,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2524,7 +2518,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 13,
|
||||
\\"previousId\\": 14,
|
||||
\\"nextId\\": 17,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2536,7 +2529,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 15,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2546,7 +2538,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 13,
|
||||
\\"previousId\\": 15,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2556,7 +2547,6 @@ exports[`move-node-1 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 11,
|
||||
\\"previousId\\": 13,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2748,7 +2738,6 @@ exports[`move-node-2 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 11,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 13,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2758,7 +2747,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 11,
|
||||
\\"previousId\\": 12,
|
||||
\\"nextId\\": 18,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2770,7 +2758,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 13,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 15,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2780,7 +2767,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 13,
|
||||
\\"previousId\\": 14,
|
||||
\\"nextId\\": 17,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2792,7 +2778,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 15,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2802,7 +2787,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 13,
|
||||
\\"previousId\\": 15,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2812,7 +2796,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 11,
|
||||
\\"previousId\\": 13,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -2822,7 +2805,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"previousId\\": 22,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -2834,7 +2816,6 @@ exports[`move-node-2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 23,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3804,7 +3785,7 @@ exports[`select2 1`] = `
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"id\\": 75,
|
||||
\\"id\\": 70,
|
||||
\\"attributes\\": {
|
||||
\\"style\\": \\"\\"
|
||||
}
|
||||
@@ -3823,7 +3804,7 @@ exports[`select2 1`] = `
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"id\\": 67,
|
||||
\\"id\\": 72,
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable select2-highlighted\\"
|
||||
}
|
||||
@@ -3842,7 +3823,6 @@ exports[`select2 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 25,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 34,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3858,7 +3838,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 26,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 28,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -3868,7 +3847,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 26,
|
||||
\\"previousId\\": 27,
|
||||
\\"nextId\\": 30,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3883,7 +3861,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 28,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -3893,7 +3870,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 26,
|
||||
\\"previousId\\": 28,
|
||||
\\"nextId\\": 31,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3907,7 +3883,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 26,
|
||||
\\"previousId\\": 30,
|
||||
\\"nextId\\": 32,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -3917,7 +3892,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 26,
|
||||
\\"previousId\\": 31,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3932,7 +3906,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 32,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3946,7 +3919,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 18,
|
||||
\\"previousId\\": -1,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3961,7 +3933,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 36,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 38,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -3971,7 +3942,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 36,
|
||||
\\"previousId\\": 37,
|
||||
\\"nextId\\": 44,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -3985,7 +3955,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 38,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": 40,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -3995,7 +3964,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 38,
|
||||
\\"previousId\\": 39,
|
||||
\\"nextId\\": 41,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4010,7 +3978,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 38,
|
||||
\\"previousId\\": 40,
|
||||
\\"nextId\\": 42,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -4020,7 +3987,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 38,
|
||||
\\"previousId\\": 41,
|
||||
\\"nextId\\": 43,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4046,7 +4012,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 38,
|
||||
\\"previousId\\": 42,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -4056,7 +4021,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 36,
|
||||
\\"previousId\\": 38,
|
||||
\\"nextId\\": 45,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -4066,7 +4030,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 36,
|
||||
\\"previousId\\": 44,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4082,62 +4045,6 @@ exports[`select2 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 45,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": -1,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable select2-highlighted\\",
|
||||
\\"role\\": \\"presentation\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 67
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 67,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"div\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-result-label\\",
|
||||
\\"id\\": \\"select2-result-label-2\\",
|
||||
\\"role\\": \\"option\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 68
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 68,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": -1,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"span\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-match\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 69
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 68,
|
||||
\\"previousId\\": 69,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"A\\",
|
||||
\\"id\\": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 45,
|
||||
\\"previousId\\": 67,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4147,12 +4054,11 @@ exports[`select2 1`] = `
|
||||
\\"role\\": \\"presentation\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 71
|
||||
\\"id\\": 67
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 71,
|
||||
\\"previousId\\": null,
|
||||
\\"parentId\\": 67,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4163,36 +4069,20 @@ exports[`select2 1`] = `
|
||||
\\"role\\": \\"option\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 72
|
||||
\\"id\\": 68
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 72,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": -1,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"span\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-match\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 72,
|
||||
\\"previousId\\": 73,
|
||||
\\"parentId\\": 68,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"B\\",
|
||||
\\"id\\": 74
|
||||
\\"id\\": 69
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 18,
|
||||
\\"previousId\\": 66,
|
||||
\\"nextId\\": 36,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4203,16 +4093,79 @@ exports[`select2 1`] = `
|
||||
\\"style\\": \\"\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 75
|
||||
\\"id\\": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 62,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"2 results are available, use up and down arrow keys to navigate.\\",
|
||||
\\"id\\": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 45,
|
||||
\\"nextId\\": 67,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable select2-highlighted\\",
|
||||
\\"role\\": \\"presentation\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 72,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"div\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-result-label\\",
|
||||
\\"id\\": \\"select2-result-label-2\\",
|
||||
\\"role\\": \\"option\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 73,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"A\\",
|
||||
\\"id\\": 74
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 68,
|
||||
\\"nextId\\": 69,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"span\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-match\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 75
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 73,
|
||||
\\"nextId\\": 74,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"span\\",
|
||||
\\"attributes\\": {
|
||||
\\"class\\": \\"select2-match\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 76
|
||||
}
|
||||
}
|
||||
@@ -4224,7 +4177,7 @@ exports[`select2 1`] = `
|
||||
\\"data\\": {
|
||||
\\"source\\": 2,
|
||||
\\"type\\": 0,
|
||||
\\"id\\": 75
|
||||
\\"id\\": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4250,7 +4203,7 @@ exports[`select2 1`] = `
|
||||
\\"data\\": {
|
||||
\\"source\\": 2,
|
||||
\\"type\\": 1,
|
||||
\\"id\\": 75
|
||||
\\"id\\": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4276,7 +4229,7 @@ exports[`select2 1`] = `
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [
|
||||
{
|
||||
\\"id\\": 75,
|
||||
\\"id\\": 70,
|
||||
\\"attributes\\": {
|
||||
\\"style\\": \\"display: none;\\"
|
||||
}
|
||||
@@ -4309,21 +4262,20 @@ exports[`select2 1`] = `
|
||||
\\"removes\\": [
|
||||
{
|
||||
\\"parentId\\": 18,
|
||||
\\"id\\": 75
|
||||
\\"id\\": 70
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 45,
|
||||
\\"id\\": 72
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 45,
|
||||
\\"id\\": 67
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 45,
|
||||
\\"id\\": 71
|
||||
}
|
||||
],
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 18,
|
||||
\\"previousId\\": 66,
|
||||
\\"nextId\\": 36,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -4334,7 +4286,7 @@ exports[`select2 1`] = `
|
||||
\\"style\\": \\"display: none;\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 75
|
||||
\\"id\\": 70
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -4350,3 +4302,177 @@ exports[`select2 1`] = `
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`serialize-before-record 1`] = `
|
||||
"[
|
||||
{
|
||||
\\"type\\": 0,
|
||||
\\"data\\": {}
|
||||
},
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"data\\": {}
|
||||
},
|
||||
{
|
||||
\\"type\\": 4,
|
||||
\\"data\\": {
|
||||
\\"href\\": \\"about:blank\\",
|
||||
\\"width\\": 1920,
|
||||
\\"height\\": 1080
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"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
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [],
|
||||
\\"removes\\": [],
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 9,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 17
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 9,
|
||||
\\"nextId\\": 17,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 18
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 9,
|
||||
\\"nextId\\": 18,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"li\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 19
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
@@ -82,7 +82,6 @@ exports[`async-checkout 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"previousId\\": 7,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -94,7 +93,6 @@ exports[`async-checkout 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 8,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -117,7 +115,6 @@ exports[`async-checkout 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 9,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -220,7 +217,6 @@ exports[`async-checkout 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"previousId\\": 8,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
@@ -232,7 +228,6 @@ exports[`async-checkout 1`] = `
|
||||
},
|
||||
{
|
||||
\\"parentId\\": 9,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 3,
|
||||
@@ -409,7 +404,6 @@ exports[`stylesheet-rules 1`] = `
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 3,
|
||||
\\"previousId\\": null,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
|
||||
12
test/html/shuffle.html
Normal file
12
test/html/shuffle.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>shuffle</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- prettier-ignore -->
|
||||
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,6 +3,7 @@ import * as path from 'path';
|
||||
import * as puppeteer from 'puppeteer';
|
||||
import { assertSnapshot, launchPuppeteer } from './utils';
|
||||
import { Suite } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { recordOptions, eventWithTime } from '../src/types';
|
||||
|
||||
interface ISuite extends Suite {
|
||||
@@ -63,7 +64,7 @@ describe('record integration tests', function (this: ISuite) {
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
assertSnapshot(snapshots, __filename, 'form');
|
||||
}).timeout(5000);
|
||||
});
|
||||
|
||||
it('can record childList mutations', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
@@ -81,7 +82,7 @@ describe('record integration tests', function (this: ISuite) {
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
assertSnapshot(snapshots, __filename, 'child-list');
|
||||
}).timeout(5000);
|
||||
});
|
||||
|
||||
it('can record character data muatations', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
@@ -219,4 +220,45 @@ describe('record integration tests', function (this: ISuite) {
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
assertSnapshot(snapshots, __filename, 'react-styled-components');
|
||||
});
|
||||
|
||||
it('will serialize node before record', 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 ul = document.querySelector('ul') as HTMLUListElement;
|
||||
let count = 3;
|
||||
while (count > 0) {
|
||||
count--;
|
||||
const li = document.createElement('li');
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
assertSnapshot(snapshots, __filename, 'serialize-before-record');
|
||||
});
|
||||
|
||||
it('will defer missing next node mutation', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
await page.goto('about:blank');
|
||||
await page.setContent(getHtml.call(this, 'shuffle.html'));
|
||||
|
||||
const text = await page.evaluate(() => {
|
||||
const els = Array.prototype.slice.call(document.querySelectorAll('li'));
|
||||
const parent = document.querySelector('ul')!;
|
||||
parent.removeChild(els[3]);
|
||||
parent.removeChild(els[2]);
|
||||
parent.removeChild(els[1]);
|
||||
parent.removeChild(els[0]);
|
||||
parent.insertBefore(els[3], els[4]);
|
||||
parent.insertBefore(els[2], els[4]);
|
||||
parent.insertBefore(els[1], els[4]);
|
||||
parent.insertBefore(els[0], els[4]);
|
||||
return parent.innerText;
|
||||
});
|
||||
|
||||
expect(text).to.equal('4\n3\n2\n1\n5');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user