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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d296beb9d397fda23bb4559c1bbbe0dcc62a8a517a41340048588fbdf6c911df
4
- data.tar.gz: 5d6a5b7b4d6cdd32e9a51ebd36929bc57923f64402ec64bfea8e43d349106c8f
3
+ metadata.gz: 2af28e148f60211bf2c09ac96275d229be3ab6af88f5855e9f0e302ea51d10b9
4
+ data.tar.gz: 71e12dbc9d0b9409011d77e9b444c7be1206243c3c936acfe59cbabdff421c09
5
5
  SHA512:
6
- metadata.gz: a3c793ece4f587ee303af163e6aba396e49f6a9021cb045e6e67281c3ff9a8f5cf41e473d87f0dd3e89c4aaf778ace87ca54bf5c7167ea0263e58e9e89b646ed
7
- data.tar.gz: 9fef8d433b59ecbd31557be05592a7edb41d6ddec641fbc5ea63e81b52642a12c7ffe98fdd48353278a2d33dd716b8034ae8a8af0f8d9427a6ff5e5214c1d582
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
- // @applitools/dom-snapshot@1.2.4
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 = [...doc.querySelectorAll('img[srcset],source[srcset]')]
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 = [...doc.querySelectorAll('img[src],source[src]')].map(srcEl =>
73
+ const srcUrls = Array.from(doc.querySelectorAll('img[src],source[src]')).map(srcEl =>
73
74
  srcEl.getAttribute('src'),
74
75
  );
75
76
 
76
- const hrefUrls = [...doc.querySelectorAll('image')]
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 = [...doc.querySelectorAll('link[rel="stylesheet"]')].map(link =>
85
+ const cssUrls = Array.from(doc.querySelectorAll('link[rel="stylesheet"]')).map(link =>
81
86
  link.getAttribute('href'),
82
87
  );
83
88
 
84
- const videoPosterUrls = [...doc.querySelectorAll('video[poster]')].map(videoEl =>
89
+ const videoPosterUrls = Array.from(doc.querySelectorAll('video[poster]')).map(videoEl =>
85
90
  videoEl.getAttribute('poster'),
86
91
  );
87
92
 
88
- return [...srcsetUrls, ...srcUrls, ...hrefUrls, ...cssUrls, ...videoPosterUrls];
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
- /* eslint-disable no-use-before-define */
103
+ function absolutizeUrl(url, absoluteUrl) {
104
+ return new URL(url, absoluteUrl).href;
105
+ }
106
+
107
+ var absolutizeUrl_1 = absolutizeUrl;
94
108
 
95
- function domNodesToCdt(docNode) {
96
- const NODE_TYPES = {
97
- ELEMENT: 1,
98
- TEXT: 3,
99
- DOCUMENT: 9,
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
- const domNodes = [
105
- {
106
- nodeType: NODE_TYPES.DOCUMENT,
107
- },
108
- ];
109
- domNodes[0].childNodeIndexes = childrenFactory(domNodes, docNode.childNodes);
110
- return domNodes;
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(domNodes, elementNodes) {
132
+ function childrenFactory(cdt, elementNodes) {
113
133
  if (!elementNodes || elementNodes.length === 0) return null;
114
134
 
115
135
  const childIndexes = [];
116
- elementNodes.forEach(elementNode => {
117
- const index = elementNodeFactory(domNodes, elementNode);
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(domNodes, elementNode) {
145
+ function elementNodeFactory(cdt, elementNode) {
127
146
  let node, manualChildNodeIndexes;
128
147
  const {nodeType} = elementNode;
129
- if ([NODE_TYPES.ELEMENT, NODE_TYPES.DOCUMENT_FRAGMENT_NODE].includes(nodeType)) {
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
- domNodes.push({
137
- nodeType: NODE_TYPES.TEXT,
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
- nodeType: nodeType,
145
- nodeName: elementNode.nodeName,
146
- attributes: nodeAttributes(elementNode).map(key => {
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(domNodes, elementNode.shadowRoot);
167
+ node.shadowRootIndex = elementNodeFactory(cdt, elementNode.shadowRoot);
168
+ docRoots.push(elementNode.shadowRoot);
174
169
  }
175
170
 
176
- if (elementNode.checked && !elementNode.attributes.checked) {
177
- node.attributes.push({name: 'checked', value: 'checked'});
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
- if (
180
- elementNode.value !== undefined &&
181
- elementNode.attributes.value === undefined &&
182
- elementNode.tagName === 'INPUT'
183
- ) {
184
- node.attributes.push({name: 'value', value: elementNode.value});
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 === NODE_TYPES.TEXT) {
200
- node = {
201
- nodeType: NODE_TYPES.TEXT,
202
- nodeValue: elementNode.nodeValue,
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
- domNodes.push(node);
213
- return domNodes.length - 1;
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
- function nodeAttributes({attributes = {}}) {
220
- return Object.keys(attributes).filter(k => attributes[k].localName);
221
- }
200
+ function nodeAttributes({attributes = {}}) {
201
+ return Object.keys(attributes).filter(k => attributes[k] && attributes[k].name);
222
202
  }
223
- }
224
203
 
225
- var domNodesToCdt_1 = domNodesToCdt;
226
- var NODE_TYPES = {
227
- ELEMENT: 1,
228
- TEXT: 3,
229
- DOCUMENT: 9,
230
- DOCUMENT_TYPE: 10,
231
- };
232
- domNodesToCdt_1.NODE_TYPES = NODE_TYPES;
233
-
234
- function extractFrames(doc = document) {
235
- return [...doc.querySelectorAll('iframe[src]:not([src=""])')]
236
- .map(srcEl => {
237
- try {
238
- const contentDoc = srcEl.contentDocument;
239
- return (
240
- contentDoc &&
241
- /^https?:$/.test(contentDoc.location.protocol) &&
242
- contentDoc.defaultView &&
243
- contentDoc.defaultView.frameElement &&
244
- contentDoc
245
- );
246
- } catch (err) {
247
- //for CORS frames
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
- .filter(x => !!x);
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 extractFrames_1 = extractFrames;
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(doc, baseUrl, urls) {
317
+ return function getResourceUrlsAndBlobs(documents, baseUrl, urls) {
277
318
  return Promise.all(
278
- urls.map(url => processResource(url, doc, baseUrl, getResourceUrlsAndBlobs.bind(null, doc))),
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 absolutizeUrl(url, absoluteUrl) {
292
- return new URL(url, absoluteUrl).href;
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 absolutizeUrl_1 = absolutizeUrl;
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
- isSameOrigin,
389
+ extractResourcesFromSvg,
302
390
  cache = {},
303
391
  }) {
304
- return function processResource(absoluteUrl, doc, baseUrl, getResourceUrlsAndBlobs) {
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, url)) {
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
- const result = {blobsObj: {[url]: {type, value}}};
409
+
410
+ let resourceUrls;
411
+ let result = {blobsObj: {[url]: {type, value}}};
321
412
  if (/text\/css/.test(type)) {
322
- const styleSheet = findStyleSheetByUrl(url, doc);
323
- if (!styleSheet) {
324
- return result;
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
- const resourceUrls = extractResourcesFromStyleSheet(styleSheet, doc.defaultView)
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
- return getResourceUrlsAndBlobs(baseUrl, resourceUrls).then(
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, url) {
346
- const msgCORS = err.message && err.message.includes('Failed to fetch');
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 && !isSameOrigin(url, baseUrl);
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.arrayBuffer().then(buff => ({
360
- url,
361
- type: resp.headers.get('Content-Type'),
362
- value: buff,
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, doc) {
371
- return styleSheetCache[url] || [...doc.styleSheets].find(styleSheet => styleSheet.href === url);
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, win = window) {
539
+ return function extractResourcesFromStyleSheet(styleSheet, doc) {
540
+ const win = doc.defaultView || (doc.ownerDocument && doc.ownerDocument.defaultView) || window;
392
541
  return uniq_1(
393
- [...(styleSheet.cssRules || [])].reduce((acc, rule) => {
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.style.getPropertyValue('src')));
399
- } else if (rule instanceof win.CSSSupportsRule || rule instanceof win.CSSMediaRule) {
400
- return acc.concat(extractResourcesFromStyleSheet(rule));
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
- [...doc.getElementsByTagName('style')].reduce((resourceUrls, styleEl) => {
433
- const styleSheet = [...doc.styleSheets].find(
434
- styleSheet => styleSheet.ownerNode === styleEl,
435
- );
436
- return resourceUrls.concat(extractResourcesFromStyleSheet(styleSheet, doc.defaultView));
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 isSameOrigin(url, baseUrl) {
445
- const blobOrData = /^(blob|data):/;
446
- if (blobOrData.test(url)) return true;
447
- if (blobOrData.test(baseUrl)) return false;
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
- const {origin} = new URL(url, baseUrl);
450
- const {origin: baseOrigin} = new URL(baseUrl);
451
- return origin === baseOrigin;
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 isSameOrigin_1 = isSameOrigin;
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 frameElement = doc.defaultView && doc.defaultView.frameElement;
481
- const url = frameElement ? frameElement.src : doc.location.href;
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
- extractLinks_1(doc)
487
- .concat(extractResourceUrlsFromStyleAttrs_1(cdt))
488
- .concat(extractResourceUrlsFromStyleTags$$1(doc)),
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(doc, url, links);
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
- return Promise.all([resourceUrlsAndBlobsPromise, ...processFramesPromise]).then(
499
- ([{resourceUrls, blobsObj}, ...framesResults]) => ({
500
- cdt,
501
- url,
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
- function absolutizeThisUrl(someUrl) {
510
- try {
511
- return absolutizeUrl_1(someUrl, url);
512
- } catch (err) {
513
- // can't do anything with a non-absolute url
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(
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Applitools
4
- VERSION = '3.15.26'.freeze
4
+ VERSION = '3.15.27'.freeze
5
5
  end
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.26
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-05 00:00:00.000000000 Z
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.26
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
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.7
162
+ rubygems_version: 2.7.10
163
163
  signing_key:
164
164
  specification_version: 4
165
165
  summary: Applitools Ruby Selenium SDK