eyes_selenium 3.16.6 → 3.16.7

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: c9163861cda50303431e9f57bc562a157ced563ce197d5a0140cc603d40dd82d
4
- data.tar.gz: d0c61e4ea52a442fb38454954166131da5cccc8932d09dc03bac464d9e4698c3
3
+ metadata.gz: 609b82f065fd2d1d3be7369ca993472bb279d9747dd307659e2c556d517210c7
4
+ data.tar.gz: 903b99fd75708e28296cec9183431e999cba2ff12e963476e6363bb9d00658d0
5
5
  SHA512:
6
- metadata.gz: 95fa86b494f42a2f184cc545f0cff725256807bbb5e6ec91e27375030d11d96faa445960d954250e6e013a91b88023eee135773c23819005d3227a834b5e270b
7
- data.tar.gz: 682478b3b88a435d1114a479d006eece679245928fa3cdcf5241bd3bd6af31ebba493de5809cd5176113ffc68b07eb49d2a0c7f82ad04e796f4ca80699ec3e47
6
+ metadata.gz: d7728155e30d8d63bd0ecfd9eab3190b6dcc015d31158c92cb31b55cf541905368d745816154a074497e4b8a69251ecc6826ca95778fd7b421edf6849116fac2
7
+ data.tar.gz: b99d3f6e4d4275c93eaf52512a08b7811452be7f49cb222ac3c152911e8e6ac10c3449c3bfd3f10e71997acb5eb7013bce7a7c3f038fdc6ea913be3e6badb050
@@ -31,6 +31,8 @@ module Applitools::Selenium
31
31
  logger.info 'Done scrolling element!'
32
32
  end
33
33
 
34
+ alias scroll_to position=
35
+
34
36
  private
35
37
 
36
38
  def transforms_offset
@@ -59,6 +59,8 @@ module Applitools::Selenium
59
59
  self.last_state_position = value
60
60
  end
61
61
 
62
+ alias scroll_to position=
63
+
62
64
  def force_offset
63
65
  Applitools::Location.from_any_attribute last_state_position
64
66
  # Applitools::Location::TOP_LEFT
@@ -4,7 +4,7 @@ module Applitools
4
4
  module Selenium
5
5
  module DomCapture
6
6
  CAPTURE_FRAME_SCRIPT = <<'SCRIPT'
7
- /* @applitools/dom-capture@7.0.14 */
7
+ /* @applitools/dom-capture@7.1.3 */
8
8
 
9
9
  function __captureDomAndPoll() {
10
10
  var captureDomAndPoll = (function () {
@@ -56,19 +56,21 @@ function __captureDomAndPoll() {
56
56
  });
57
57
 
58
58
  async function getImageSizes({bgImages, timeout = 5000, Image = window.Image}) {
59
- return (await Promise.all(
60
- Array.from(bgImages).map(url =>
61
- Promise.race([
62
- new Promise(resolve => {
63
- const img = new Image();
64
- img.onload = () => resolve({url, width: img.naturalWidth, height: img.naturalHeight});
65
- img.onerror = () => resolve();
66
- img.src = url;
67
- }),
68
- psetTimeout(timeout),
69
- ]),
70
- ),
71
- )).reduce((images, curr) => {
59
+ return (
60
+ await Promise.all(
61
+ Array.from(bgImages).map(url =>
62
+ Promise.race([
63
+ new Promise(resolve => {
64
+ const img = new Image();
65
+ img.onload = () => resolve({url, width: img.naturalWidth, height: img.naturalHeight});
66
+ img.onerror = () => resolve();
67
+ img.src = url;
68
+ }),
69
+ psetTimeout(timeout),
70
+ ]),
71
+ ),
72
+ )
73
+ ).reduce((images, curr) => {
72
74
  if (curr) {
73
75
  images[curr.url] = {width: curr.width, height: curr.height};
74
76
  }
@@ -115,10 +117,10 @@ function __captureDomAndPoll() {
115
117
  parseCss,
116
118
  CSSImportRule,
117
119
  absolutizeUrl,
118
- fetchCss,
120
+ getCssFromCache,
119
121
  unfetchedToken,
120
122
  }) {
121
- return async function getBundledCssFromCssText(cssText, resourceUrl) {
123
+ return function getBundledCssFromCssText(cssText, styleBaseUrl) {
122
124
  let unfetchedResources;
123
125
  let bundledCss = '';
124
126
 
@@ -126,13 +128,13 @@ function __captureDomAndPoll() {
126
128
  const styleSheet = parseCss(cssText);
127
129
  for (const rule of Array.from(styleSheet.cssRules)) {
128
130
  if (rule instanceof CSSImportRule) {
129
- const nestedUrl = absolutizeUrl(rule.href, resourceUrl);
130
- const nestedResource = await fetchCss(nestedUrl);
131
+ const nestedUrl = absolutizeUrl(rule.href, styleBaseUrl);
132
+ const nestedResource = getCssFromCache(nestedUrl);
131
133
  if (nestedResource !== undefined) {
132
134
  const {
133
135
  bundledCss: nestedCssText,
134
136
  unfetchedResources: nestedUnfetchedResources,
135
- } = await getBundledCssFromCssText(nestedResource, nestedUrl);
137
+ } = getBundledCssFromCssText(nestedResource, nestedUrl);
136
138
 
137
139
  nestedUnfetchedResources && (unfetchedResources = new Set(nestedUnfetchedResources));
138
140
  bundledCss = `${nestedCssText}${bundledCss}`;
@@ -143,10 +145,10 @@ function __captureDomAndPoll() {
143
145
  }
144
146
  }
145
147
  } catch (ex) {
146
- console.log(`error during getBundledCssFromCssText, resourceUrl=${resourceUrl}`, ex);
148
+ console.log(`error during getBundledCssFromCssText, styleBaseUrl=${styleBaseUrl}`, ex);
147
149
  }
148
150
 
149
- bundledCss = `${bundledCss}${getCss(cssText, resourceUrl)}`;
151
+ bundledCss = `${bundledCss}${getCss(cssText, styleBaseUrl)}`;
150
152
 
151
153
  return {
152
154
  bundledCss,
@@ -189,22 +191,48 @@ function __captureDomAndPoll() {
189
191
 
190
192
  var fetchCss = makeFetchCss;
191
193
 
192
- function makeExtractCssFromNode({fetchCss, absolutizeUrl}) {
193
- return async function extractCssFromNode(node, baseUrl) {
194
- let cssText, resourceUrl, isUnfetched;
194
+ var getHrefAttr = function getHrefAttr(node) {
195
+ const attr = Array.from(node.attributes).find(attr => attr.name.toLowerCase() === 'href');
196
+ return attr && attr.value;
197
+ };
198
+
199
+ var isLinkToStyleSheet = function isLinkToStyleSheet(node) {
200
+ return (
201
+ node.nodeName &&
202
+ node.nodeName.toUpperCase() === 'LINK' &&
203
+ node.attributes &&
204
+ Array.from(node.attributes).find(
205
+ attr => attr.name.toLowerCase() === 'rel' && attr.value.toLowerCase() === 'stylesheet',
206
+ )
207
+ );
208
+ };
209
+
210
+ function isDataUrl(url) {
211
+ return url && url.startsWith('data:');
212
+ }
213
+
214
+ var isDataUrl_1 = isDataUrl;
215
+
216
+ function makeExtractCssFromNode({getCssFromCache, absolutizeUrl}) {
217
+ return function extractCssFromNode(node, baseUrl) {
218
+ let cssText, styleBaseUrl, isUnfetched;
195
219
  if (isStyleElement(node)) {
196
220
  cssText = Array.from(node.childNodes)
197
221
  .map(node => node.nodeValue)
198
222
  .join('');
199
- resourceUrl = baseUrl;
223
+ styleBaseUrl = baseUrl;
200
224
  } else if (isLinkToStyleSheet(node)) {
201
- resourceUrl = absolutizeUrl(getHrefAttr(node), baseUrl);
202
- cssText = await fetchCss(resourceUrl);
203
- if (cssText === undefined) {
204
- isUnfetched = true;
225
+ const href = getHrefAttr(node);
226
+ if (!isDataUrl_1(href)) {
227
+ styleBaseUrl = absolutizeUrl(href, baseUrl);
228
+ cssText = getCssFromCache(styleBaseUrl);
229
+ } else {
230
+ styleBaseUrl = baseUrl;
231
+ cssText = href.match(/,(.+)/)[1];
205
232
  }
233
+ isUnfetched = cssText === undefined;
206
234
  }
207
- return {cssText, resourceUrl, isUnfetched};
235
+ return {cssText, styleBaseUrl, isUnfetched};
208
236
  };
209
237
  }
210
238
 
@@ -212,41 +240,25 @@ function __captureDomAndPoll() {
212
240
  return node.nodeName && node.nodeName.toUpperCase() === 'STYLE';
213
241
  }
214
242
 
215
- function getHrefAttr(node) {
216
- const attr = Array.from(node.attributes).find(attr => attr.name.toLowerCase() === 'href');
217
- return attr && attr.value;
218
- }
219
-
220
- function isLinkToStyleSheet(node) {
221
- return (
222
- node.nodeName &&
223
- node.nodeName.toUpperCase() === 'LINK' &&
224
- node.attributes &&
225
- Array.from(node.attributes).find(
226
- attr => attr.name.toLowerCase() === 'rel' && attr.value.toLowerCase() === 'stylesheet',
227
- )
228
- );
229
- }
230
-
231
243
  var extractCssFromNode = makeExtractCssFromNode;
232
244
 
233
245
  function makeCaptureNodeCss({extractCssFromNode, getBundledCssFromCssText, unfetchedToken}) {
234
- return async function captureNodeCss(node, baseUrl) {
235
- const {resourceUrl, cssText, isUnfetched} = await extractCssFromNode(node, baseUrl);
246
+ return function captureNodeCss(node, baseUrl) {
247
+ const {styleBaseUrl, cssText, isUnfetched} = extractCssFromNode(node, baseUrl);
236
248
 
237
249
  let unfetchedResources;
238
250
  let bundledCss = '';
239
251
  if (cssText) {
240
- const {
241
- bundledCss: nestedCss,
242
- unfetchedResources: nestedUnfetched,
243
- } = await getBundledCssFromCssText(cssText, resourceUrl);
252
+ const {bundledCss: nestedCss, unfetchedResources: nestedUnfetched} = getBundledCssFromCssText(
253
+ cssText,
254
+ styleBaseUrl,
255
+ );
244
256
 
245
257
  bundledCss += nestedCss;
246
258
  unfetchedResources = new Set(nestedUnfetched);
247
259
  } else if (isUnfetched) {
248
- bundledCss += `${unfetchedToken}${resourceUrl}${unfetchedToken}`;
249
- unfetchedResources = new Set([resourceUrl]);
260
+ bundledCss += `${unfetchedToken}${styleBaseUrl}${unfetchedToken}`;
261
+ unfetchedResources = new Set([styleBaseUrl]);
250
262
  }
251
263
  return {bundledCss, unfetchedResources};
252
264
  };
@@ -258,37 +270,157 @@ function __captureDomAndPoll() {
258
270
  ELEMENT: 1,
259
271
  TEXT: 3,
260
272
  };
261
- const API_VERSION = '1.0.0';
273
+
274
+ var nodeTypes = {NODE_TYPES};
275
+
276
+ const {NODE_TYPES: NODE_TYPES$1} = nodeTypes;
277
+
278
+
279
+
280
+
281
+
282
+ function makePrefetchAllCss(fetchCss) {
283
+ return async function prefetchAllCss(doc = document) {
284
+ const cssMap = {};
285
+ const start = Date.now();
286
+ const promises = [];
287
+ doFetchAllCssFromFrame(doc, cssMap, promises);
288
+ await Promise.all(promises);
289
+ console.log('[prefetchAllCss]', Date.now() - start);
290
+
291
+ return function fetchCssSync(url) {
292
+ return cssMap[url];
293
+ };
294
+
295
+ async function fetchNodeCss(node, baseUrl, cssMap) {
296
+ let cssText, resourceUrl;
297
+ if (isLinkToStyleSheet(node)) {
298
+ resourceUrl = absolutizeUrl_1(getHrefAttr(node), baseUrl);
299
+ cssText = await fetchCss(resourceUrl);
300
+ if (cssText !== undefined) {
301
+ cssMap[resourceUrl] = cssText;
302
+ }
303
+ }
304
+ if (cssText) {
305
+ await fetchBundledCss(cssText, resourceUrl, cssMap);
306
+ }
307
+ }
308
+
309
+ async function fetchBundledCss(cssText, resourceUrl, cssMap) {
310
+ try {
311
+ const styleSheet = parseCss_1(cssText);
312
+ const promises = [];
313
+ for (const rule of Array.from(styleSheet.cssRules)) {
314
+ if (rule instanceof CSSImportRule) {
315
+ promises.push(
316
+ (async () => {
317
+ const nestedUrl = absolutizeUrl_1(rule.href, resourceUrl);
318
+ const cssText = await fetchCss(nestedUrl);
319
+ cssMap[nestedUrl] = cssText;
320
+ if (cssText !== undefined) {
321
+ await fetchBundledCss(cssText, nestedUrl, cssMap);
322
+ }
323
+ })(),
324
+ );
325
+ }
326
+ }
327
+ await Promise.all(promises);
328
+ } catch (ex) {
329
+ console.log(`error during fetchBundledCss, resourceUrl=${resourceUrl}`, ex);
330
+ }
331
+ }
332
+
333
+ function doFetchAllCssFromFrame(frameDoc, cssMap, promises) {
334
+ fetchAllCssFromNode(frameDoc.documentElement);
335
+
336
+ function fetchAllCssFromNode(node) {
337
+ promises.push(fetchNodeCss(node, frameDoc.location.href, cssMap));
338
+
339
+ switch (node.nodeType) {
340
+ case NODE_TYPES$1.ELEMENT: {
341
+ const tagName = node.tagName.toUpperCase();
342
+ if (tagName === 'IFRAME') {
343
+ return fetchAllCssFromIframe(node);
344
+ } else {
345
+ return fetchAllCssFromElement(node);
346
+ }
347
+ }
348
+ }
349
+ }
350
+
351
+ async function fetchAllCssFromElement(el) {
352
+ Array.prototype.map.call(el.childNodes, fetchAllCssFromNode);
353
+ }
354
+
355
+ async function fetchAllCssFromIframe(el) {
356
+ fetchAllCssFromElement(el);
357
+ try {
358
+ doFetchAllCssFromFrame(el.contentDocument, cssMap, promises);
359
+ } catch (ex) {
360
+ console.log(ex);
361
+ }
362
+ }
363
+ }
364
+ };
365
+ }
366
+
367
+ var prefetchAllCss = makePrefetchAllCss;
368
+
369
+ const {NODE_TYPES: NODE_TYPES$2} = nodeTypes;
370
+
371
+ const API_VERSION = '1.1.0';
262
372
 
263
373
  async function captureFrame(
264
374
  {styleProps, rectProps, ignoredTagNames} = defaultDomProps,
265
375
  doc = document,
376
+ addStats = false,
266
377
  ) {
267
- const start = Date.now();
378
+ const performance = {total: {}, prefetchCss: {}, doCaptureFrame: {}, waitForImages: {}};
379
+ function startTime(obj) {
380
+ obj.startTime = Date.now();
381
+ }
382
+ function endTime(obj) {
383
+ obj.endTime = Date.now();
384
+ obj.ellapsedTime = obj.endTime - obj.startTime;
385
+ }
386
+ const promises = [];
387
+ startTime(performance.total);
268
388
  const unfetchedResources = new Set();
269
389
  const iframeCors = [];
270
390
  const iframeToken = '@@@@@';
271
391
  const unfetchedToken = '#####';
272
392
  const separator = '-----';
273
393
 
274
- const fetchCss$$1 = fetchCss(fetch);
394
+ startTime(performance.prefetchCss);
395
+ const prefetchAllCss$$1 = prefetchAllCss(fetchCss(fetch));
396
+ const getCssFromCache = await prefetchAllCss$$1(doc);
397
+ endTime(performance.prefetchCss);
398
+
275
399
  const getBundledCssFromCssText$$1 = getBundledCssFromCssText({
276
400
  parseCss: parseCss_1,
277
401
  CSSImportRule,
278
- fetchCss: fetchCss$$1,
402
+ getCssFromCache,
279
403
  absolutizeUrl: absolutizeUrl_1,
280
404
  unfetchedToken,
281
405
  });
282
- const extractCssFromNode$$1 = extractCssFromNode({fetchCss: fetchCss$$1, absolutizeUrl: absolutizeUrl_1});
406
+ const extractCssFromNode$$1 = extractCssFromNode({getCssFromCache, absolutizeUrl: absolutizeUrl_1});
283
407
  const captureNodeCss$$1 = captureNodeCss({
284
408
  extractCssFromNode: extractCssFromNode$$1,
285
409
  getBundledCssFromCssText: getBundledCssFromCssText$$1,
286
410
  unfetchedToken,
287
411
  });
288
412
 
413
+ startTime(performance.doCaptureFrame);
414
+ const capturedFrame = doCaptureFrame(doc);
415
+ endTime(performance.doCaptureFrame);
416
+
417
+ startTime(performance.waitForImages);
418
+ await Promise.all(promises);
419
+ endTime(performance.waitForImages);
420
+
289
421
  // Note: Change the API_VERSION when changing json structure.
290
- const capturedFrame = await doCaptureFrame(doc);
291
422
  capturedFrame.version = API_VERSION;
423
+ capturedFrame.scriptVersion = '7.1.3';
292
424
 
293
425
  const iframePrefix = iframeCors.length ? `${iframeCors.join('\n')}\n` : '';
294
426
  const unfetchedPrefix = unfetchedResources.size
@@ -301,10 +433,20 @@ function __captureDomAndPoll() {
301
433
  iframeStartToken: `"${iframeToken}`,
302
434
  iframeEndToken: `${iframeToken}"`,
303
435
  });
436
+
437
+ endTime(performance.total);
438
+
439
+ function stats() {
440
+ if (!addStats) {
441
+ return '';
442
+ }
443
+ return `\n${separator}\n${JSON.stringify(performance)}`;
444
+ }
445
+
304
446
  const ret = `${metaPrefix}\n${unfetchedPrefix}${separator}\n${iframePrefix}${separator}\n${JSON.stringify(
305
447
  capturedFrame,
306
- )}`;
307
- console.log('[captureFrame]', Date.now() - start);
448
+ )}${stats()}`;
449
+ console.log('[captureFrame]', JSON.stringify(performance));
308
450
  return ret;
309
451
 
310
452
  function filter(x) {
@@ -322,16 +464,16 @@ function __captureDomAndPoll() {
322
464
  };
323
465
  }
324
466
 
325
- async function doCaptureFrame(frameDoc) {
467
+ function doCaptureFrame(frameDoc) {
326
468
  const bgImages = new Set();
327
469
  let bundledCss = '';
328
- const ret = await captureNode(frameDoc.documentElement);
470
+ const ret = captureNode(frameDoc.documentElement);
329
471
  ret.css = bundledCss;
330
- ret.images = await getImageSizes_1({bgImages});
472
+ promises.push(getImageSizes_1({bgImages}).then(images => (ret.images = images)));
331
473
  return ret;
332
474
 
333
- async function captureNode(node) {
334
- const {bundledCss: nodeCss, unfetchedResources: nodeUnfetched} = await captureNodeCss$$1(
475
+ function captureNode(node) {
476
+ const {bundledCss: nodeCss, unfetchedResources: nodeUnfetched} = captureNodeCss$$1(
335
477
  node,
336
478
  frameDoc.location.href,
337
479
  );
@@ -339,15 +481,15 @@ function __captureDomAndPoll() {
339
481
  if (nodeUnfetched) for (const elem of nodeUnfetched) unfetchedResources.add(elem);
340
482
 
341
483
  switch (node.nodeType) {
342
- case NODE_TYPES.TEXT: {
484
+ case NODE_TYPES$2.TEXT: {
343
485
  return captureTextNode(node);
344
486
  }
345
- case NODE_TYPES.ELEMENT: {
487
+ case NODE_TYPES$2.ELEMENT: {
346
488
  const tagName = node.tagName.toUpperCase();
347
489
  if (tagName === 'IFRAME') {
348
- return await iframeToJSON(node);
490
+ return iframeToJSON(node);
349
491
  } else {
350
- return await await elementToJSON(node);
492
+ return elementToJSON(node);
351
493
  }
352
494
  }
353
495
  default: {
@@ -356,10 +498,8 @@ function __captureDomAndPoll() {
356
498
  }
357
499
  }
358
500
 
359
- async function elementToJSON(el) {
360
- const childNodes = (await Promise.all(
361
- Array.prototype.map.call(el.childNodes, captureNode),
362
- )).filter(filter);
501
+ function elementToJSON(el) {
502
+ const childNodes = Array.prototype.map.call(el.childNodes, captureNode).filter(filter);
363
503
 
364
504
  const tagName = el.tagName.toUpperCase();
365
505
  if (ignoredTagNames.indexOf(tagName) > -1) return null;
@@ -369,6 +509,13 @@ function __captureDomAndPoll() {
369
509
 
370
510
  const style = {};
371
511
  for (const p of styleProps) style[p] = computedStyle.getPropertyValue(p);
512
+ if (!style['border-width']) {
513
+ style['border-width'] = `${computedStyle.getPropertyValue(
514
+ 'border-top-width',
515
+ )} ${computedStyle.getPropertyValue('border-right-width')} ${computedStyle.getPropertyValue(
516
+ 'border-bottom-width',
517
+ )} ${computedStyle.getPropertyValue('border-left-width')}`;
518
+ }
372
519
 
373
520
  const rect = {};
374
521
  for (const p of rectProps) rect[p] = boundingClientRect[p];
@@ -394,8 +541,8 @@ function __captureDomAndPoll() {
394
541
  };
395
542
  }
396
543
 
397
- async function iframeToJSON(el) {
398
- const obj = await elementToJSON(el);
544
+ function iframeToJSON(el) {
545
+ const obj = elementToJSON(el);
399
546
  let doc;
400
547
  try {
401
548
  doc = el.contentDocument;
@@ -405,7 +552,7 @@ function __captureDomAndPoll() {
405
552
  }
406
553
  try {
407
554
  if (doc) {
408
- obj.childNodes = [await doCaptureFrame(el.contentDocument)];
555
+ obj.childNodes = [doCaptureFrame(el.contentDocument)];
409
556
  } else {
410
557
  markFrameAsCors();
411
558
  }
@@ -31,7 +31,7 @@ module Applitools
31
31
  self.options = {
32
32
  ignore_caret: true,
33
33
  ignore_mismatch: false,
34
- send_dom: nil,
34
+ send_dom: true,
35
35
  script_hooks: { beforeCaptureScreenshot: '' }
36
36
  }
37
37
  self.regions = {}
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Applitools
4
- VERSION = '3.16.6'.freeze
4
+ VERSION = '3.16.7'.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.16.6
4
+ version: 3.16.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Applitools Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-05 00:00:00.000000000 Z
11
+ date: 2020-03-06 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.16.6
19
+ version: 3.16.7
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.16.6
26
+ version: 3.16.7
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: selenium-webdriver
29
29
  requirement: !ruby/object:Gem::Requirement