@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,38 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
class TestResultContainer {
|
|
4
|
-
/**
|
|
5
|
-
* @param {TestResults} [testResults]
|
|
6
|
-
* @param {Error} [exception]
|
|
7
|
-
*/
|
|
8
|
-
constructor(testResults, exception) {
|
|
9
|
-
this._testResults = testResults
|
|
10
|
-
this._exception = exception
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @return {TestResults}
|
|
15
|
-
*/
|
|
16
|
-
getTestResults() {
|
|
17
|
-
return this._testResults
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @return {Error}
|
|
22
|
-
*/
|
|
23
|
-
getException() {
|
|
24
|
-
return this._exception
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @override
|
|
29
|
-
* @return {string}
|
|
30
|
-
*/
|
|
31
|
-
toString() {
|
|
32
|
-
return `${this._testResults ? this._testResults.toString() : ''} - ${
|
|
33
|
-
this._exception ? this._exception.toString() : ''
|
|
34
|
-
}`
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
exports.TestResultContainer = TestResultContainer
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {ArgumentGuard, TypeUtils, GeneralUtils} = require('@applitools/eyes-common')
|
|
4
|
-
const {TestFailedError, TestResultsStatus} = require('@applitools/eyes-sdk-core')
|
|
5
|
-
|
|
6
|
-
const {TestResultContainer} = require('./TestResultContainer')
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @implements {Iterable<TestResultContainer>}
|
|
10
|
-
*/
|
|
11
|
-
class TestResultsSummary {
|
|
12
|
-
/**
|
|
13
|
-
* @param {(TestResults|Error|TestResultContainer)[]} allResults
|
|
14
|
-
*/
|
|
15
|
-
constructor(allResults) {
|
|
16
|
-
ArgumentGuard.isArray(allResults, 'ArgumentGuard')
|
|
17
|
-
|
|
18
|
-
this._passed = 0
|
|
19
|
-
this._unresolved = 0
|
|
20
|
-
this._failed = 0
|
|
21
|
-
this._exceptions = 0
|
|
22
|
-
this._mismatches = 0
|
|
23
|
-
this._missing = 0
|
|
24
|
-
this._matches = 0
|
|
25
|
-
|
|
26
|
-
this._allResults = []
|
|
27
|
-
|
|
28
|
-
for (let result of allResults) {
|
|
29
|
-
if (!(result instanceof TestResultContainer)) {
|
|
30
|
-
if (result instanceof TestFailedError) {
|
|
31
|
-
result = new TestResultContainer(result.getTestResults(), result)
|
|
32
|
-
} else if (result instanceof Error) {
|
|
33
|
-
result = new TestResultContainer(undefined, result)
|
|
34
|
-
} else {
|
|
35
|
-
result = new TestResultContainer(result)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
this._allResults.push(result)
|
|
40
|
-
|
|
41
|
-
if (result.getException() !== undefined) {
|
|
42
|
-
this._exceptions += 1
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const testResults = result.getTestResults()
|
|
46
|
-
if (TypeUtils.isNotNull(testResults)) {
|
|
47
|
-
if (TypeUtils.isNotNull(testResults.getStatus())) {
|
|
48
|
-
switch (testResults.getStatus()) {
|
|
49
|
-
case TestResultsStatus.Failed:
|
|
50
|
-
this._failed += 1
|
|
51
|
-
break
|
|
52
|
-
case TestResultsStatus.Passed:
|
|
53
|
-
this._passed += 1
|
|
54
|
-
break
|
|
55
|
-
case TestResultsStatus.Unresolved:
|
|
56
|
-
this._unresolved += 1
|
|
57
|
-
break
|
|
58
|
-
default:
|
|
59
|
-
break
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this._matches += testResults.getMatches()
|
|
64
|
-
this._missing += testResults.getMissing()
|
|
65
|
-
this._mismatches += testResults.getMismatches()
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @return {IterableIterator<TestResultContainer>} Iterator to go over the TestResultContainers in the chain.
|
|
72
|
-
*/
|
|
73
|
-
[Symbol.iterator]() {
|
|
74
|
-
return this._allResults[Symbol.iterator]()
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @return {TestResultContainer[]}
|
|
79
|
-
*/
|
|
80
|
-
getAllResults() {
|
|
81
|
-
return this._allResults
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @return {string}
|
|
86
|
-
*/
|
|
87
|
-
toString() {
|
|
88
|
-
// eslint-disable-next-line prefer-template
|
|
89
|
-
return (
|
|
90
|
-
'result summary {' +
|
|
91
|
-
'\n\tall results=\n\t\t' +
|
|
92
|
-
GeneralUtils.toString(this._allResults) +
|
|
93
|
-
'\n\tpassed=' +
|
|
94
|
-
this._passed +
|
|
95
|
-
'\n\tunresolved=' +
|
|
96
|
-
this._unresolved +
|
|
97
|
-
'\n\tfailed=' +
|
|
98
|
-
this._failed +
|
|
99
|
-
'\n\texceptions=' +
|
|
100
|
-
this._exceptions +
|
|
101
|
-
'\n\tmismatches=' +
|
|
102
|
-
this._mismatches +
|
|
103
|
-
'\n\tmissing=' +
|
|
104
|
-
this._missing +
|
|
105
|
-
'\n\tmatches=' +
|
|
106
|
-
this._matches +
|
|
107
|
-
'\n}'
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
exports.TestResultsSummary = TestResultsSummary
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {EyesRunner} = require('./EyesRunner')
|
|
4
|
-
const {TestResultsSummary} = require('./TestResultsSummary')
|
|
5
|
-
|
|
6
|
-
class VisualGridRunner extends EyesRunner {
|
|
7
|
-
/**
|
|
8
|
-
* @param {number} [concurrentSessions]
|
|
9
|
-
*/
|
|
10
|
-
constructor(concurrentSessions) {
|
|
11
|
-
super()
|
|
12
|
-
|
|
13
|
-
this._concurrentSessions = concurrentSessions
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @return {number}
|
|
18
|
-
*/
|
|
19
|
-
getConcurrentSessions() {
|
|
20
|
-
return this._concurrentSessions
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {boolean} [shouldThrowException=true]
|
|
25
|
-
* @return {Promise<TestResultsSummary>}
|
|
26
|
-
*/
|
|
27
|
-
async getAllTestResults(shouldThrowException = true) {
|
|
28
|
-
if (this._eyesInstances.length > 0) {
|
|
29
|
-
const resultsPromise = []
|
|
30
|
-
const allResults = []
|
|
31
|
-
|
|
32
|
-
for (const eyesInstance of this._eyesInstances) {
|
|
33
|
-
resultsPromise.push(eyesInstance.closeAndReturnResults(false))
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const results = await Promise.all(resultsPromise)
|
|
37
|
-
for (const result of results) {
|
|
38
|
-
allResults.push(...result.getAllResults())
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (shouldThrowException === true) {
|
|
42
|
-
for (const result of allResults) {
|
|
43
|
-
if (result.getException()) {
|
|
44
|
-
throw result.getException()
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
await this._closeAllBatches()
|
|
50
|
-
return new TestResultsSummary(allResults)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return null
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
exports.VisualGridRunner = VisualGridRunner
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {makeClientFunctionWrapper} = require('./makeClientFunctionWrapper')
|
|
4
|
-
const hash = require('./hash')
|
|
5
|
-
|
|
6
|
-
// TODO
|
|
7
|
-
// This should be used for running functions with saving their compiled Testcafe data
|
|
8
|
-
// Alos this handles the Testcafe return value size limitation
|
|
9
|
-
// Use this function for Dom Capture (or remove it..)
|
|
10
|
-
|
|
11
|
-
function makeSafeExecuteFunction(driver) {
|
|
12
|
-
const functionsCache = {}
|
|
13
|
-
const clientFunctionWrapper = makeClientFunctionWrapper({})
|
|
14
|
-
|
|
15
|
-
return async func => {
|
|
16
|
-
const funcId = hash(func.toString())
|
|
17
|
-
let wrappedFunc
|
|
18
|
-
if (!functionsCache[funcId]) {
|
|
19
|
-
functionsCache[funcId] = await clientFunctionWrapper(func)
|
|
20
|
-
wrappedFunc = functionsCache[funcId]
|
|
21
|
-
} else {
|
|
22
|
-
wrappedFunc = functionsCache[funcId]
|
|
23
|
-
}
|
|
24
|
-
return wrappedFunc(driver)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = makeSafeExecuteFunction
|
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const {Location, RectangleSize, ArgumentGuard, TypeUtils} = require('@applitools/eyes-common')
|
|
4
|
-
|
|
5
|
-
const {Frame} = require('../frames/Frame')
|
|
6
|
-
const {FrameChain} = require('../frames/FrameChain')
|
|
7
|
-
const {ScrollPositionProvider} = require('../positioning/ScrollPositionProvider')
|
|
8
|
-
const {TestCafeExecutor} = require('../TestCafeExecutor')
|
|
9
|
-
const {EyesWebElement} = require('./EyesWebElement')
|
|
10
|
-
const {EyesWebElementPromise} = require('./EyesWebElementPromise')
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Wraps a target locator so we can keep track of which frames have been switched to.
|
|
14
|
-
*/
|
|
15
|
-
class EyesTargetLocator {
|
|
16
|
-
/**
|
|
17
|
-
* Initialized a new EyesTargetLocator object.
|
|
18
|
-
*
|
|
19
|
-
* @param {Logger} logger - A Logger instance.
|
|
20
|
-
* @param {EyesWebDriver} driver - The WebDriver from which the targetLocator was received.
|
|
21
|
-
* @param {TargetLocator} targetLocator - The actual TargetLocator object.
|
|
22
|
-
*/
|
|
23
|
-
constructor(logger, driver) {
|
|
24
|
-
ArgumentGuard.notNull(logger, 'logger')
|
|
25
|
-
ArgumentGuard.notNull(driver, 'driver')
|
|
26
|
-
|
|
27
|
-
this._logger = logger
|
|
28
|
-
this._driver = driver
|
|
29
|
-
this._jsExecutor = new TestCafeExecutor(driver._driver)
|
|
30
|
-
|
|
31
|
-
/** @type {ScrollPositionMemento} */
|
|
32
|
-
this._defaultContentPositionMemento = undefined
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// noinspection JSCheckFunctionSignatures
|
|
36
|
-
/**
|
|
37
|
-
* Schedules a command to switch the focus of all future commands to another frame on the page. The target frame may
|
|
38
|
-
* be specified as one of the following:
|
|
39
|
-
*
|
|
40
|
-
* - A number that specifies a (zero-based) index into [window.frames](
|
|
41
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Window.frames).
|
|
42
|
-
* - A string, which correspond to a `id` or `name` of element.
|
|
43
|
-
* - A {@link WebElement} reference, which correspond to a `frame` or `iframe` DOM element.
|
|
44
|
-
* - The `null` value, to select the topmost frame on the page. Passing `null`
|
|
45
|
-
* is the same as calling {@link #defaultContent defaultContent()}.
|
|
46
|
-
*
|
|
47
|
-
* @override
|
|
48
|
-
* @param {number|string|WebElement|null} varArg - The frame locator.
|
|
49
|
-
* @return {Promise} - A promise that will be resolved when the driver has changed focus to the specified frame.
|
|
50
|
-
*/
|
|
51
|
-
async frame(varArg) {
|
|
52
|
-
if (varArg == null) {
|
|
53
|
-
this._logger.verbose('EyesTargetLocator.frame(null)')
|
|
54
|
-
await this.defaultContent()
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (TypeUtils.isInteger(varArg)) {
|
|
59
|
-
/** @type {number} */
|
|
60
|
-
const frameIndex = varArg
|
|
61
|
-
this._logger.verbose(`Found integer (${frameIndex})`)
|
|
62
|
-
// Finding the target element so and reporting it using onWillSwitch.
|
|
63
|
-
this._logger.verbose('Getting frames list...')
|
|
64
|
-
const frames = await this._driver.findElementsByCssSelector('frame, iframe')
|
|
65
|
-
if (frameIndex > frames.length) {
|
|
66
|
-
throw new TypeError(`Frame index [${frameIndex}] is invalid!`)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
this._logger.verbose('Done! getting the specific frame...')
|
|
70
|
-
this._logger.verbose('Done! Making preparations...')
|
|
71
|
-
await this.willSwitchToFrame(frames[frameIndex])
|
|
72
|
-
|
|
73
|
-
this._logger.verbose('Done! Switching to frame...')
|
|
74
|
-
await this._targetLocator.frame(frameIndex)
|
|
75
|
-
this._logger.verbose('Done!')
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (TypeUtils.isString(varArg)) {
|
|
80
|
-
/** @type {string} */
|
|
81
|
-
const nameOrId = varArg
|
|
82
|
-
this._logger.verbose(`Found string ('${nameOrId}')`)
|
|
83
|
-
// Finding the target element so we can report it.
|
|
84
|
-
// We use find elements(plural) to avoid exception when the element is not found.
|
|
85
|
-
this._logger.verbose('Getting frames by name...')
|
|
86
|
-
let frames = await this._driver.findElementsByName(nameOrId)
|
|
87
|
-
if (frames.length === 0) {
|
|
88
|
-
this._logger.verbose('No frames Found! Trying by id...')
|
|
89
|
-
// If there are no frames by this name, we'll try the id
|
|
90
|
-
frames = await this._driver.findElementsById(nameOrId)
|
|
91
|
-
if (frames.length === 0) {
|
|
92
|
-
// No such frame, bummer
|
|
93
|
-
throw new TypeError(`No frame with name or id '${nameOrId}' exists!`)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
this._logger.verbose('Done! Making preparations...')
|
|
98
|
-
await this.willSwitchToFrame(frames[0])
|
|
99
|
-
|
|
100
|
-
this._logger.verbose(`Done! Switching to frame ${nameOrId} ...`)
|
|
101
|
-
await this._targetLocator.frame(frames[0])
|
|
102
|
-
|
|
103
|
-
this._logger.verbose('Done!')
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** @type {WebElement} */
|
|
108
|
-
const frameElement = varArg
|
|
109
|
-
this._logger.verbose('Probably, WebElement')
|
|
110
|
-
this._logger.verbose('Making preparations...')
|
|
111
|
-
await this.willSwitchToFrame(frameElement)
|
|
112
|
-
|
|
113
|
-
this._logger.verbose('Done! Switching to frame...')
|
|
114
|
-
await this._targetLocator.frame(frameElement)
|
|
115
|
-
|
|
116
|
-
this._logger.verbose('Done!')
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* @inheritDoc
|
|
121
|
-
*/
|
|
122
|
-
async parentFrame() {
|
|
123
|
-
this._logger.verbose('enter')
|
|
124
|
-
if (this._driver.getFrameChain().size() !== 0) {
|
|
125
|
-
this._logger.verbose('Making preparations...')
|
|
126
|
-
const frame = this._driver.getFrameChain().pop()
|
|
127
|
-
await frame.returnToOriginalPosition(this._driver)
|
|
128
|
-
this._logger.verbose('Done! Switching to parent frame...')
|
|
129
|
-
await EyesTargetLocator.tryParentFrame(this._targetLocator, this._driver.getFrameChain())
|
|
130
|
-
this._logger.verbose('Done!')
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* @param {TargetLocator} targetLocator
|
|
136
|
-
* @param {FrameChain} frameChainToParent
|
|
137
|
-
* @return {Promise}
|
|
138
|
-
*/
|
|
139
|
-
static async tryParentFrame(targetLocator, frameChainToParent) {
|
|
140
|
-
try {
|
|
141
|
-
await targetLocator.parentFrame()
|
|
142
|
-
} catch (ignored) {
|
|
143
|
-
await targetLocator.defaultContent()
|
|
144
|
-
for (const frame of frameChainToParent) {
|
|
145
|
-
await targetLocator.frame(frame.getReference())
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Switches into every frame in the frame chain. This is used as way to switch into nested frames (while considering
|
|
152
|
-
* scroll) in a single call.
|
|
153
|
-
*
|
|
154
|
-
* @param {FrameChain} frameChain - The path to the frame to switch to.
|
|
155
|
-
* @return {Promise} - A promise that will be resolved when the command has completed.
|
|
156
|
-
*/
|
|
157
|
-
async framesDoScroll(frameChain) {
|
|
158
|
-
this._logger.verbose('enter')
|
|
159
|
-
await this.defaultContent()
|
|
160
|
-
const scrollRootElement = await this._driver.getEyes().getCurrentFrameScrollRootElement()
|
|
161
|
-
const scrollProvider = new ScrollPositionProvider(
|
|
162
|
-
this._logger,
|
|
163
|
-
this._jsExecutor,
|
|
164
|
-
scrollRootElement,
|
|
165
|
-
)
|
|
166
|
-
this._defaultContentPositionMemento = await scrollProvider.getState()
|
|
167
|
-
|
|
168
|
-
for (const frame of frameChain.getFrames()) {
|
|
169
|
-
this._logger.verbose('Scrolling by parent scroll position...')
|
|
170
|
-
const frameLocation = frame.getLocation()
|
|
171
|
-
await scrollProvider.setPosition(frameLocation)
|
|
172
|
-
this._logger.verbose('Done! Switching to frame...')
|
|
173
|
-
await this.frame(frame.getReference())
|
|
174
|
-
const newFrame = this._driver.getFrameChain().peek()
|
|
175
|
-
newFrame.setScrollRootElement(frame.getScrollRootElement())
|
|
176
|
-
this._logger.verbose('Done!')
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this._logger.verbose('Done switching into nested frames!')
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Switches into every frame in the frame chain. This is used as way to switch into nested frames (while considering
|
|
184
|
-
* scroll) in a single call.
|
|
185
|
-
*
|
|
186
|
-
* @param {FrameChain|string[]} varArg - The path to the frame to switch to. Or the path to the frame to check.
|
|
187
|
-
* This is a list of frame names/IDs (where each frame is nested in the previous frame).
|
|
188
|
-
* @return {Promise} - The WebDriver with the switched context.
|
|
189
|
-
*/
|
|
190
|
-
async frames(varArg) {
|
|
191
|
-
this._logger.verbose('enter')
|
|
192
|
-
|
|
193
|
-
if (varArg instanceof FrameChain) {
|
|
194
|
-
this._logger.verbose('found frameChain')
|
|
195
|
-
await this.defaultContent()
|
|
196
|
-
|
|
197
|
-
for (const frame of varArg.getFrames()) {
|
|
198
|
-
await this.frame(frame.getReference())
|
|
199
|
-
const newFrame = this._driver.getFrameChain().peek()
|
|
200
|
-
newFrame.setScrollRootElement(frame.getScrollRootElement())
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
this._logger.verbose('Done switching into nested frames!')
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (Array.isArray(varArg)) {
|
|
208
|
-
this._logger.verbose('found array')
|
|
209
|
-
|
|
210
|
-
for (const frameNameOrId of varArg) {
|
|
211
|
-
this._logger.verbose('Switching to frame...')
|
|
212
|
-
await this._driver.switchTo().frame(frameNameOrId)
|
|
213
|
-
this._logger.verbose('Done!')
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
this._logger.verbose('Done switching into nested frames!')
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// noinspection JSCheckFunctionSignatures
|
|
221
|
-
/**
|
|
222
|
-
* @inheritDoc
|
|
223
|
-
*/
|
|
224
|
-
async window(nameOrHandle) {
|
|
225
|
-
this._logger.verbose('enter')
|
|
226
|
-
this._driver.getFrameChain().clear()
|
|
227
|
-
this._logger.verbose('Done! Switching to window...')
|
|
228
|
-
await this._targetLocator.window(nameOrHandle)
|
|
229
|
-
this._logger.verbose('Done!')
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* @inheritDoc
|
|
234
|
-
*/
|
|
235
|
-
async defaultContent() {
|
|
236
|
-
this._logger.verbose('enter')
|
|
237
|
-
if (this._driver.getFrameChain().size() !== 0) {
|
|
238
|
-
this._logger.verbose('Making preparations...')
|
|
239
|
-
this._driver.getFrameChain().clear()
|
|
240
|
-
this._logger.verbose('Done! Switching to default content...')
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
await this._driver._driver.switchToMainWindow()
|
|
245
|
-
} catch (e) {
|
|
246
|
-
this._logger.log('testcafe failed to switchToMainWindow (retrying), error', JSON.stringify(e))
|
|
247
|
-
await this._driver._driver.switchToMainWindow()
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
this._logger.verbose('Done!')
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// noinspection JSCheckFunctionSignatures
|
|
254
|
-
/**
|
|
255
|
-
* Schedules a command retrieve the {@code document.activeElement} element on the current document, or
|
|
256
|
-
* {@code document.body} if activeElement is not available.
|
|
257
|
-
*
|
|
258
|
-
* @override
|
|
259
|
-
* @return {!EyesWebElementPromise}
|
|
260
|
-
*/
|
|
261
|
-
activeElement() {
|
|
262
|
-
this._logger.verbose('Switching to element...')
|
|
263
|
-
const id = this._driver.execute(/* new Command(Name.GET_ACTIVE_ELEMENT) */)
|
|
264
|
-
|
|
265
|
-
this._logger.verbose('Done!')
|
|
266
|
-
return new EyesWebElementPromise(this._logger, this._driver, id, 'activeElement')
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Schedules a command to change focus to the active modal dialog, such as those opened by `window.alert()`,
|
|
271
|
-
* `window.confirm()`, and `window.prompt()`. The returned promise will be rejected with a
|
|
272
|
-
* {@linkplain error.NoSuchAlertError} if there are no open alerts.
|
|
273
|
-
*
|
|
274
|
-
* @return {!AlertPromise} - The open alert.
|
|
275
|
-
*/
|
|
276
|
-
alert() {
|
|
277
|
-
this._logger.verbose('Switching to alert...')
|
|
278
|
-
const result = this._targetLocator.alert()
|
|
279
|
-
this._logger.verbose('Done!')
|
|
280
|
-
return result
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* @return {Promise}
|
|
285
|
-
*/
|
|
286
|
-
async resetScroll() {
|
|
287
|
-
this._logger.verbose('enter')
|
|
288
|
-
if (this._defaultContentPositionMemento != null) {
|
|
289
|
-
const scrollRootElement = await this._driver.getEyes().getCurrentFrameScrollRootElement()
|
|
290
|
-
const scrollProvider = new ScrollPositionProvider(
|
|
291
|
-
this._logger,
|
|
292
|
-
this._jsExecutor,
|
|
293
|
-
scrollRootElement,
|
|
294
|
-
)
|
|
295
|
-
await scrollProvider.restoreState(this._defaultContentPositionMemento)
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Will be called before switching into a frame.
|
|
301
|
-
*
|
|
302
|
-
* @param {WebElement} targetFrame - The element about to be switched to.
|
|
303
|
-
* @return {Promise}
|
|
304
|
-
*/
|
|
305
|
-
async willSwitchToFrame(targetFrame) {
|
|
306
|
-
ArgumentGuard.notNull(targetFrame, 'targetFrame')
|
|
307
|
-
|
|
308
|
-
const eyesFrame =
|
|
309
|
-
targetFrame instanceof EyesWebElement
|
|
310
|
-
? targetFrame
|
|
311
|
-
: new EyesWebElement(this._logger, this._driver, targetFrame)
|
|
312
|
-
|
|
313
|
-
const rect = await eyesFrame.getRect()
|
|
314
|
-
const sizeAndBorders = await eyesFrame.getSizeAndBorders()
|
|
315
|
-
|
|
316
|
-
const contentLocation = new Location(rect.x + sizeAndBorders.left, rect.y + sizeAndBorders.top)
|
|
317
|
-
const originalLocation = await ScrollPositionProvider.getCurrentPositionStatic(
|
|
318
|
-
this._jsExecutor,
|
|
319
|
-
this._driver.findElement('html'),
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
const frame = new Frame(
|
|
323
|
-
this._logger,
|
|
324
|
-
targetFrame,
|
|
325
|
-
contentLocation,
|
|
326
|
-
new RectangleSize(rect),
|
|
327
|
-
new RectangleSize(sizeAndBorders),
|
|
328
|
-
originalLocation,
|
|
329
|
-
this._driver,
|
|
330
|
-
)
|
|
331
|
-
this._driver.getFrameChain().push(frame)
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
exports.EyesTargetLocator = EyesTargetLocator
|