@applitools/eyes-testcafe 2.0.0-beta.9 → 3.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.
- package/CHANGELOG.md +540 -0
- package/LICENSE +1 -1
- package/README.md +7 -531
- package/dist/api.js +51 -0
- package/dist/extract-environment.js +15 -0
- package/dist/index-legacy.js +5 -0
- package/dist/index.js +19 -0
- package/dist/legacy.js +225 -0
- package/dist/spec-driver.js +245 -0
- package/package.json +73 -77
- package/types/index-legacy.d.ts +2 -0
- package/types/index.d.ts +1833 -0
- package/dist/captureFrameAndPoll.js +0 -1468
- package/dist/captureFrameAndPollForIE.js +0 -12569
- package/index.js +0 -30
- package/lib/BordersAwareElementContentLocationProvider.js +0 -79
- package/lib/Eyes.js +0 -927
- package/lib/EyesFactory.js +0 -73
- package/lib/EyesTestCafe.js +0 -1277
- package/lib/EyesTestcafeUtils.js +0 -440
- package/lib/EyesVisualGrid.js +0 -345
- package/lib/ImageOrientationHandler.js +0 -31
- package/lib/JavascriptHandler.js +0 -20
- package/lib/TestCafeExecutor.js +0 -57
- package/lib/capture/EyesWebDriverScreenshot.js +0 -650
- package/lib/capture/EyesWebDriverScreenshotFactory.js +0 -32
- package/lib/capture/FirefoxScreenshotImageProvider.js +0 -63
- package/lib/capture/ImageProviderFactory.js +0 -38
- package/lib/capture/SafariScreenshotImageProvider.js +0 -254
- package/lib/capture/TakesScreenshotImageProvider.js +0 -35
- package/lib/errors/EyesDriverOperationError.js +0 -10
- package/lib/errors/NoFramesError.js +0 -7
- package/lib/fluent/AccessibilityRegionByElement.js +0 -46
- package/lib/fluent/AccessibilityRegionBySelector.js +0 -58
- package/lib/fluent/FloatingRegionByElement.js +0 -56
- package/lib/fluent/FloatingRegionBySelector.js +0 -63
- package/lib/fluent/FrameLocator.js +0 -110
- package/lib/fluent/IgnoreRegionByElement.js +0 -51
- package/lib/fluent/IgnoreRegionBySelector.js +0 -57
- package/lib/fluent/SelectorByElement.js +0 -37
- package/lib/fluent/SelectorByLocator.js +0 -47
- package/lib/fluent/Target.js +0 -17
- package/lib/fluent/TestcafeCheckSettings.js +0 -352
- package/lib/frames/Frame.js +0 -149
- package/lib/frames/FrameChain.js +0 -175
- package/lib/getCaptureDomScript.js +0 -14
- package/lib/hash.js +0 -15
- package/lib/isTestcafeSelector.js +0 -7
- package/lib/makeClientFunctionWrapper.js +0 -61
- package/lib/positioning/CssTranslatePositionMemento.js +0 -39
- package/lib/positioning/CssTranslatePositionProvider.js +0 -130
- package/lib/positioning/ElementPositionMemento.js +0 -36
- package/lib/positioning/ElementPositionProvider.js +0 -88
- package/lib/positioning/FirefoxRegionPositionCompensation.js +0 -45
- package/lib/positioning/ImageRotation.js +0 -22
- package/lib/positioning/OverflowAwareCssTranslatePositionProvider.js +0 -17
- package/lib/positioning/OverflowAwareScrollPositionProvider.js +0 -17
- package/lib/positioning/RegionPositionCompensationFactory.js +0 -37
- package/lib/positioning/SafariRegionPositionCompensation.js +0 -26
- package/lib/positioning/ScrollPositionMemento.js +0 -36
- package/lib/positioning/ScrollPositionProvider.js +0 -118
- package/lib/positioning/fixImageMarkPosition.js +0 -36
- package/lib/regionVisibility/MoveToRegionVisibilityStrategy.js +0 -55
- package/lib/regionVisibility/NopRegionVisibilityStrategy.js +0 -35
- package/lib/regionVisibility/RegionVisibilityStrategy.js +0 -30
- package/lib/runner/ClassicRunner.js +0 -49
- package/lib/runner/EyesRunner.js +0 -41
- package/lib/runner/TestResultContainer.js +0 -38
- package/lib/runner/TestResultsSummary.js +0 -112
- package/lib/runner/VisualGridRunner.js +0 -57
- package/lib/safeExecuteFunction.js +0 -28
- package/lib/wrappers/EyesTargetLocator.js +0 -335
- package/lib/wrappers/EyesWebDriver.js +0 -571
- package/lib/wrappers/EyesWebElement.js +0 -383
- package/lib/wrappers/EyesWebElementPromise.js +0 -68
|
@@ -1,650 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {
|
|
4
|
-
ArgumentGuard,
|
|
5
|
-
CoordinatesType,
|
|
6
|
-
Region,
|
|
7
|
-
Location,
|
|
8
|
-
RectangleSize,
|
|
9
|
-
} = require('@applitools/eyes-common')
|
|
10
|
-
const {
|
|
11
|
-
EyesScreenshot,
|
|
12
|
-
CoordinatesTypeConversionError,
|
|
13
|
-
OutOfBoundsError,
|
|
14
|
-
} = require('@applitools/eyes-sdk-core')
|
|
15
|
-
|
|
16
|
-
const {TestCafeExecutor} = require('../TestCafeExecutor')
|
|
17
|
-
const {ScrollPositionProvider} = require('../positioning/ScrollPositionProvider')
|
|
18
|
-
const {FrameChain} = require('../frames/FrameChain')
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @readonly
|
|
22
|
-
* @enum {number}
|
|
23
|
-
*/
|
|
24
|
-
const ScreenshotType = {
|
|
25
|
-
VIEWPORT: 1,
|
|
26
|
-
ENTIRE_FRAME: 2,
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @ignore
|
|
31
|
-
*/
|
|
32
|
-
class EyesWebDriverScreenshot extends EyesScreenshot {
|
|
33
|
-
/**
|
|
34
|
-
* @private
|
|
35
|
-
* @param {Logger} logger - A Logger instance.
|
|
36
|
-
* @param {EyesWebDriver} driver - The web driver used to get the screenshot.
|
|
37
|
-
* @param {MutableImage} image - The actual screenshot image.
|
|
38
|
-
*/
|
|
39
|
-
constructor(logger, driver, image) {
|
|
40
|
-
super(image)
|
|
41
|
-
|
|
42
|
-
ArgumentGuard.notNull(logger, 'logger')
|
|
43
|
-
ArgumentGuard.notNull(driver, 'driver')
|
|
44
|
-
|
|
45
|
-
this._logger = logger
|
|
46
|
-
this._driver = driver
|
|
47
|
-
/** @type {FrameChain} */
|
|
48
|
-
this._frameChain = driver.getFrameChain()
|
|
49
|
-
/** @type {Location} */
|
|
50
|
-
this._currentFrameScrollPosition = null
|
|
51
|
-
/** @type {ScreenshotType} */
|
|
52
|
-
this._screenshotType = null
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The top/left coordinates of the frame window(!) relative to the top/left of the screenshot. Used for
|
|
56
|
-
* calculations, so can also be outside(!) the screenshot.
|
|
57
|
-
*
|
|
58
|
-
* @type {Location} */
|
|
59
|
-
this._frameLocationInScreenshot = null
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* The top/left coordinates of the frame window(!) relative to the top/left of the screenshot. Used for
|
|
63
|
-
* calculations, so can also be outside(!) the screenshot.
|
|
64
|
-
*
|
|
65
|
-
* @type {Region} */
|
|
66
|
-
this._frameWindow = null
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @type {Region}
|
|
70
|
-
*/
|
|
71
|
-
this._regionWindow = null
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Creates a frame(!) window screenshot.
|
|
76
|
-
*
|
|
77
|
-
* @param {Logger} logger - A Logger instance.
|
|
78
|
-
* @param {EyesWebDriver} driver - The web driver used to get the screenshot.
|
|
79
|
-
* @param {MutableImage} image - The actual screenshot image.
|
|
80
|
-
* @param {RectangleSize} entireFrameSize - The full internal size of the frame.
|
|
81
|
-
* @return {Promise<EyesWebDriverScreenshot>}
|
|
82
|
-
*/
|
|
83
|
-
static async fromFrameSize(logger, driver, image, entireFrameSize) {
|
|
84
|
-
const screenshot = new EyesWebDriverScreenshot(logger, driver, image)
|
|
85
|
-
// The frame comprises the entire screenshot.
|
|
86
|
-
screenshot._screenshotType = ScreenshotType.ENTIRE_FRAME
|
|
87
|
-
|
|
88
|
-
screenshot._currentFrameScrollPosition = Location.ZERO
|
|
89
|
-
screenshot._frameLocationInScreenshot = Location.ZERO
|
|
90
|
-
screenshot._frameWindow = new Region(Location.ZERO, entireFrameSize)
|
|
91
|
-
screenshot._regionWindow = new Region(0, 0, 0, 0)
|
|
92
|
-
return screenshot
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Creates a frame(!) window screenshot.
|
|
97
|
-
*
|
|
98
|
-
* @param {Logger} logger - A Logger instance.
|
|
99
|
-
* @param {EyesWebDriver} driver - The web driver used to get the screenshot.
|
|
100
|
-
* @param {MutableImage} image - The actual screenshot image.
|
|
101
|
-
* @param {Region} screenshotRegion - The region of the screenshot.
|
|
102
|
-
* @return {Promise<EyesWebDriverScreenshot>}
|
|
103
|
-
*/
|
|
104
|
-
static async fromFrameRegion(logger, driver, image, screenshotRegion) {
|
|
105
|
-
const screenshot = new EyesWebDriverScreenshot(logger, driver, image)
|
|
106
|
-
// The frame comprises the entire screenshot.
|
|
107
|
-
screenshot._screenshotType = ScreenshotType.ENTIRE_FRAME
|
|
108
|
-
|
|
109
|
-
screenshot._currentFrameScrollPosition = Location.ZERO
|
|
110
|
-
screenshot._frameLocationInScreenshot = Location.ZERO
|
|
111
|
-
screenshot._frameWindow = new Region(Location.ZERO, screenshotRegion.getSize())
|
|
112
|
-
screenshot._regionWindow = new Region(screenshotRegion)
|
|
113
|
-
return screenshot
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Creates a frame(!) window screenshot from screenshot type and location.
|
|
118
|
-
*
|
|
119
|
-
* @param {Logger} logger - A Logger instance.
|
|
120
|
-
* @param {EyesWebDriver} driver - The web driver used to get the screenshot.
|
|
121
|
-
* @param {MutableImage} image - The actual screenshot image.
|
|
122
|
-
* @param {ScreenshotType} [screenshotType] - The screenshot's type (e.g., viewport/full page).
|
|
123
|
-
* @param {Location} [frameLocationInScreenshot[ The current frame's location in the screenshot.
|
|
124
|
-
* @return {Promise<EyesWebDriverScreenshot>}
|
|
125
|
-
*/
|
|
126
|
-
static async fromScreenshotType(
|
|
127
|
-
logger,
|
|
128
|
-
driver,
|
|
129
|
-
image,
|
|
130
|
-
screenshotType = ScreenshotType.VIEWPORT,
|
|
131
|
-
frameLocationInScreenshot = Location.ZERO,
|
|
132
|
-
) {
|
|
133
|
-
const screenshot = new EyesWebDriverScreenshot(logger, driver, image)
|
|
134
|
-
|
|
135
|
-
screenshot._screenshotType = await screenshot._updateScreenshotType(screenshotType, image)
|
|
136
|
-
|
|
137
|
-
let positionProvider = driver.getEyes().getCurrentFramePositionProvider()
|
|
138
|
-
if (!positionProvider) {
|
|
139
|
-
positionProvider = driver.getEyes().getPositionProvider()
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
screenshot._frameChain = driver.getFrameChain()
|
|
143
|
-
const frameSize = await screenshot._getFrameSize(positionProvider)
|
|
144
|
-
|
|
145
|
-
screenshot._currentFrameScrollPosition = await screenshot._getUpdatedScrollPosition(
|
|
146
|
-
positionProvider,
|
|
147
|
-
)
|
|
148
|
-
screenshot._frameLocationInScreenshot = await screenshot._getUpdatedFrameLocationInScreenshot(
|
|
149
|
-
frameLocationInScreenshot,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
logger.verbose('Calculating frame window...')
|
|
153
|
-
screenshot._frameWindow = new Region(screenshot._frameLocationInScreenshot, frameSize)
|
|
154
|
-
screenshot._frameWindow.intersect(new Region(0, 0, image.getWidth(), image.getHeight()))
|
|
155
|
-
|
|
156
|
-
if (screenshot._frameWindow.getWidth() <= 0 || screenshot._frameWindow.getHeight() <= 0) {
|
|
157
|
-
throw new Error('Got empty frame window for screenshot!')
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
screenshot._regionWindow = new Region(0, 0, 0, 0)
|
|
161
|
-
logger.verbose('Done!')
|
|
162
|
-
return screenshot
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* @private
|
|
167
|
-
* @return {Promise<Location>}
|
|
168
|
-
*/
|
|
169
|
-
async _getDefaultContentScrollPosition() {
|
|
170
|
-
const jsExecutor = new TestCafeExecutor(this._driver)
|
|
171
|
-
let defaultContentScrollPosition
|
|
172
|
-
if (this._frameChain.size() === 0) {
|
|
173
|
-
defaultContentScrollPosition = await this._getCurrentFrameScrollRootElement(jsExecutor)
|
|
174
|
-
} else {
|
|
175
|
-
const originalFC = new FrameChain(this._logger, this._frameChain)
|
|
176
|
-
const switchTo = this._driver.switchTo()
|
|
177
|
-
const currentFC = this._driver.getEyes().getOriginalFC()
|
|
178
|
-
await switchTo.frames(currentFC)
|
|
179
|
-
defaultContentScrollPosition = await this._getCurrentFrameScrollRootElement(jsExecutor)
|
|
180
|
-
await switchTo.frames(originalFC)
|
|
181
|
-
}
|
|
182
|
-
return defaultContentScrollPosition
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* @private
|
|
187
|
-
* @return {Promise<Location>}
|
|
188
|
-
*/
|
|
189
|
-
async _getCurrentFrameScrollRootElement(executor) {
|
|
190
|
-
const scrollRootElement = await this._driver.getEyes().getCurrentFrameScrollRootElement()
|
|
191
|
-
const positionProvider = new ScrollPositionProvider(this._logger, executor, scrollRootElement)
|
|
192
|
-
return positionProvider.getCurrentPosition()
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* @private
|
|
197
|
-
* @return {Promise<Location>}
|
|
198
|
-
*/
|
|
199
|
-
async _calcFrameLocationInScreenshot() {
|
|
200
|
-
const windowScroll = await this._getDefaultContentScrollPosition()
|
|
201
|
-
this._logger.verbose('Getting first frame...')
|
|
202
|
-
const firstFrame = this._frameChain.getFrame(0)
|
|
203
|
-
this._logger.verbose('Done!')
|
|
204
|
-
let locationInScreenshot = new Location(firstFrame.getLocation())
|
|
205
|
-
|
|
206
|
-
// We only consider scroll of the default content if this is a viewport screenshot.
|
|
207
|
-
if (this._screenshotType === ScreenshotType.VIEWPORT) {
|
|
208
|
-
locationInScreenshot = locationInScreenshot.offset(-windowScroll.getX(), -windowScroll.getY())
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
this._logger.verbose('Iterating over frames...')
|
|
212
|
-
let frame
|
|
213
|
-
for (let i = 1, l = this._frameChain.size(); i < l; i += 1) {
|
|
214
|
-
this._logger.verbose('Getting next frame...')
|
|
215
|
-
frame = this._frameChain.getFrame(i)
|
|
216
|
-
this._logger.verbose('Done!')
|
|
217
|
-
const frameLocation = frame.getLocation()
|
|
218
|
-
// For inner frames we must consider the scroll
|
|
219
|
-
const frameOriginalLocation = frame.getOriginalLocation()
|
|
220
|
-
// Offsetting the location in the screenshot
|
|
221
|
-
locationInScreenshot = locationInScreenshot.offset(
|
|
222
|
-
frameLocation.getX() - frameOriginalLocation.getX(),
|
|
223
|
-
frameLocation.getY() - frameOriginalLocation.getY(),
|
|
224
|
-
)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
this._logger.verbose('Done!')
|
|
228
|
-
return locationInScreenshot
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* @private
|
|
233
|
-
* @param {Location} frameLocationInScreenshot
|
|
234
|
-
* @return {Promise<Location>}
|
|
235
|
-
*/
|
|
236
|
-
async _getUpdatedFrameLocationInScreenshot(frameLocationInScreenshot) {
|
|
237
|
-
this._logger.verbose(`frameLocationInScreenshot: ${frameLocationInScreenshot}`)
|
|
238
|
-
|
|
239
|
-
if (this._frameChain.size() > 0) {
|
|
240
|
-
return this._calcFrameLocationInScreenshot()
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (!frameLocationInScreenshot) {
|
|
244
|
-
return new Location(Location.ZERO)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return frameLocationInScreenshot
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// noinspection JSMethodCanBeStatic
|
|
251
|
-
/**
|
|
252
|
-
* @private
|
|
253
|
-
* @param {PositionProvider} positionProvider
|
|
254
|
-
* @return {Promise<Location>}
|
|
255
|
-
*/
|
|
256
|
-
async _getUpdatedScrollPosition(positionProvider) {
|
|
257
|
-
try {
|
|
258
|
-
const currentPosition = await positionProvider.getCurrentPosition()
|
|
259
|
-
if (!currentPosition) {
|
|
260
|
-
return new Location(Location.ZERO)
|
|
261
|
-
}
|
|
262
|
-
return currentPosition
|
|
263
|
-
} catch (ignored) {
|
|
264
|
-
return new Location(Location.ZERO)
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* @private
|
|
270
|
-
* @param {PositionProvider} positionProvider
|
|
271
|
-
* @return {Promise<RectangleSize>}
|
|
272
|
-
*/
|
|
273
|
-
async _getFrameSize(positionProvider) {
|
|
274
|
-
if (this._frameChain.size() === 0) {
|
|
275
|
-
// get entire page size might throw an exception for applications which don't support Javascript (e.g., Appium).
|
|
276
|
-
// In that case we'll use the viewport size as the frame's size.
|
|
277
|
-
try {
|
|
278
|
-
return await positionProvider.getEntireSize()
|
|
279
|
-
} catch (ignored) {
|
|
280
|
-
return this._driver.getDefaultContentViewportSize()
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return this._frameChain.getCurrentFrameInnerSize()
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* @private
|
|
289
|
-
* @param {ScreenshotType} screenshotType
|
|
290
|
-
* @param {MutableImage} image
|
|
291
|
-
* @return {Promise<ScreenshotType>}
|
|
292
|
-
*/
|
|
293
|
-
async _updateScreenshotType(screenshotType, image) {
|
|
294
|
-
if (!screenshotType) {
|
|
295
|
-
let viewportSize = await this._driver.getEyes().getViewportSize()
|
|
296
|
-
const scaleViewport = this._driver.getEyes().shouldStitchContent()
|
|
297
|
-
|
|
298
|
-
if (scaleViewport) {
|
|
299
|
-
const pixelRatio = this._driver.getEyes().getDevicePixelRatio()
|
|
300
|
-
viewportSize = viewportSize.scale(pixelRatio)
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (
|
|
304
|
-
image.getWidth() <= viewportSize.getWidth() &&
|
|
305
|
-
image.getHeight() <= viewportSize.getHeight()
|
|
306
|
-
) {
|
|
307
|
-
return ScreenshotType.VIEWPORT
|
|
308
|
-
}
|
|
309
|
-
return ScreenshotType.ENTIRE_FRAME
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return screenshotType
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* @return {Region} - The region of the frame which is available in the screenshot, in screenshot coordinates.
|
|
317
|
-
*/
|
|
318
|
-
getFrameWindow() {
|
|
319
|
-
return this._frameWindow
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* @return {FrameChain} - A copy of the frame chain which was available when the screenshot was created.
|
|
324
|
-
*/
|
|
325
|
-
getFrameChain() {
|
|
326
|
-
return new FrameChain(this._logger, this._frameChain)
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// noinspection JSUnusedGlobalSymbols
|
|
330
|
-
/**
|
|
331
|
-
* Returns a part of the screenshot based on the given region.
|
|
332
|
-
*
|
|
333
|
-
* @override
|
|
334
|
-
* @param {Region} region - The region for which we should get the sub screenshot.
|
|
335
|
-
* @param {boolean} throwIfClipped - Throw an EyesException if the region is not fully contained in the screenshot.
|
|
336
|
-
* @return {Promise<EyesWebDriverScreenshot>} - A screenshot instance containing the given region.
|
|
337
|
-
*/
|
|
338
|
-
async getSubScreenshot(region, throwIfClipped) {
|
|
339
|
-
this._logger.verbose(`getSubScreenshot([${region}], ${throwIfClipped})`)
|
|
340
|
-
|
|
341
|
-
ArgumentGuard.notNull(region, 'region')
|
|
342
|
-
|
|
343
|
-
// We calculate intersection based on as-is coordinates.
|
|
344
|
-
const asIsSubScreenshotRegion = this.getIntersectedRegion(
|
|
345
|
-
region,
|
|
346
|
-
CoordinatesType.SCREENSHOT_AS_IS,
|
|
347
|
-
)
|
|
348
|
-
|
|
349
|
-
if (
|
|
350
|
-
asIsSubScreenshotRegion.isSizeEmpty() ||
|
|
351
|
-
(throwIfClipped && !asIsSubScreenshotRegion.getSize().equals(region.getSize()))
|
|
352
|
-
) {
|
|
353
|
-
throw new OutOfBoundsError(
|
|
354
|
-
`Region [${region}] is out of screenshot bounds [${this._frameWindow}]`,
|
|
355
|
-
)
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const subScreenshotImage = await this._image.getImagePart(asIsSubScreenshotRegion)
|
|
359
|
-
const result = await EyesWebDriverScreenshot.fromFrameRegion(
|
|
360
|
-
this._logger,
|
|
361
|
-
this._driver,
|
|
362
|
-
subScreenshotImage,
|
|
363
|
-
new Region(
|
|
364
|
-
region.getLeft(),
|
|
365
|
-
region.getRight(),
|
|
366
|
-
subScreenshotImage.getWidth(),
|
|
367
|
-
subScreenshotImage.getHeight(),
|
|
368
|
-
),
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
this._logger.verbose('Done!')
|
|
372
|
-
return result
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// noinspection JSUnusedGlobalSymbols
|
|
376
|
-
/**
|
|
377
|
-
* Returns a part of the screenshot based on the given region.
|
|
378
|
-
*
|
|
379
|
-
* @override
|
|
380
|
-
* @param {Region} region - The region for which we should get the sub screenshot.
|
|
381
|
-
* @param {boolean} throwIfClipped - Throw an EyesException if the region is not fully contained in the screenshot.
|
|
382
|
-
* @return {Promise<EyesWebDriverScreenshot>} - A screenshot instance containing the given region.
|
|
383
|
-
*/
|
|
384
|
-
async getSubScreenshotForRegion(region, throwIfClipped) {
|
|
385
|
-
this._logger.verbose(`getSubScreenshotForRegion([${region}], ${throwIfClipped})`)
|
|
386
|
-
|
|
387
|
-
ArgumentGuard.notNull(region, 'region')
|
|
388
|
-
|
|
389
|
-
// We calculate intersection based on as-is coordinates.
|
|
390
|
-
const asIsSubScreenshotRegion = this.getIntersectedRegion(
|
|
391
|
-
region,
|
|
392
|
-
CoordinatesType.SCREENSHOT_AS_IS,
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
asIsSubScreenshotRegion.isEmpty() ||
|
|
397
|
-
(throwIfClipped && !asIsSubScreenshotRegion.getSize().equals(region.getSize()))
|
|
398
|
-
) {
|
|
399
|
-
throw new OutOfBoundsError(
|
|
400
|
-
`Region [${region}] is out of screenshot bounds [${this._frameWindow}]`,
|
|
401
|
-
)
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const subScreenshotImage = await this._image.getImagePart(asIsSubScreenshotRegion)
|
|
405
|
-
const result = await EyesWebDriverScreenshot.fromFrameRegion(
|
|
406
|
-
this._logger,
|
|
407
|
-
this._driver,
|
|
408
|
-
subScreenshotImage,
|
|
409
|
-
new Region(
|
|
410
|
-
region.getLocation(),
|
|
411
|
-
new RectangleSize(subScreenshotImage.getWidth(), subScreenshotImage.getHeight()),
|
|
412
|
-
),
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
this._logger.verbose('Done!')
|
|
416
|
-
return result
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// noinspection JSUnusedGlobalSymbols
|
|
420
|
-
/**
|
|
421
|
-
* Converts a location's coordinates with the {@code from} coordinates type to the {@code to} coordinates type.
|
|
422
|
-
*
|
|
423
|
-
* @override
|
|
424
|
-
* @param {Location} location - The location which coordinates needs to be converted.
|
|
425
|
-
* @param {CoordinatesType} from - The current coordinates type for {@code location}.
|
|
426
|
-
* @param {CoordinatesType} to - The target coordinates type for {@code location}.
|
|
427
|
-
* @return {Location} - A new location which is the transformation of {@code location} to the {@code to} coordinates
|
|
428
|
-
* type.
|
|
429
|
-
*/
|
|
430
|
-
convertLocation(location, from, to) {
|
|
431
|
-
ArgumentGuard.notNull(location, 'location')
|
|
432
|
-
ArgumentGuard.notNull(from, 'from')
|
|
433
|
-
ArgumentGuard.notNull(to, 'to')
|
|
434
|
-
|
|
435
|
-
let result = new Location(location)
|
|
436
|
-
|
|
437
|
-
if (from === to) {
|
|
438
|
-
return result
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// If we're not inside a frame, and the screenshot is the entire page, then the context as-is/relative
|
|
442
|
-
// are the same (notice screenshot as-is might be different, e.g., if it is actually a sub-screenshot of a region).
|
|
443
|
-
if (this._frameChain.size() === 0 && this._screenshotType === ScreenshotType.ENTIRE_FRAME) {
|
|
444
|
-
if (
|
|
445
|
-
(from === CoordinatesType.CONTEXT_RELATIVE || from === CoordinatesType.CONTEXT_AS_IS) &&
|
|
446
|
-
to === CoordinatesType.SCREENSHOT_AS_IS
|
|
447
|
-
) {
|
|
448
|
-
// If this is not a sub-screenshot, this will have no effect.
|
|
449
|
-
result = result.offset(
|
|
450
|
-
this._frameLocationInScreenshot.getX(),
|
|
451
|
-
this._frameLocationInScreenshot.getY(),
|
|
452
|
-
)
|
|
453
|
-
|
|
454
|
-
// If this is not a region subscreenshot, this will have no effect.
|
|
455
|
-
result = result.offset(-this._regionWindow.getLeft(), -this._regionWindow.getTop())
|
|
456
|
-
} else if (
|
|
457
|
-
from === CoordinatesType.SCREENSHOT_AS_IS &&
|
|
458
|
-
(to === CoordinatesType.CONTEXT_RELATIVE || to === CoordinatesType.CONTEXT_AS_IS)
|
|
459
|
-
) {
|
|
460
|
-
result = result.offset(
|
|
461
|
-
-this._frameLocationInScreenshot.getX(),
|
|
462
|
-
-this._frameLocationInScreenshot.getY(),
|
|
463
|
-
)
|
|
464
|
-
}
|
|
465
|
-
return result
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
switch (from) {
|
|
469
|
-
case CoordinatesType.CONTEXT_AS_IS: {
|
|
470
|
-
switch (to) {
|
|
471
|
-
case CoordinatesType.CONTEXT_RELATIVE:
|
|
472
|
-
result = result.offset(
|
|
473
|
-
this._currentFrameScrollPosition.getX(),
|
|
474
|
-
this._currentFrameScrollPosition.getY(),
|
|
475
|
-
)
|
|
476
|
-
break
|
|
477
|
-
case CoordinatesType.SCREENSHOT_AS_IS:
|
|
478
|
-
result = result.offset(
|
|
479
|
-
this._frameLocationInScreenshot.getX(),
|
|
480
|
-
this._frameLocationInScreenshot.getY(),
|
|
481
|
-
)
|
|
482
|
-
break
|
|
483
|
-
default:
|
|
484
|
-
throw new CoordinatesTypeConversionError(from, to)
|
|
485
|
-
}
|
|
486
|
-
break
|
|
487
|
-
}
|
|
488
|
-
case CoordinatesType.CONTEXT_RELATIVE: {
|
|
489
|
-
switch (to) {
|
|
490
|
-
case CoordinatesType.SCREENSHOT_AS_IS:
|
|
491
|
-
// First, convert context-relative to context-as-is.
|
|
492
|
-
result = result.offset(
|
|
493
|
-
-this._currentFrameScrollPosition.getX(),
|
|
494
|
-
-this._currentFrameScrollPosition.getY(),
|
|
495
|
-
)
|
|
496
|
-
// Now convert context-as-is to screenshot-as-is.
|
|
497
|
-
result = result.offset(
|
|
498
|
-
this._frameLocationInScreenshot.getX(),
|
|
499
|
-
this._frameLocationInScreenshot.getY(),
|
|
500
|
-
)
|
|
501
|
-
break
|
|
502
|
-
case CoordinatesType.CONTEXT_AS_IS:
|
|
503
|
-
result = result.offset(
|
|
504
|
-
-this._currentFrameScrollPosition.getX(),
|
|
505
|
-
-this._currentFrameScrollPosition.getY(),
|
|
506
|
-
)
|
|
507
|
-
break
|
|
508
|
-
default:
|
|
509
|
-
throw new CoordinatesTypeConversionError(from, to)
|
|
510
|
-
}
|
|
511
|
-
break
|
|
512
|
-
}
|
|
513
|
-
case CoordinatesType.SCREENSHOT_AS_IS: {
|
|
514
|
-
switch (to) {
|
|
515
|
-
case CoordinatesType.CONTEXT_RELATIVE:
|
|
516
|
-
// First convert to context-as-is.
|
|
517
|
-
result = result.offset(
|
|
518
|
-
-this._frameLocationInScreenshot.getX(),
|
|
519
|
-
-this._frameLocationInScreenshot.getY(),
|
|
520
|
-
)
|
|
521
|
-
// Now convert to context-relative.
|
|
522
|
-
result = result.offset(
|
|
523
|
-
this._currentFrameScrollPosition.getX(),
|
|
524
|
-
this._currentFrameScrollPosition.getY(),
|
|
525
|
-
)
|
|
526
|
-
break
|
|
527
|
-
case CoordinatesType.CONTEXT_AS_IS:
|
|
528
|
-
result = result.offset(
|
|
529
|
-
-this._frameLocationInScreenshot.getX(),
|
|
530
|
-
-this._frameLocationInScreenshot.getY(),
|
|
531
|
-
)
|
|
532
|
-
break
|
|
533
|
-
default:
|
|
534
|
-
throw new CoordinatesTypeConversionError(from, to)
|
|
535
|
-
}
|
|
536
|
-
break
|
|
537
|
-
}
|
|
538
|
-
default: {
|
|
539
|
-
throw new CoordinatesTypeConversionError(from, to)
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
return result
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// noinspection JSUnusedGlobalSymbols
|
|
546
|
-
/**
|
|
547
|
-
* @override
|
|
548
|
-
* @param {Location} location
|
|
549
|
-
* @param {CoordinatesType} coordinatesType
|
|
550
|
-
* @return {Location}
|
|
551
|
-
*/
|
|
552
|
-
getLocationInScreenshot(location, coordinatesType) {
|
|
553
|
-
this._location = this.convertLocation(
|
|
554
|
-
location,
|
|
555
|
-
coordinatesType,
|
|
556
|
-
CoordinatesType.SCREENSHOT_AS_IS,
|
|
557
|
-
)
|
|
558
|
-
|
|
559
|
-
// Making sure it's within the screenshot bounds
|
|
560
|
-
if (!this._frameWindow.contains(location)) {
|
|
561
|
-
throw new OutOfBoundsError(
|
|
562
|
-
`Location ${location} ('${coordinatesType}') is not visible in screenshot!`,
|
|
563
|
-
)
|
|
564
|
-
}
|
|
565
|
-
return this._location
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* @override
|
|
570
|
-
* @param {Region} region
|
|
571
|
-
* @param {CoordinatesType} resultCoordinatesType
|
|
572
|
-
* @return {Region}
|
|
573
|
-
*/
|
|
574
|
-
getIntersectedRegion(region, resultCoordinatesType) {
|
|
575
|
-
if (region.isEmpty()) {
|
|
576
|
-
return new Region(region)
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
const originalCoordinatesType = region.getCoordinatesType()
|
|
580
|
-
let intersectedRegion = this.convertRegionLocation(
|
|
581
|
-
region,
|
|
582
|
-
originalCoordinatesType,
|
|
583
|
-
CoordinatesType.SCREENSHOT_AS_IS,
|
|
584
|
-
)
|
|
585
|
-
|
|
586
|
-
switch (originalCoordinatesType) {
|
|
587
|
-
// If the request was context based, we intersect with the frame window.
|
|
588
|
-
case CoordinatesType.CONTEXT_AS_IS:
|
|
589
|
-
case CoordinatesType.CONTEXT_RELATIVE:
|
|
590
|
-
intersectedRegion.intersect(this._frameWindow)
|
|
591
|
-
break
|
|
592
|
-
// If the request is screenshot based, we intersect with the image
|
|
593
|
-
case CoordinatesType.SCREENSHOT_AS_IS:
|
|
594
|
-
intersectedRegion.intersect(
|
|
595
|
-
new Region(0, 0, this._image.getWidth(), this._image.getHeight()),
|
|
596
|
-
)
|
|
597
|
-
break
|
|
598
|
-
default:
|
|
599
|
-
throw new CoordinatesTypeConversionError(
|
|
600
|
-
`Unknown coordinates type: '${originalCoordinatesType}'`,
|
|
601
|
-
)
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// If the intersection is empty we don't want to convert the coordinates.
|
|
605
|
-
if (intersectedRegion.isEmpty()) {
|
|
606
|
-
return intersectedRegion
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
// Converting the result to the required coordinates type.
|
|
610
|
-
intersectedRegion = this.convertRegionLocation(
|
|
611
|
-
intersectedRegion,
|
|
612
|
-
CoordinatesType.SCREENSHOT_AS_IS,
|
|
613
|
-
resultCoordinatesType,
|
|
614
|
-
)
|
|
615
|
-
return intersectedRegion
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
// noinspection JSUnusedGlobalSymbols
|
|
619
|
-
/**
|
|
620
|
-
* Gets the elements region in the screenshot.
|
|
621
|
-
*
|
|
622
|
-
* @param {WebElement} element - The element which region we want to intersect.
|
|
623
|
-
* @return {Promise<Region>} - The intersected region, in {@code SCREENSHOT_AS_IS} coordinates type.
|
|
624
|
-
*/
|
|
625
|
-
async getIntersectedRegionFromElement(element) {
|
|
626
|
-
ArgumentGuard.notNull(element, 'element')
|
|
627
|
-
|
|
628
|
-
const rect = await element.getRect()
|
|
629
|
-
|
|
630
|
-
// Since the element coordinates are in context relative
|
|
631
|
-
let elementRegion = new Region(rect.x, rect.y, rect.width, rect.height)
|
|
632
|
-
|
|
633
|
-
// Since the element coordinates are in context relative
|
|
634
|
-
elementRegion = this.getIntersectedRegion(elementRegion, CoordinatesType.CONTEXT_RELATIVE)
|
|
635
|
-
|
|
636
|
-
if (!elementRegion.isEmpty()) {
|
|
637
|
-
elementRegion = this.convertRegionLocation(
|
|
638
|
-
elementRegion,
|
|
639
|
-
CoordinatesType.CONTEXT_RELATIVE,
|
|
640
|
-
CoordinatesType.SCREENSHOT_AS_IS,
|
|
641
|
-
)
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
return elementRegion
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
EyesWebDriverScreenshot.ScreenshotType = Object.freeze(ScreenshotType)
|
|
649
|
-
exports.EyesWebDriverScreenshot = EyesWebDriverScreenshot
|
|
650
|
-
exports.ScreenshotType = ScreenshotType
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {EyesScreenshotFactory} = require('@applitools/eyes-sdk-core')
|
|
4
|
-
|
|
5
|
-
const {EyesWebDriverScreenshot} = require('./EyesWebDriverScreenshot')
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Encapsulates the instantiation of an {@link EyesWebDriverScreenshot} .
|
|
9
|
-
*
|
|
10
|
-
* @ignore
|
|
11
|
-
*/
|
|
12
|
-
class EyesWebDriverScreenshotFactory extends EyesScreenshotFactory {
|
|
13
|
-
/**
|
|
14
|
-
* @param {Logger} logger
|
|
15
|
-
* @param {EyesWebDriver} driver
|
|
16
|
-
*/
|
|
17
|
-
constructor(logger, driver) {
|
|
18
|
-
super()
|
|
19
|
-
|
|
20
|
-
this._logger = logger
|
|
21
|
-
this._driver = driver
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @inheritDoc
|
|
26
|
-
*/
|
|
27
|
-
async makeScreenshot(image) {
|
|
28
|
-
return EyesWebDriverScreenshot.fromScreenshotType(this._logger, this._driver, image)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
exports.EyesWebDriverScreenshotFactory = EyesWebDriverScreenshotFactory
|