@percy/dom 1.19.1-alpha.0 → 1.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/bundle.js +146 -149
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -37,6 +37,7 @@ const domSnapshot = await page.evaluate(() => PercyDOM.serialize(options))
|
|
|
37
37
|
|
|
38
38
|
- `enableJavaScript` — When true, does not serialize some DOM elements
|
|
39
39
|
- `domTransformation` — Function to transform the DOM after serialization
|
|
40
|
+
- `disableShadowDOM` — disable shadow DOM capturing, this option can be passed to `percySnapshot` its part of per-snapshot config.
|
|
40
41
|
|
|
41
42
|
## Serialized Content
|
|
42
43
|
|
package/dist/bundle.js
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
function serializeInputElements(_ref) {
|
|
11
11
|
let {
|
|
12
12
|
dom,
|
|
13
|
-
clone
|
|
13
|
+
clone,
|
|
14
|
+
warnings
|
|
14
15
|
} = _ref;
|
|
15
16
|
for (let elem of dom.querySelectorAll('input, textarea, select')) {
|
|
16
17
|
let inputId = elem.getAttribute('data-percy-element-id');
|
|
@@ -39,23 +40,12 @@
|
|
|
39
40
|
cloneEl.setAttribute('value', elem.value);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
-
// find inputs inside shadow host and recursively serialize them.
|
|
44
|
-
for (let shadowHost of dom.querySelectorAll('[data-percy-shadow-host]')) {
|
|
45
|
-
let percyElementId = shadowHost.getAttribute('data-percy-element-id');
|
|
46
|
-
let cloneShadowHost = clone.querySelector(`[data-percy-element-id="${percyElementId}"]`);
|
|
47
|
-
if (shadowHost.shadowRoot && cloneShadowHost.shadowRoot) {
|
|
48
|
-
serializeInputElements({
|
|
49
|
-
dom: shadowHost.shadowRoot,
|
|
50
|
-
clone: cloneShadowHost.shadowRoot
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
43
|
}
|
|
55
44
|
|
|
56
45
|
// Adds a `<base>` element to the serialized iframe's `<head>`. This is necessary when
|
|
57
46
|
// embedded documents are serialized and their contents become root-relative.
|
|
58
47
|
function setBaseURI(dom) {
|
|
48
|
+
/* istanbul ignore if: sanity check */
|
|
59
49
|
if (!new URL(dom.baseURI).hostname) return;
|
|
60
50
|
let $base = document.createElement('base');
|
|
61
51
|
$base.href = dom.baseURI;
|
|
@@ -69,7 +59,8 @@
|
|
|
69
59
|
clone,
|
|
70
60
|
warnings,
|
|
71
61
|
resources,
|
|
72
|
-
enableJavaScript
|
|
62
|
+
enableJavaScript,
|
|
63
|
+
disableShadowDOM
|
|
73
64
|
} = _ref;
|
|
74
65
|
for (let frame of dom.querySelectorAll('iframe')) {
|
|
75
66
|
var _clone$head;
|
|
@@ -94,7 +85,8 @@
|
|
|
94
85
|
let serialized = serializeDOM({
|
|
95
86
|
domTransformation: setBaseURI,
|
|
96
87
|
dom: frame.contentDocument,
|
|
97
|
-
enableJavaScript
|
|
88
|
+
enableJavaScript,
|
|
89
|
+
disableShadowDOM
|
|
98
90
|
});
|
|
99
91
|
|
|
100
92
|
// append serialized warnings and resources
|
|
@@ -112,19 +104,61 @@
|
|
|
112
104
|
cloneEl.remove();
|
|
113
105
|
}
|
|
114
106
|
}
|
|
107
|
+
}
|
|
115
108
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
109
|
+
// Creates a resource object from an element's unique ID and data URL
|
|
110
|
+
function resourceFromDataURL(uid, dataURL) {
|
|
111
|
+
// split dataURL into desired parts
|
|
112
|
+
let [data, content] = dataURL.split(',');
|
|
113
|
+
let [, mimetype] = data.split(':');
|
|
114
|
+
[mimetype] = mimetype.split(';');
|
|
115
|
+
|
|
116
|
+
// build a URL for the serialized asset
|
|
117
|
+
let [, ext] = mimetype.split('/');
|
|
118
|
+
let path = `/__serialized__/${uid}.${ext}`;
|
|
119
|
+
let url = new URL(path, document.URL).toString();
|
|
120
|
+
|
|
121
|
+
// return the url, base64 content, and mimetype
|
|
122
|
+
return {
|
|
123
|
+
url,
|
|
124
|
+
content,
|
|
125
|
+
mimetype
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function resourceFromText(uid, mimetype, data) {
|
|
129
|
+
// build a URL for the serialized asset
|
|
130
|
+
let [, ext] = mimetype.split('/');
|
|
131
|
+
let path = `/__serialized__/${uid}.${ext}`;
|
|
132
|
+
let url = new URL(path, document.URL).toString();
|
|
133
|
+
// converts text to base64
|
|
134
|
+
let content = window.btoa(data);
|
|
135
|
+
|
|
136
|
+
// return the url, base64 content, and mimetype
|
|
137
|
+
return {
|
|
138
|
+
url,
|
|
139
|
+
content,
|
|
140
|
+
mimetype
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Returns a mostly random uid.
|
|
145
|
+
function uid() {
|
|
146
|
+
return `_${Math.random().toString(36).substr(2, 9)}`;
|
|
147
|
+
}
|
|
148
|
+
function markElement(domElement, disableShadowDOM) {
|
|
149
|
+
var _domElement$tagName;
|
|
150
|
+
// Mark elements that are to be serialized later with a data attribute.
|
|
151
|
+
if (['input', 'textarea', 'select', 'iframe', 'canvas', 'video', 'style'].includes((_domElement$tagName = domElement.tagName) === null || _domElement$tagName === void 0 ? void 0 : _domElement$tagName.toLowerCase())) {
|
|
152
|
+
if (!domElement.getAttribute('data-percy-element-id')) {
|
|
153
|
+
domElement.setAttribute('data-percy-element-id', uid());
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// add special marker for shadow host
|
|
158
|
+
if (!disableShadowDOM && domElement.shadowRoot) {
|
|
159
|
+
domElement.setAttribute('data-percy-shadow-host', '');
|
|
160
|
+
if (!domElement.getAttribute('data-percy-element-id')) {
|
|
161
|
+
domElement.setAttribute('data-percy-element-id', uid());
|
|
128
162
|
}
|
|
129
163
|
}
|
|
130
164
|
}
|
|
@@ -145,24 +179,35 @@
|
|
|
145
179
|
}
|
|
146
180
|
return true;
|
|
147
181
|
}
|
|
148
|
-
|
|
149
|
-
|
|
182
|
+
function styleSheetFromNode(node) {
|
|
183
|
+
/* istanbul ignore if: sanity check */
|
|
184
|
+
if (node.sheet) return node.sheet;
|
|
185
|
+
|
|
186
|
+
// Cloned style nodes don't have a sheet instance unless they are within
|
|
187
|
+
// a document; we get it by temporarily adding the rules to DOM
|
|
188
|
+
const tempStyle = document.createElement('style');
|
|
189
|
+
tempStyle.setAttribute('data-percy-style-helper', '');
|
|
190
|
+
tempStyle.innerHTML = node.innerHTML;
|
|
191
|
+
const clone = document.cloneNode();
|
|
192
|
+
clone.appendChild(tempStyle);
|
|
193
|
+
const sheet = tempStyle.sheet;
|
|
194
|
+
// Cleanup node
|
|
195
|
+
tempStyle.remove();
|
|
196
|
+
return sheet;
|
|
197
|
+
}
|
|
150
198
|
function serializeCSSOM(_ref) {
|
|
151
199
|
let {
|
|
152
200
|
dom,
|
|
153
201
|
clone,
|
|
154
|
-
|
|
202
|
+
resources,
|
|
203
|
+
cache
|
|
155
204
|
} = _ref;
|
|
205
|
+
// in-memory CSSOM into their respective DOM nodes.
|
|
156
206
|
for (let styleSheet of dom.styleSheets) {
|
|
157
207
|
if (isCSSOM(styleSheet)) {
|
|
158
208
|
let styleId = styleSheet.ownerNode.getAttribute('data-percy-element-id');
|
|
159
|
-
if (!styleId) {
|
|
160
|
-
let attributes = Array.from(styleSheet.ownerNode.attributes).map(attr => `${attr.name}: ${attr.value}`);
|
|
161
|
-
warnings.add(`stylesheet with attributes - [ ${attributes} ] - was not serialized`);
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
209
|
let cloneOwnerNode = clone.querySelector(`[data-percy-element-id="${styleId}"]`);
|
|
165
|
-
if (styleSheetsMatch(styleSheet, cloneOwnerNode
|
|
210
|
+
if (styleSheetsMatch(styleSheet, styleSheetFromNode(cloneOwnerNode))) continue;
|
|
166
211
|
let style = document.createElement('style');
|
|
167
212
|
style.type = 'text/css';
|
|
168
213
|
style.setAttribute('data-percy-element-id', styleId);
|
|
@@ -173,39 +218,30 @@
|
|
|
173
218
|
}
|
|
174
219
|
}
|
|
175
220
|
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
221
|
+
// clone Adopted Stylesheets
|
|
222
|
+
// Regarding ordering of the adopted stylesheets - https://github.com/WICG/construct-stylesheets/issues/93
|
|
223
|
+
for (let sheet of dom.adoptedStyleSheets) {
|
|
224
|
+
const styleLink = document.createElement('link');
|
|
225
|
+
styleLink.setAttribute('rel', 'stylesheet');
|
|
226
|
+
if (!cache.has(sheet)) {
|
|
227
|
+
const styles = Array.from(sheet.cssRules).map(cssRule => cssRule.cssText).join('\n');
|
|
228
|
+
let resource = resourceFromText(uid(), 'text/css', styles);
|
|
229
|
+
resources.add(resource);
|
|
230
|
+
cache.set(sheet, resource.url);
|
|
231
|
+
}
|
|
232
|
+
styleLink.setAttribute('data-percy-adopted-stylesheets-serialized', 'true');
|
|
233
|
+
styleLink.setAttribute('data-percy-serialized-attribute-href', cache.get(sheet));
|
|
234
|
+
|
|
235
|
+
/* istanbul ignore next: tested, but coverage is stripped */
|
|
236
|
+
if (clone.constructor.name === 'HTMLDocument' || clone.constructor.name === 'DocumentFragment') {
|
|
237
|
+
// handle document and iframe
|
|
238
|
+
clone.body.prepend(styleLink);
|
|
239
|
+
} else if (clone.constructor.name === 'ShadowRoot') {
|
|
240
|
+
clone.prepend(styleLink);
|
|
185
241
|
}
|
|
186
242
|
}
|
|
187
243
|
}
|
|
188
244
|
|
|
189
|
-
// Creates a resource object from an element's unique ID and data URL
|
|
190
|
-
function resourceFromDataURL(uid, dataURL) {
|
|
191
|
-
// split dataURL into desired parts
|
|
192
|
-
let [data, content] = dataURL.split(',');
|
|
193
|
-
let [, mimetype] = data.split(':');
|
|
194
|
-
[mimetype] = mimetype.split(';');
|
|
195
|
-
|
|
196
|
-
// build a URL for the serialized asset
|
|
197
|
-
let [, ext] = mimetype.split('/');
|
|
198
|
-
let path = `/__serialized__/${uid}.${ext}`;
|
|
199
|
-
let url = new URL(path, document.URL).toString();
|
|
200
|
-
|
|
201
|
-
// return the url, base64 content, and mimetype
|
|
202
|
-
return {
|
|
203
|
-
url,
|
|
204
|
-
content,
|
|
205
|
-
mimetype
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
245
|
// Serialize in-memory canvas elements into images.
|
|
210
246
|
function serializeCanvas(_ref) {
|
|
211
247
|
let {
|
|
@@ -228,7 +264,6 @@
|
|
|
228
264
|
resources.add(resource);
|
|
229
265
|
|
|
230
266
|
// create an image element in the cloned dom
|
|
231
|
-
// TODO: this works, verify if this is fine?
|
|
232
267
|
let img = document.createElement('img');
|
|
233
268
|
// use a data attribute to avoid making a real request
|
|
234
269
|
img.setAttribute('data-percy-serialized-attribute-src', resource.url);
|
|
@@ -257,19 +292,6 @@
|
|
|
257
292
|
}
|
|
258
293
|
cloneEl.remove();
|
|
259
294
|
}
|
|
260
|
-
|
|
261
|
-
// find canvas inside shadow host and recursively serialize them.
|
|
262
|
-
for (let shadowHost of dom.querySelectorAll('[data-percy-shadow-host]')) {
|
|
263
|
-
let percyElementId = shadowHost.getAttribute('data-percy-element-id');
|
|
264
|
-
let cloneShadowHost = clone.querySelector(`[data-percy-element-id="${percyElementId}"]`);
|
|
265
|
-
if (shadowHost.shadowRoot && cloneShadowHost.shadowRoot) {
|
|
266
|
-
serializeCanvas({
|
|
267
|
-
dom: shadowHost.shadowRoot,
|
|
268
|
-
clone: cloneShadowHost.shadowRoot,
|
|
269
|
-
resources
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
295
|
}
|
|
274
296
|
|
|
275
297
|
// Captures the current frame of videos and sets the poster image
|
|
@@ -306,44 +328,6 @@
|
|
|
306
328
|
// use a data attribute to avoid making a real request
|
|
307
329
|
cloneEl.setAttribute('data-percy-serialized-attribute-poster', resource.url);
|
|
308
330
|
}
|
|
309
|
-
|
|
310
|
-
// find video inside shadow host and recursively serialize them.
|
|
311
|
-
for (let shadowHost of dom.querySelectorAll('[data-percy-shadow-host]')) {
|
|
312
|
-
let percyElementId = shadowHost.getAttribute('data-percy-element-id');
|
|
313
|
-
let cloneShadowHost = clone.querySelector(`[data-percy-element-id="${percyElementId}"]`);
|
|
314
|
-
if (shadowHost.shadowRoot && cloneShadowHost.shadowRoot) {
|
|
315
|
-
serializeVideos({
|
|
316
|
-
dom: shadowHost.shadowRoot,
|
|
317
|
-
clone: cloneShadowHost.shadowRoot,
|
|
318
|
-
resources,
|
|
319
|
-
warnings
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Returns a mostly random uid.
|
|
326
|
-
function uid() {
|
|
327
|
-
return `_${Math.random().toString(36).substr(2, 9)}`;
|
|
328
|
-
}
|
|
329
|
-
function markElement(domElement) {
|
|
330
|
-
var _domElement$tagName;
|
|
331
|
-
// Mark elements that are to be serialized later with a data attribute.
|
|
332
|
-
if (['input', 'textarea', 'select', 'iframe', 'canvas', 'video', 'style'].includes((_domElement$tagName = domElement.tagName) === null || _domElement$tagName === void 0 ? void 0 : _domElement$tagName.toLowerCase())) {
|
|
333
|
-
if (!domElement.getAttribute('data-percy-element-id')) {
|
|
334
|
-
domElement.setAttribute('data-percy-element-id', uid());
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// add special marker for shadow host
|
|
339
|
-
if (domElement.shadowRoot) {
|
|
340
|
-
if (!domElement.getAttribute('data-percy-shadow-host')) {
|
|
341
|
-
domElement.setAttribute('data-percy-shadow-host', '');
|
|
342
|
-
}
|
|
343
|
-
if (!domElement.getAttribute('data-percy-element-id')) {
|
|
344
|
-
domElement.setAttribute('data-percy-element-id', uid());
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
331
|
}
|
|
348
332
|
|
|
349
333
|
/**
|
|
@@ -353,7 +337,7 @@
|
|
|
353
337
|
*/
|
|
354
338
|
|
|
355
339
|
// returns document fragment
|
|
356
|
-
const deepClone = host => {
|
|
340
|
+
const deepClone = (host, disableShadowDOM) => {
|
|
357
341
|
// clones shadow DOM and light DOM for a given node
|
|
358
342
|
let cloneNode = (node, parent) => {
|
|
359
343
|
let walkTree = (nextn, nextp) => {
|
|
@@ -364,12 +348,12 @@
|
|
|
364
348
|
};
|
|
365
349
|
|
|
366
350
|
// mark the node before cloning
|
|
367
|
-
markElement(node);
|
|
351
|
+
markElement(node, disableShadowDOM);
|
|
368
352
|
let clone = node.cloneNode();
|
|
369
353
|
parent.appendChild(clone);
|
|
370
354
|
|
|
371
355
|
// clone shadow DOM
|
|
372
|
-
if (node.shadowRoot) {
|
|
356
|
+
if (node.shadowRoot && !disableShadowDOM) {
|
|
373
357
|
// create shadowRoot
|
|
374
358
|
if (clone.shadowRoot) {
|
|
375
359
|
// it may be set up in a custom element's constructor
|
|
@@ -379,15 +363,6 @@
|
|
|
379
363
|
mode: 'open'
|
|
380
364
|
});
|
|
381
365
|
}
|
|
382
|
-
|
|
383
|
-
// clone stylesheets in shadowRoot
|
|
384
|
-
for (let sheet of node.shadowRoot.adoptedStyleSheets) {
|
|
385
|
-
let cssText = Array.from(sheet.rules).map(rule => rule.cssText).join('\n');
|
|
386
|
-
let style = document.createElement('style');
|
|
387
|
-
style.appendChild(document.createTextNode(cssText));
|
|
388
|
-
clone.shadowRoot.prepend(style);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
366
|
// clone dom elements
|
|
392
367
|
walkTree(node.shadowRoot.firstChild, clone.shadowRoot);
|
|
393
368
|
}
|
|
@@ -403,13 +378,12 @@
|
|
|
403
378
|
/**
|
|
404
379
|
* Deep clone a document while also preserving shadow roots and converting adoptedStylesheets to <style> tags.
|
|
405
380
|
*/
|
|
406
|
-
const cloneNodeAndShadow =
|
|
407
|
-
let
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return cloneDocument;
|
|
381
|
+
const cloneNodeAndShadow = ctx => {
|
|
382
|
+
let cloneDocumentFragment = deepClone(ctx.dom.documentElement, ctx.disableShadowDOM);
|
|
383
|
+
cloneDocumentFragment.documentElement = cloneDocumentFragment.firstChild;
|
|
384
|
+
cloneDocumentFragment.head = cloneDocumentFragment.querySelector('head');
|
|
385
|
+
cloneDocumentFragment.body = cloneDocumentFragment.querySelector('body');
|
|
386
|
+
return cloneDocumentFragment;
|
|
413
387
|
};
|
|
414
388
|
|
|
415
389
|
/**
|
|
@@ -432,7 +406,7 @@
|
|
|
432
406
|
// Since only chromium currently supports declarative shadow DOM - https://caniuse.com/declarative-shadow-dom
|
|
433
407
|
function injectDeclarativeShadowDOMPolyfill(ctx) {
|
|
434
408
|
let clone = ctx.clone;
|
|
435
|
-
let scriptEl =
|
|
409
|
+
let scriptEl = document.createElement('script');
|
|
436
410
|
scriptEl.setAttribute('id', '__percy_shadowdom_helper');
|
|
437
411
|
scriptEl.setAttribute('data-percy-injected', true);
|
|
438
412
|
scriptEl.innerHTML = `
|
|
@@ -453,7 +427,9 @@
|
|
|
453
427
|
document.addEventListener("DOMContentLoaded", () => reversePolyFill());
|
|
454
428
|
}
|
|
455
429
|
`.replace(/(\n|\s{2}|\t)/g, '');
|
|
456
|
-
|
|
430
|
+
|
|
431
|
+
// run polyfill as first thing post dom content is loaded
|
|
432
|
+
clone.head.prepend(scriptEl);
|
|
457
433
|
}
|
|
458
434
|
|
|
459
435
|
// Returns a copy or new doctype for a document.
|
|
@@ -482,6 +458,28 @@
|
|
|
482
458
|
// include the doctype with the html string
|
|
483
459
|
return doctype(ctx.dom) + html;
|
|
484
460
|
}
|
|
461
|
+
function serializeElements(ctx) {
|
|
462
|
+
serializeInputElements(ctx);
|
|
463
|
+
serializeFrames(ctx);
|
|
464
|
+
serializeVideos(ctx);
|
|
465
|
+
if (!ctx.enableJavaScript) {
|
|
466
|
+
serializeCSSOM(ctx);
|
|
467
|
+
serializeCanvas(ctx);
|
|
468
|
+
}
|
|
469
|
+
for (const shadowHost of ctx.dom.querySelectorAll('[data-percy-shadow-host]')) {
|
|
470
|
+
let percyElementId = shadowHost.getAttribute('data-percy-element-id');
|
|
471
|
+
let cloneShadowHost = ctx.clone.querySelector(`[data-percy-element-id="${percyElementId}"]`);
|
|
472
|
+
if (shadowHost.shadowRoot && cloneShadowHost.shadowRoot) {
|
|
473
|
+
serializeElements({
|
|
474
|
+
...ctx,
|
|
475
|
+
dom: shadowHost.shadowRoot,
|
|
476
|
+
clone: cloneShadowHost.shadowRoot
|
|
477
|
+
});
|
|
478
|
+
} else {
|
|
479
|
+
ctx.warnings.add('data-percy-shadow-host does not have shadowRoot');
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
485
483
|
|
|
486
484
|
// Serializes a document and returns the resulting DOM string.
|
|
487
485
|
function serializeDOM(options) {
|
|
@@ -490,24 +488,21 @@
|
|
|
490
488
|
// allow snake_case or camelCase
|
|
491
489
|
enableJavaScript = options === null || options === void 0 ? void 0 : options.enable_javascript,
|
|
492
490
|
domTransformation = options === null || options === void 0 ? void 0 : options.dom_transformation,
|
|
493
|
-
stringifyResponse = options === null || options === void 0 ? void 0 : options.stringify_response
|
|
491
|
+
stringifyResponse = options === null || options === void 0 ? void 0 : options.stringify_response,
|
|
492
|
+
disableShadowDOM = options === null || options === void 0 ? void 0 : options.disable_shadow_dom
|
|
494
493
|
} = options || {};
|
|
495
494
|
|
|
496
495
|
// keep certain records throughout serialization
|
|
497
496
|
let ctx = {
|
|
498
497
|
resources: new Set(),
|
|
499
498
|
warnings: new Set(),
|
|
500
|
-
|
|
499
|
+
cache: new Map(),
|
|
500
|
+
enableJavaScript,
|
|
501
|
+
disableShadowDOM
|
|
501
502
|
};
|
|
502
503
|
ctx.dom = dom;
|
|
503
|
-
ctx.clone = cloneNodeAndShadow(ctx
|
|
504
|
-
|
|
505
|
-
serializeFrames(ctx);
|
|
506
|
-
serializeVideos(ctx);
|
|
507
|
-
if (!enableJavaScript) {
|
|
508
|
-
serializeCSSOM(ctx);
|
|
509
|
-
serializeCanvas(ctx);
|
|
510
|
-
}
|
|
504
|
+
ctx.clone = cloneNodeAndShadow(ctx);
|
|
505
|
+
serializeElements(ctx);
|
|
511
506
|
if (domTransformation) {
|
|
512
507
|
try {
|
|
513
508
|
domTransformation(ctx.clone.documentElement);
|
|
@@ -515,7 +510,9 @@
|
|
|
515
510
|
console.error('Could not transform the dom:', err.message);
|
|
516
511
|
}
|
|
517
512
|
}
|
|
518
|
-
|
|
513
|
+
if (!disableShadowDOM) {
|
|
514
|
+
injectDeclarativeShadowDOMPolyfill(ctx);
|
|
515
|
+
}
|
|
519
516
|
let result = {
|
|
520
517
|
html: serializeHTML(ctx),
|
|
521
518
|
warnings: Array.from(ctx.warnings),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/dom",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"interactor.js": "^2.0.0-beta.10"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "609ae53aa84ab2f7054a21214b36dccd71025780"
|
|
38
38
|
}
|