@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.
- package/CHANGELOG.md +467 -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,571 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {Selector} = require('testcafe')
|
|
4
|
-
const {ArgumentGuard, /* MutableImage, */ GeneralUtils} = require('@applitools/eyes-common')
|
|
5
|
-
|
|
6
|
-
const fs = require('fs')
|
|
7
|
-
const path = require('path')
|
|
8
|
-
const rmrf = require('rimraf')
|
|
9
|
-
|
|
10
|
-
const {ClientFunction} = require('testcafe')
|
|
11
|
-
const {FrameChain} = require('../frames/FrameChain')
|
|
12
|
-
const {EyesTestcafeUtils} = require('../EyesTestcafeUtils')
|
|
13
|
-
const {EyesWebElement} = require('./EyesWebElement')
|
|
14
|
-
// const {EyesWebElementPromise} = require('./EyesWebElementPromise')
|
|
15
|
-
const {EyesTargetLocator} = require('./EyesTargetLocator')
|
|
16
|
-
const {TestCafeExecutor} = require('../TestCafeExecutor')
|
|
17
|
-
|
|
18
|
-
const SCREENSHOTS_PATH = '/.applitools__screenshots'
|
|
19
|
-
const getViewport = () => ({
|
|
20
|
-
// eslint-disable-next-line no-undef
|
|
21
|
-
width: Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
|
|
22
|
-
// eslint-disable-next-line no-undef
|
|
23
|
-
height: Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* An Eyes implementation of the interfaces implemented by {@link IWebDriver}.
|
|
28
|
-
* Used so we'll be able to return the users an object with the same functionality as {@link WebDriver}.
|
|
29
|
-
*
|
|
30
|
-
* @extends {WebDriver}
|
|
31
|
-
* @implements {EyesJsExecutor}
|
|
32
|
-
*/
|
|
33
|
-
class EyesWebDriver {
|
|
34
|
-
/**
|
|
35
|
-
* @param {Logger} logger
|
|
36
|
-
* @param {Eyes} eyes
|
|
37
|
-
* @param {WebDriver} driver
|
|
38
|
-
*/
|
|
39
|
-
constructor(logger, eyes, driver) {
|
|
40
|
-
ArgumentGuard.notNull(logger, 'logger')
|
|
41
|
-
ArgumentGuard.notNull(eyes, 'eyes')
|
|
42
|
-
ArgumentGuard.notNull(driver, 'driver')
|
|
43
|
-
|
|
44
|
-
this._logger = logger
|
|
45
|
-
this._eyes = eyes
|
|
46
|
-
this._driver = driver
|
|
47
|
-
|
|
48
|
-
this._elementsIds = new Map()
|
|
49
|
-
this._frameChain = new FrameChain(logger)
|
|
50
|
-
|
|
51
|
-
/** @type {ImageRotation} */
|
|
52
|
-
this._rotation = null
|
|
53
|
-
/** @type {RectangleSize} */
|
|
54
|
-
this._defaultContentViewportSize = null
|
|
55
|
-
|
|
56
|
-
this._executor = new TestCafeExecutor(driver)
|
|
57
|
-
this._clientFunctions = {}
|
|
58
|
-
|
|
59
|
-
// this._logger.verbose("Driver session is " + this.getSessionId());
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// noinspection JSUnusedGlobalSymbols
|
|
63
|
-
/**
|
|
64
|
-
* @return {Eyes}
|
|
65
|
-
*/
|
|
66
|
-
getEyes() {
|
|
67
|
-
return this._eyes
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @return {WebDriver}
|
|
72
|
-
*/
|
|
73
|
-
getRemoteWebDriver() {
|
|
74
|
-
// noinspection JSUnresolvedVariable
|
|
75
|
-
return this._driver.driver || this._driver
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @inheritDoc
|
|
80
|
-
*/
|
|
81
|
-
execute(command) {
|
|
82
|
-
return this._driver.execute(command)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @inheritDoc
|
|
87
|
-
*/
|
|
88
|
-
setFileDetector(detector) {
|
|
89
|
-
return this._driver.setFileDetector(detector)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @inheritDoc
|
|
94
|
-
*/
|
|
95
|
-
getExecutor() {
|
|
96
|
-
return this._driver.getExecutor()
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
getDriver() {
|
|
100
|
-
return this._driver
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @inheritDoc
|
|
105
|
-
*/
|
|
106
|
-
getSession() {
|
|
107
|
-
return this._driver.getSession()
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* @inheritDoc
|
|
112
|
-
*/
|
|
113
|
-
getCapabilities() {
|
|
114
|
-
return this._driver.getCapabilities()
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @inheritDoc
|
|
119
|
-
*/
|
|
120
|
-
quit() {
|
|
121
|
-
return this._driver.quit()
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* @inheritDoc
|
|
126
|
-
*/
|
|
127
|
-
actions(options) {
|
|
128
|
-
return this._driver.actions(options)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* @inheritDoc
|
|
133
|
-
*/
|
|
134
|
-
touchActions() {
|
|
135
|
-
return this._driver.touchActions()
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* @inheritDoc
|
|
140
|
-
*/
|
|
141
|
-
|
|
142
|
-
async executeScript(script, ...varArgs) {
|
|
143
|
-
EyesTestcafeUtils.handleSpecialCommands(script, ...varArgs)
|
|
144
|
-
return this._executor.executeScript(script, ...varArgs)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* @inheritDoc
|
|
149
|
-
*/
|
|
150
|
-
executeAsyncScript(script, ...varArgs) {
|
|
151
|
-
EyesTestcafeUtils.handleSpecialCommands(script, ...varArgs)
|
|
152
|
-
return this._driver.executeAsyncScript(script, ...varArgs)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* @inheritDoc
|
|
157
|
-
*/
|
|
158
|
-
call(fn, optScope, ...varArgs) {
|
|
159
|
-
return this._driver.call(fn, optScope, ...varArgs)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* @inheritDoc
|
|
164
|
-
*/
|
|
165
|
-
wait(condition, optTimeout, optMessage) {
|
|
166
|
-
return this._driver.wait(condition, optTimeout, optMessage)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @inheritDoc
|
|
171
|
-
*/
|
|
172
|
-
sleep(ms) {
|
|
173
|
-
return this._driver.sleep(ms)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* @inheritDoc
|
|
178
|
-
*/
|
|
179
|
-
getWindowHandle() {
|
|
180
|
-
return this._driver.getWindowHandle()
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* @inheritDoc
|
|
185
|
-
*/
|
|
186
|
-
getAllWindowHandles() {
|
|
187
|
-
return this._driver.getAllWindowHandles()
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* @inheritDoc
|
|
192
|
-
*/
|
|
193
|
-
getPageSource() {
|
|
194
|
-
return this._driver.getPageSource()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* @inheritDoc
|
|
199
|
-
*/
|
|
200
|
-
close() {
|
|
201
|
-
return this._driver.close()
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* @inheritDoc
|
|
206
|
-
*/
|
|
207
|
-
get(url) {
|
|
208
|
-
this._frameChain.clear()
|
|
209
|
-
return this._driver.get(url)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* @inheritDoc
|
|
214
|
-
*/
|
|
215
|
-
getCurrentUrl() {
|
|
216
|
-
// eslint-disable-next-line no-undef
|
|
217
|
-
return this._evalWithDriver(() => window.location.href)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* @inheritDoc
|
|
222
|
-
*/
|
|
223
|
-
async getTitle() {
|
|
224
|
-
return Selector('title').with({boundTestRun: this._driver}).innerText
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// noinspection JSCheckFunctionSignatures
|
|
228
|
-
/**
|
|
229
|
-
* @inheritDoc
|
|
230
|
-
* @param {!(By|Function)} locator The locator strategy to use when searching for the element.
|
|
231
|
-
* @return {EyesWebElementPromise} - A promise that will resolve to a EyesWebElement.
|
|
232
|
-
*/
|
|
233
|
-
findElement(locator) {
|
|
234
|
-
return Selector(locator).with({boundTestRun: this._driver})
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// noinspection JSCheckFunctionSignatures
|
|
238
|
-
/**
|
|
239
|
-
* @inheritDoc
|
|
240
|
-
* @param {!(By|Function)} locator The locator strategy to use when searching for the element.
|
|
241
|
-
* @return {!Promise<!Array<!EyesWebElement>>} - A promise that will be resolved to an array of the located
|
|
242
|
-
* {@link EyesWebElement}s.
|
|
243
|
-
*/
|
|
244
|
-
async findElements(locator) {
|
|
245
|
-
const elements = await Selector(locator).with({boundTestRun: this._driver})
|
|
246
|
-
return elements.map(element => {
|
|
247
|
-
element = new EyesWebElement(this._logger, this, element)
|
|
248
|
-
// For Remote web elements, we can keep the IDs
|
|
249
|
-
this._elementsIds.set(element.getId(), element)
|
|
250
|
-
return element
|
|
251
|
-
})
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* @inheritDoc
|
|
256
|
-
*/
|
|
257
|
-
async takeScreenshot() {
|
|
258
|
-
this._logger.log('Getting screenshot from TestCafe')
|
|
259
|
-
const filename = Math.random()
|
|
260
|
-
.toString()
|
|
261
|
-
.slice(2)
|
|
262
|
-
const filepath = path.resolve(SCREENSHOTS_PATH, filename)
|
|
263
|
-
const screenshotPath = await this._driver.takeScreenshot(filepath)
|
|
264
|
-
if (!screenshotPath) {
|
|
265
|
-
throw new Error('Failed to get Testcafe screenshot')
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
this._logger.log('screenshot created at', screenshotPath)
|
|
269
|
-
try {
|
|
270
|
-
return fs.readFileSync(screenshotPath)
|
|
271
|
-
} finally {
|
|
272
|
-
const screenshotFolder = path.dirname(screenshotPath)
|
|
273
|
-
rmrf.sync(screenshotFolder)
|
|
274
|
-
this._logger.log('screenshot folder deleted at', screenshotFolder)
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
async getViewport() {
|
|
279
|
-
return this._executor.executeScript(getViewport)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
async resizeWindow(width, height) {
|
|
283
|
-
return this._driver.resizeWindow(width, height)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* @inheritDoc
|
|
288
|
-
*/
|
|
289
|
-
navigate() {
|
|
290
|
-
return this._driver.navigate()
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* @inheritDoc
|
|
295
|
-
* @return {EyesTargetLocator} - The target locator interface for this instance.
|
|
296
|
-
*/
|
|
297
|
-
switchTo() {
|
|
298
|
-
return new EyesTargetLocator(this._logger, this)
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Found elements are sometimes accessed by their IDs (e.g. tapping an element in Appium).
|
|
303
|
-
*
|
|
304
|
-
* @return {Map<string, WebElement>} - Maps of IDs for found elements.
|
|
305
|
-
*/
|
|
306
|
-
getElementIds() {
|
|
307
|
-
return this._elementsIds
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// noinspection JSUnusedGlobalSymbols
|
|
311
|
-
/**
|
|
312
|
-
* @return {ImageRotation} - The image rotation data.
|
|
313
|
-
*/
|
|
314
|
-
getRotation() {
|
|
315
|
-
return this._rotation
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* @param {ImageRotation} rotation - The image rotation data.
|
|
320
|
-
*/
|
|
321
|
-
setRotation(rotation) {
|
|
322
|
-
this._rotation = rotation
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// noinspection JSUnusedGlobalSymbols
|
|
326
|
-
/**
|
|
327
|
-
* @param {string} className
|
|
328
|
-
* @return {EyesWebElementPromise} - A promise that will resolve to a EyesWebElement.
|
|
329
|
-
*/
|
|
330
|
-
findElementByClassName(className) {
|
|
331
|
-
// noinspection JSCheckFunctionSignatures
|
|
332
|
-
return this.findElement(toClassName(className))
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// noinspection JSUnusedGlobalSymbols
|
|
336
|
-
/**
|
|
337
|
-
* @param {string} className
|
|
338
|
-
* @return {!Promise<!Array<!EyesWebElement>>} - A promise that will resolve to an array of EyesWebElements.
|
|
339
|
-
*/
|
|
340
|
-
findElementsByClassName(className) {
|
|
341
|
-
// noinspection JSCheckFunctionSignatures
|
|
342
|
-
return this.findElements(toClassName(className))
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// noinspection JSUnusedGlobalSymbols
|
|
346
|
-
/**
|
|
347
|
-
* @param {string} cssSelector
|
|
348
|
-
* @return {EyesWebElementPromise} - A promise that will resolve to a EyesWebElement.
|
|
349
|
-
*/
|
|
350
|
-
findElementByCssSelector(cssSelector) {
|
|
351
|
-
// noinspection JSCheckFunctionSignatures
|
|
352
|
-
return this.findElement(cssSelector)
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// noinspection JSUnusedGlobalSymbols
|
|
356
|
-
/**
|
|
357
|
-
* @param {string} cssSelector
|
|
358
|
-
* @return {!Promise<!Array<!EyesWebElement>>} - A promise that will resolve to an array of EyesWebElements.
|
|
359
|
-
*/
|
|
360
|
-
findElementsByCssSelector(cssSelector) {
|
|
361
|
-
// noinspection JSCheckFunctionSignatures
|
|
362
|
-
return this.findElements(cssSelector)
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// noinspection JSUnusedGlobalSymbols
|
|
366
|
-
/**
|
|
367
|
-
* @param {string} id
|
|
368
|
-
* @return {EyesWebElementPromise} - A promise that will resolve to a EyesWebElement.
|
|
369
|
-
*/
|
|
370
|
-
findElementById(id) {
|
|
371
|
-
// noinspection JSCheckFunctionSignatures
|
|
372
|
-
return this.findElement(`#${escapeCss(id)}`)
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// noinspection JSUnusedGlobalSymbols
|
|
376
|
-
/**
|
|
377
|
-
* @param {string} id
|
|
378
|
-
* @return {!Promise<!Array<!EyesWebElement>>} - A promise that will resolve to an array of EyesWebElements.
|
|
379
|
-
*/
|
|
380
|
-
findElementsById(id) {
|
|
381
|
-
// noinspection JSCheckFunctionSignatures
|
|
382
|
-
return this.findElements(`#${escapeCss(id)}`)
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// noinspection JSUnusedGlobalSymbols
|
|
386
|
-
/**
|
|
387
|
-
* @param {string} name
|
|
388
|
-
* @return {!Promise<!Array<!EyesWebElement>>} - A promise that will resolve to an array of EyesWebElements.
|
|
389
|
-
*/
|
|
390
|
-
findElementsByName(name) {
|
|
391
|
-
// noinspection JSCheckFunctionSignatures
|
|
392
|
-
return this.findElements(`*[name="${escapeCss(name)}"]`)
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* @param {boolean} [forceQuery=true] - If true, we will perform the query even if we have a cached viewport size.
|
|
397
|
-
* @return {Promise<RectangleSize>} - The viewport size of the default content (outer most frame).
|
|
398
|
-
*/
|
|
399
|
-
async getDefaultContentViewportSize(forceQuery = true) {
|
|
400
|
-
this._logger.verbose('getDefaultContentViewportSize()')
|
|
401
|
-
if (this._defaultContentViewportSize && !forceQuery) {
|
|
402
|
-
this._logger.verbose('Using cached viewport size: ', this._defaultContentViewportSize)
|
|
403
|
-
return this._defaultContentViewportSize
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
const switchTo = this.switchTo()
|
|
407
|
-
const currentFrames = this._frameChain.clone()
|
|
408
|
-
|
|
409
|
-
// Optimization
|
|
410
|
-
if (currentFrames.size() > 0) {
|
|
411
|
-
await switchTo.defaultContent()
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
this._logger.verbose('Extracting viewport size...')
|
|
415
|
-
this._defaultContentViewportSize = await EyesTestcafeUtils.getViewportSizeOrDisplaySize(
|
|
416
|
-
this._logger,
|
|
417
|
-
this._driver,
|
|
418
|
-
)
|
|
419
|
-
this._logger.verbose('Done! Viewport size: ', this._defaultContentViewportSize)
|
|
420
|
-
|
|
421
|
-
if (currentFrames.size() > 0) {
|
|
422
|
-
await switchTo.frames(currentFrames)
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
return this._defaultContentViewportSize
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* @return {FrameChain} - The current frame chain.
|
|
430
|
-
*/
|
|
431
|
-
getFrameChain() {
|
|
432
|
-
return this._frameChain
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* @return {Promise<string>}
|
|
437
|
-
*/
|
|
438
|
-
async getUserAgent() {
|
|
439
|
-
try {
|
|
440
|
-
// eslint-disable-next-line no-undef
|
|
441
|
-
const userAgent = await this._evalWithDriver(() => navigator.userAgent, 'getUserAgent')()
|
|
442
|
-
this._logger.verbose(`user agent: ${userAgent}`)
|
|
443
|
-
return userAgent
|
|
444
|
-
} catch (err) {
|
|
445
|
-
this._logger.verbose(`Failed to obtain user-agent string ${err}`)
|
|
446
|
-
return null
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
_evalWithDriver(func, functionName) {
|
|
451
|
-
if (!this._clientFunctions[functionName]) {
|
|
452
|
-
this._clientFunctions[functionName] = ClientFunction(func)
|
|
453
|
-
}
|
|
454
|
-
return this._clientFunctions[functionName].with({boundTestRun: this._driver})
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// noinspection JSUnusedGlobalSymbols
|
|
458
|
-
/**
|
|
459
|
-
* @return {Promise<string>} - A copy of the current frame chain.
|
|
460
|
-
*/
|
|
461
|
-
async getSessionId() {
|
|
462
|
-
return String(Math.random()).slice(2)
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Returns {@code true} if current WebDriver is mobile web driver (Android or IOS)
|
|
467
|
-
*
|
|
468
|
-
* @package
|
|
469
|
-
* @return {boolean}
|
|
470
|
-
*/
|
|
471
|
-
async isMobile() {
|
|
472
|
-
// TODO
|
|
473
|
-
return false
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* @override
|
|
478
|
-
*/
|
|
479
|
-
toString() {
|
|
480
|
-
return GeneralUtils.toString(this, ['_logger', '_eyes'])
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* Rotates the image as necessary. The rotation is either manually forced by passing a non-null ImageRotation, or
|
|
485
|
-
* automatically inferred.
|
|
486
|
-
*
|
|
487
|
-
* @param {Logger} logger - The underlying driver which produced the screenshot.
|
|
488
|
-
* @param {IWebDriver} driver - The underlying driver which produced the screenshot.
|
|
489
|
-
* @param {MutableImage} image - The image to normalize.
|
|
490
|
-
* @param {ImageRotation} rotation - The degrees by which to rotate the image: positive values = clockwise rotation,
|
|
491
|
-
* negative values = counter-clockwise, 0 = force no rotation, null = rotate automatically as needed.
|
|
492
|
-
* @return {Promise<MutableImage>} - A normalized image.
|
|
493
|
-
*/
|
|
494
|
-
static async normalizeRotation(logger, driver, image, rotation) {
|
|
495
|
-
ArgumentGuard.notNull(logger, 'logger')
|
|
496
|
-
ArgumentGuard.notNull(driver, 'driver')
|
|
497
|
-
ArgumentGuard.notNull(image, 'image')
|
|
498
|
-
|
|
499
|
-
let degrees
|
|
500
|
-
if (rotation) {
|
|
501
|
-
degrees = rotation.getRotation()
|
|
502
|
-
} else {
|
|
503
|
-
logger.verbose('Trying to automatically normalize rotation...')
|
|
504
|
-
degrees = await EyesTestcafeUtils.tryAutomaticRotation(logger, driver, image)
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
return image.rotate(degrees)
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
function toClassName(name) {
|
|
512
|
-
const names = name
|
|
513
|
-
.split(/\s+/g)
|
|
514
|
-
.filter(s => s.length > 0)
|
|
515
|
-
.map(s => escapeCss(s))
|
|
516
|
-
return Selector(`.${names.join('.')}`)
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Escapes a CSS string.
|
|
521
|
-
* @param {string} css the string to escape.
|
|
522
|
-
* @return {string} the escaped string.
|
|
523
|
-
* @throws {TypeError} if the input value is not a string.
|
|
524
|
-
* @see https://drafts.csswg.org/cssom/#serialize-an-identifier
|
|
525
|
-
*/
|
|
526
|
-
function escapeCss(css) {
|
|
527
|
-
if (typeof css !== 'string') {
|
|
528
|
-
throw new TypeError('input must be a string')
|
|
529
|
-
}
|
|
530
|
-
let ret = ''
|
|
531
|
-
const n = css.length
|
|
532
|
-
for (let i = 0; i < n; i++) {
|
|
533
|
-
const c = css.charCodeAt(i)
|
|
534
|
-
if (c === 0x0) {
|
|
535
|
-
throw new Error('Invalid character when escaping css')
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
if (
|
|
539
|
-
(c >= 0x0001 && c <= 0x001f) ||
|
|
540
|
-
c === 0x007f ||
|
|
541
|
-
(i === 0 && c >= 0x0030 && c <= 0x0039) ||
|
|
542
|
-
(i === 1 && c >= 0x0030 && c <= 0x0039 && css.charCodeAt(0) === 0x002d)
|
|
543
|
-
) {
|
|
544
|
-
ret += `\\${c.toString(16)} `
|
|
545
|
-
continue
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (i === 0 && c === 0x002d && n === 1) {
|
|
549
|
-
ret += `\\${css.charAt(i)}`
|
|
550
|
-
continue
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (
|
|
554
|
-
c >= 0x0080 ||
|
|
555
|
-
c === 0x002d || // -
|
|
556
|
-
c === 0x005f || // _
|
|
557
|
-
(c >= 0x0030 && c <= 0x0039) || // [0-9]
|
|
558
|
-
(c >= 0x0041 && c <= 0x005a) || // [A-Z]
|
|
559
|
-
(c >= 0x0061 && c <= 0x007a)
|
|
560
|
-
) {
|
|
561
|
-
// [a-z]
|
|
562
|
-
ret += css.charAt(i)
|
|
563
|
-
continue
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
ret += `\\${css.charAt(i)}`
|
|
567
|
-
}
|
|
568
|
-
return ret
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
exports.EyesWebDriver = EyesWebDriver
|