eyes_selenium 3.15.26 → 3.15.27
Sign up to get free protection for your applications and to get access to all the features.
- 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
|