Impl record iframe (#481)
* Impl record iframe * iframe observe * temp: add bundle file to git * update bundle * update with pick * update bundle * fix fragment map remove * feat: add an option to determine whether to pause CSS animation when playback is paused (#428) set pauseAnimation to true by default * fix: elements would lose some states like scroll position because of "virtual parent" optimization (#427) * fix: elements would lose some state like scroll position because of "virtual parent" optimization * refactor: the bugfix code bug: elements would lose some state like scroll position because of "virtual parent" optimization * fix: an error occured at applyMutation(remove nodes part) error message: Uncaught (in promise) DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node * pick fixes * revert ignore file * re-impl iframe record * re-impl iframe replay * code housekeeping * move multi layer dimension calculation to replay side * update test cases * teardown test server * upgrade rrweb-snapshot with iframe load timeout Co-authored-by: Lucky Feng <yun.feng@smartx.com>
This commit is contained in:
@@ -1727,6 +1727,708 @@ exports[`frozen 1`] = `
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`iframe 1`] = `
|
||||
"[
|
||||
{
|
||||
\\"type\\": 0,
|
||||
\\"data\\": {}
|
||||
},
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"data\\": {}
|
||||
},
|
||||
{
|
||||
\\"type\\": 4,
|
||||
\\"data\\": {
|
||||
\\"href\\": \\"about:blank\\",
|
||||
\\"width\\": 1920,
|
||||
\\"height\\": 1080
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 19,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 20,
|
||||
\\"id\\": 22
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 20,
|
||||
\\"id\\": 23
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 20,
|
||||
\\"id\\": 21
|
||||
}
|
||||
],
|
||||
\\"id\\": 20
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": []
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"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\\": \\"title\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"Main\\",
|
||||
\\"id\\": 11
|
||||
}
|
||||
],
|
||||
\\"id\\": 10
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 12
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"style\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n iframe {\\\\n width: 500px;\\\\n height: 500px;\\\\n }\\\\n \\",
|
||||
\\"isStyle\\": true,
|
||||
\\"id\\": 14
|
||||
}
|
||||
],
|
||||
\\"id\\": 13
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 15
|
||||
}
|
||||
],
|
||||
\\"id\\": 4
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 16
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 18
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"iframe\\",
|
||||
\\"attributes\\": {
|
||||
\\"id\\": \\"one\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 19
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n \\",
|
||||
\\"id\\": 24
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"script\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||
\\"id\\": 26
|
||||
}
|
||||
],
|
||||
\\"id\\": 25
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n \\\\n \\",
|
||||
\\"id\\": 27
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"script\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||
\\"id\\": 29
|
||||
}
|
||||
],
|
||||
\\"id\\": 28
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n\\\\n\\",
|
||||
\\"id\\": 30
|
||||
}
|
||||
],
|
||||
\\"id\\": 17
|
||||
}
|
||||
],
|
||||
\\"id\\": 3
|
||||
}
|
||||
],
|
||||
\\"id\\": 1
|
||||
},
|
||||
\\"initialOffset\\": {
|
||||
\\"left\\": 0,
|
||||
\\"top\\": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [],
|
||||
\\"removes\\": [],
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 17,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"iframe\\",
|
||||
\\"attributes\\": {
|
||||
\\"id\\": \\"two\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 31
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 47,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 48,
|
||||
\\"id\\": 50
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 48,
|
||||
\\"id\\": 51
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 48,
|
||||
\\"id\\": 49
|
||||
}
|
||||
],
|
||||
\\"id\\": 48
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": []
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 53,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"name\\": \\"html\\",
|
||||
\\"publicId\\": \\"\\",
|
||||
\\"systemId\\": \\"\\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 55
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {
|
||||
\\"lang\\": \\"en\\"
|
||||
},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 58
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"meta\\",
|
||||
\\"attributes\\": {
|
||||
\\"charset\\": \\"UTF-8\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 59
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 60
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"meta\\",
|
||||
\\"attributes\\": {
|
||||
\\"name\\": \\"viewport\\",
|
||||
\\"content\\": \\"width=device-width, initial-scale=1.0\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 61
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 62
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"title\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"Frame 2\\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 64
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 63
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 65
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 57
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 66
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n frame 2\\\\n \\\\n \\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 68
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"script\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 70
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 69
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n\\\\n\\",
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 71
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 67
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 56
|
||||
}
|
||||
],
|
||||
\\"id\\": 54
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": []
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 31,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"name\\": \\"html\\",
|
||||
\\"publicId\\": \\"\\",
|
||||
\\"systemId\\": \\"\\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 33
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {
|
||||
\\"lang\\": \\"en\\"
|
||||
},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 36
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"meta\\",
|
||||
\\"attributes\\": {
|
||||
\\"charset\\": \\"UTF-8\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 37
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 38
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"meta\\",
|
||||
\\"attributes\\": {
|
||||
\\"name\\": \\"viewport\\",
|
||||
\\"content\\": \\"width=device-width, initial-scale=1.0\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 39
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 40
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"title\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"Frame 1\\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 42
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 41
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 43
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 35
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 44
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n frame 1\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 46
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"iframe\\",
|
||||
\\"attributes\\": {
|
||||
\\"id\\": \\"three\\",
|
||||
\\"frameborder\\": \\"0\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 47
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 52
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"iframe\\",
|
||||
\\"attributes\\": {
|
||||
\\"id\\": \\"four\\",
|
||||
\\"frameborder\\": \\"0\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 53
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n\\\\n\\",
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 72
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 45
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 32,
|
||||
\\"id\\": 34
|
||||
}
|
||||
],
|
||||
\\"id\\": 32
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": []
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 73,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 74,
|
||||
\\"id\\": 76
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 74,
|
||||
\\"id\\": 77
|
||||
}
|
||||
],
|
||||
\\"rootId\\": 74,
|
||||
\\"id\\": 75
|
||||
}
|
||||
],
|
||||
\\"id\\": 74
|
||||
}
|
||||
}
|
||||
],
|
||||
\\"removes\\": [],
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": []
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [],
|
||||
\\"removes\\": [],
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 67,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"iframe\\",
|
||||
\\"attributes\\": {
|
||||
\\"id\\": \\"five\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"rootId\\": 54,
|
||||
\\"id\\": 73
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`ignore 1`] = `
|
||||
"[
|
||||
{
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
EventType,
|
||||
eventWithTime,
|
||||
IncrementalSource
|
||||
} from '../../src/types';
|
||||
import { EventType, eventWithTime, IncrementalSource } from '../../src/types';
|
||||
|
||||
const now = Date.now();
|
||||
const events: eventWithTime[] = [
|
||||
@@ -27,68 +23,124 @@ const events: eventWithTime[] = [
|
||||
},
|
||||
// full snapshot:
|
||||
{
|
||||
"data": {
|
||||
"node": {
|
||||
"id": 1, "type": 0, "childNodes": [{ "id": 2, "name": "html", "type": 1, "publicId": "", "systemId": "" }, {
|
||||
"id": 3, "type": 2, "tagName": "html", "attributes": { "lang": "en" }, "childNodes": [{
|
||||
"id": 4, "type": 2, "tagName": "head", "attributes": {}, "childNodes": [
|
||||
data: {
|
||||
node: {
|
||||
id: 1,
|
||||
type: 0,
|
||||
childNodes: [
|
||||
{ id: 2, name: 'html', type: 1, publicId: '', systemId: '' },
|
||||
{
|
||||
id: 3,
|
||||
type: 2,
|
||||
tagName: 'html',
|
||||
attributes: { lang: 'en' },
|
||||
childNodes: [
|
||||
{
|
||||
"id": 101, "type": 2, "tagName": "style", "attributes": { "data-jss": "", "data-meta": "sk, Unthemed, Static" }, "childNodes": [{ "id": 102, "type": 3, "isStyle": true, "textContent": "\n.c01x {\n opacity: 1;\n transform: translateX(0);\n}\n" }]
|
||||
id: 4,
|
||||
type: 2,
|
||||
tagName: 'head',
|
||||
attributes: {},
|
||||
childNodes: [
|
||||
{
|
||||
id: 101,
|
||||
type: 2,
|
||||
tagName: 'style',
|
||||
attributes: {
|
||||
'data-jss': '',
|
||||
'data-meta': 'sk, Unthemed, Static',
|
||||
},
|
||||
childNodes: [
|
||||
{
|
||||
id: 102,
|
||||
type: 3,
|
||||
isStyle: true,
|
||||
textContent:
|
||||
'\n.c01x {\n opacity: 1;\n transform: translateX(0);\n}\n',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 105,
|
||||
type: 2,
|
||||
tagName: 'style',
|
||||
attributes: {
|
||||
_cssText:
|
||||
'.css-1uxxxx3 { position: fixed; top: 0px; right: 0px; left: 4rem; z-index: 15; flex-shrink: 0; height: 0.25rem; overflow: hidden; background-color: rgb(17, 171, 209); }.css-1c9xxxx { height: 0.25rem; background-color: rgb(190, 232, 242); opacity: 0; transition: opacity 0.5s ease 0s; }.css-lsxxx { padding-left: 4rem; }',
|
||||
'data-emotion': 'css',
|
||||
},
|
||||
childNodes: [
|
||||
{ id: 106, type: 3, isStyle: true, textContent: '' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": 105, "type": 2, "tagName": "style", "attributes":
|
||||
{ "_cssText": ".css-1uxxxx3 { position: fixed; top: 0px; right: 0px; left: 4rem; z-index: 15; flex-shrink: 0; height: 0.25rem; overflow: hidden; background-color: rgb(17, 171, 209); }.css-1c9xxxx { height: 0.25rem; background-color: rgb(190, 232, 242); opacity: 0; transition: opacity 0.5s ease 0s; }.css-lsxxx { padding-left: 4rem; }", "data-emotion": "css" }, "childNodes": [{ "id": 106, "type": 3, "isStyle": true, "textContent": "" }]
|
||||
}]
|
||||
}, {
|
||||
"id": 107, "type": 2, "tagName": "body", "attributes": {}, "childNodes": []
|
||||
}]
|
||||
}]
|
||||
}, "initialOffset": { "top": 0, "left": 0 }
|
||||
id: 107,
|
||||
type: 2,
|
||||
tagName: 'body',
|
||||
attributes: {},
|
||||
childNodes: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
initialOffset: { top: 0, left: 0 },
|
||||
},
|
||||
"type": EventType.FullSnapshot,
|
||||
"timestamp": now + 100
|
||||
type: EventType.FullSnapshot,
|
||||
timestamp: now + 100,
|
||||
},
|
||||
// mutation that adds stylesheet
|
||||
{
|
||||
"data": {
|
||||
"adds": [
|
||||
data: {
|
||||
adds: [
|
||||
{
|
||||
"node": {
|
||||
"id": 255, "type": 2, "tagName": "style", "attributes": { "data-jss": "", "data-meta": "Col, Themed, Dynamic" }, "childNodes": []
|
||||
node: {
|
||||
id: 255,
|
||||
type: 2,
|
||||
tagName: 'style',
|
||||
attributes: { 'data-jss': '', 'data-meta': 'Col, Themed, Dynamic' },
|
||||
childNodes: [],
|
||||
},
|
||||
"nextId": 101,
|
||||
"parentId": 4
|
||||
nextId: 101,
|
||||
parentId: 4,
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": 256, "type": 3, "isStyle": true, "textContent": "\n.c011xx {\n padding: 1.3125rem;\n flex: none;\n width: 100%;\n}\n"
|
||||
node: {
|
||||
id: 256,
|
||||
type: 3,
|
||||
isStyle: true,
|
||||
textContent:
|
||||
'\n.c011xx {\n padding: 1.3125rem;\n flex: none;\n width: 100%;\n}\n',
|
||||
},
|
||||
"nextId": null,
|
||||
"parentId": 255
|
||||
nextId: null,
|
||||
parentId: 255,
|
||||
},
|
||||
],
|
||||
"texts": [],
|
||||
"source": IncrementalSource.Mutation,
|
||||
"removes": [],
|
||||
"attributes": []
|
||||
texts: [],
|
||||
source: IncrementalSource.Mutation,
|
||||
removes: [],
|
||||
attributes: [],
|
||||
},
|
||||
"type": EventType.IncrementalSnapshot,
|
||||
"timestamp": now + 500
|
||||
type: EventType.IncrementalSnapshot,
|
||||
timestamp: now + 500,
|
||||
},
|
||||
// adds StyleSheetRule
|
||||
{
|
||||
"data": {
|
||||
"id": 105, "adds": [
|
||||
data: {
|
||||
id: 105,
|
||||
adds: [
|
||||
{
|
||||
"rule": ".css-1fbxx79{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-width:60rem;min-height:100vh;}",
|
||||
"index": 2
|
||||
}
|
||||
rule:
|
||||
'.css-1fbxx79{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-width:60rem;min-height:100vh;}',
|
||||
index: 2,
|
||||
},
|
||||
],
|
||||
"source": IncrementalSource.StyleSheetRule
|
||||
source: IncrementalSource.StyleSheetRule,
|
||||
},
|
||||
"type": EventType.IncrementalSnapshot,
|
||||
"timestamp": now + 1000
|
||||
}
|
||||
type: EventType.IncrementalSnapshot,
|
||||
timestamp: now + 1000,
|
||||
},
|
||||
];
|
||||
|
||||
export default events;
|
||||
export default events;
|
||||
|
||||
13
test/html/frame1.html
Normal file
13
test/html/frame1.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Frame 1</title>
|
||||
</head>
|
||||
<body>
|
||||
frame 1
|
||||
<iframe id="three" frameborder="0"></iframe>
|
||||
<iframe id="four" src="./frame2.html" frameborder="0"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
18
test/html/frame2.html
Normal file
18
test/html/frame2.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Frame 2</title>
|
||||
</head>
|
||||
<body>
|
||||
frame 2
|
||||
</body>
|
||||
<script>
|
||||
const iframe5 = document.createElement('iframe');
|
||||
iframe5.id = 'five';
|
||||
setTimeout(() => {
|
||||
document.body.appendChild(iframe5);
|
||||
}, 10);
|
||||
</script>
|
||||
</html>
|
||||
25
test/html/main.html
Normal file
25
test/html/main.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Main</title>
|
||||
<style>
|
||||
iframe {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="one"></iframe>
|
||||
</body>
|
||||
<script>
|
||||
const iframe2 = document.createElement('iframe');
|
||||
iframe2.id = 'two';
|
||||
iframe2.src = './html/frame1.html';
|
||||
setTimeout(() => {
|
||||
document.body.appendChild(iframe2);
|
||||
}, 10);
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as http from 'http';
|
||||
import * as url from 'url';
|
||||
import * as puppeteer from 'puppeteer';
|
||||
import { assertSnapshot, launchPuppeteer } from './utils';
|
||||
import { Suite } from 'mocha';
|
||||
@@ -8,10 +10,48 @@ import { recordOptions, eventWithTime, EventType } from '../src/types';
|
||||
import { visitSnapshot, NodeType } from 'rrweb-snapshot';
|
||||
|
||||
interface ISuite extends Suite {
|
||||
server: http.Server;
|
||||
code: string;
|
||||
browser: puppeteer.Browser;
|
||||
}
|
||||
|
||||
interface IMimeType {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
const server = () =>
|
||||
new Promise<http.Server>((resolve) => {
|
||||
const mimeType: IMimeType = {
|
||||
'.html': 'text/html',
|
||||
'.js': 'text/javascript',
|
||||
'.css': 'text/css',
|
||||
};
|
||||
const s = http.createServer((req, res) => {
|
||||
const parsedUrl = url.parse(req.url!);
|
||||
const sanitizePath = path
|
||||
.normalize(parsedUrl.pathname!)
|
||||
.replace(/^(\.\.[\/\\])+/, '');
|
||||
let pathname = path.join(__dirname, sanitizePath);
|
||||
try {
|
||||
const data = fs.readFileSync(pathname);
|
||||
const ext = path.parse(pathname).ext;
|
||||
res.setHeader('Content-type', mimeType[ext] || 'text/plain');
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET');
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-type');
|
||||
setTimeout(() => {
|
||||
res.end(data);
|
||||
// mock delay
|
||||
}, 100);
|
||||
} catch (error) {
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
s.listen(3030).on('listening', () => {
|
||||
resolve(s);
|
||||
});
|
||||
});
|
||||
|
||||
describe('record integration tests', function (this: ISuite) {
|
||||
this.timeout(10_000);
|
||||
|
||||
@@ -44,6 +84,7 @@ describe('record integration tests', function (this: ISuite) {
|
||||
};
|
||||
|
||||
before(async () => {
|
||||
this.server = await server();
|
||||
this.browser = await launchPuppeteer();
|
||||
|
||||
const bundlePath = path.resolve(__dirname, '../dist/rrweb.min.js');
|
||||
@@ -52,6 +93,7 @@ describe('record integration tests', function (this: ISuite) {
|
||||
|
||||
after(async () => {
|
||||
await this.browser.close();
|
||||
this.server.close();
|
||||
});
|
||||
|
||||
it('can record form interactions', async () => {
|
||||
@@ -367,4 +409,14 @@ describe('record integration tests', function (this: ISuite) {
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
assertSnapshot(snapshots, __filename, 'log');
|
||||
});
|
||||
|
||||
it('should nest record iframe', async () => {
|
||||
const page: puppeteer.Page = await this.browser.newPage();
|
||||
await page.goto(`http://localhost:3030/html`);
|
||||
await page.setContent(getHtml.call(this, 'main.html'));
|
||||
|
||||
await page.waitFor(500);
|
||||
const snapshots = await page.evaluate('window.snapshots');
|
||||
assertSnapshot(snapshots, __filename, 'iframe');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Suite } from 'mocha';
|
||||
import {
|
||||
launchPuppeteer,
|
||||
sampleEvents as events,
|
||||
sampleStyleSheetRemoveEvents as stylesheetRemoveEvents
|
||||
sampleStyleSheetRemoveEvents as stylesheetRemoveEvents,
|
||||
} from './utils';
|
||||
import styleSheetRuleEvents from './events/style-sheet-rule-events';
|
||||
|
||||
@@ -127,17 +127,19 @@ describe('replayer', function (this: ISuite) {
|
||||
`);
|
||||
const currentTime = await this.page.evaluate(`
|
||||
replayer.getCurrentTime();
|
||||
`)
|
||||
`);
|
||||
const currentState = await this.page.evaluate(`
|
||||
replayer['service']['state']['value'];
|
||||
`)
|
||||
expect(actionLength).to.equal(0)
|
||||
`);
|
||||
expect(actionLength).to.equal(0);
|
||||
expect(currentTime).to.equal(2500);
|
||||
expect(currentState).to.equal('paused');
|
||||
});
|
||||
|
||||
it('can fast forward past StyleSheetRule changes on virtual elements', async () => {
|
||||
await this.page.evaluate(`events = ${JSON.stringify(styleSheetRuleEvents)}`);
|
||||
await this.page.evaluate(
|
||||
`events = ${JSON.stringify(styleSheetRuleEvents)}`,
|
||||
);
|
||||
const actionLength = await this.page.evaluate(`
|
||||
const { Replayer } = rrweb;
|
||||
const replayer = new Replayer(events);
|
||||
@@ -145,12 +147,16 @@ describe('replayer', function (this: ISuite) {
|
||||
replayer['timer']['actions'].length;
|
||||
`);
|
||||
expect(actionLength).to.equal(
|
||||
styleSheetRuleEvents.filter((e) => e.timestamp - styleSheetRuleEvents[0].timestamp >= 1500).length,
|
||||
styleSheetRuleEvents.filter(
|
||||
(e) => e.timestamp - styleSheetRuleEvents[0].timestamp >= 1500,
|
||||
).length,
|
||||
);
|
||||
});
|
||||
|
||||
it('can handle removing style elements', async () => {
|
||||
await this.page.evaluate(`events = ${JSON.stringify(stylesheetRemoveEvents)}`);
|
||||
await this.page.evaluate(
|
||||
`events = ${JSON.stringify(stylesheetRemoveEvents)}`,
|
||||
);
|
||||
const actionLength = await this.page.evaluate(`
|
||||
const { Replayer } = rrweb;
|
||||
const replayer = new Replayer(events);
|
||||
@@ -158,7 +164,9 @@ describe('replayer', function (this: ISuite) {
|
||||
replayer['timer']['actions'].length;
|
||||
`);
|
||||
expect(actionLength).to.equal(
|
||||
stylesheetRemoveEvents.filter((e) => e.timestamp - stylesheetRemoveEvents[0].timestamp >= 2500).length,
|
||||
stylesheetRemoveEvents.filter(
|
||||
(e) => e.timestamp - stylesheetRemoveEvents[0].timestamp >= 2500,
|
||||
).length,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user