eyes_selenium 3.15.26 → 3.15.27
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.
- checksums.yaml +4 -4
- data/lib/applitools/selenium/scripts/process_page_and_poll.rb +440 -216
- data/lib/applitools/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2af28e148f60211bf2c09ac96275d229be3ab6af88f5855e9f0e302ea51d10b9
|
4
|
+
data.tar.gz: 71e12dbc9d0b9409011d77e9b444c7be1206243c3c936acfe59cbabdff421c09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e41c8a4d0be46ce3f407aed3d846bf70c8513179420d0f0c25cc633aa89c1af85e11896e010eab98d8d305d6a5e4f9cdd5c926e32201ebd78f02c9778ddddd4c
|
7
|
+
data.tar.gz: 25c70ecb50a750956bd32aa0d02e3ac014b87fd869f598d0dea7c2f3b2497e7189d8fc9e18c29059481d3483b6cc47af7f431fedfc71dc7c341987ac0d560340
|
@@ -2,7 +2,8 @@ module Applitools
|
|
2
2
|
module Selenium
|
3
3
|
module Scripts
|
4
4
|
PROCESS_PAGE_AND_POLL = <<'END'
|
5
|
-
|
5
|
+
/* @applitools/dom-snapshot@1.4.6 */
|
6
|
+
|
6
7
|
function __processPageAndPoll() {
|
7
8
|
var processPageAndPoll = (function () {
|
8
9
|
'use strict';
|
@@ -60,7 +61,7 @@ function __processPageAndPoll() {
|
|
60
61
|
var arrayBufferToBase64_1 = arrayBufferToBase64;
|
61
62
|
|
62
63
|
function extractLinks(doc = document) {
|
63
|
-
const srcsetUrls =
|
64
|
+
const srcsetUrls = Array.from(doc.querySelectorAll('img[srcset],source[srcset]'))
|
64
65
|
.map(srcsetEl =>
|
65
66
|
srcsetEl
|
66
67
|
.getAttribute('srcset')
|
@@ -69,188 +70,228 @@ function __processPageAndPoll() {
|
|
69
70
|
)
|
70
71
|
.reduce((acc, urls) => acc.concat(urls), []);
|
71
72
|
|
72
|
-
const srcUrls =
|
73
|
+
const srcUrls = Array.from(doc.querySelectorAll('img[src],source[src]')).map(srcEl =>
|
73
74
|
srcEl.getAttribute('src'),
|
74
75
|
);
|
75
76
|
|
76
|
-
const
|
77
|
+
const imageUrls = Array.from(doc.querySelectorAll('image,use'))
|
77
78
|
.map(hrefEl => hrefEl.getAttribute('href') || hrefEl.getAttribute('xlink:href'))
|
79
|
+
.filter(u => u && u[0] !== '#');
|
80
|
+
|
81
|
+
const objectUrls = Array.from(doc.querySelectorAll('object'))
|
82
|
+
.map(el => el.getAttribute('data'))
|
78
83
|
.filter(Boolean);
|
79
84
|
|
80
|
-
const cssUrls =
|
85
|
+
const cssUrls = Array.from(doc.querySelectorAll('link[rel="stylesheet"]')).map(link =>
|
81
86
|
link.getAttribute('href'),
|
82
87
|
);
|
83
88
|
|
84
|
-
const videoPosterUrls =
|
89
|
+
const videoPosterUrls = Array.from(doc.querySelectorAll('video[poster]')).map(videoEl =>
|
85
90
|
videoEl.getAttribute('poster'),
|
86
91
|
);
|
87
92
|
|
88
|
-
return
|
93
|
+
return Array.from(srcsetUrls)
|
94
|
+
.concat(Array.from(srcUrls))
|
95
|
+
.concat(Array.from(imageUrls))
|
96
|
+
.concat(Array.from(cssUrls))
|
97
|
+
.concat(Array.from(videoPosterUrls))
|
98
|
+
.concat(Array.from(objectUrls));
|
89
99
|
}
|
90
100
|
|
91
101
|
var extractLinks_1 = extractLinks;
|
92
102
|
|
93
|
-
|
103
|
+
function absolutizeUrl(url, absoluteUrl) {
|
104
|
+
return new URL(url, absoluteUrl).href;
|
105
|
+
}
|
106
|
+
|
107
|
+
var absolutizeUrl_1 = absolutizeUrl;
|
94
108
|
|
95
|
-
function
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
DOCUMENT_TYPE: 10,
|
101
|
-
DOCUMENT_FRAGMENT_NODE: 11,
|
102
|
-
};
|
109
|
+
function uuid() {
|
110
|
+
return window.crypto.getRandomValues(new Uint32Array(1))[0];
|
111
|
+
}
|
112
|
+
|
113
|
+
var uuid_1 = uuid;
|
103
114
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
115
|
+
function isInlineFrame(frame) {
|
116
|
+
return (
|
117
|
+
frame && frame.contentDocument && !/^https?:$/.test(frame.contentDocument.location.protocol)
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
121
|
+
var isInlineFrame_1 = isInlineFrame;
|
122
|
+
|
123
|
+
function domNodesToCdt(docNode, url) {
|
124
|
+
const cdt = [{nodeType: Node.DOCUMENT_NODE}];
|
125
|
+
const docRoots = [docNode];
|
126
|
+
const canvasElements = [];
|
127
|
+
const inlineFrames = [];
|
128
|
+
|
129
|
+
cdt[0].childNodeIndexes = childrenFactory(cdt, docNode.childNodes);
|
130
|
+
return {cdt, docRoots, canvasElements, inlineFrames};
|
111
131
|
|
112
|
-
function childrenFactory(
|
132
|
+
function childrenFactory(cdt, elementNodes) {
|
113
133
|
if (!elementNodes || elementNodes.length === 0) return null;
|
114
134
|
|
115
135
|
const childIndexes = [];
|
116
|
-
|
117
|
-
const index = elementNodeFactory(
|
136
|
+
Array.prototype.forEach.call(elementNodes, elementNode => {
|
137
|
+
const index = elementNodeFactory(cdt, elementNode);
|
118
138
|
if (index !== null) {
|
119
139
|
childIndexes.push(index);
|
120
140
|
}
|
121
141
|
});
|
122
|
-
|
123
142
|
return childIndexes;
|
124
143
|
}
|
125
144
|
|
126
|
-
function elementNodeFactory(
|
145
|
+
function elementNodeFactory(cdt, elementNode) {
|
127
146
|
let node, manualChildNodeIndexes;
|
128
147
|
const {nodeType} = elementNode;
|
129
|
-
|
148
|
+
let dummyUrl, frameBase;
|
149
|
+
|
150
|
+
if ([Node.ELEMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE].includes(nodeType)) {
|
130
151
|
if (elementNode.nodeName !== 'SCRIPT') {
|
131
152
|
if (
|
132
153
|
elementNode.nodeName === 'STYLE' &&
|
133
154
|
elementNode.sheet &&
|
134
155
|
elementNode.sheet.cssRules.length
|
135
156
|
) {
|
136
|
-
|
137
|
-
|
138
|
-
nodeValue: [...elementNode.sheet.cssRules].map(rule => rule.cssText).join(''),
|
139
|
-
});
|
140
|
-
manualChildNodeIndexes = [domNodes.length - 1];
|
157
|
+
cdt.push(getCssRulesNode(elementNode));
|
158
|
+
manualChildNodeIndexes = [cdt.length - 1];
|
141
159
|
}
|
142
160
|
|
143
|
-
node =
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
let value = elementNode.attributes[key].value;
|
148
|
-
const name = elementNode.attributes[key].localName;
|
149
|
-
|
150
|
-
if (/^blob:/.test(value)) {
|
151
|
-
value = value.replace(/^blob:/, '');
|
152
|
-
} else if (
|
153
|
-
elementNode.nodeName === 'IFRAME' &&
|
154
|
-
name === 'src' &&
|
155
|
-
!elementNode.contentDocument &&
|
156
|
-
!value.match(/^\s*data:/)
|
157
|
-
) {
|
158
|
-
value = '';
|
159
|
-
}
|
160
|
-
return {
|
161
|
-
name,
|
162
|
-
value,
|
163
|
-
};
|
164
|
-
}),
|
165
|
-
childNodeIndexes:
|
166
|
-
manualChildNodeIndexes ||
|
167
|
-
(elementNode.childNodes.length
|
168
|
-
? childrenFactory(domNodes, elementNode.childNodes)
|
169
|
-
: []),
|
170
|
-
};
|
161
|
+
node = getBasicNode(elementNode);
|
162
|
+
node.childNodeIndexes =
|
163
|
+
manualChildNodeIndexes ||
|
164
|
+
(elementNode.childNodes.length ? childrenFactory(cdt, elementNode.childNodes) : []);
|
171
165
|
|
172
166
|
if (elementNode.shadowRoot) {
|
173
|
-
node.shadowRootIndex = elementNodeFactory(
|
167
|
+
node.shadowRootIndex = elementNodeFactory(cdt, elementNode.shadowRoot);
|
168
|
+
docRoots.push(elementNode.shadowRoot);
|
174
169
|
}
|
175
170
|
|
176
|
-
if (elementNode.
|
177
|
-
|
171
|
+
if (elementNode.nodeName === 'CANVAS') {
|
172
|
+
dummyUrl = absolutizeUrl_1(`applitools-canvas-${uuid_1()}.png`, url);
|
173
|
+
node.attributes.push({name: 'data-applitools-src', value: dummyUrl});
|
174
|
+
canvasElements.push({element: elementNode, url: dummyUrl});
|
178
175
|
}
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
176
|
+
|
177
|
+
if (elementNode.nodeName === 'IFRAME' && isInlineFrame_1(elementNode)) {
|
178
|
+
frameBase = getFrameBaseUrl(elementNode);
|
179
|
+
dummyUrl = absolutizeUrl_1(`?applitools-iframe=${uuid_1()}`, frameBase || url);
|
180
|
+
node.attributes.push({name: 'data-applitools-src', value: dummyUrl});
|
181
|
+
inlineFrames.push({element: elementNode, url: dummyUrl});
|
185
182
|
}
|
186
183
|
} else {
|
187
|
-
node =
|
188
|
-
nodeType: NODE_TYPES.ELEMENT,
|
189
|
-
nodeName: 'SCRIPT',
|
190
|
-
attributes: nodeAttributes(elementNode)
|
191
|
-
.map(key => ({
|
192
|
-
name: elementNode.attributes[key].localName,
|
193
|
-
value: elementNode.attributes[key].value,
|
194
|
-
}))
|
195
|
-
.filter(attr => attr.name !== 'src'),
|
196
|
-
childNodeIndexes: [],
|
197
|
-
};
|
184
|
+
node = getScriptNode(elementNode);
|
198
185
|
}
|
199
|
-
} else if (nodeType ===
|
200
|
-
node =
|
201
|
-
|
202
|
-
|
203
|
-
};
|
204
|
-
} else if (nodeType === NODE_TYPES.DOCUMENT_TYPE) {
|
205
|
-
node = {
|
206
|
-
nodeType: NODE_TYPES.DOCUMENT_TYPE,
|
207
|
-
nodeName: elementNode.nodeName,
|
208
|
-
};
|
186
|
+
} else if (nodeType === Node.TEXT_NODE) {
|
187
|
+
node = getTextNode(elementNode);
|
188
|
+
} else if (nodeType === Node.DOCUMENT_TYPE_NODE) {
|
189
|
+
node = getDocNode(elementNode);
|
209
190
|
}
|
210
191
|
|
211
192
|
if (node) {
|
212
|
-
|
213
|
-
return
|
193
|
+
cdt.push(node);
|
194
|
+
return cdt.length - 1;
|
214
195
|
} else {
|
215
|
-
// console.log(`Unknown nodeType: ${nodeType}`);
|
216
196
|
return null;
|
217
197
|
}
|
198
|
+
}
|
218
199
|
|
219
|
-
|
220
|
-
|
221
|
-
}
|
200
|
+
function nodeAttributes({attributes = {}}) {
|
201
|
+
return Object.keys(attributes).filter(k => attributes[k] && attributes[k].name);
|
222
202
|
}
|
223
|
-
}
|
224
203
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
204
|
+
function getCssRulesNode(elementNode) {
|
205
|
+
return {
|
206
|
+
nodeType: Node.TEXT_NODE,
|
207
|
+
nodeValue: Array.from(elementNode.sheet.cssRules)
|
208
|
+
.map(rule => rule.cssText)
|
209
|
+
.join(''),
|
210
|
+
};
|
211
|
+
}
|
212
|
+
|
213
|
+
function getBasicNode(elementNode) {
|
214
|
+
const node = {
|
215
|
+
nodeType: elementNode.nodeType,
|
216
|
+
nodeName: elementNode.nodeName,
|
217
|
+
attributes: nodeAttributes(elementNode).map(key => {
|
218
|
+
let value = elementNode.attributes[key].value;
|
219
|
+
const name = elementNode.attributes[key].name;
|
220
|
+
if (/^blob:/.test(value)) {
|
221
|
+
value = value.replace(/^blob:/, '');
|
222
|
+
}
|
223
|
+
return {
|
224
|
+
name,
|
225
|
+
value,
|
226
|
+
};
|
227
|
+
}),
|
228
|
+
};
|
229
|
+
|
230
|
+
if (elementNode.tagName === 'INPUT' && ['checkbox', 'radio'].includes(elementNode.type)) {
|
231
|
+
if (elementNode.attributes.checked && !elementNode.checked) {
|
232
|
+
const idx = node.attributes.findIndex(a => a.name === 'checked');
|
233
|
+
node.attributes.splice(idx, 1);
|
234
|
+
}
|
235
|
+
if (!elementNode.attributes.checked && elementNode.checked) {
|
236
|
+
node.attributes.push({name: 'checked'});
|
248
237
|
}
|
249
|
-
}
|
250
|
-
|
238
|
+
}
|
239
|
+
|
240
|
+
if (
|
241
|
+
elementNode.tagName === 'INPUT' &&
|
242
|
+
elementNode.type === 'text' &&
|
243
|
+
(elementNode.attributes.value && elementNode.attributes.value.value) !== elementNode.value
|
244
|
+
) {
|
245
|
+
const nodeAttr = node.attributes.find(a => a.name === 'value');
|
246
|
+
if (nodeAttr) {
|
247
|
+
nodeAttr.value = elementNode.value;
|
248
|
+
} else {
|
249
|
+
node.attributes.push({name: 'value', value: elementNode.value});
|
250
|
+
}
|
251
|
+
}
|
252
|
+
return node;
|
253
|
+
}
|
254
|
+
|
255
|
+
function getScriptNode(elementNode) {
|
256
|
+
return {
|
257
|
+
nodeType: Node.ELEMENT_NODE,
|
258
|
+
nodeName: 'SCRIPT',
|
259
|
+
attributes: nodeAttributes(elementNode)
|
260
|
+
.map(key => ({
|
261
|
+
name: elementNode.attributes[key].name,
|
262
|
+
value: elementNode.attributes[key].value,
|
263
|
+
}))
|
264
|
+
.filter(attr => attr.name !== 'src'),
|
265
|
+
childNodeIndexes: [],
|
266
|
+
};
|
267
|
+
}
|
268
|
+
|
269
|
+
function getTextNode(elementNode) {
|
270
|
+
return {
|
271
|
+
nodeType: Node.TEXT_NODE,
|
272
|
+
nodeValue: elementNode.nodeValue,
|
273
|
+
};
|
274
|
+
}
|
275
|
+
|
276
|
+
function getDocNode(elementNode) {
|
277
|
+
return {
|
278
|
+
nodeType: Node.DOCUMENT_TYPE_NODE,
|
279
|
+
nodeName: elementNode.nodeName,
|
280
|
+
};
|
281
|
+
}
|
282
|
+
|
283
|
+
function getFrameBaseUrl(frameElement) {
|
284
|
+
const href =
|
285
|
+
frameElement.contentDocument.querySelectorAll('base') &&
|
286
|
+
frameElement.contentDocument.querySelectorAll('base')[0] &&
|
287
|
+
frameElement.contentDocument.querySelectorAll('base')[0].href;
|
288
|
+
if (href && !href.includes('about:blank')) {
|
289
|
+
return href;
|
290
|
+
}
|
291
|
+
}
|
251
292
|
}
|
252
293
|
|
253
|
-
var
|
294
|
+
var domNodesToCdt_1 = domNodesToCdt;
|
254
295
|
|
255
296
|
function uniq(arr) {
|
256
297
|
const result = [];
|
@@ -273,9 +314,9 @@ function __processPageAndPoll() {
|
|
273
314
|
var aggregateResourceUrlsAndBlobs_1 = aggregateResourceUrlsAndBlobs;
|
274
315
|
|
275
316
|
function makeGetResourceUrlsAndBlobs({processResource, aggregateResourceUrlsAndBlobs}) {
|
276
|
-
return function getResourceUrlsAndBlobs(
|
317
|
+
return function getResourceUrlsAndBlobs(documents, baseUrl, urls) {
|
277
318
|
return Promise.all(
|
278
|
-
urls.map(url => processResource(url,
|
319
|
+
urls.map(url => processResource(url, documents, baseUrl, getResourceUrlsAndBlobs)),
|
279
320
|
).then(resourceUrlsAndBlobsArr => aggregateResourceUrlsAndBlobs(resourceUrlsAndBlobsArr));
|
280
321
|
};
|
281
322
|
}
|
@@ -288,26 +329,74 @@ function __processPageAndPoll() {
|
|
288
329
|
|
289
330
|
var filterInlineUrl_1 = filterInlineUrl;
|
290
331
|
|
291
|
-
function
|
292
|
-
|
332
|
+
function toUnAnchoredUri(url) {
|
333
|
+
const m = url && url.match(/(^[^#]*)/);
|
334
|
+
const res = (m && m[1]) || url;
|
335
|
+
return (res && res.replace(/\?\s*$/, '')) || url;
|
293
336
|
}
|
294
337
|
|
295
|
-
var
|
338
|
+
var toUnAnchoredUri_1 = toUnAnchoredUri;
|
339
|
+
|
340
|
+
function createTempStylsheet(cssContent) {
|
341
|
+
if (!cssContent) {
|
342
|
+
console.log('[dom-snapshot] error createTempStylsheet called without cssContent');
|
343
|
+
return;
|
344
|
+
}
|
345
|
+
const head = document.head || document.querySelectorAll('head')[0];
|
346
|
+
const style = document.createElement('style');
|
347
|
+
style.type = 'text/css';
|
348
|
+
style.setAttribute('data-desc', 'Applitools tmp variable created by DOM SNAPSHOT');
|
349
|
+
head.appendChild(style);
|
350
|
+
|
351
|
+
// This is required for IE8 and below.
|
352
|
+
if (style.styleSheet) {
|
353
|
+
style.styleSheet.cssText = cssContent;
|
354
|
+
} else {
|
355
|
+
style.appendChild(document.createTextNode(cssContent));
|
356
|
+
}
|
357
|
+
return style.sheet;
|
358
|
+
}
|
359
|
+
|
360
|
+
var createTempStyleSheet = createTempStylsheet;
|
361
|
+
|
362
|
+
function makeExtractResourcesFromStyle({extractResourcesFromStyleSheet}) {
|
363
|
+
return function extractResourcesFromStyle(styleSheet, cssContent, doc = document) {
|
364
|
+
let corsFreeStyleSheet;
|
365
|
+
try {
|
366
|
+
styleSheet.cssRules;
|
367
|
+
corsFreeStyleSheet = styleSheet;
|
368
|
+
} catch (e) {
|
369
|
+
console.log(
|
370
|
+
`[dom-snapshot] could not access cssRules for ${styleSheet.href} ${e}\ncreating temp style for access.`,
|
371
|
+
);
|
372
|
+
corsFreeStyleSheet = createTempStyleSheet(cssContent);
|
373
|
+
}
|
374
|
+
|
375
|
+
const result = extractResourcesFromStyleSheet(corsFreeStyleSheet, doc);
|
376
|
+
if (corsFreeStyleSheet !== styleSheet) {
|
377
|
+
corsFreeStyleSheet.ownerNode.parentNode.removeChild(corsFreeStyleSheet.ownerNode);
|
378
|
+
}
|
379
|
+
return result;
|
380
|
+
};
|
381
|
+
}
|
382
|
+
|
383
|
+
var extractResourcesFromStyle = makeExtractResourcesFromStyle;
|
296
384
|
|
297
385
|
function makeProcessResource({
|
298
386
|
fetchUrl,
|
299
387
|
findStyleSheetByUrl,
|
300
388
|
extractResourcesFromStyleSheet,
|
301
|
-
|
389
|
+
extractResourcesFromSvg,
|
302
390
|
cache = {},
|
303
391
|
}) {
|
304
|
-
|
392
|
+
const extractResourcesFromStyle$$1 = extractResourcesFromStyle({extractResourcesFromStyleSheet});
|
393
|
+
return function processResource(absoluteUrl, documents, baseUrl, getResourceUrlsAndBlobs) {
|
305
394
|
return cache[absoluteUrl] || (cache[absoluteUrl] = doProcessResource(absoluteUrl));
|
306
395
|
|
307
396
|
function doProcessResource(url) {
|
308
397
|
return fetchUrl(url)
|
309
398
|
.catch(e => {
|
310
|
-
if (probablyCORS(e
|
399
|
+
if (probablyCORS(e)) {
|
311
400
|
return {probablyCORS: true, url};
|
312
401
|
} else {
|
313
402
|
throw e;
|
@@ -317,24 +406,35 @@ function __processPageAndPoll() {
|
|
317
406
|
if (probablyCORS) {
|
318
407
|
return {resourceUrls: [url]};
|
319
408
|
}
|
320
|
-
|
409
|
+
|
410
|
+
let resourceUrls;
|
411
|
+
let result = {blobsObj: {[url]: {type, value}}};
|
321
412
|
if (/text\/css/.test(type)) {
|
322
|
-
const styleSheet = findStyleSheetByUrl(url,
|
323
|
-
if (
|
324
|
-
|
413
|
+
const styleSheet = findStyleSheetByUrl(url, documents);
|
414
|
+
if (styleSheet) {
|
415
|
+
resourceUrls = extractResourcesFromStyle$$1(styleSheet, value, documents[0]);
|
416
|
+
}
|
417
|
+
} else if (/image\/svg/.test(type)) {
|
418
|
+
try {
|
419
|
+
resourceUrls = extractResourcesFromSvg(value);
|
420
|
+
} catch (e) {
|
421
|
+
console.log('could not parse svg content', e);
|
325
422
|
}
|
326
|
-
|
423
|
+
}
|
424
|
+
|
425
|
+
if (resourceUrls) {
|
426
|
+
resourceUrls = resourceUrls
|
427
|
+
.map(toUnAnchoredUri_1)
|
327
428
|
.map(resourceUrl => absolutizeUrl_1(resourceUrl, url.replace(/^blob:/, '')))
|
328
429
|
.filter(filterInlineUrl_1);
|
329
|
-
|
430
|
+
result = getResourceUrlsAndBlobs(documents, baseUrl, resourceUrls).then(
|
330
431
|
({resourceUrls, blobsObj}) => ({
|
331
432
|
resourceUrls,
|
332
433
|
blobsObj: Object.assign(blobsObj, {[url]: {type, value}}),
|
333
434
|
}),
|
334
435
|
);
|
335
|
-
} else {
|
336
|
-
return result;
|
337
436
|
}
|
437
|
+
return result;
|
338
438
|
})
|
339
439
|
.catch(err => {
|
340
440
|
console.log('[dom-snapshot] error while fetching', url, err);
|
@@ -342,62 +442,114 @@ function __processPageAndPoll() {
|
|
342
442
|
});
|
343
443
|
}
|
344
444
|
|
345
|
-
function probablyCORS(err
|
346
|
-
const msgCORS =
|
445
|
+
function probablyCORS(err) {
|
446
|
+
const msgCORS =
|
447
|
+
err.message &&
|
448
|
+
(err.message.includes('Failed to fetch') || err.message.includes('Network request failed'));
|
347
449
|
const nameCORS = err.name && err.name.includes('TypeError');
|
348
|
-
return msgCORS && nameCORS
|
450
|
+
return msgCORS && nameCORS;
|
349
451
|
}
|
350
452
|
};
|
351
453
|
}
|
352
454
|
|
353
455
|
var processResource = makeProcessResource;
|
354
456
|
|
457
|
+
function getUrlFromCssText(cssText) {
|
458
|
+
const re = /url\((?!['"]?:)['"]?([^'")]*)['"]?\)/g;
|
459
|
+
const ret = [];
|
460
|
+
let result;
|
461
|
+
while ((result = re.exec(cssText)) !== null) {
|
462
|
+
ret.push(result[1]);
|
463
|
+
}
|
464
|
+
return ret;
|
465
|
+
}
|
466
|
+
|
467
|
+
var getUrlFromCssText_1 = getUrlFromCssText;
|
468
|
+
|
469
|
+
function flat(arr) {
|
470
|
+
return [].concat(...arr);
|
471
|
+
}
|
472
|
+
|
473
|
+
var flat_1 = flat;
|
474
|
+
|
475
|
+
function makeExtractResourcesFromSvg({parser, decoder, extractResourceUrlsFromStyleTags}) {
|
476
|
+
return function(svgArrayBuffer) {
|
477
|
+
const decooder = decoder || new TextDecoder('utf-8');
|
478
|
+
const svgStr = decooder.decode(svgArrayBuffer);
|
479
|
+
const domparser = parser || new DOMParser();
|
480
|
+
const doc = domparser.parseFromString(svgStr, 'image/svg+xml');
|
481
|
+
|
482
|
+
const fromImages = Array.from(doc.getElementsByTagName('image'))
|
483
|
+
.concat(Array.from(doc.getElementsByTagName('use')))
|
484
|
+
.map(e => e.getAttribute('href') || e.getAttribute('xlink:href'));
|
485
|
+
const fromObjects = Array.from(doc.getElementsByTagName('object')).map(e =>
|
486
|
+
e.getAttribute('data'),
|
487
|
+
);
|
488
|
+
const fromStyleTags = extractResourceUrlsFromStyleTags(doc, false);
|
489
|
+
const fromStyleAttrs = urlsFromStyleAttrOfDoc(doc);
|
490
|
+
|
491
|
+
return fromImages
|
492
|
+
.concat(fromObjects)
|
493
|
+
.concat(fromStyleTags)
|
494
|
+
.concat(fromStyleAttrs)
|
495
|
+
.filter(u => u[0] !== '#');
|
496
|
+
};
|
497
|
+
}
|
498
|
+
|
499
|
+
function urlsFromStyleAttrOfDoc(doc) {
|
500
|
+
return flat_1(
|
501
|
+
Array.from(doc.querySelectorAll('*[style]'))
|
502
|
+
.map(e => e.style.cssText)
|
503
|
+
.map(getUrlFromCssText_1)
|
504
|
+
.filter(Boolean),
|
505
|
+
);
|
506
|
+
}
|
507
|
+
|
508
|
+
var makeExtractResourcesFromSvg_1 = makeExtractResourcesFromSvg;
|
509
|
+
|
355
510
|
/* global window */
|
356
511
|
|
357
512
|
function fetchUrl(url, fetch = window.fetch) {
|
358
513
|
return fetch(url, {cache: 'force-cache', credentials: 'same-origin'}).then(resp =>
|
359
|
-
resp.
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
514
|
+
resp.status === 200
|
515
|
+
? resp.arrayBuffer().then(buff => ({
|
516
|
+
url,
|
517
|
+
type: resp.headers.get('Content-Type'),
|
518
|
+
value: buff,
|
519
|
+
}))
|
520
|
+
: Promise.reject(`bad status code ${resp.status}`),
|
364
521
|
);
|
365
522
|
}
|
366
523
|
|
367
524
|
var fetchUrl_1 = fetchUrl;
|
368
525
|
|
369
526
|
function makeFindStyleSheetByUrl({styleSheetCache}) {
|
370
|
-
return function findStyleSheetByUrl(url,
|
371
|
-
|
527
|
+
return function findStyleSheetByUrl(url, documents) {
|
528
|
+
const allStylesheets = flat_1(documents.map(d => Array.from(d.styleSheets)));
|
529
|
+
return (
|
530
|
+
styleSheetCache[url] ||
|
531
|
+
allStylesheets.find(styleSheet => styleSheet.href && toUnAnchoredUri_1(styleSheet.href) === url)
|
532
|
+
);
|
372
533
|
};
|
373
534
|
}
|
374
535
|
|
375
536
|
var findStyleSheetByUrl = makeFindStyleSheetByUrl;
|
376
537
|
|
377
|
-
function getUrlFromCssText(cssText) {
|
378
|
-
const re = /url\((?!['"]?:)['"]?([^'")]*)['"]?\)/g;
|
379
|
-
const ret = [];
|
380
|
-
let result;
|
381
|
-
while ((result = re.exec(cssText)) !== null) {
|
382
|
-
ret.push(result[1]);
|
383
|
-
}
|
384
|
-
return ret;
|
385
|
-
}
|
386
|
-
|
387
|
-
var getUrlFromCssText_1 = getUrlFromCssText;
|
388
|
-
|
389
|
-
// NOTE this code is very similar to the node part of visual-grid-client, but there is a different related to the browser's cssom with import rules
|
390
538
|
function makeExtractResourcesFromStyleSheet({styleSheetCache}) {
|
391
|
-
return function extractResourcesFromStyleSheet(styleSheet,
|
539
|
+
return function extractResourcesFromStyleSheet(styleSheet, doc) {
|
540
|
+
const win = doc.defaultView || (doc.ownerDocument && doc.ownerDocument.defaultView) || window;
|
392
541
|
return uniq_1(
|
393
|
-
|
542
|
+
Array.from(styleSheet.cssRules || []).reduce((acc, rule) => {
|
394
543
|
if (rule instanceof win.CSSImportRule) {
|
395
544
|
styleSheetCache[rule.styleSheet.href] = rule.styleSheet;
|
396
545
|
return acc.concat(rule.href);
|
397
546
|
} else if (rule instanceof win.CSSFontFaceRule) {
|
398
|
-
return acc.concat(getUrlFromCssText_1(rule.
|
399
|
-
} else if (
|
400
|
-
|
547
|
+
return acc.concat(getUrlFromCssText_1(rule.cssText));
|
548
|
+
} else if (
|
549
|
+
(win.CSSSupportsRule && rule instanceof win.CSSSupportsRule) ||
|
550
|
+
rule instanceof win.CSSMediaRule
|
551
|
+
) {
|
552
|
+
return acc.concat(extractResourcesFromStyleSheet(rule, doc));
|
401
553
|
} else if (rule instanceof win.CSSStyleRule) {
|
402
554
|
for (let i = 0, ii = rule.style.length; i < ii; i++) {
|
403
555
|
const urls = getUrlFromCssText_1(rule.style.getPropertyValue(rule.style[i]));
|
@@ -427,13 +579,15 @@ function __processPageAndPoll() {
|
|
427
579
|
var extractResourceUrlsFromStyleAttrs_1 = extractResourceUrlsFromStyleAttrs;
|
428
580
|
|
429
581
|
function makeExtractResourceUrlsFromStyleTags(extractResourcesFromStyleSheet) {
|
430
|
-
return function extractResourceUrlsFromStyleTags(doc) {
|
582
|
+
return function extractResourceUrlsFromStyleTags(doc, onlyDocStylesheet = true) {
|
431
583
|
return uniq_1(
|
432
|
-
|
433
|
-
const styleSheet =
|
434
|
-
styleSheet => styleSheet.ownerNode === styleEl
|
435
|
-
|
436
|
-
return
|
584
|
+
Array.from(doc.querySelectorAll('style')).reduce((resourceUrls, styleEl) => {
|
585
|
+
const styleSheet = onlyDocStylesheet
|
586
|
+
? Array.from(doc.styleSheets).find(styleSheet => styleSheet.ownerNode === styleEl)
|
587
|
+
: styleEl.sheet;
|
588
|
+
return styleSheet
|
589
|
+
? resourceUrls.concat(extractResourcesFromStyleSheet(styleSheet, doc))
|
590
|
+
: resourceUrls;
|
437
591
|
}, []),
|
438
592
|
);
|
439
593
|
};
|
@@ -441,28 +595,90 @@ function __processPageAndPoll() {
|
|
441
595
|
|
442
596
|
var extractResourceUrlsFromStyleTags = makeExtractResourceUrlsFromStyleTags;
|
443
597
|
|
444
|
-
function
|
445
|
-
|
446
|
-
|
447
|
-
|
598
|
+
function base64ToArrayBuffer(base64) {
|
599
|
+
var binary_string = window.atob(base64);
|
600
|
+
var len = binary_string.length;
|
601
|
+
var bytes = new Uint8Array(len);
|
602
|
+
for (var i = 0; i < len; i++) {
|
603
|
+
bytes[i] = binary_string.charCodeAt(i);
|
604
|
+
}
|
605
|
+
return bytes.buffer;
|
606
|
+
}
|
607
|
+
|
608
|
+
var base64ToArrayBuffer_1 = base64ToArrayBuffer;
|
609
|
+
|
610
|
+
function buildCanvasBlobs(canvasElements) {
|
611
|
+
return canvasElements.map(({url, element}) => {
|
612
|
+
const data = element.toDataURL('image/png');
|
613
|
+
const value = base64ToArrayBuffer_1(data.split(',')[1]);
|
614
|
+
return {url, type: 'image/png', value};
|
615
|
+
});
|
616
|
+
}
|
617
|
+
|
618
|
+
var buildCanvasBlobs_1 = buildCanvasBlobs;
|
619
|
+
|
620
|
+
function extractFrames(documents = [document]) {
|
621
|
+
const iframes = flat_1(
|
622
|
+
documents.map(d => Array.from(d.querySelectorAll('iframe[src]:not([src=""])'))),
|
623
|
+
);
|
624
|
+
return iframes
|
625
|
+
.filter(f => isAccessibleFrame(f) && !isInlineFrame_1(f))
|
626
|
+
.map(f => f.contentDocument);
|
627
|
+
}
|
628
|
+
|
629
|
+
function isAccessibleFrame(frame) {
|
630
|
+
try {
|
631
|
+
const doc = frame.contentDocument;
|
632
|
+
return !!(doc && doc.defaultView && doc.defaultView.frameElement);
|
633
|
+
} catch (err) {
|
634
|
+
// for CORS frames
|
635
|
+
}
|
636
|
+
}
|
637
|
+
|
638
|
+
var extractFrames_1 = extractFrames;
|
639
|
+
|
640
|
+
const getBaesUrl = function(doc) {
|
641
|
+
const baseUrl = doc.querySelectorAll('base')[0] && doc.querySelectorAll('base')[0].href;
|
642
|
+
if (baseUrl) {
|
643
|
+
return baseUrl;
|
644
|
+
}
|
645
|
+
const frameElement = doc.defaultView && doc.defaultView.frameElement;
|
646
|
+
if (frameElement) {
|
647
|
+
return frameElement.src || getBaesUrl(frameElement.ownerDocument);
|
648
|
+
}
|
649
|
+
return doc.location.href;
|
650
|
+
};
|
651
|
+
|
652
|
+
var getBaseUrl = getBaesUrl;
|
448
653
|
|
449
|
-
|
450
|
-
const
|
451
|
-
|
654
|
+
function toUriEncoding(url) {
|
655
|
+
const result =
|
656
|
+
(url &&
|
657
|
+
url.replace(/(\\[0-9a-fA-F]{1,6}\s?)/g, s => {
|
658
|
+
const int = parseInt(s.substr(1).trim(), 16);
|
659
|
+
return String.fromCodePoint(int);
|
660
|
+
})) ||
|
661
|
+
url;
|
662
|
+
return result;
|
452
663
|
}
|
453
664
|
|
454
|
-
var
|
665
|
+
var toUriEncoding_1 = toUriEncoding;
|
455
666
|
|
456
667
|
function processPage(doc = document) {
|
457
668
|
const styleSheetCache = {};
|
458
669
|
const extractResourcesFromStyleSheet$$1 = extractResourcesFromStyleSheet({styleSheetCache});
|
459
670
|
const findStyleSheetByUrl$$1 = findStyleSheetByUrl({styleSheetCache});
|
671
|
+
const extractResourceUrlsFromStyleTags$$1 = extractResourceUrlsFromStyleTags(
|
672
|
+
extractResourcesFromStyleSheet$$1,
|
673
|
+
);
|
674
|
+
|
675
|
+
const extractResourcesFromSvg = makeExtractResourcesFromSvg_1({extractResourceUrlsFromStyleTags: extractResourceUrlsFromStyleTags$$1});
|
460
676
|
const processResource$$1 = processResource({
|
461
677
|
fetchUrl: fetchUrl_1,
|
462
678
|
findStyleSheetByUrl: findStyleSheetByUrl$$1,
|
463
679
|
extractResourcesFromStyleSheet: extractResourcesFromStyleSheet$$1,
|
680
|
+
extractResourcesFromSvg,
|
464
681
|
absolutizeUrl: absolutizeUrl_1,
|
465
|
-
isSameOrigin: isSameOrigin_1,
|
466
682
|
});
|
467
683
|
|
468
684
|
const getResourceUrlsAndBlobs$$1 = getResourceUrlsAndBlobs({
|
@@ -470,52 +686,60 @@ function __processPageAndPoll() {
|
|
470
686
|
aggregateResourceUrlsAndBlobs: aggregateResourceUrlsAndBlobs_1,
|
471
687
|
});
|
472
688
|
|
473
|
-
const extractResourceUrlsFromStyleTags$$1 = extractResourceUrlsFromStyleTags(
|
474
|
-
extractResourcesFromStyleSheet$$1,
|
475
|
-
);
|
476
|
-
|
477
689
|
return doProcessPage(doc);
|
478
690
|
|
479
|
-
function doProcessPage(doc) {
|
480
|
-
const
|
481
|
-
const
|
482
|
-
|
483
|
-
const cdt = domNodesToCdt_1(doc);
|
691
|
+
function doProcessPage(doc, baesUrl = null) {
|
692
|
+
const url = baesUrl || getBaseUrl(doc);
|
693
|
+
const {cdt, docRoots, canvasElements, inlineFrames} = domNodesToCdt_1(doc, url);
|
484
694
|
|
695
|
+
const linkUrls = flat_1(docRoots.map(extractLinks_1));
|
696
|
+
const styleTagUrls = flat_1(docRoots.map(extractResourceUrlsFromStyleTags$$1));
|
697
|
+
const absolutizeThisUrl = getAbsolutizeByUrl(url);
|
485
698
|
const links = uniq_1(
|
486
|
-
|
487
|
-
.concat(
|
488
|
-
.concat(
|
699
|
+
Array.from(linkUrls)
|
700
|
+
.concat(Array.from(styleTagUrls))
|
701
|
+
.concat(extractResourceUrlsFromStyleAttrs_1(cdt)),
|
489
702
|
)
|
703
|
+
.map(toUnAnchoredUri_1)
|
704
|
+
.map(toUriEncoding_1)
|
490
705
|
.map(absolutizeThisUrl)
|
491
706
|
.filter(filterInlineUrlsIfExisting);
|
492
707
|
|
493
|
-
const resourceUrlsAndBlobsPromise = getResourceUrlsAndBlobs$$1(
|
494
|
-
|
495
|
-
const frameDocs = extractFrames_1(doc);
|
496
|
-
const processFramesPromise = frameDocs.map(doProcessPage);
|
708
|
+
const resourceUrlsAndBlobsPromise = getResourceUrlsAndBlobs$$1(docRoots, url, links);
|
709
|
+
const canvasBlobs = buildCanvasBlobs_1(canvasElements);
|
497
710
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
resourceUrls,
|
503
|
-
blobs: blobsObjToArray(blobsObj),
|
504
|
-
frames: framesResults,
|
505
|
-
srcAttr: frameElement ? frameElement.getAttribute('src') : undefined,
|
506
|
-
}),
|
711
|
+
const frameDocs = extractFrames_1(docRoots);
|
712
|
+
const processFramesPromise = frameDocs.map(f => doProcessPage(f, null));
|
713
|
+
const processInlineFramesPromise = inlineFrames.map(({element, url}) =>
|
714
|
+
doProcessPage(element.contentDocument, url),
|
507
715
|
);
|
508
716
|
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
717
|
+
const frameElement = doc.defaultView && doc.defaultView.frameElement;
|
718
|
+
return Promise.all([
|
719
|
+
resourceUrlsAndBlobsPromise,
|
720
|
+
...processFramesPromise,
|
721
|
+
...processInlineFramesPromise,
|
722
|
+
]).then(([{resourceUrls, blobsObj}, ...framesResults]) => ({
|
723
|
+
cdt,
|
724
|
+
url,
|
725
|
+
resourceUrls,
|
726
|
+
blobs: [...blobsObjToArray(blobsObj), ...canvasBlobs],
|
727
|
+
frames: framesResults,
|
728
|
+
srcAttr: frameElement ? frameElement.getAttribute('src') : undefined,
|
729
|
+
}));
|
516
730
|
}
|
517
731
|
}
|
518
732
|
|
733
|
+
function getAbsolutizeByUrl(url) {
|
734
|
+
return function(someUrl) {
|
735
|
+
try {
|
736
|
+
return absolutizeUrl_1(someUrl, url);
|
737
|
+
} catch (err) {
|
738
|
+
// can't do anything with a non-absolute url
|
739
|
+
}
|
740
|
+
};
|
741
|
+
}
|
742
|
+
|
519
743
|
function blobsObjToArray(blobsObj) {
|
520
744
|
return Object.keys(blobsObj).map(blobUrl =>
|
521
745
|
Object.assign(
|
data/lib/applitools/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eyes_selenium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.15.
|
4
|
+
version: 3.15.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Applitools Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eyes_core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.15.
|
19
|
+
version: 3.15.27
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.15.
|
26
|
+
version: 3.15.27
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: selenium-webdriver
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
159
|
version: '0'
|
160
160
|
requirements: []
|
161
161
|
rubyforge_project:
|
162
|
-
rubygems_version: 2.7.
|
162
|
+
rubygems_version: 2.7.10
|
163
163
|
signing_key:
|
164
164
|
specification_version: 4
|
165
165
|
summary: Applitools Ruby Selenium SDK
|