@applitools/eyes-testcafe 2.0.0-beta.9 → 2.0.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +467 -0
  2. package/LICENSE +1 -1
  3. package/README.md +7 -531
  4. package/dist/api.js +51 -0
  5. package/dist/extract-environment.js +15 -0
  6. package/dist/index-legacy.js +5 -0
  7. package/dist/index.js +19 -0
  8. package/dist/legacy.js +225 -0
  9. package/dist/spec-driver.js +245 -0
  10. package/package.json +73 -77
  11. package/types/index-legacy.d.ts +2 -0
  12. package/types/index.d.ts +1833 -0
  13. package/dist/captureFrameAndPoll.js +0 -1468
  14. package/dist/captureFrameAndPollForIE.js +0 -12569
  15. package/index.js +0 -30
  16. package/lib/BordersAwareElementContentLocationProvider.js +0 -79
  17. package/lib/Eyes.js +0 -927
  18. package/lib/EyesFactory.js +0 -73
  19. package/lib/EyesTestCafe.js +0 -1277
  20. package/lib/EyesTestcafeUtils.js +0 -440
  21. package/lib/EyesVisualGrid.js +0 -345
  22. package/lib/ImageOrientationHandler.js +0 -31
  23. package/lib/JavascriptHandler.js +0 -20
  24. package/lib/TestCafeExecutor.js +0 -57
  25. package/lib/capture/EyesWebDriverScreenshot.js +0 -650
  26. package/lib/capture/EyesWebDriverScreenshotFactory.js +0 -32
  27. package/lib/capture/FirefoxScreenshotImageProvider.js +0 -63
  28. package/lib/capture/ImageProviderFactory.js +0 -38
  29. package/lib/capture/SafariScreenshotImageProvider.js +0 -254
  30. package/lib/capture/TakesScreenshotImageProvider.js +0 -35
  31. package/lib/errors/EyesDriverOperationError.js +0 -10
  32. package/lib/errors/NoFramesError.js +0 -7
  33. package/lib/fluent/AccessibilityRegionByElement.js +0 -46
  34. package/lib/fluent/AccessibilityRegionBySelector.js +0 -58
  35. package/lib/fluent/FloatingRegionByElement.js +0 -56
  36. package/lib/fluent/FloatingRegionBySelector.js +0 -63
  37. package/lib/fluent/FrameLocator.js +0 -110
  38. package/lib/fluent/IgnoreRegionByElement.js +0 -51
  39. package/lib/fluent/IgnoreRegionBySelector.js +0 -57
  40. package/lib/fluent/SelectorByElement.js +0 -37
  41. package/lib/fluent/SelectorByLocator.js +0 -47
  42. package/lib/fluent/Target.js +0 -17
  43. package/lib/fluent/TestcafeCheckSettings.js +0 -352
  44. package/lib/frames/Frame.js +0 -149
  45. package/lib/frames/FrameChain.js +0 -175
  46. package/lib/getCaptureDomScript.js +0 -14
  47. package/lib/hash.js +0 -15
  48. package/lib/isTestcafeSelector.js +0 -7
  49. package/lib/makeClientFunctionWrapper.js +0 -61
  50. package/lib/positioning/CssTranslatePositionMemento.js +0 -39
  51. package/lib/positioning/CssTranslatePositionProvider.js +0 -130
  52. package/lib/positioning/ElementPositionMemento.js +0 -36
  53. package/lib/positioning/ElementPositionProvider.js +0 -88
  54. package/lib/positioning/FirefoxRegionPositionCompensation.js +0 -45
  55. package/lib/positioning/ImageRotation.js +0 -22
  56. package/lib/positioning/OverflowAwareCssTranslatePositionProvider.js +0 -17
  57. package/lib/positioning/OverflowAwareScrollPositionProvider.js +0 -17
  58. package/lib/positioning/RegionPositionCompensationFactory.js +0 -37
  59. package/lib/positioning/SafariRegionPositionCompensation.js +0 -26
  60. package/lib/positioning/ScrollPositionMemento.js +0 -36
  61. package/lib/positioning/ScrollPositionProvider.js +0 -118
  62. package/lib/positioning/fixImageMarkPosition.js +0 -36
  63. package/lib/regionVisibility/MoveToRegionVisibilityStrategy.js +0 -55
  64. package/lib/regionVisibility/NopRegionVisibilityStrategy.js +0 -35
  65. package/lib/regionVisibility/RegionVisibilityStrategy.js +0 -30
  66. package/lib/runner/ClassicRunner.js +0 -49
  67. package/lib/runner/EyesRunner.js +0 -41
  68. package/lib/runner/TestResultContainer.js +0 -38
  69. package/lib/runner/TestResultsSummary.js +0 -112
  70. package/lib/runner/VisualGridRunner.js +0 -57
  71. package/lib/safeExecuteFunction.js +0 -28
  72. package/lib/wrappers/EyesTargetLocator.js +0 -335
  73. package/lib/wrappers/EyesWebDriver.js +0 -571
  74. package/lib/wrappers/EyesWebElement.js +0 -383
  75. package/lib/wrappers/EyesWebElementPromise.js +0 -68
@@ -1,440 +0,0 @@
1
- 'use strict'
2
-
3
- const {RectangleSize, ArgumentGuard} = require('@applitools/eyes-common')
4
- const {EyesJsBrowserUtils, GeneralUtils, EyesError} = require('@applitools/eyes-sdk-core')
5
-
6
- const {EyesDriverOperationError} = require('./errors/EyesDriverOperationError')
7
- const {ImageOrientationHandler} = require('./ImageOrientationHandler')
8
- const {JavascriptHandler} = require('./JavascriptHandler')
9
-
10
- const JS_GET_ENTIRE_PAGE_SIZE =
11
- 'var width = Math.max(arguments[0].clientWidth, arguments[0].scrollWidth);' +
12
- 'var height = Math.max(arguments[0].clientHeight, arguments[0].scrollHeight);' +
13
- 'return [width, height];'
14
-
15
- let imageOrientationHandler = new (class ImageOrientationHandlerImpl extends ImageOrientationHandler {
16
- /**
17
- * @inheritDoc
18
- */
19
- async isLandscapeOrientation(driver) {
20
- // noinspection JSValidateTypes
21
- try {
22
- const capabilities = await driver.getCapabilities()
23
- return EyesTestcafeUtils.isLandscapeOrientationFromCaps(capabilities)
24
- } catch (err) {
25
- throw new EyesDriverOperationError('Failed to get orientation!', err)
26
- }
27
- }
28
-
29
- /**
30
- * @inheritDoc
31
- */
32
- async tryAutomaticRotation() {
33
- // eslint-disable-line no-unused-vars
34
- return 0
35
- }
36
- })()
37
-
38
- let javascriptHandler = new (class JavascriptHandlerImpl extends JavascriptHandler {})()
39
-
40
- /**
41
- * @param {Logger} logger
42
- * @param {IWebDriver} driver
43
- * @param {RectangleSize} browserSize - The size to set
44
- * @param {RectangleSize} requiredViewportSize - The size to expect
45
- * @param {number} sleep
46
- * @param {number} retriesLeft
47
- * @return {Promise<boolean>}
48
- */
49
- async function setBrowserSizeLoop(logger, driver, requiredViewportSize, sleep, retriesLeft) {
50
- logger.verbose(`Setting browser size to required viewport size ${requiredViewportSize}`)
51
- await driver.resizeWindow(requiredViewportSize.getWidth(), requiredViewportSize.getHeight())
52
-
53
- let rect = await driver.getViewport()
54
- let currentSize = new RectangleSize(rect)
55
- logger.verbose(`Current viewport size: ${currentSize}`)
56
- if (currentSize.equals(requiredViewportSize)) {
57
- return true
58
- }
59
-
60
- const requiredBrowserSize = new RectangleSize({
61
- width:
62
- requiredViewportSize.getWidth() + (requiredViewportSize.getWidth() - currentSize.getWidth()),
63
- height:
64
- requiredViewportSize.getHeight() +
65
- (requiredViewportSize.getHeight() - currentSize.getHeight()),
66
- })
67
-
68
- logger.verbose(
69
- `Setting browser size to ${requiredBrowserSize} required viewport size ${requiredViewportSize}`,
70
- )
71
- await driver.resizeWindow(requiredBrowserSize.getWidth(), requiredBrowserSize.getHeight())
72
-
73
- rect = await driver.getViewport()
74
- currentSize = new RectangleSize(rect)
75
- logger.verbose(`Current viewport size: ${currentSize}`)
76
- if (currentSize.equals(requiredViewportSize)) {
77
- return true
78
- }
79
-
80
- if (retriesLeft <= 1) {
81
- logger.verbose('Failed to set browser size: retries is out.')
82
- return false
83
- }
84
-
85
- return setBrowserSizeLoop(logger, driver, requiredViewportSize, sleep, retriesLeft - 1)
86
- }
87
-
88
- // noinspection OverlyComplexFunctionJS
89
- /**
90
- * @param {Logger} logger
91
- * @param {WebDriver} driver
92
- * @param {RectangleSize} requiredSize
93
- * @param {RectangleSize} actualVSize
94
- * @param {RectangleSize} browserSize
95
- * @param {number} widthDiff
96
- * @param {number} widthStep
97
- * @param {number} heightDiff
98
- * @param {number} heightStep
99
- * @param {number} currWidthChange
100
- * @param {number} currHeightChange
101
- * @param {number} retriesLeft
102
- * @param {RectangleSize} lastRequiredBrowserSize
103
- * @return {Promise<boolean>}
104
- */
105
- async function setViewportSizeLoop(
106
- logger,
107
- driver,
108
- requiredSize,
109
- actualVSize,
110
- browserSize,
111
- widthDiff,
112
- widthStep,
113
- heightDiff,
114
- heightStep,
115
- currWidthChange,
116
- currHeightChange,
117
- retriesLeft,
118
- lastRequiredBrowserSize,
119
- ) {
120
- logger.verbose(`Retries left: ${retriesLeft}`)
121
-
122
- // We specifically use "<=" (and not "<"), so to give an extra resize attempt in addition to reaching the diff, due
123
- // to floating point issues.
124
- if (
125
- Math.abs(currWidthChange) <= Math.abs(widthDiff) &&
126
- actualVSize.getWidth() !== requiredSize.getWidth()
127
- ) {
128
- currWidthChange += widthStep
129
- }
130
-
131
- if (
132
- Math.abs(currHeightChange) <= Math.abs(heightDiff) &&
133
- actualVSize.getHeight() !== requiredSize.getHeight()
134
- ) {
135
- currHeightChange += heightStep
136
- }
137
-
138
- const requiredBrowserSize = new RectangleSize({
139
- width: browserSize.getWidth() + currWidthChange,
140
- height: browserSize.getHeight() + currHeightChange,
141
- })
142
-
143
- if (requiredBrowserSize.equals(lastRequiredBrowserSize)) {
144
- logger.verbose('Browser size is as required but viewport size does not match!')
145
- logger.verbose(`Browser size: ${requiredBrowserSize}, Viewport size: ${actualVSize}`)
146
- logger.verbose('Stopping viewport size attempts.')
147
- return true
148
- }
149
-
150
- await EyesTestcafeUtils.setBrowserSize(logger, driver, requiredBrowserSize)
151
- lastRequiredBrowserSize = requiredBrowserSize
152
- const finalViewportSize = await EyesTestcafeUtils.getViewportSize(driver)
153
-
154
- logger.verbose(`Current viewport size: ${finalViewportSize}`)
155
- if (finalViewportSize.equals(requiredSize)) {
156
- return true
157
- }
158
-
159
- if (
160
- (Math.abs(currWidthChange) <= Math.abs(widthDiff) ||
161
- Math.abs(currHeightChange) <= Math.abs(heightDiff)) &&
162
- retriesLeft > 1
163
- ) {
164
- return setViewportSizeLoop(
165
- logger,
166
- driver,
167
- requiredSize,
168
- finalViewportSize,
169
- browserSize,
170
- widthDiff,
171
- widthStep,
172
- heightDiff,
173
- heightStep,
174
- currWidthChange,
175
- currHeightChange,
176
- retriesLeft - 1,
177
- lastRequiredBrowserSize,
178
- )
179
- }
180
-
181
- throw new Error('EyesError: failed to set window size! Zoom workaround failed.')
182
- }
183
-
184
- /**
185
- * Handles browser related functionality.
186
- */
187
- class EyesTestcafeUtils extends EyesJsBrowserUtils {
188
- /**
189
- * @param {ImageOrientationHandler} value
190
- */
191
- static setImageOrientationHandler(value) {
192
- imageOrientationHandler = value
193
- }
194
-
195
- /**
196
- * @param {IWebDriver} driver - The driver for which to check if it represents a mobile device.
197
- * @return {Promise<boolean>} {@code true} if the platform running the test is a mobile platform. {@code false}
198
- * otherwise.
199
- */
200
- static async isMobileDevice(driver) {
201
- const capabilities = await driver.getCapabilities()
202
- return EyesTestcafeUtils.isMobileDeviceFromCaps(capabilities)
203
- }
204
-
205
- /**
206
- * Overriding EyesJsBrowserUtils.setOverflow for testcafe
207
- */
208
- static async setOverflow(executor, value, rootElement) {
209
- ArgumentGuard.notNull(executor, 'executor')
210
- ArgumentGuard.notNull(rootElement, 'rootElement')
211
-
212
- const script =
213
- `var el = arguments[0]; var origOverflow = el.style['overflow']; var newOverflow = '${value}'; ` +
214
- 'el.style["overflow"] = newOverflow; ' +
215
- "if (newOverflow.toUpperCase() === 'HIDDEN' && origOverflow.toUpperCase() !== 'HIDDEN') { el.setAttribute('data-applitools-original-overflow', origOverflow); } " +
216
- 'return origOverflow;'
217
-
218
- try {
219
- const result = await executor.executeScript(script, rootElement)
220
- await GeneralUtils.sleep(200)
221
- return result
222
- } catch (err) {
223
- throw new EyesError(`Failed to set overflow ${JSON.stringify(err)}`)
224
- }
225
- }
226
-
227
- /**
228
- * @param {Capabilities} capabilities - The driver's capabilities.
229
- * @return {boolean} {@code true} if the platform running the test is a mobile platform. {@code false} otherwise.
230
- */
231
- static isMobileDeviceFromCaps(capabilities) {
232
- const platformName = (
233
- capabilities.get('platformName') || capabilities.get('platform')
234
- ).toUpperCase()
235
- return platformName === 'ANDROID' || ['MAC', 'IOS'].includes(platformName)
236
- }
237
-
238
- /**
239
- * @param {IWebDriver} driver - The driver for which to check the orientation.
240
- * @return {Promise<boolean>} {@code true} if this is a mobile device and is in landscape orientation. {@code
241
- * false} otherwise.
242
- */
243
- static isLandscapeOrientation(driver) {
244
- return imageOrientationHandler.isLandscapeOrientation(driver)
245
- }
246
-
247
- /**
248
- * @param {Capabilities} capabilities - The driver's capabilities.
249
- * @return {boolean} {@code true} if this is a mobile device and is in landscape orientation. {@code false} otherwise.
250
- */
251
- static isLandscapeOrientationFromCaps(capabilities) {
252
- const capsOrientation = capabilities.get('orientation') || capabilities.get('deviceOrientation')
253
- return capsOrientation === 'LANDSCAPE'
254
- }
255
-
256
- /**
257
- * @param {Logger} logger
258
- * @param {IWebDriver} driver
259
- * @param {MutableImage} image
260
- * @return {Promise<number>}
261
- */
262
- static tryAutomaticRotation(logger, driver, image) {
263
- return imageOrientationHandler.tryAutomaticRotation(logger, driver, image)
264
- }
265
-
266
- /**
267
- * @param {JavascriptHandler} handler
268
- */
269
- static setJavascriptHandler(handler) {
270
- javascriptHandler = handler
271
- }
272
-
273
- /**
274
- * @param {string} script
275
- * @param {...object} args
276
- */
277
- static handleSpecialCommands(script, ...args) {
278
- return javascriptHandler.handle(script, ...args)
279
- }
280
-
281
- /**
282
- * Gets entire element size.
283
- *
284
- * @param {EyesJsExecutor} executor
285
- * @param {WebElement} element
286
- * @return {RectangleSize} - The entire element size
287
- */
288
- static async getEntireElementSize(executor, element) {
289
- try {
290
- const result = await executor.executeScript(JS_GET_ENTIRE_PAGE_SIZE, element)
291
- return new RectangleSize(Math.ceil(result[0]) || 0, Math.ceil(result[1]) || 0)
292
- } catch (err) {
293
- throw new EyesDriverOperationError('Failed to extract entire size!', err)
294
- }
295
- }
296
-
297
- /**
298
- * @param {Logger} logger - The logger to use.
299
- * @param {EyesWebDriver|WebDriver} driver - The web driver to use.
300
- * @return {Promise<RectangleSize>} - The viewport size of the current context, or the display size if the viewport
301
- * size cannot be retrieved.
302
- */
303
- static async getViewportSizeOrDisplaySize(logger, driver) {
304
- try {
305
- logger.verbose('getViewportSizeOrDisplaySize()')
306
- return await EyesTestcafeUtils.getViewportSize(driver)
307
- } catch (err) {
308
- logger.verbose('Failed to extract viewport size using Javascript:', err)
309
-
310
- // If we failed to extract the viewport size using JS, will use the window size instead.
311
- logger.verbose('Using window size as viewport size.')
312
- let {width, height} = await driver.getViewport()
313
-
314
- // noinspection EmptyCatchBlockJS
315
- try {
316
- const isLandscape = await EyesTestcafeUtils.isLandscapeOrientation(driver)
317
- if (isLandscape && height > width) {
318
- const temp = width
319
- // noinspection JSSuspiciousNameCombination
320
- width = height
321
- height = temp
322
- }
323
- } catch (ignored) {
324
- // Not every IWebDriver supports querying for orientation.
325
- }
326
-
327
- logger.verbose(`Done! Size ${width} x ${height}`)
328
- return new RectangleSize({width, height})
329
- }
330
- }
331
-
332
- /**
333
- * @param {Logger} logger - The logger to use.
334
- * @param {IWebDriver} driver - The web driver to use.
335
- * @param {RectangleSize} requiredViewportSize - The size to expect
336
- */
337
- static async setBrowserSize(logger, driver, requiredViewportSize) {
338
- const SLEEP = 1000
339
- const RETRIES = 3
340
- return setBrowserSizeLoop(logger, driver, requiredViewportSize, SLEEP, RETRIES)
341
- }
342
-
343
- /**
344
- * @param {Logger} logger - The logger to use.
345
- * @param {IWebDriver} driver - The web driver to use.
346
- * @param {RectangleSize} actualViewportSize
347
- * @param {RectangleSize} requiredViewportSize
348
- * @return {Promise<undefined>}
349
- */
350
- static async setBrowserSizeByViewportSize(logger, driver, requiredViewportSize) {
351
- return EyesTestcafeUtils.setBrowserSize(logger, driver, requiredViewportSize)
352
- }
353
-
354
- /**
355
- * Tries to set the viewport size
356
- *
357
- * @param {Logger} logger - The logger to use.
358
- * @param {EyesWebDriver|WebDriver} driver - The web driver to use.
359
- * @param {RectangleSize} requiredSize - The viewport size.
360
- * @return {Promise<boolean>}
361
- */
362
- static async setViewportSize(logger, driver, requiredSize) {
363
- ArgumentGuard.notNull(requiredSize, 'requiredSize')
364
-
365
- // First we will set the window size to the required size.
366
- // Then we'll check the viewport size and increase the window size accordingly.
367
- logger.verbose(`setViewportSize(${requiredSize})`)
368
- const initViewportSize = await EyesTestcafeUtils.getViewportSize(driver)
369
- logger.verbose(`Initial viewport size: ${initViewportSize}`)
370
-
371
- // If the viewport size is already the required size
372
- if (initViewportSize.equals(requiredSize)) {
373
- logger.verbose('Required size already set.')
374
- return true
375
- }
376
-
377
- await EyesTestcafeUtils.setBrowserSizeByViewportSize(logger, driver, requiredSize)
378
- const actualViewportSize = await EyesTestcafeUtils.getViewportSize(driver)
379
-
380
- if (actualViewportSize.equals(requiredSize)) {
381
- return true
382
- }
383
-
384
- // Additional attempt. This Solves the "maximized browser" bug
385
- // (border size for maximized browser sometimes different than non-maximized, so the original browser size
386
- // calculation is wrong).
387
- logger.verbose('Trying workaround for maximization...')
388
- await EyesTestcafeUtils.setBrowserSizeByViewportSize(
389
- logger,
390
- driver,
391
- actualViewportSize,
392
- requiredSize,
393
- )
394
- const finalViewportSize = await EyesTestcafeUtils.getViewportSize(driver)
395
-
396
- logger.verbose(`Current viewport size: ${finalViewportSize}`)
397
- if (finalViewportSize.equals(requiredSize)) {
398
- return true
399
- }
400
-
401
- const MAX_DIFF = 3
402
- const widthDiff = finalViewportSize.getWidth() - requiredSize.getWidth()
403
- const widthStep = widthDiff > 0 ? -1 : 1 // -1 for smaller size, 1 for larger
404
- const heightDiff = finalViewportSize.getHeight() - requiredSize.getHeight()
405
- const heightStep = heightDiff > 0 ? -1 : 1
406
-
407
- const rect = await driver.getViewport()
408
- const browserSize = new RectangleSize(rect)
409
-
410
- const currWidthChange = 0
411
- const currHeightChange = 0
412
- // We try the zoom workaround only if size difference is reasonable.
413
- if (Math.abs(widthDiff) <= MAX_DIFF && Math.abs(heightDiff) <= MAX_DIFF) {
414
- logger.verbose('Trying workaround for zoom...')
415
- const retriesLeft =
416
- Math.abs((widthDiff === 0 ? 1 : widthDiff) * (heightDiff === 0 ? 1 : heightDiff)) * 2
417
-
418
- const lastRequiredBrowserSize = null
419
- return setViewportSizeLoop(
420
- logger,
421
- driver,
422
- requiredSize,
423
- finalViewportSize,
424
- browserSize,
425
- widthDiff,
426
- widthStep,
427
- heightDiff,
428
- heightStep,
429
- currWidthChange,
430
- currHeightChange,
431
- retriesLeft,
432
- lastRequiredBrowserSize,
433
- )
434
- }
435
-
436
- throw new Error('EyesError: failed to set window size!')
437
- }
438
- }
439
-
440
- exports.EyesTestcafeUtils = EyesTestcafeUtils