codeceptjs 4.0.0-beta.2 → 4.0.0-beta.4
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/README.md +2 -2
- package/bin/codecept.js +84 -81
- package/lib/actor.js +13 -13
- package/lib/ai.js +10 -13
- package/lib/assert/empty.js +20 -21
- package/lib/assert/equal.js +37 -39
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +46 -47
- package/lib/assert/throws.js +13 -11
- package/lib/assert/truth.js +19 -22
- package/lib/assert.js +4 -2
- package/lib/cli.js +56 -49
- package/lib/codecept.js +145 -155
- package/lib/colorUtils.js +3 -3
- package/lib/command/configMigrate.js +58 -52
- package/lib/command/definitions.js +88 -89
- package/lib/command/dryRun.js +79 -81
- package/lib/command/generate.js +197 -188
- package/lib/command/gherkin/init.js +27 -16
- package/lib/command/gherkin/snippets.js +21 -21
- package/lib/command/gherkin/steps.js +8 -8
- package/lib/command/info.js +40 -38
- package/lib/command/init.js +290 -288
- package/lib/command/interactive.js +32 -32
- package/lib/command/list.js +26 -26
- package/lib/command/run-multiple/chunk.js +5 -5
- package/lib/command/run-multiple/collection.js +3 -3
- package/lib/command/run-multiple/run.js +6 -2
- package/lib/command/run-multiple.js +113 -93
- package/lib/command/run-rerun.js +20 -25
- package/lib/command/run-workers.js +64 -66
- package/lib/command/run.js +26 -29
- package/lib/command/utils.js +80 -65
- package/lib/command/workers/runTests.js +11 -12
- package/lib/config.js +10 -9
- package/lib/container.js +40 -48
- package/lib/data/context.js +60 -59
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +29 -29
- package/lib/data/table.js +26 -20
- package/lib/event.js +163 -167
- package/lib/heal.js +14 -18
- package/lib/helper/AI.js +130 -41
- package/lib/helper/ApiDataFactory.js +74 -70
- package/lib/helper/Appium.js +416 -388
- package/lib/helper/ExpectHelper.js +40 -48
- package/lib/helper/FileSystem.js +80 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +51 -51
- package/lib/helper/JSONResponse.js +65 -62
- package/lib/helper/Mochawesome.js +28 -28
- package/lib/helper/Nightmare.js +664 -571
- package/lib/helper/Playwright.js +1367 -1222
- package/lib/helper/Protractor.js +663 -635
- package/lib/helper/Puppeteer.js +1232 -1132
- package/lib/helper/REST.js +183 -68
- package/lib/helper/SoftExpectHelper.js +2 -2
- package/lib/helper/TestCafe.js +490 -486
- package/lib/helper/WebDriver.js +1246 -1297
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- package/lib/helper/errors/ConnectionRefused.js +1 -1
- package/lib/helper/errors/ElementAssertion.js +2 -2
- package/lib/helper/errors/ElementNotFound.js +2 -2
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
- package/lib/helper/extras/Console.js +1 -1
- package/lib/helper/extras/PlaywrightPropEngine.js +4 -4
- package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
- package/lib/helper/extras/PlaywrightRestartOpts.js +21 -18
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +3 -3
- package/lib/helper/network/actions.js +14 -7
- package/lib/helper/network/utils.js +4 -3
- package/lib/helper/scripts/blurElement.js +1 -1
- package/lib/helper/scripts/focusElement.js +1 -1
- package/lib/helper/scripts/highlightElement.js +1 -1
- package/lib/helper/scripts/isElementClickable.js +1 -1
- package/lib/helper/testcafe/testControllerHolder.js +1 -1
- package/lib/helper/testcafe/testcafe-utils.js +7 -8
- package/lib/helper.js +1 -3
- package/lib/history.js +6 -5
- package/lib/hooks.js +6 -6
- package/lib/html.js +7 -7
- package/lib/index.js +25 -41
- package/lib/interfaces/bdd.js +47 -64
- package/lib/interfaces/featureConfig.js +19 -19
- package/lib/interfaces/gherkin.js +124 -118
- package/lib/interfaces/scenarioConfig.js +29 -29
- package/lib/listener/artifacts.js +9 -9
- package/lib/listener/config.js +24 -24
- package/lib/listener/exit.js +12 -12
- package/lib/listener/helpers.js +42 -42
- package/lib/listener/mocha.js +11 -11
- package/lib/listener/retry.js +32 -30
- package/lib/listener/steps.js +50 -53
- package/lib/listener/timeout.js +54 -54
- package/lib/locator.js +7 -11
- package/lib/mochaFactory.js +18 -15
- package/lib/output.js +19 -15
- package/lib/parser.js +15 -12
- package/lib/pause.js +45 -38
- package/lib/plugin/allure.js +15 -15
- package/lib/plugin/autoDelay.js +29 -37
- package/lib/plugin/autoLogin.js +70 -65
- package/lib/plugin/commentStep.js +18 -18
- package/lib/plugin/coverage.js +112 -67
- package/lib/plugin/customLocator.js +21 -20
- package/lib/plugin/debugErrors.js +24 -24
- package/lib/plugin/eachElement.js +38 -38
- package/lib/plugin/fakerTransform.js +6 -6
- package/lib/plugin/heal.js +67 -108
- package/lib/plugin/pauseOnFail.js +11 -11
- package/lib/plugin/retryFailedStep.js +32 -39
- package/lib/plugin/retryTo.js +46 -40
- package/lib/plugin/screenshotOnFail.js +109 -87
- package/lib/plugin/selenoid.js +131 -118
- package/lib/plugin/standardActingHelpers.js +2 -8
- package/lib/plugin/stepByStepReport.js +110 -91
- package/lib/plugin/stepTimeout.js +24 -23
- package/lib/plugin/subtitles.js +34 -35
- package/lib/plugin/tryTo.js +40 -30
- package/lib/plugin/wdio.js +78 -75
- package/lib/recorder.js +14 -17
- package/lib/rerun.js +11 -10
- package/lib/scenario.js +25 -23
- package/lib/secret.js +4 -3
- package/lib/session.js +10 -10
- package/lib/step.js +12 -9
- package/lib/store.js +2 -3
- package/lib/transform.js +1 -1
- package/lib/translation.js +7 -8
- package/lib/ui.js +12 -14
- package/lib/utils.js +70 -72
- package/lib/within.js +10 -10
- package/lib/workerStorage.js +27 -25
- package/lib/workers.js +29 -33
- package/package.json +67 -68
- package/translations/de-DE.js +2 -1
- package/translations/fr-FR.js +2 -2
- package/translations/index.js +9 -13
- package/translations/it-IT.js +1 -1
- package/translations/ja-JP.js +1 -1
- package/translations/pl-PL.js +1 -1
- package/translations/pt-BR.js +1 -1
- package/translations/ru-RU.js +1 -1
- package/translations/zh-CN.js +1 -1
- package/translations/zh-TW.js +1 -1
- package/typings/index.d.ts +423 -65
- package/typings/promiseBasedTypes.d.ts +41 -172
- package/typings/types.d.ts +43 -178
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
- package/lib/helper/MockServer.js +0 -223
package/lib/helper/Protractor.js
CHANGED
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
let
|
|
21
|
-
let
|
|
22
|
-
let Button;
|
|
23
|
-
let ProtractorBy;
|
|
24
|
-
let ProtractorExpectedConditions;
|
|
25
|
-
|
|
26
|
-
let withinStore = {};
|
|
27
|
-
let Runner;
|
|
1
|
+
let EC
|
|
2
|
+
let Key
|
|
3
|
+
let Button
|
|
4
|
+
let ProtractorBy
|
|
5
|
+
let ProtractorExpectedConditions
|
|
6
|
+
|
|
7
|
+
const path = require('path')
|
|
8
|
+
|
|
9
|
+
const Helper = require('@codeceptjs/helper')
|
|
10
|
+
const stringIncludes = require('../assert/include').includes
|
|
11
|
+
const { urlEquals, equals } = require('../assert/equal')
|
|
12
|
+
const { empty } = require('../assert/empty')
|
|
13
|
+
const { truth } = require('../assert/truth')
|
|
14
|
+
const { xpathLocator, fileExists, convertCssPropertiesToCamelCase, screenshotOutputFolder } = require('../utils')
|
|
15
|
+
const { isColorProperty, convertColorToRGBA } = require('../colorUtils')
|
|
16
|
+
const ElementNotFound = require('./errors/ElementNotFound')
|
|
17
|
+
const ConnectionRefused = require('./errors/ConnectionRefused')
|
|
18
|
+
const Locator = require('../locator')
|
|
19
|
+
|
|
20
|
+
let withinStore = {}
|
|
21
|
+
let Runner
|
|
28
22
|
|
|
29
23
|
/**
|
|
30
24
|
* Protractor helper is based on [Protractor library](http://www.protractortest.org) and used for testing web applications.
|
|
@@ -118,12 +112,14 @@ let Runner;
|
|
|
118
112
|
class Protractor extends Helper {
|
|
119
113
|
constructor(config) {
|
|
120
114
|
// process.env.SELENIUM_PROMISE_MANAGER = false; // eslint-disable-line
|
|
121
|
-
super(config)
|
|
115
|
+
super(config)
|
|
122
116
|
|
|
123
|
-
this.isRunning = false
|
|
124
|
-
this._setConfig(config)
|
|
117
|
+
this.isRunning = false
|
|
118
|
+
this._setConfig(config)
|
|
125
119
|
|
|
126
|
-
console.log(
|
|
120
|
+
console.log(
|
|
121
|
+
'Protractor helper is deprecated as well as Protractor itself.\nThis helper will be removed in next major release',
|
|
122
|
+
)
|
|
127
123
|
}
|
|
128
124
|
|
|
129
125
|
_validateConfig(config) {
|
|
@@ -142,206 +138,213 @@ class Protractor extends Helper {
|
|
|
142
138
|
capabilities: {},
|
|
143
139
|
angular: true,
|
|
144
140
|
restart: true,
|
|
145
|
-
}
|
|
141
|
+
}
|
|
146
142
|
|
|
147
|
-
config = Object.assign(defaults, config)
|
|
143
|
+
config = Object.assign(defaults, config)
|
|
148
144
|
|
|
149
|
-
if (!config.allScriptsTimeout) config.allScriptsTimeout = config.scriptsTimeout
|
|
150
|
-
if (!config.scriptTimeout) config.scriptTimeout = config.scriptsTimeout
|
|
151
|
-
if (config.proxy) config.capabilities.proxy = config.proxy
|
|
152
|
-
if (config.browser) config.capabilities.browserName = config.browser
|
|
145
|
+
if (!config.allScriptsTimeout) config.allScriptsTimeout = config.scriptsTimeout
|
|
146
|
+
if (!config.scriptTimeout) config.scriptTimeout = config.scriptsTimeout
|
|
147
|
+
if (config.proxy) config.capabilities.proxy = config.proxy
|
|
148
|
+
if (config.browser) config.capabilities.browserName = config.browser
|
|
153
149
|
|
|
154
|
-
config.waitForTimeoutInSeconds = config.waitForTimeout / 1000
|
|
155
|
-
return config
|
|
150
|
+
config.waitForTimeoutInSeconds = config.waitForTimeout / 1000 // convert to seconds
|
|
151
|
+
return config
|
|
156
152
|
}
|
|
157
153
|
|
|
158
154
|
async _init() {
|
|
159
155
|
process.on('unhandledRejection', (reason) => {
|
|
160
156
|
if (reason.message.indexOf('ECONNREFUSED') > 0) {
|
|
161
|
-
this.browser = null
|
|
157
|
+
this.browser = null
|
|
162
158
|
}
|
|
163
|
-
})
|
|
159
|
+
})
|
|
164
160
|
|
|
165
|
-
Runner = require('protractor/built/runner').Runner
|
|
166
|
-
ProtractorBy = require('protractor').ProtractorBy
|
|
167
|
-
Key = require('protractor').Key
|
|
168
|
-
Button = require('protractor').Button
|
|
169
|
-
ProtractorExpectedConditions = require('protractor').ProtractorExpectedConditions
|
|
161
|
+
Runner = require('protractor/built/runner').Runner
|
|
162
|
+
ProtractorBy = require('protractor').ProtractorBy
|
|
163
|
+
Key = require('protractor').Key
|
|
164
|
+
Button = require('protractor').Button
|
|
165
|
+
ProtractorExpectedConditions = require('protractor').ProtractorExpectedConditions
|
|
170
166
|
|
|
171
|
-
return Promise.resolve()
|
|
167
|
+
return Promise.resolve()
|
|
172
168
|
}
|
|
173
169
|
|
|
174
170
|
static _checkRequirements() {
|
|
175
171
|
try {
|
|
176
|
-
require('protractor')
|
|
177
|
-
require('assert').ok(require('protractor/built/runner').Runner)
|
|
172
|
+
require('protractor')
|
|
173
|
+
require('assert').ok(require('protractor/built/runner').Runner)
|
|
178
174
|
} catch (e) {
|
|
179
|
-
return ['protractor@^5.3.0']
|
|
175
|
+
return ['protractor@^5.3.0']
|
|
180
176
|
}
|
|
181
177
|
}
|
|
182
178
|
|
|
183
179
|
static _config() {
|
|
184
180
|
return [
|
|
185
181
|
{ name: 'url', message: 'Base url of site to be tested', default: 'http://localhost' },
|
|
186
|
-
{
|
|
182
|
+
{
|
|
183
|
+
name: 'driver',
|
|
184
|
+
message: 'Protractor driver (local, direct, session, hosted, sauce, browserstack)',
|
|
185
|
+
default: 'hosted',
|
|
186
|
+
},
|
|
187
187
|
{ name: 'browser', message: 'Browser in which testing will be performed', default: 'chrome' },
|
|
188
188
|
{ name: 'rootElement', message: 'Root element of AngularJS application', default: 'body' },
|
|
189
189
|
{
|
|
190
|
-
name: 'angular',
|
|
190
|
+
name: 'angular',
|
|
191
|
+
message: 'Enable AngularJS synchronization',
|
|
192
|
+
default: false,
|
|
193
|
+
type: 'confirm',
|
|
191
194
|
},
|
|
192
|
-
|
|
193
|
-
];
|
|
195
|
+
]
|
|
194
196
|
}
|
|
195
197
|
|
|
196
198
|
async _beforeStep() {
|
|
197
199
|
if (!this.insideAngular) {
|
|
198
|
-
return this.amOutsideAngularApp()
|
|
200
|
+
return this.amOutsideAngularApp()
|
|
199
201
|
}
|
|
200
202
|
}
|
|
201
203
|
|
|
202
204
|
async _beforeSuite() {
|
|
203
205
|
if (!this.options.restart && !this.options.manualStart && !this.isRunning) {
|
|
204
|
-
this.debugSection('Session', 'Starting singleton browser session')
|
|
205
|
-
return this._startBrowser()
|
|
206
|
+
this.debugSection('Session', 'Starting singleton browser session')
|
|
207
|
+
return this._startBrowser()
|
|
206
208
|
}
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
async _startBrowser() {
|
|
210
212
|
try {
|
|
211
|
-
const runner = new Runner(this.options)
|
|
212
|
-
this.browser = runner.createBrowser()
|
|
213
|
-
await this.browser.ready
|
|
213
|
+
const runner = new Runner(this.options)
|
|
214
|
+
this.browser = runner.createBrowser()
|
|
215
|
+
await this.browser.ready
|
|
214
216
|
} catch (err) {
|
|
215
217
|
if (err.toString().indexOf('ECONNREFUSED')) {
|
|
216
|
-
throw new ConnectionRefused(err)
|
|
218
|
+
throw new ConnectionRefused(err)
|
|
217
219
|
}
|
|
218
|
-
throw err
|
|
220
|
+
throw err
|
|
219
221
|
}
|
|
220
222
|
if (this.options.angular) {
|
|
221
|
-
await this.amInsideAngularApp()
|
|
223
|
+
await this.amInsideAngularApp()
|
|
222
224
|
} else {
|
|
223
|
-
await this.amOutsideAngularApp()
|
|
225
|
+
await this.amOutsideAngularApp()
|
|
224
226
|
}
|
|
225
227
|
|
|
226
|
-
loadGlobals(this.browser)
|
|
228
|
+
loadGlobals(this.browser)
|
|
227
229
|
|
|
228
230
|
if (this.options.windowSize === 'maximize') {
|
|
229
|
-
await this.resizeWindow(this.options.windowSize)
|
|
231
|
+
await this.resizeWindow(this.options.windowSize)
|
|
230
232
|
} else if (this.options.windowSize) {
|
|
231
|
-
const size = this.options.windowSize.split('x')
|
|
232
|
-
await this.resizeWindow(parseInt(size[0], 10), parseInt(size[1], 10))
|
|
233
|
+
const size = this.options.windowSize.split('x')
|
|
234
|
+
await this.resizeWindow(parseInt(size[0], 10), parseInt(size[1], 10))
|
|
233
235
|
}
|
|
234
|
-
this.context = this.options.rootElement
|
|
235
|
-
this.isRunning = true
|
|
236
|
-
return this.browser.ready
|
|
236
|
+
this.context = this.options.rootElement
|
|
237
|
+
this.isRunning = true
|
|
238
|
+
return this.browser.ready
|
|
237
239
|
}
|
|
238
240
|
|
|
239
241
|
async _before() {
|
|
240
|
-
if (this.options.restart && !this.options.manualStart) return this._startBrowser()
|
|
241
|
-
if (!this.isRunning && !this.options.manualStart) return this._startBrowser()
|
|
242
|
+
if (this.options.restart && !this.options.manualStart) return this._startBrowser()
|
|
243
|
+
if (!this.isRunning && !this.options.manualStart) return this._startBrowser()
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
async _after() {
|
|
245
|
-
if (!this.browser) return
|
|
246
|
-
if (!this.isRunning) return
|
|
247
|
+
if (!this.browser) return
|
|
248
|
+
if (!this.isRunning) return
|
|
247
249
|
if (this.options.restart) {
|
|
248
|
-
this.isRunning = false
|
|
249
|
-
return this.browser.quit()
|
|
250
|
+
this.isRunning = false
|
|
251
|
+
return this.browser.quit()
|
|
250
252
|
}
|
|
251
|
-
if (this.options.keepBrowserState) return
|
|
253
|
+
if (this.options.keepBrowserState) return
|
|
252
254
|
|
|
253
|
-
const dialog = await this.grabPopupText()
|
|
255
|
+
const dialog = await this.grabPopupText()
|
|
254
256
|
if (dialog) {
|
|
255
|
-
await this.cancelPopup()
|
|
257
|
+
await this.cancelPopup()
|
|
256
258
|
}
|
|
257
259
|
if (!this.options.keepCookies) {
|
|
258
|
-
await this.browser.manage().deleteAllCookies()
|
|
260
|
+
await this.browser.manage().deleteAllCookies()
|
|
259
261
|
}
|
|
260
|
-
let url
|
|
262
|
+
let url
|
|
261
263
|
try {
|
|
262
|
-
url = await this.browser.getCurrentUrl()
|
|
264
|
+
url = await this.browser.getCurrentUrl()
|
|
263
265
|
} catch (err) {
|
|
264
266
|
// Ignore, as above will throw if no webpage has been loaded
|
|
265
267
|
}
|
|
266
268
|
if (url && !/data:,/i.test(url)) {
|
|
267
|
-
await this.browser.executeScript('localStorage.clear();')
|
|
269
|
+
await this.browser.executeScript('localStorage.clear();')
|
|
268
270
|
}
|
|
269
|
-
return this.closeOtherTabs()
|
|
271
|
+
return this.closeOtherTabs()
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
async _failed() {
|
|
273
|
-
await this._withinEnd()
|
|
275
|
+
await this._withinEnd()
|
|
274
276
|
}
|
|
275
277
|
|
|
276
278
|
async _finishTest() {
|
|
277
|
-
if (!this.options.restart && this.isRunning) return this.browser.quit()
|
|
279
|
+
if (!this.options.restart && this.isRunning) return this.browser.quit()
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
async _withinBegin(locator) {
|
|
281
|
-
withinStore.elFn = this.browser.findElement
|
|
282
|
-
withinStore.elsFn = this.browser.findElements
|
|
283
|
+
withinStore.elFn = this.browser.findElement
|
|
284
|
+
withinStore.elsFn = this.browser.findElements
|
|
283
285
|
|
|
284
|
-
const frame = isFrameLocator(locator)
|
|
286
|
+
const frame = isFrameLocator(locator)
|
|
285
287
|
|
|
286
288
|
if (frame) {
|
|
287
289
|
if (Array.isArray(frame)) {
|
|
288
|
-
withinStore.frame = frame.join('>')
|
|
289
|
-
return this.switchTo(null)
|
|
290
|
-
|
|
290
|
+
withinStore.frame = frame.join('>')
|
|
291
|
+
return this.switchTo(null).then(() =>
|
|
292
|
+
frame.reduce((p, frameLocator) => p.then(() => this.switchTo(frameLocator)), Promise.resolve()),
|
|
293
|
+
)
|
|
291
294
|
}
|
|
292
|
-
withinStore.frame = frame
|
|
293
|
-
return this.switchTo(locator)
|
|
295
|
+
withinStore.frame = frame
|
|
296
|
+
return this.switchTo(locator)
|
|
294
297
|
}
|
|
295
298
|
|
|
296
|
-
this.context = locator
|
|
297
|
-
const context = await global.element(guessLocator(locator) || global.by.css(locator))
|
|
298
|
-
if (!context) throw new ElementNotFound(locator)
|
|
299
|
+
this.context = locator
|
|
300
|
+
const context = await global.element(guessLocator(locator) || global.by.css(locator))
|
|
301
|
+
if (!context) throw new ElementNotFound(locator)
|
|
299
302
|
|
|
300
|
-
this.browser.findElement = l => (l ? context.element(l).getWebElement() : context.getWebElement())
|
|
301
|
-
this.browser.findElements = l => context.all(l).getWebElements()
|
|
302
|
-
return context
|
|
303
|
+
this.browser.findElement = (l) => (l ? context.element(l).getWebElement() : context.getWebElement())
|
|
304
|
+
this.browser.findElements = (l) => context.all(l).getWebElements()
|
|
305
|
+
return context
|
|
303
306
|
}
|
|
304
307
|
|
|
305
308
|
async _withinEnd() {
|
|
306
|
-
if (!isWithin()) return
|
|
309
|
+
if (!isWithin()) return
|
|
307
310
|
if (withinStore.frame) {
|
|
308
|
-
withinStore = {}
|
|
309
|
-
return this.switchTo(null)
|
|
311
|
+
withinStore = {}
|
|
312
|
+
return this.switchTo(null)
|
|
310
313
|
}
|
|
311
|
-
this.browser.findElement = withinStore.elFn
|
|
312
|
-
this.browser.findElements = withinStore.elsFn
|
|
313
|
-
withinStore = {}
|
|
314
|
-
this.context = this.options.rootElement
|
|
314
|
+
this.browser.findElement = withinStore.elFn
|
|
315
|
+
this.browser.findElements = withinStore.elsFn
|
|
316
|
+
withinStore = {}
|
|
317
|
+
this.context = this.options.rootElement
|
|
315
318
|
}
|
|
316
319
|
|
|
317
320
|
_session() {
|
|
318
|
-
const defaultSession = this.browser
|
|
321
|
+
const defaultSession = this.browser
|
|
319
322
|
return {
|
|
320
323
|
start: async (opts) => {
|
|
321
|
-
opts = this._validateConfig(Object.assign(this.options, opts))
|
|
322
|
-
this.debugSection('New Browser', JSON.stringify(opts))
|
|
323
|
-
const runner = new Runner(opts)
|
|
324
|
-
const res = await this.browser.executeScript('return [window.outerWidth, window.outerHeight]')
|
|
325
|
-
const browser = runner.createBrowser(null, this.browser)
|
|
326
|
-
await browser.ready
|
|
327
|
-
await browser.waitForAngularEnabled(this.insideAngular)
|
|
328
|
-
await browser.manage().window().setSize(parseInt(res[0], 10), parseInt(res[1], 10))
|
|
329
|
-
return browser.ready
|
|
324
|
+
opts = this._validateConfig(Object.assign(this.options, opts))
|
|
325
|
+
this.debugSection('New Browser', JSON.stringify(opts))
|
|
326
|
+
const runner = new Runner(opts)
|
|
327
|
+
const res = await this.browser.executeScript('return [window.outerWidth, window.outerHeight]')
|
|
328
|
+
const browser = runner.createBrowser(null, this.browser)
|
|
329
|
+
await browser.ready
|
|
330
|
+
await browser.waitForAngularEnabled(this.insideAngular)
|
|
331
|
+
await browser.manage().window().setSize(parseInt(res[0], 10), parseInt(res[1], 10))
|
|
332
|
+
return browser.ready
|
|
330
333
|
},
|
|
331
334
|
stop: async (browser) => {
|
|
332
|
-
return browser.close()
|
|
335
|
+
return browser.close()
|
|
333
336
|
},
|
|
334
337
|
loadVars: async (browser) => {
|
|
335
|
-
if (isWithin()) throw new Error(
|
|
336
|
-
this.browser = browser
|
|
337
|
-
loadGlobals(this.browser)
|
|
338
|
+
if (isWithin()) throw new Error("Can't start session inside within block")
|
|
339
|
+
this.browser = browser
|
|
340
|
+
loadGlobals(this.browser)
|
|
338
341
|
},
|
|
339
342
|
restoreVars: async () => {
|
|
340
|
-
if (isWithin()) await this._withinEnd()
|
|
341
|
-
this.browser = defaultSession
|
|
342
|
-
loadGlobals(this.browser)
|
|
343
|
+
if (isWithin()) await this._withinEnd()
|
|
344
|
+
this.browser = defaultSession
|
|
345
|
+
loadGlobals(this.browser)
|
|
343
346
|
},
|
|
344
|
-
}
|
|
347
|
+
}
|
|
345
348
|
}
|
|
346
349
|
|
|
347
350
|
/**
|
|
@@ -362,7 +365,7 @@ class Protractor extends Helper {
|
|
|
362
365
|
* @param {function} fn async functuion that executed with Protractor helper as argument
|
|
363
366
|
*/
|
|
364
367
|
useProtractorTo(description, fn) {
|
|
365
|
-
return this._useTo(...arguments)
|
|
368
|
+
return this._useTo(...arguments)
|
|
366
369
|
}
|
|
367
370
|
|
|
368
371
|
/**
|
|
@@ -370,9 +373,9 @@ class Protractor extends Helper {
|
|
|
370
373
|
* start using WebDriver instead of Protractor in this session
|
|
371
374
|
*/
|
|
372
375
|
async amOutsideAngularApp() {
|
|
373
|
-
if (!this.browser) return
|
|
374
|
-
await this.browser.waitForAngularEnabled(false)
|
|
375
|
-
return Promise.resolve(this.insideAngular = false)
|
|
376
|
+
if (!this.browser) return
|
|
377
|
+
await this.browser.waitForAngularEnabled(false)
|
|
378
|
+
return Promise.resolve((this.insideAngular = false))
|
|
376
379
|
}
|
|
377
380
|
|
|
378
381
|
/**
|
|
@@ -380,8 +383,8 @@ class Protractor extends Helper {
|
|
|
380
383
|
* Should be used after "amOutsideAngularApp"
|
|
381
384
|
*/
|
|
382
385
|
async amInsideAngularApp() {
|
|
383
|
-
await this.browser.waitForAngularEnabled(true)
|
|
384
|
-
return Promise.resolve(this.insideAngular = true)
|
|
386
|
+
await this.browser.waitForAngularEnabled(true)
|
|
387
|
+
return Promise.resolve((this.insideAngular = true))
|
|
385
388
|
}
|
|
386
389
|
|
|
387
390
|
/**
|
|
@@ -399,15 +402,15 @@ class Protractor extends Helper {
|
|
|
399
402
|
*
|
|
400
403
|
*/
|
|
401
404
|
async _locate(locator, smartWait = false) {
|
|
402
|
-
return this._smartWait(() => this.browser.findElements(guessLocator(locator) || global.by.css(locator)), smartWait)
|
|
405
|
+
return this._smartWait(() => this.browser.findElements(guessLocator(locator) || global.by.css(locator)), smartWait)
|
|
403
406
|
}
|
|
404
407
|
|
|
405
408
|
async _smartWait(fn, enabled = true) {
|
|
406
|
-
if (!this.options.smartWait || !enabled) return fn()
|
|
407
|
-
await this.browser.manage().timeouts().implicitlyWait(this.options.smartWait)
|
|
408
|
-
const res = await fn()
|
|
409
|
-
await this.browser.manage().timeouts().implicitlyWait(0)
|
|
410
|
-
return res
|
|
409
|
+
if (!this.options.smartWait || !enabled) return fn()
|
|
410
|
+
await this.browser.manage().timeouts().implicitlyWait(this.options.smartWait)
|
|
411
|
+
const res = await fn()
|
|
412
|
+
await this.browser.manage().timeouts().implicitlyWait(0)
|
|
413
|
+
return res
|
|
411
414
|
}
|
|
412
415
|
|
|
413
416
|
/**
|
|
@@ -418,7 +421,7 @@ class Protractor extends Helper {
|
|
|
418
421
|
* ```
|
|
419
422
|
*/
|
|
420
423
|
async _locateCheckable(locator) {
|
|
421
|
-
return findCheckable.call(this, this.browser, locator)
|
|
424
|
+
return findCheckable.call(this, this.browser, locator)
|
|
422
425
|
}
|
|
423
426
|
|
|
424
427
|
/**
|
|
@@ -429,7 +432,7 @@ class Protractor extends Helper {
|
|
|
429
432
|
* ```
|
|
430
433
|
*/
|
|
431
434
|
async _locateClickable(locator) {
|
|
432
|
-
return findClickable.call(this, this.browser, locator)
|
|
435
|
+
return findClickable.call(this, this.browser, locator)
|
|
433
436
|
}
|
|
434
437
|
|
|
435
438
|
/**
|
|
@@ -440,47 +443,47 @@ class Protractor extends Helper {
|
|
|
440
443
|
* ```
|
|
441
444
|
*/
|
|
442
445
|
async _locateFields(locator) {
|
|
443
|
-
return findFields.call(this, this.browser, locator)
|
|
446
|
+
return findFields.call(this, this.browser, locator)
|
|
444
447
|
}
|
|
445
448
|
|
|
446
449
|
/**
|
|
447
450
|
* {{> amOnPage }}
|
|
448
451
|
*/
|
|
449
452
|
async amOnPage(url) {
|
|
450
|
-
if (
|
|
451
|
-
url = this.options.url + url
|
|
453
|
+
if (!/^\w+\:\/\//.test(url)) {
|
|
454
|
+
url = this.options.url + url
|
|
452
455
|
}
|
|
453
|
-
const res = await this.browser.get(url)
|
|
454
|
-
this.debug(`Visited ${url}`)
|
|
455
|
-
return res
|
|
456
|
+
const res = await this.browser.get(url)
|
|
457
|
+
this.debug(`Visited ${url}`)
|
|
458
|
+
return res
|
|
456
459
|
}
|
|
457
460
|
|
|
458
461
|
/**
|
|
459
462
|
* {{> click }}
|
|
460
463
|
*/
|
|
461
464
|
async click(locator, context = null) {
|
|
462
|
-
let matcher = this.browser
|
|
465
|
+
let matcher = this.browser
|
|
463
466
|
if (context) {
|
|
464
|
-
const els = await this._locate(context, true)
|
|
465
|
-
assertElementExists(els, context)
|
|
466
|
-
matcher = els[0]
|
|
467
|
+
const els = await this._locate(context, true)
|
|
468
|
+
assertElementExists(els, context)
|
|
469
|
+
matcher = els[0]
|
|
467
470
|
}
|
|
468
|
-
const el = await findClickable.call(this, matcher, locator)
|
|
469
|
-
return el.click()
|
|
471
|
+
const el = await findClickable.call(this, matcher, locator)
|
|
472
|
+
return el.click()
|
|
470
473
|
}
|
|
471
474
|
|
|
472
475
|
/**
|
|
473
476
|
* {{> doubleClick }}
|
|
474
477
|
*/
|
|
475
478
|
async doubleClick(locator, context = null) {
|
|
476
|
-
let matcher = this.browser
|
|
479
|
+
let matcher = this.browser
|
|
477
480
|
if (context) {
|
|
478
|
-
const els = await this._locate(context, true)
|
|
479
|
-
assertElementExists(els, context)
|
|
480
|
-
matcher = els[0]
|
|
481
|
+
const els = await this._locate(context, true)
|
|
482
|
+
assertElementExists(els, context)
|
|
483
|
+
matcher = els[0]
|
|
481
484
|
}
|
|
482
|
-
const el = await findClickable.call(this, matcher, locator)
|
|
483
|
-
return this.browser.actions().doubleClick(el).perform()
|
|
485
|
+
const el = await findClickable.call(this, matcher, locator)
|
|
486
|
+
return this.browser.actions().doubleClick(el).perform()
|
|
484
487
|
}
|
|
485
488
|
|
|
486
489
|
/**
|
|
@@ -491,98 +494,98 @@ class Protractor extends Helper {
|
|
|
491
494
|
* just press button if no selector is given
|
|
492
495
|
*/
|
|
493
496
|
if (locator === undefined) {
|
|
494
|
-
return this.browser.actions().click(Button.RIGHT).perform()
|
|
497
|
+
return this.browser.actions().click(Button.RIGHT).perform()
|
|
495
498
|
}
|
|
496
|
-
let matcher = this.browser
|
|
499
|
+
let matcher = this.browser
|
|
497
500
|
if (context) {
|
|
498
|
-
const els = await this._locate(context, true)
|
|
499
|
-
assertElementExists(els, context)
|
|
500
|
-
matcher = els[0]
|
|
501
|
+
const els = await this._locate(context, true)
|
|
502
|
+
assertElementExists(els, context)
|
|
503
|
+
matcher = els[0]
|
|
501
504
|
}
|
|
502
|
-
const el = await findClickable.call(this, matcher, locator)
|
|
505
|
+
const el = await findClickable.call(this, matcher, locator)
|
|
503
506
|
|
|
504
|
-
await this.browser.actions().mouseMove(el).perform()
|
|
505
|
-
return this.browser.actions().click(Button.RIGHT).perform()
|
|
507
|
+
await this.browser.actions().mouseMove(el).perform()
|
|
508
|
+
return this.browser.actions().click(Button.RIGHT).perform()
|
|
506
509
|
}
|
|
507
510
|
|
|
508
511
|
/**
|
|
509
512
|
* {{> moveCursorTo }}
|
|
510
513
|
*/
|
|
511
514
|
async moveCursorTo(locator, offsetX = null, offsetY = null) {
|
|
512
|
-
let offset = null
|
|
515
|
+
let offset = null
|
|
513
516
|
if (offsetX !== null || offsetY !== null) {
|
|
514
|
-
offset = { x: offsetX, y: offsetY }
|
|
517
|
+
offset = { x: offsetX, y: offsetY }
|
|
515
518
|
}
|
|
516
|
-
const els = await this._locate(locator, true)
|
|
517
|
-
assertElementExists(els, locator)
|
|
518
|
-
return this.browser.actions().mouseMove(els[0], offset).perform()
|
|
519
|
+
const els = await this._locate(locator, true)
|
|
520
|
+
assertElementExists(els, locator)
|
|
521
|
+
return this.browser.actions().mouseMove(els[0], offset).perform()
|
|
519
522
|
}
|
|
520
523
|
|
|
521
524
|
/**
|
|
522
525
|
* {{> see }}
|
|
523
526
|
*/
|
|
524
527
|
async see(text, context = null) {
|
|
525
|
-
return proceedSee.call(this, 'assert', text, context)
|
|
528
|
+
return proceedSee.call(this, 'assert', text, context)
|
|
526
529
|
}
|
|
527
530
|
|
|
528
531
|
/**
|
|
529
532
|
* {{> seeTextEquals }}
|
|
530
533
|
*/
|
|
531
534
|
async seeTextEquals(text, context = null) {
|
|
532
|
-
return proceedSee.call(this, 'assert', text, context, true)
|
|
535
|
+
return proceedSee.call(this, 'assert', text, context, true)
|
|
533
536
|
}
|
|
534
537
|
|
|
535
538
|
/**
|
|
536
539
|
* {{> dontSee }}
|
|
537
540
|
*/
|
|
538
541
|
dontSee(text, context = null) {
|
|
539
|
-
return proceedSee.call(this, 'negate', text, context)
|
|
542
|
+
return proceedSee.call(this, 'negate', text, context)
|
|
540
543
|
}
|
|
541
544
|
|
|
542
545
|
/**
|
|
543
546
|
* {{> grabBrowserLogs }}
|
|
544
547
|
*/
|
|
545
548
|
async grabBrowserLogs() {
|
|
546
|
-
return this.browser.manage().logs().get('browser')
|
|
549
|
+
return this.browser.manage().logs().get('browser')
|
|
547
550
|
}
|
|
548
551
|
|
|
549
552
|
/**
|
|
550
553
|
* {{> grabCurrentUrl }}
|
|
551
554
|
*/
|
|
552
555
|
async grabCurrentUrl() {
|
|
553
|
-
return this.browser.getCurrentUrl()
|
|
556
|
+
return this.browser.getCurrentUrl()
|
|
554
557
|
}
|
|
555
558
|
|
|
556
559
|
/**
|
|
557
560
|
* {{> selectOption }}
|
|
558
561
|
*/
|
|
559
562
|
async selectOption(select, option) {
|
|
560
|
-
const fields = await findFields(this.browser, select)
|
|
561
|
-
assertElementExists(fields, select, 'Selectable field')
|
|
563
|
+
const fields = await findFields(this.browser, select)
|
|
564
|
+
assertElementExists(fields, select, 'Selectable field')
|
|
562
565
|
if (!Array.isArray(option)) {
|
|
563
|
-
option = [option]
|
|
566
|
+
option = [option]
|
|
564
567
|
}
|
|
565
|
-
const field = fields[0]
|
|
566
|
-
const promises = []
|
|
568
|
+
const field = fields[0]
|
|
569
|
+
const promises = []
|
|
567
570
|
for (const key in option) {
|
|
568
|
-
const opt = xpathLocator.literal(option[key])
|
|
569
|
-
let els = await field.findElements(global.by.xpath(Locator.select.byVisibleText(opt)))
|
|
571
|
+
const opt = xpathLocator.literal(option[key])
|
|
572
|
+
let els = await field.findElements(global.by.xpath(Locator.select.byVisibleText(opt)))
|
|
570
573
|
if (!els.length) {
|
|
571
|
-
els = await field.findElements(global.by.xpath(Locator.select.byValue(opt)))
|
|
574
|
+
els = await field.findElements(global.by.xpath(Locator.select.byValue(opt)))
|
|
572
575
|
}
|
|
573
|
-
els.forEach(el => promises.push(el.click()))
|
|
576
|
+
els.forEach((el) => promises.push(el.click()))
|
|
574
577
|
}
|
|
575
578
|
|
|
576
|
-
return Promise.all(promises)
|
|
579
|
+
return Promise.all(promises)
|
|
577
580
|
}
|
|
578
581
|
|
|
579
582
|
/**
|
|
580
583
|
* {{> fillField }}
|
|
581
584
|
*/
|
|
582
585
|
async fillField(field, value) {
|
|
583
|
-
const els = await findFields(this.browser, field)
|
|
584
|
-
await els[0].clear()
|
|
585
|
-
return els[0].sendKeys(value.toString())
|
|
586
|
+
const els = await findFields(this.browser, field)
|
|
587
|
+
await els[0].clear()
|
|
588
|
+
return els[0].sendKeys(value.toString())
|
|
586
589
|
}
|
|
587
590
|
|
|
588
591
|
/**
|
|
@@ -590,266 +593,268 @@ class Protractor extends Helper {
|
|
|
590
593
|
* {{ keys }}
|
|
591
594
|
*/
|
|
592
595
|
async pressKey(key) {
|
|
593
|
-
let modifier
|
|
594
|
-
if (Array.isArray(key) && ~['Control', 'Command', 'Shift', 'Alt'].indexOf(key[0])) {
|
|
595
|
-
modifier = Key[key[0].toUpperCase()]
|
|
596
|
-
key = key[1]
|
|
596
|
+
let modifier
|
|
597
|
+
if (Array.isArray(key) && ~['Control', 'Command', 'Shift', 'Alt'].indexOf(key[0])) {
|
|
598
|
+
modifier = Key[key[0].toUpperCase()]
|
|
599
|
+
key = key[1]
|
|
597
600
|
}
|
|
598
601
|
|
|
599
602
|
// guess special key in Selenium Webdriver list
|
|
600
603
|
if (Key[key.toUpperCase()]) {
|
|
601
|
-
key = Key[key.toUpperCase()]
|
|
604
|
+
key = Key[key.toUpperCase()]
|
|
602
605
|
}
|
|
603
606
|
|
|
604
|
-
const action = this.browser.actions()
|
|
605
|
-
if (modifier) action.keyDown(modifier)
|
|
606
|
-
action.sendKeys(key)
|
|
607
|
-
if (modifier) action.keyUp(modifier)
|
|
608
|
-
return action.perform()
|
|
607
|
+
const action = this.browser.actions()
|
|
608
|
+
if (modifier) action.keyDown(modifier)
|
|
609
|
+
action.sendKeys(key)
|
|
610
|
+
if (modifier) action.keyUp(modifier)
|
|
611
|
+
return action.perform()
|
|
609
612
|
}
|
|
610
613
|
|
|
611
614
|
/**
|
|
612
615
|
* {{> attachFile }}
|
|
613
616
|
*/
|
|
614
617
|
async attachFile(locator, pathToFile) {
|
|
615
|
-
const file = path.join(global.codecept_dir, pathToFile)
|
|
618
|
+
const file = path.join(global.codecept_dir, pathToFile)
|
|
616
619
|
if (!fileExists(file)) {
|
|
617
|
-
throw new Error(`File at ${file} can not be found on local system`)
|
|
620
|
+
throw new Error(`File at ${file} can not be found on local system`)
|
|
618
621
|
}
|
|
619
|
-
const els = await findFields(this.browser, locator)
|
|
620
|
-
assertElementExists(els, locator, 'Field')
|
|
622
|
+
const els = await findFields(this.browser, locator)
|
|
623
|
+
assertElementExists(els, locator, 'Field')
|
|
621
624
|
if (this.options.browser !== 'phantomjs') {
|
|
622
|
-
const remote = require('selenium-webdriver/remote')
|
|
623
|
-
this.browser.setFileDetector(new remote.FileDetector())
|
|
625
|
+
const remote = require('selenium-webdriver/remote')
|
|
626
|
+
this.browser.setFileDetector(new remote.FileDetector())
|
|
624
627
|
}
|
|
625
|
-
return els[0].sendKeys(file)
|
|
628
|
+
return els[0].sendKeys(file)
|
|
626
629
|
}
|
|
627
630
|
|
|
628
631
|
/**
|
|
629
632
|
* {{> seeInField }}
|
|
630
633
|
*/
|
|
631
634
|
async seeInField(field, value) {
|
|
632
|
-
const _value =
|
|
633
|
-
return proceedSeeInField.call(this, 'assert', field, _value)
|
|
635
|
+
const _value = typeof value === 'boolean' ? value : value.toString()
|
|
636
|
+
return proceedSeeInField.call(this, 'assert', field, _value)
|
|
634
637
|
}
|
|
635
638
|
|
|
636
639
|
/**
|
|
637
640
|
* {{> dontSeeInField }}
|
|
638
641
|
*/
|
|
639
642
|
async dontSeeInField(field, value) {
|
|
640
|
-
const _value =
|
|
641
|
-
return proceedSeeInField.call(this, 'negate', field, _value)
|
|
643
|
+
const _value = typeof value === 'boolean' ? value : value.toString()
|
|
644
|
+
return proceedSeeInField.call(this, 'negate', field, _value)
|
|
642
645
|
}
|
|
643
646
|
|
|
644
647
|
/**
|
|
645
648
|
* {{> appendField }}
|
|
646
649
|
*/
|
|
647
650
|
async appendField(field, value) {
|
|
648
|
-
const els = await findFields(this.browser, field)
|
|
649
|
-
assertElementExists(els, field, 'Field')
|
|
650
|
-
return els[0].sendKeys(value.toString())
|
|
651
|
+
const els = await findFields(this.browser, field)
|
|
652
|
+
assertElementExists(els, field, 'Field')
|
|
653
|
+
return els[0].sendKeys(value.toString())
|
|
651
654
|
}
|
|
652
655
|
|
|
653
656
|
/**
|
|
654
657
|
* {{> clearField }}
|
|
655
658
|
*/
|
|
656
659
|
async clearField(field) {
|
|
657
|
-
const els = await findFields(this.browser, field)
|
|
658
|
-
assertElementExists(els, field, 'Field')
|
|
659
|
-
return els[0].clear()
|
|
660
|
+
const els = await findFields(this.browser, field)
|
|
661
|
+
assertElementExists(els, field, 'Field')
|
|
662
|
+
return els[0].clear()
|
|
660
663
|
}
|
|
661
664
|
|
|
662
665
|
/**
|
|
663
666
|
* {{> checkOption }}
|
|
664
667
|
*/
|
|
665
668
|
async checkOption(field, context = null) {
|
|
666
|
-
let matcher = this.browser
|
|
669
|
+
let matcher = this.browser
|
|
667
670
|
if (context) {
|
|
668
|
-
const els = await this._locate(context, true)
|
|
669
|
-
assertElementExists(els, context)
|
|
670
|
-
matcher = els[0]
|
|
671
|
+
const els = await this._locate(context, true)
|
|
672
|
+
assertElementExists(els, context)
|
|
673
|
+
matcher = els[0]
|
|
671
674
|
}
|
|
672
|
-
const els = await findCheckable(matcher, field)
|
|
673
|
-
assertElementExists(els, field, 'Checkbox or radio')
|
|
674
|
-
const isSelected = await els[0].isSelected()
|
|
675
|
-
if (!isSelected) return els[0].click()
|
|
675
|
+
const els = await findCheckable(matcher, field)
|
|
676
|
+
assertElementExists(els, field, 'Checkbox or radio')
|
|
677
|
+
const isSelected = await els[0].isSelected()
|
|
678
|
+
if (!isSelected) return els[0].click()
|
|
676
679
|
}
|
|
677
680
|
|
|
678
681
|
/**
|
|
679
682
|
* {{> uncheckOption }}
|
|
680
683
|
*/
|
|
681
684
|
async uncheckOption(field, context = null) {
|
|
682
|
-
let matcher = this.browser
|
|
685
|
+
let matcher = this.browser
|
|
683
686
|
if (context) {
|
|
684
|
-
const els = await this._locate(context, true)
|
|
685
|
-
assertElementExists(els, context)
|
|
686
|
-
matcher = els[0]
|
|
687
|
+
const els = await this._locate(context, true)
|
|
688
|
+
assertElementExists(els, context)
|
|
689
|
+
matcher = els[0]
|
|
687
690
|
}
|
|
688
|
-
const els = await findCheckable(matcher, field)
|
|
689
|
-
assertElementExists(els, field, 'Checkbox or radio')
|
|
690
|
-
const isSelected = await els[0].isSelected()
|
|
691
|
-
if (isSelected) return els[0].click()
|
|
691
|
+
const els = await findCheckable(matcher, field)
|
|
692
|
+
assertElementExists(els, field, 'Checkbox or radio')
|
|
693
|
+
const isSelected = await els[0].isSelected()
|
|
694
|
+
if (isSelected) return els[0].click()
|
|
692
695
|
}
|
|
693
696
|
|
|
694
697
|
/**
|
|
695
698
|
* {{> seeCheckboxIsChecked }}
|
|
696
699
|
*/
|
|
697
700
|
async seeCheckboxIsChecked(field) {
|
|
698
|
-
return proceedIsChecked.call(this, 'assert', field)
|
|
701
|
+
return proceedIsChecked.call(this, 'assert', field)
|
|
699
702
|
}
|
|
700
703
|
|
|
701
704
|
/**
|
|
702
705
|
* {{> dontSeeCheckboxIsChecked }}
|
|
703
706
|
*/
|
|
704
707
|
async dontSeeCheckboxIsChecked(field) {
|
|
705
|
-
return proceedIsChecked.call(this, 'negate', field)
|
|
708
|
+
return proceedIsChecked.call(this, 'negate', field)
|
|
706
709
|
}
|
|
707
710
|
|
|
708
711
|
/**
|
|
709
712
|
* {{> grabTextFromAll }}
|
|
710
713
|
*/
|
|
711
714
|
async grabTextFromAll(locator) {
|
|
712
|
-
const els = await this._locate(locator)
|
|
713
|
-
const texts = []
|
|
715
|
+
const els = await this._locate(locator)
|
|
716
|
+
const texts = []
|
|
714
717
|
for (const el of els) {
|
|
715
|
-
texts.push(await el.getText())
|
|
718
|
+
texts.push(await el.getText())
|
|
716
719
|
}
|
|
717
|
-
return texts
|
|
720
|
+
return texts
|
|
718
721
|
}
|
|
719
722
|
|
|
720
723
|
/**
|
|
721
724
|
* {{> grabTextFrom }}
|
|
722
725
|
*/
|
|
723
726
|
async grabTextFrom(locator) {
|
|
724
|
-
const texts = await this.grabTextFromAll(locator)
|
|
725
|
-
assertElementExists(texts, locator)
|
|
727
|
+
const texts = await this.grabTextFromAll(locator)
|
|
728
|
+
assertElementExists(texts, locator)
|
|
726
729
|
if (texts.length > 1) {
|
|
727
|
-
this.debugSection('GrabText', `Using first element out of ${texts.length}`)
|
|
730
|
+
this.debugSection('GrabText', `Using first element out of ${texts.length}`)
|
|
728
731
|
}
|
|
729
732
|
|
|
730
|
-
return texts[0]
|
|
733
|
+
return texts[0]
|
|
731
734
|
}
|
|
732
735
|
|
|
733
736
|
/**
|
|
734
737
|
* {{> grabHTMLFromAll }}
|
|
735
738
|
*/
|
|
736
739
|
async grabHTMLFromAll(locator) {
|
|
737
|
-
const els = await this._locate(locator)
|
|
740
|
+
const els = await this._locate(locator)
|
|
738
741
|
|
|
739
|
-
const html = await Promise.all(
|
|
740
|
-
|
|
741
|
-
|
|
742
|
+
const html = await Promise.all(
|
|
743
|
+
els.map((el) => {
|
|
744
|
+
return this.browser.executeScript('return arguments[0].innerHTML;', el)
|
|
745
|
+
}),
|
|
746
|
+
)
|
|
742
747
|
|
|
743
|
-
return html
|
|
748
|
+
return html
|
|
744
749
|
}
|
|
745
750
|
|
|
746
751
|
/**
|
|
747
752
|
* {{> grabHTMLFrom }}
|
|
748
753
|
*/
|
|
749
754
|
async grabHTMLFrom(locator) {
|
|
750
|
-
const html = await this.grabHTMLFromAll(locator)
|
|
751
|
-
assertElementExists(html, locator)
|
|
755
|
+
const html = await this.grabHTMLFromAll(locator)
|
|
756
|
+
assertElementExists(html, locator)
|
|
752
757
|
if (html.length > 1) {
|
|
753
|
-
this.debugSection('GrabHTMl', `Using first element out of ${html.length}`)
|
|
758
|
+
this.debugSection('GrabHTMl', `Using first element out of ${html.length}`)
|
|
754
759
|
}
|
|
755
760
|
|
|
756
|
-
return html[0]
|
|
761
|
+
return html[0]
|
|
757
762
|
}
|
|
758
763
|
|
|
759
764
|
/**
|
|
760
765
|
* {{> grabValueFromAll }}
|
|
761
766
|
*/
|
|
762
767
|
async grabValueFromAll(locator) {
|
|
763
|
-
const els = await findFields(this.browser, locator)
|
|
764
|
-
const values = await Promise.all(els.map(el => el.getAttribute('value')))
|
|
768
|
+
const els = await findFields(this.browser, locator)
|
|
769
|
+
const values = await Promise.all(els.map((el) => el.getAttribute('value')))
|
|
765
770
|
|
|
766
|
-
return values
|
|
771
|
+
return values
|
|
767
772
|
}
|
|
768
773
|
|
|
769
774
|
/**
|
|
770
775
|
* {{> grabValueFrom }}
|
|
771
776
|
*/
|
|
772
777
|
async grabValueFrom(locator) {
|
|
773
|
-
const values = await this.grabValueFromAll(locator)
|
|
774
|
-
assertElementExists(values, locator, 'Field')
|
|
778
|
+
const values = await this.grabValueFromAll(locator)
|
|
779
|
+
assertElementExists(values, locator, 'Field')
|
|
775
780
|
if (values.length > 1) {
|
|
776
|
-
this.debugSection('GrabValue', `Using first element out of ${values.length}`)
|
|
781
|
+
this.debugSection('GrabValue', `Using first element out of ${values.length}`)
|
|
777
782
|
}
|
|
778
783
|
|
|
779
|
-
return values[0]
|
|
784
|
+
return values[0]
|
|
780
785
|
}
|
|
781
786
|
|
|
782
787
|
/**
|
|
783
788
|
* {{> grabCssPropertyFromAll }}
|
|
784
789
|
*/
|
|
785
790
|
async grabCssPropertyFromAll(locator, cssProperty) {
|
|
786
|
-
const els = await this._locate(locator, true)
|
|
787
|
-
const values = await Promise.all(els.map(el => el.getCssValue(cssProperty)))
|
|
791
|
+
const els = await this._locate(locator, true)
|
|
792
|
+
const values = await Promise.all(els.map((el) => el.getCssValue(cssProperty)))
|
|
788
793
|
|
|
789
|
-
return values
|
|
794
|
+
return values
|
|
790
795
|
}
|
|
791
796
|
|
|
792
797
|
/**
|
|
793
798
|
* {{> grabCssPropertyFrom }}
|
|
794
799
|
*/
|
|
795
800
|
async grabCssPropertyFrom(locator, cssProperty) {
|
|
796
|
-
const cssValues = await this.grabCssPropertyFromAll(locator, cssProperty)
|
|
797
|
-
assertElementExists(cssValues, locator)
|
|
801
|
+
const cssValues = await this.grabCssPropertyFromAll(locator, cssProperty)
|
|
802
|
+
assertElementExists(cssValues, locator)
|
|
798
803
|
|
|
799
804
|
if (cssValues.length > 1) {
|
|
800
|
-
this.debugSection('GrabCSS', `Using first element out of ${cssValues.length}`)
|
|
805
|
+
this.debugSection('GrabCSS', `Using first element out of ${cssValues.length}`)
|
|
801
806
|
}
|
|
802
807
|
|
|
803
|
-
return cssValues[0]
|
|
808
|
+
return cssValues[0]
|
|
804
809
|
}
|
|
805
810
|
|
|
806
811
|
/**
|
|
807
812
|
* {{> grabAttributeFromAll }}
|
|
808
813
|
*/
|
|
809
814
|
async grabAttributeFromAll(locator, attr) {
|
|
810
|
-
const els = await this._locate(locator)
|
|
811
|
-
const array = []
|
|
815
|
+
const els = await this._locate(locator)
|
|
816
|
+
const array = []
|
|
812
817
|
|
|
813
818
|
for (let index = 0; index < els.length; index++) {
|
|
814
|
-
const el = els[index]
|
|
815
|
-
array.push(await el.getAttribute(attr))
|
|
819
|
+
const el = els[index]
|
|
820
|
+
array.push(await el.getAttribute(attr))
|
|
816
821
|
}
|
|
817
|
-
return array
|
|
822
|
+
return array
|
|
818
823
|
}
|
|
819
824
|
|
|
820
825
|
/**
|
|
821
826
|
* {{> grabAttributeFrom }}
|
|
822
827
|
*/
|
|
823
828
|
async grabAttributeFrom(locator, attr) {
|
|
824
|
-
const attrs = await this.grabAttributeFromAll(locator, attr)
|
|
825
|
-
assertElementExists(attrs, locator)
|
|
829
|
+
const attrs = await this.grabAttributeFromAll(locator, attr)
|
|
830
|
+
assertElementExists(attrs, locator)
|
|
826
831
|
if (attrs.length > 1) {
|
|
827
|
-
this.debugSection('GrabAttribute', `Using first element out of ${attrs.length}`)
|
|
832
|
+
this.debugSection('GrabAttribute', `Using first element out of ${attrs.length}`)
|
|
828
833
|
}
|
|
829
834
|
|
|
830
|
-
return attrs[0]
|
|
835
|
+
return attrs[0]
|
|
831
836
|
}
|
|
832
837
|
|
|
833
838
|
/**
|
|
834
839
|
* {{> seeInTitle }}
|
|
835
840
|
*/
|
|
836
841
|
async seeInTitle(text) {
|
|
837
|
-
return this.browser.getTitle().then(title => stringIncludes('web page title').assert(text, title))
|
|
842
|
+
return this.browser.getTitle().then((title) => stringIncludes('web page title').assert(text, title))
|
|
838
843
|
}
|
|
839
844
|
|
|
840
845
|
/**
|
|
841
846
|
* {{> seeTitleEquals }}
|
|
842
847
|
*/
|
|
843
848
|
async seeTitleEquals(text) {
|
|
844
|
-
const title = await this.browser.getTitle()
|
|
845
|
-
return equals('web page title').assert(title, text)
|
|
849
|
+
const title = await this.browser.getTitle()
|
|
850
|
+
return equals('web page title').assert(title, text)
|
|
846
851
|
}
|
|
847
852
|
|
|
848
853
|
/**
|
|
849
854
|
* {{> dontSeeInTitle }}
|
|
850
855
|
*/
|
|
851
856
|
async dontSeeInTitle(text) {
|
|
852
|
-
return this.browser.getTitle().then(title => stringIncludes('web page title').negate(text, title))
|
|
857
|
+
return this.browser.getTitle().then((title) => stringIncludes('web page title').negate(text, title))
|
|
853
858
|
}
|
|
854
859
|
|
|
855
860
|
/**
|
|
@@ -857,188 +862,202 @@ class Protractor extends Helper {
|
|
|
857
862
|
*/
|
|
858
863
|
async grabTitle() {
|
|
859
864
|
return this.browser.getTitle().then((title) => {
|
|
860
|
-
this.debugSection('Title', title)
|
|
861
|
-
return title
|
|
862
|
-
})
|
|
865
|
+
this.debugSection('Title', title)
|
|
866
|
+
return title
|
|
867
|
+
})
|
|
863
868
|
}
|
|
864
869
|
|
|
865
870
|
/**
|
|
866
871
|
* {{> seeElement }}
|
|
867
872
|
*/
|
|
868
873
|
async seeElement(locator) {
|
|
869
|
-
let els = await this._locate(locator, true)
|
|
870
|
-
els = await Promise.all(els.map(el => el.isDisplayed()))
|
|
871
|
-
return empty('elements').negate(els.filter(v => v).fill('ELEMENT'))
|
|
874
|
+
let els = await this._locate(locator, true)
|
|
875
|
+
els = await Promise.all(els.map((el) => el.isDisplayed()))
|
|
876
|
+
return empty('elements').negate(els.filter((v) => v).fill('ELEMENT'))
|
|
872
877
|
}
|
|
873
878
|
|
|
874
879
|
/**
|
|
875
880
|
* {{> dontSeeElement }}
|
|
876
881
|
*/
|
|
877
882
|
async dontSeeElement(locator) {
|
|
878
|
-
let els = await this._locate(locator, false)
|
|
879
|
-
els = await Promise.all(els.map(el => el.isDisplayed()))
|
|
880
|
-
return empty('elements').assert(els.filter(v => v).fill('ELEMENT'))
|
|
883
|
+
let els = await this._locate(locator, false)
|
|
884
|
+
els = await Promise.all(els.map((el) => el.isDisplayed()))
|
|
885
|
+
return empty('elements').assert(els.filter((v) => v).fill('ELEMENT'))
|
|
881
886
|
}
|
|
882
887
|
|
|
883
888
|
/**
|
|
884
889
|
* {{> seeElementInDOM }}
|
|
885
890
|
*/
|
|
886
891
|
async seeElementInDOM(locator) {
|
|
887
|
-
return this.browser
|
|
892
|
+
return this.browser
|
|
893
|
+
.findElements(guessLocator(locator) || global.by.css(locator))
|
|
894
|
+
.then((els) => empty('elements').negate(els.fill('ELEMENT')))
|
|
888
895
|
}
|
|
889
896
|
|
|
890
897
|
/**
|
|
891
898
|
* {{> dontSeeElementInDOM }}
|
|
892
899
|
*/
|
|
893
900
|
async dontSeeElementInDOM(locator) {
|
|
894
|
-
return this.browser
|
|
901
|
+
return this.browser
|
|
902
|
+
.findElements(guessLocator(locator) || global.by.css(locator))
|
|
903
|
+
.then((els) => empty('elements').assert(els.fill('ELEMENT')))
|
|
895
904
|
}
|
|
896
905
|
|
|
897
906
|
/**
|
|
898
907
|
* {{> seeInSource }}
|
|
899
908
|
*/
|
|
900
909
|
async seeInSource(text) {
|
|
901
|
-
return this.browser.getPageSource().then(source => stringIncludes('HTML source of a page').assert(text, source))
|
|
910
|
+
return this.browser.getPageSource().then((source) => stringIncludes('HTML source of a page').assert(text, source))
|
|
902
911
|
}
|
|
903
912
|
|
|
904
913
|
/**
|
|
905
914
|
* {{> grabSource }}
|
|
906
915
|
*/
|
|
907
916
|
async grabSource() {
|
|
908
|
-
return this.browser.getPageSource()
|
|
917
|
+
return this.browser.getPageSource()
|
|
909
918
|
}
|
|
910
919
|
|
|
911
920
|
/**
|
|
912
921
|
* {{> dontSeeInSource }}
|
|
913
922
|
*/
|
|
914
923
|
async dontSeeInSource(text) {
|
|
915
|
-
return this.browser.getPageSource().then(source => stringIncludes('HTML source of a page').negate(text, source))
|
|
924
|
+
return this.browser.getPageSource().then((source) => stringIncludes('HTML source of a page').negate(text, source))
|
|
916
925
|
}
|
|
917
926
|
|
|
918
927
|
/**
|
|
919
928
|
* {{> seeNumberOfElements }}
|
|
920
929
|
*/
|
|
921
930
|
async seeNumberOfElements(locator, num) {
|
|
922
|
-
const elements = await this._locate(locator)
|
|
923
|
-
return equals(
|
|
931
|
+
const elements = await this._locate(locator)
|
|
932
|
+
return equals(
|
|
933
|
+
`expected number of elements (${new Locator(locator)}) is ${num}, but found ${elements.length}`,
|
|
934
|
+
).assert(elements.length, num)
|
|
924
935
|
}
|
|
925
936
|
|
|
926
937
|
/**
|
|
927
938
|
* {{> seeNumberOfVisibleElements }}
|
|
928
939
|
*/
|
|
929
940
|
async seeNumberOfVisibleElements(locator, num) {
|
|
930
|
-
const res = await this.grabNumberOfVisibleElements(locator)
|
|
931
|
-
return equals(`expected number of visible elements (${
|
|
941
|
+
const res = await this.grabNumberOfVisibleElements(locator)
|
|
942
|
+
return equals(`expected number of visible elements (${new Locator(locator)}) is ${num}, but found ${res}`).assert(
|
|
943
|
+
res,
|
|
944
|
+
num,
|
|
945
|
+
)
|
|
932
946
|
}
|
|
933
947
|
|
|
934
948
|
/**
|
|
935
949
|
* {{> grabNumberOfVisibleElements }}
|
|
936
950
|
*/
|
|
937
951
|
async grabNumberOfVisibleElements(locator) {
|
|
938
|
-
let els = await this._locate(locator)
|
|
939
|
-
els = await Promise.all(els.map(el => el.isDisplayed()))
|
|
940
|
-
return els.length
|
|
952
|
+
let els = await this._locate(locator)
|
|
953
|
+
els = await Promise.all(els.map((el) => el.isDisplayed()))
|
|
954
|
+
return els.length
|
|
941
955
|
}
|
|
942
956
|
|
|
943
957
|
/**
|
|
944
958
|
* {{> seeCssPropertiesOnElements }}
|
|
945
959
|
*/
|
|
946
960
|
async seeCssPropertiesOnElements(locator, cssProperties) {
|
|
947
|
-
const els = await this._locate(locator)
|
|
948
|
-
assertElementExists(els, locator)
|
|
961
|
+
const els = await this._locate(locator)
|
|
962
|
+
assertElementExists(els, locator)
|
|
949
963
|
|
|
950
|
-
const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties)
|
|
964
|
+
const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties)
|
|
951
965
|
|
|
952
|
-
const attributeNames = Object.keys(cssPropertiesCamelCase)
|
|
953
|
-
const expectedValues = attributeNames.map(name => cssPropertiesCamelCase[name])
|
|
954
|
-
const missingAttributes = []
|
|
966
|
+
const attributeNames = Object.keys(cssPropertiesCamelCase)
|
|
967
|
+
const expectedValues = attributeNames.map((name) => cssPropertiesCamelCase[name])
|
|
968
|
+
const missingAttributes = []
|
|
955
969
|
|
|
956
970
|
for (const el of els) {
|
|
957
|
-
const attributeValues = await Promise.all(attributeNames.map(attr => el.getCssValue(attr)))
|
|
971
|
+
const attributeValues = await Promise.all(attributeNames.map((attr) => el.getCssValue(attr)))
|
|
958
972
|
|
|
959
973
|
const missing = attributeValues.filter((actual, i) => {
|
|
960
|
-
const prop = attributeNames[i]
|
|
961
|
-
let propValue = actual
|
|
974
|
+
const prop = attributeNames[i]
|
|
975
|
+
let propValue = actual
|
|
962
976
|
if (isColorProperty(prop) && propValue) {
|
|
963
|
-
propValue = convertColorToRGBA(propValue)
|
|
977
|
+
propValue = convertColorToRGBA(propValue)
|
|
964
978
|
}
|
|
965
|
-
return propValue !== expectedValues[i]
|
|
966
|
-
})
|
|
979
|
+
return propValue !== expectedValues[i]
|
|
980
|
+
})
|
|
967
981
|
if (missing.length) {
|
|
968
|
-
missingAttributes.push(...missing)
|
|
982
|
+
missingAttributes.push(...missing)
|
|
969
983
|
}
|
|
970
984
|
}
|
|
971
|
-
return equals(
|
|
985
|
+
return equals(
|
|
986
|
+
`all elements (${new Locator(locator)}) to have CSS property ${JSON.stringify(cssProperties)}`,
|
|
987
|
+
).assert(missingAttributes.length, 0)
|
|
972
988
|
}
|
|
973
989
|
|
|
974
990
|
/**
|
|
975
991
|
* {{> seeAttributesOnElements }}
|
|
976
992
|
*/
|
|
977
993
|
async seeAttributesOnElements(locator, attributes) {
|
|
978
|
-
const els = await this._locate(locator)
|
|
979
|
-
assertElementExists(els, locator)
|
|
994
|
+
const els = await this._locate(locator)
|
|
995
|
+
assertElementExists(els, locator)
|
|
980
996
|
|
|
981
|
-
const attributeNames = Object.keys(attributes)
|
|
982
|
-
const expectedValues = attributeNames.map(name => attributes[name])
|
|
983
|
-
const missingAttributes = []
|
|
997
|
+
const attributeNames = Object.keys(attributes)
|
|
998
|
+
const expectedValues = attributeNames.map((name) => attributes[name])
|
|
999
|
+
const missingAttributes = []
|
|
984
1000
|
|
|
985
1001
|
for (const el of els) {
|
|
986
|
-
const attributeValues = await Promise.all(attributeNames.map(attr => el.getAttribute(attr)))
|
|
1002
|
+
const attributeValues = await Promise.all(attributeNames.map((attr) => el.getAttribute(attr)))
|
|
987
1003
|
const missing = attributeValues.filter((actual, i) => {
|
|
988
1004
|
if (expectedValues[i] instanceof RegExp) {
|
|
989
|
-
return expectedValues[i].test(actual)
|
|
1005
|
+
return expectedValues[i].test(actual)
|
|
990
1006
|
}
|
|
991
|
-
return actual !== expectedValues[i]
|
|
992
|
-
})
|
|
1007
|
+
return actual !== expectedValues[i]
|
|
1008
|
+
})
|
|
993
1009
|
if (missing.length) {
|
|
994
|
-
missingAttributes.push(...missing)
|
|
1010
|
+
missingAttributes.push(...missing)
|
|
995
1011
|
}
|
|
996
1012
|
}
|
|
997
1013
|
|
|
998
|
-
return equals(`all elements (${
|
|
1014
|
+
return equals(`all elements (${new Locator(locator)}) to have attributes ${JSON.stringify(attributes)}`).assert(
|
|
1015
|
+
missingAttributes.length,
|
|
1016
|
+
0,
|
|
1017
|
+
)
|
|
999
1018
|
}
|
|
1000
1019
|
|
|
1001
1020
|
/**
|
|
1002
1021
|
* {{> executeScript }}
|
|
1003
1022
|
*/
|
|
1004
1023
|
async executeScript() {
|
|
1005
|
-
return this.browser.executeScript.apply(this.browser, arguments)
|
|
1024
|
+
return this.browser.executeScript.apply(this.browser, arguments)
|
|
1006
1025
|
}
|
|
1007
1026
|
|
|
1008
1027
|
/**
|
|
1009
1028
|
* {{> executeAsyncScript }}
|
|
1010
1029
|
*/
|
|
1011
1030
|
async executeAsyncScript() {
|
|
1012
|
-
this.browser.manage().timeouts().setScriptTimeout(this.options.scriptTimeout)
|
|
1013
|
-
return this.browser.executeAsyncScript.apply(this.browser, arguments)
|
|
1031
|
+
this.browser.manage().timeouts().setScriptTimeout(this.options.scriptTimeout)
|
|
1032
|
+
return this.browser.executeAsyncScript.apply(this.browser, arguments)
|
|
1014
1033
|
}
|
|
1015
1034
|
|
|
1016
1035
|
/**
|
|
1017
1036
|
* {{> seeInCurrentUrl }}
|
|
1018
1037
|
*/
|
|
1019
1038
|
async seeInCurrentUrl(url) {
|
|
1020
|
-
return this.browser.getCurrentUrl().then(currentUrl => stringIncludes('url').assert(url, currentUrl))
|
|
1039
|
+
return this.browser.getCurrentUrl().then((currentUrl) => stringIncludes('url').assert(url, currentUrl))
|
|
1021
1040
|
}
|
|
1022
1041
|
|
|
1023
1042
|
/**
|
|
1024
1043
|
* {{> dontSeeInCurrentUrl }}
|
|
1025
1044
|
*/
|
|
1026
1045
|
async dontSeeInCurrentUrl(url) {
|
|
1027
|
-
return this.browser.getCurrentUrl().then(currentUrl => stringIncludes('url').negate(url, currentUrl))
|
|
1046
|
+
return this.browser.getCurrentUrl().then((currentUrl) => stringIncludes('url').negate(url, currentUrl))
|
|
1028
1047
|
}
|
|
1029
1048
|
|
|
1030
1049
|
/**
|
|
1031
1050
|
* {{> seeCurrentUrlEquals }}
|
|
1032
1051
|
*/
|
|
1033
1052
|
async seeCurrentUrlEquals(url) {
|
|
1034
|
-
return this.browser.getCurrentUrl().then(currentUrl => urlEquals(this.options.url).assert(url, currentUrl))
|
|
1053
|
+
return this.browser.getCurrentUrl().then((currentUrl) => urlEquals(this.options.url).assert(url, currentUrl))
|
|
1035
1054
|
}
|
|
1036
1055
|
|
|
1037
1056
|
/**
|
|
1038
1057
|
* {{> dontSeeCurrentUrlEquals }}
|
|
1039
1058
|
*/
|
|
1040
1059
|
async dontSeeCurrentUrlEquals(url) {
|
|
1041
|
-
return this.browser.getCurrentUrl().then(currentUrl => urlEquals(this.options.url).negate(url, currentUrl))
|
|
1060
|
+
return this.browser.getCurrentUrl().then((currentUrl) => urlEquals(this.options.url).negate(url, currentUrl))
|
|
1042
1061
|
}
|
|
1043
1062
|
|
|
1044
1063
|
/**
|
|
@@ -1046,56 +1065,56 @@ class Protractor extends Helper {
|
|
|
1046
1065
|
*
|
|
1047
1066
|
*/
|
|
1048
1067
|
async saveElementScreenshot(locator, fileName) {
|
|
1049
|
-
const outputFile = screenshotOutputFolder(fileName)
|
|
1068
|
+
const outputFile = screenshotOutputFolder(fileName)
|
|
1050
1069
|
|
|
1051
1070
|
const writeFile = (png, outputFile) => {
|
|
1052
|
-
const fs = require('fs')
|
|
1053
|
-
const stream = fs.createWriteStream(outputFile)
|
|
1054
|
-
stream.write(Buffer.from(png, 'base64'))
|
|
1055
|
-
stream.end()
|
|
1056
|
-
return new Promise(resolve => stream.on('finish', resolve))
|
|
1057
|
-
}
|
|
1071
|
+
const fs = require('fs')
|
|
1072
|
+
const stream = fs.createWriteStream(outputFile)
|
|
1073
|
+
stream.write(Buffer.from(png, 'base64'))
|
|
1074
|
+
stream.end()
|
|
1075
|
+
return new Promise((resolve) => stream.on('finish', resolve)) // eslint-disable-line no-promise-executor-return
|
|
1076
|
+
}
|
|
1058
1077
|
|
|
1059
|
-
const res = await this._locate(locator)
|
|
1060
|
-
assertElementExists(res, locator)
|
|
1061
|
-
if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`)
|
|
1062
|
-
const elem = res[0]
|
|
1063
|
-
this.debug(`Screenshot of ${
|
|
1064
|
-
const png = await elem.takeScreenshot()
|
|
1065
|
-
return writeFile(png, outputFile)
|
|
1078
|
+
const res = await this._locate(locator)
|
|
1079
|
+
assertElementExists(res, locator)
|
|
1080
|
+
if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`)
|
|
1081
|
+
const elem = res[0]
|
|
1082
|
+
this.debug(`Screenshot of ${new Locator(locator)} element has been saved to ${outputFile}`)
|
|
1083
|
+
const png = await elem.takeScreenshot()
|
|
1084
|
+
return writeFile(png, outputFile)
|
|
1066
1085
|
}
|
|
1067
1086
|
|
|
1068
1087
|
/**
|
|
1069
1088
|
* {{> saveScreenshot }}
|
|
1070
1089
|
*/
|
|
1071
1090
|
async saveScreenshot(fileName, fullPage = false) {
|
|
1072
|
-
const outputFile = screenshotOutputFolder(fileName)
|
|
1091
|
+
const outputFile = screenshotOutputFolder(fileName)
|
|
1073
1092
|
|
|
1074
1093
|
const writeFile = (png, outputFile) => {
|
|
1075
|
-
const fs = require('fs')
|
|
1076
|
-
const stream = fs.createWriteStream(outputFile)
|
|
1077
|
-
stream.write(Buffer.from(png, 'base64'))
|
|
1078
|
-
stream.end()
|
|
1079
|
-
return new Promise(resolve => stream.on('finish', resolve))
|
|
1080
|
-
}
|
|
1094
|
+
const fs = require('fs')
|
|
1095
|
+
const stream = fs.createWriteStream(outputFile)
|
|
1096
|
+
stream.write(Buffer.from(png, 'base64'))
|
|
1097
|
+
stream.end()
|
|
1098
|
+
return new Promise((resolve) => stream.on('finish', resolve)) // eslint-disable-line no-promise-executor-return
|
|
1099
|
+
}
|
|
1081
1100
|
|
|
1082
1101
|
if (!fullPage) {
|
|
1083
|
-
this.debug(`Screenshot has been saved to ${outputFile}`)
|
|
1084
|
-
const png = await this.browser.takeScreenshot()
|
|
1085
|
-
return writeFile(png, outputFile)
|
|
1102
|
+
this.debug(`Screenshot has been saved to ${outputFile}`)
|
|
1103
|
+
const png = await this.browser.takeScreenshot()
|
|
1104
|
+
return writeFile(png, outputFile)
|
|
1086
1105
|
}
|
|
1087
1106
|
|
|
1088
|
-
let { width, height } = await this.browser.executeScript(() => ({
|
|
1107
|
+
let { width, height } = await this.browser.executeScript(() => ({
|
|
1089
1108
|
height: document.body.scrollHeight,
|
|
1090
1109
|
width: document.body.scrollWidth,
|
|
1091
|
-
}))
|
|
1110
|
+
}))
|
|
1092
1111
|
|
|
1093
|
-
if (height < 100) height = 500
|
|
1112
|
+
if (height < 100) height = 500
|
|
1094
1113
|
|
|
1095
|
-
await this.browser.manage().window().setSize(width, height)
|
|
1096
|
-
this.debug(`Screenshot has been saved to ${outputFile}, size: ${width}x${height}`)
|
|
1097
|
-
const png = await this.browser.takeScreenshot()
|
|
1098
|
-
return writeFile(png, outputFile)
|
|
1114
|
+
await this.browser.manage().window().setSize(width, height)
|
|
1115
|
+
this.debug(`Screenshot has been saved to ${outputFile}, size: ${width}x${height}`)
|
|
1116
|
+
const png = await this.browser.takeScreenshot()
|
|
1117
|
+
return writeFile(png, outputFile)
|
|
1099
1118
|
}
|
|
1100
1119
|
|
|
1101
1120
|
/**
|
|
@@ -1103,23 +1122,29 @@ class Protractor extends Helper {
|
|
|
1103
1122
|
*/
|
|
1104
1123
|
async clearCookie(cookie = null) {
|
|
1105
1124
|
if (!cookie) {
|
|
1106
|
-
return this.browser.manage().deleteAllCookies()
|
|
1125
|
+
return this.browser.manage().deleteAllCookies()
|
|
1107
1126
|
}
|
|
1108
|
-
return this.browser.manage().deleteCookie(cookie)
|
|
1127
|
+
return this.browser.manage().deleteCookie(cookie)
|
|
1109
1128
|
}
|
|
1110
1129
|
|
|
1111
1130
|
/**
|
|
1112
1131
|
* {{> seeCookie }}
|
|
1113
1132
|
*/
|
|
1114
1133
|
async seeCookie(name) {
|
|
1115
|
-
return this.browser
|
|
1134
|
+
return this.browser
|
|
1135
|
+
.manage()
|
|
1136
|
+
.getCookie(name)
|
|
1137
|
+
.then((res) => truth(`cookie ${name}`, 'to be set').assert(res))
|
|
1116
1138
|
}
|
|
1117
1139
|
|
|
1118
1140
|
/**
|
|
1119
1141
|
* {{> dontSeeCookie }}
|
|
1120
1142
|
*/
|
|
1121
1143
|
async dontSeeCookie(name) {
|
|
1122
|
-
return this.browser
|
|
1144
|
+
return this.browser
|
|
1145
|
+
.manage()
|
|
1146
|
+
.getCookie(name)
|
|
1147
|
+
.then((res) => truth(`cookie ${name}`, 'to be set').negate(res))
|
|
1123
1148
|
}
|
|
1124
1149
|
|
|
1125
1150
|
/**
|
|
@@ -1128,8 +1153,8 @@ class Protractor extends Helper {
|
|
|
1128
1153
|
* Returns cookie in JSON [format](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).
|
|
1129
1154
|
*/
|
|
1130
1155
|
async grabCookie(name) {
|
|
1131
|
-
if (!name) return this.browser.manage().getCookies()
|
|
1132
|
-
return this.browser.manage().getCookie(name)
|
|
1156
|
+
if (!name) return this.browser.manage().getCookies()
|
|
1157
|
+
return this.browser.manage().getCookie(name)
|
|
1133
1158
|
}
|
|
1134
1159
|
|
|
1135
1160
|
/**
|
|
@@ -1138,26 +1163,26 @@ class Protractor extends Helper {
|
|
|
1138
1163
|
* libraries](http://jster.net/category/windows-modals-popups). Appium: support only web testing
|
|
1139
1164
|
*/
|
|
1140
1165
|
async acceptPopup() {
|
|
1141
|
-
return this.browser.switchTo().alert().accept()
|
|
1166
|
+
return this.browser.switchTo().alert().accept()
|
|
1142
1167
|
}
|
|
1143
1168
|
|
|
1144
1169
|
/**
|
|
1145
1170
|
* Dismisses the active JavaScript popup, as created by window.alert|window.confirm|window.prompt.
|
|
1146
1171
|
*/
|
|
1147
1172
|
async cancelPopup() {
|
|
1148
|
-
return this.browser.switchTo().alert().dismiss()
|
|
1173
|
+
return this.browser.switchTo().alert().dismiss()
|
|
1149
1174
|
}
|
|
1150
1175
|
|
|
1151
1176
|
/**
|
|
1152
1177
|
* {{> seeInPopup }}
|
|
1153
1178
|
*/
|
|
1154
1179
|
async seeInPopup(text) {
|
|
1155
|
-
const popupAlert = await this.browser.switchTo().alert()
|
|
1156
|
-
const res = await popupAlert.getText()
|
|
1180
|
+
const popupAlert = await this.browser.switchTo().alert()
|
|
1181
|
+
const res = await popupAlert.getText()
|
|
1157
1182
|
if (res === null) {
|
|
1158
|
-
throw new Error('Popup is not opened')
|
|
1183
|
+
throw new Error('Popup is not opened')
|
|
1159
1184
|
}
|
|
1160
|
-
stringIncludes('text in popup').assert(text, res)
|
|
1185
|
+
stringIncludes('text in popup').assert(text, res)
|
|
1161
1186
|
}
|
|
1162
1187
|
|
|
1163
1188
|
/**
|
|
@@ -1169,17 +1194,17 @@ class Protractor extends Helper {
|
|
|
1169
1194
|
*/
|
|
1170
1195
|
async grabPopupText() {
|
|
1171
1196
|
try {
|
|
1172
|
-
const dialog = await this.browser.switchTo().alert()
|
|
1197
|
+
const dialog = await this.browser.switchTo().alert()
|
|
1173
1198
|
|
|
1174
1199
|
if (dialog) {
|
|
1175
|
-
return dialog.getText()
|
|
1200
|
+
return dialog.getText()
|
|
1176
1201
|
}
|
|
1177
1202
|
} catch (e) {
|
|
1178
1203
|
if (e.message.match(/no.*?(alert|modal)/i)) {
|
|
1179
1204
|
// Don't throw an error
|
|
1180
|
-
return null
|
|
1205
|
+
return null
|
|
1181
1206
|
}
|
|
1182
|
-
throw e
|
|
1207
|
+
throw e
|
|
1183
1208
|
}
|
|
1184
1209
|
}
|
|
1185
1210
|
|
|
@@ -1188,24 +1213,21 @@ class Protractor extends Helper {
|
|
|
1188
1213
|
*/
|
|
1189
1214
|
async resizeWindow(width, height) {
|
|
1190
1215
|
if (width === 'maximize') {
|
|
1191
|
-
const res = await this.browser.executeScript('return [screen.width, screen.height]')
|
|
1192
|
-
return this.browser.manage().window().setSize(parseInt(res[0], 10), parseInt(res[1], 10))
|
|
1216
|
+
const res = await this.browser.executeScript('return [screen.width, screen.height]')
|
|
1217
|
+
return this.browser.manage().window().setSize(parseInt(res[0], 10), parseInt(res[1], 10))
|
|
1193
1218
|
}
|
|
1194
|
-
return this.browser.manage().window().setSize(parseInt(width, 10), parseInt(height, 10))
|
|
1219
|
+
return this.browser.manage().window().setSize(parseInt(width, 10), parseInt(height, 10))
|
|
1195
1220
|
}
|
|
1196
1221
|
|
|
1197
1222
|
/**
|
|
1198
1223
|
* {{> dragAndDrop }}
|
|
1199
1224
|
*/
|
|
1200
1225
|
async dragAndDrop(srcElement, destElement) {
|
|
1201
|
-
const srcEl = await this._locate(srcElement, true)
|
|
1202
|
-
const destEl = await this._locate(destElement, true)
|
|
1203
|
-
assertElementExists(srcEl, srcElement)
|
|
1204
|
-
assertElementExists(destEl, destElement)
|
|
1205
|
-
return this.browser
|
|
1206
|
-
.actions()
|
|
1207
|
-
.dragAndDrop(srcEl[0], destEl[0])
|
|
1208
|
-
.perform();
|
|
1226
|
+
const srcEl = await this._locate(srcElement, true)
|
|
1227
|
+
const destEl = await this._locate(destElement, true)
|
|
1228
|
+
assertElementExists(srcEl, srcElement)
|
|
1229
|
+
assertElementExists(destEl, destElement)
|
|
1230
|
+
return this.browser.actions().dragAndDrop(srcEl[0], destEl[0]).perform()
|
|
1209
1231
|
}
|
|
1210
1232
|
|
|
1211
1233
|
/**
|
|
@@ -1216,19 +1238,24 @@ class Protractor extends Helper {
|
|
|
1216
1238
|
* ```
|
|
1217
1239
|
*/
|
|
1218
1240
|
async closeOtherTabs() {
|
|
1219
|
-
const client = this.browser
|
|
1241
|
+
const client = this.browser
|
|
1220
1242
|
|
|
1221
|
-
const handles = await client.getAllWindowHandles()
|
|
1222
|
-
const currentHandle = await client.getWindowHandle()
|
|
1223
|
-
const otherHandles = handles.filter(handle => handle !== currentHandle)
|
|
1243
|
+
const handles = await client.getAllWindowHandles()
|
|
1244
|
+
const currentHandle = await client.getWindowHandle()
|
|
1245
|
+
const otherHandles = handles.filter((handle) => handle !== currentHandle)
|
|
1224
1246
|
|
|
1225
|
-
if (!otherHandles || !otherHandles.length) return
|
|
1226
|
-
let p = Promise.resolve()
|
|
1247
|
+
if (!otherHandles || !otherHandles.length) return
|
|
1248
|
+
let p = Promise.resolve()
|
|
1227
1249
|
otherHandles.forEach((handle) => {
|
|
1228
|
-
p = p.then(() =>
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1250
|
+
p = p.then(() =>
|
|
1251
|
+
client
|
|
1252
|
+
.switchTo()
|
|
1253
|
+
.window(handle)
|
|
1254
|
+
.then(() => client.close()),
|
|
1255
|
+
)
|
|
1256
|
+
})
|
|
1257
|
+
p = p.then(() => client.switchTo().window(currentHandle))
|
|
1258
|
+
return p
|
|
1232
1259
|
}
|
|
1233
1260
|
|
|
1234
1261
|
/**
|
|
@@ -1239,14 +1266,14 @@ class Protractor extends Helper {
|
|
|
1239
1266
|
* ```
|
|
1240
1267
|
*/
|
|
1241
1268
|
async closeCurrentTab() {
|
|
1242
|
-
const client = this.browser
|
|
1269
|
+
const client = this.browser
|
|
1243
1270
|
|
|
1244
|
-
const currentHandle = await client.getWindowHandle()
|
|
1245
|
-
const nextHandle = await this._getWindowHandle(-1)
|
|
1271
|
+
const currentHandle = await client.getWindowHandle()
|
|
1272
|
+
const nextHandle = await this._getWindowHandle(-1)
|
|
1246
1273
|
|
|
1247
|
-
await client.switchTo().window(currentHandle)
|
|
1248
|
-
await client.close()
|
|
1249
|
-
return client.switchTo().window(nextHandle)
|
|
1274
|
+
await client.switchTo().window(currentHandle)
|
|
1275
|
+
await client.close()
|
|
1276
|
+
return client.switchTo().window(nextHandle)
|
|
1250
1277
|
}
|
|
1251
1278
|
|
|
1252
1279
|
/**
|
|
@@ -1254,12 +1281,12 @@ class Protractor extends Helper {
|
|
|
1254
1281
|
* @param {Number} offset Offset from current handle index. i.e. offset < 0 will go to the previous handle and positive number will go to the next window handle in sequence.
|
|
1255
1282
|
*/
|
|
1256
1283
|
async _getWindowHandle(offset = 0) {
|
|
1257
|
-
const client = this.browser
|
|
1258
|
-
const handles = await client.getAllWindowHandles()
|
|
1259
|
-
const index = handles.indexOf(await client.getWindowHandle())
|
|
1260
|
-
const nextIndex = index + offset
|
|
1284
|
+
const client = this.browser
|
|
1285
|
+
const handles = await client.getAllWindowHandles()
|
|
1286
|
+
const index = handles.indexOf(await client.getWindowHandle())
|
|
1287
|
+
const nextIndex = index + offset
|
|
1261
1288
|
|
|
1262
|
-
return handles[nextIndex]
|
|
1289
|
+
return handles[nextIndex]
|
|
1263
1290
|
// return handles[(index + offset) % handles.length];
|
|
1264
1291
|
}
|
|
1265
1292
|
|
|
@@ -1271,10 +1298,10 @@ class Protractor extends Helper {
|
|
|
1271
1298
|
* ```
|
|
1272
1299
|
*/
|
|
1273
1300
|
async openNewTab() {
|
|
1274
|
-
const client = this.browser
|
|
1275
|
-
await this.executeScript('window.open("about:blank")')
|
|
1276
|
-
const handles = await client.getAllWindowHandles()
|
|
1277
|
-
await client.switchTo().window(handles[handles.length - 1])
|
|
1301
|
+
const client = this.browser
|
|
1302
|
+
await this.executeScript('window.open("about:blank")')
|
|
1303
|
+
const handles = await client.getAllWindowHandles()
|
|
1304
|
+
await client.switchTo().window(handles[handles.length - 1])
|
|
1278
1305
|
}
|
|
1279
1306
|
|
|
1280
1307
|
/**
|
|
@@ -1286,13 +1313,13 @@ class Protractor extends Helper {
|
|
|
1286
1313
|
* ```
|
|
1287
1314
|
*/
|
|
1288
1315
|
async switchToNextTab(num = 1) {
|
|
1289
|
-
const client = this.browser
|
|
1290
|
-
const newHandle = await this._getWindowHandle(num)
|
|
1316
|
+
const client = this.browser
|
|
1317
|
+
const newHandle = await this._getWindowHandle(num)
|
|
1291
1318
|
|
|
1292
1319
|
if (!newHandle) {
|
|
1293
|
-
throw new Error(`There is no ability to switch to next tab with offset ${num}`)
|
|
1320
|
+
throw new Error(`There is no ability to switch to next tab with offset ${num}`)
|
|
1294
1321
|
}
|
|
1295
|
-
return client.switchTo().window(newHandle)
|
|
1322
|
+
return client.switchTo().window(newHandle)
|
|
1296
1323
|
}
|
|
1297
1324
|
|
|
1298
1325
|
/**
|
|
@@ -1304,21 +1331,21 @@ class Protractor extends Helper {
|
|
|
1304
1331
|
* ```
|
|
1305
1332
|
*/
|
|
1306
1333
|
async switchToPreviousTab(num = 1) {
|
|
1307
|
-
const client = this.browser
|
|
1308
|
-
const newHandle = await this._getWindowHandle(-1 * num)
|
|
1334
|
+
const client = this.browser
|
|
1335
|
+
const newHandle = await this._getWindowHandle(-1 * num)
|
|
1309
1336
|
|
|
1310
1337
|
if (!newHandle) {
|
|
1311
|
-
throw new Error(`There is no ability to switch to previous tab with offset ${num}`)
|
|
1338
|
+
throw new Error(`There is no ability to switch to previous tab with offset ${num}`)
|
|
1312
1339
|
}
|
|
1313
|
-
return client.switchTo().window(newHandle)
|
|
1340
|
+
return client.switchTo().window(newHandle)
|
|
1314
1341
|
}
|
|
1315
1342
|
|
|
1316
1343
|
/**
|
|
1317
1344
|
* {{> grabNumberOfOpenTabs }}
|
|
1318
1345
|
*/
|
|
1319
1346
|
async grabNumberOfOpenTabs() {
|
|
1320
|
-
const pages = await this.browser.getAllWindowHandles()
|
|
1321
|
-
return pages.length
|
|
1347
|
+
const pages = await this.browser.getAllWindowHandles()
|
|
1348
|
+
return pages.length
|
|
1322
1349
|
}
|
|
1323
1350
|
|
|
1324
1351
|
/**
|
|
@@ -1326,51 +1353,51 @@ class Protractor extends Helper {
|
|
|
1326
1353
|
*/
|
|
1327
1354
|
async switchTo(locator) {
|
|
1328
1355
|
if (Number.isInteger(locator)) {
|
|
1329
|
-
return this.browser.switchTo().frame(locator)
|
|
1356
|
+
return this.browser.switchTo().frame(locator)
|
|
1330
1357
|
}
|
|
1331
1358
|
if (!locator) {
|
|
1332
|
-
return this.browser.switchTo().frame(null)
|
|
1359
|
+
return this.browser.switchTo().frame(null)
|
|
1333
1360
|
}
|
|
1334
1361
|
|
|
1335
|
-
const els = await this._locate(withStrictLocator.call(this, locator), true)
|
|
1336
|
-
assertElementExists(els, locator)
|
|
1337
|
-
return this.browser.switchTo().frame(els[0])
|
|
1362
|
+
const els = await this._locate(withStrictLocator.call(this, locator), true)
|
|
1363
|
+
assertElementExists(els, locator)
|
|
1364
|
+
return this.browser.switchTo().frame(els[0])
|
|
1338
1365
|
}
|
|
1339
1366
|
|
|
1340
1367
|
/**
|
|
1341
1368
|
* {{> wait }}
|
|
1342
1369
|
*/
|
|
1343
1370
|
wait(sec) {
|
|
1344
|
-
return this.browser.sleep(sec * 1000)
|
|
1371
|
+
return this.browser.sleep(sec * 1000)
|
|
1345
1372
|
}
|
|
1346
1373
|
|
|
1347
1374
|
/**
|
|
1348
1375
|
* {{> waitForElement }}
|
|
1349
1376
|
*/
|
|
1350
1377
|
async waitForElement(locator, sec = null) {
|
|
1351
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1352
|
-
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1353
|
-
return this.browser.wait(EC.presenceOf(el), aSec * 1000)
|
|
1378
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1379
|
+
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1380
|
+
return this.browser.wait(EC.presenceOf(el), aSec * 1000)
|
|
1354
1381
|
}
|
|
1355
1382
|
|
|
1356
1383
|
async waitUntilExists(locator, sec = null) {
|
|
1357
1384
|
console.log(`waitUntilExists deprecated:
|
|
1358
1385
|
* use 'waitForElement' to wait for element to be attached
|
|
1359
|
-
* use 'waitForDetached to wait for element to be removed'`)
|
|
1360
|
-
return this.waitForDetached(locator, sec)
|
|
1386
|
+
* use 'waitForDetached to wait for element to be removed'`)
|
|
1387
|
+
return this.waitForDetached(locator, sec)
|
|
1361
1388
|
}
|
|
1362
1389
|
|
|
1363
1390
|
/**
|
|
1364
1391
|
* {{> waitForDetached }}
|
|
1365
1392
|
*/
|
|
1366
1393
|
async waitForDetached(locator, sec = null) {
|
|
1367
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1368
|
-
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1394
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1395
|
+
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1369
1396
|
return this.browser.wait(EC.not(EC.presenceOf(el)), aSec * 1000).catch((err) => {
|
|
1370
1397
|
if (err.message && err.message.indexOf('Wait timed out after') > -1) {
|
|
1371
|
-
throw new Error(`element (${JSON.stringify(locator)}) still on page after ${sec} sec`)
|
|
1372
|
-
} else throw err
|
|
1373
|
-
})
|
|
1398
|
+
throw new Error(`element (${JSON.stringify(locator)}) still on page after ${sec} sec`)
|
|
1399
|
+
} else throw err
|
|
1400
|
+
})
|
|
1374
1401
|
}
|
|
1375
1402
|
|
|
1376
1403
|
/**
|
|
@@ -1381,41 +1408,41 @@ class Protractor extends Helper {
|
|
|
1381
1408
|
* ```
|
|
1382
1409
|
*/
|
|
1383
1410
|
async waitForClickable(locator, sec = null) {
|
|
1384
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1385
|
-
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1386
|
-
return this.browser.wait(EC.elementToBeClickable(el), aSec * 1000)
|
|
1411
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1412
|
+
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1413
|
+
return this.browser.wait(EC.elementToBeClickable(el), aSec * 1000)
|
|
1387
1414
|
}
|
|
1388
1415
|
|
|
1389
1416
|
/**
|
|
1390
1417
|
* {{> waitForVisible }}
|
|
1391
1418
|
*/
|
|
1392
1419
|
async waitForVisible(locator, sec = null) {
|
|
1393
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1394
|
-
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1395
|
-
return this.browser.wait(EC.visibilityOf(el), aSec * 1000)
|
|
1420
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1421
|
+
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1422
|
+
return this.browser.wait(EC.visibilityOf(el), aSec * 1000)
|
|
1396
1423
|
}
|
|
1397
1424
|
|
|
1398
1425
|
/**
|
|
1399
1426
|
* {{> waitToHide }}
|
|
1400
1427
|
*/
|
|
1401
1428
|
async waitToHide(locator, sec = null) {
|
|
1402
|
-
return this.waitForInvisible(locator, sec)
|
|
1429
|
+
return this.waitForInvisible(locator, sec)
|
|
1403
1430
|
}
|
|
1404
1431
|
|
|
1405
1432
|
/**
|
|
1406
1433
|
* {{> waitForInvisible }}
|
|
1407
1434
|
*/
|
|
1408
1435
|
async waitForInvisible(locator, sec = null) {
|
|
1409
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1410
|
-
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1411
|
-
return this.browser.wait(EC.invisibilityOf(el), aSec * 1000)
|
|
1436
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1437
|
+
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1438
|
+
return this.browser.wait(EC.invisibilityOf(el), aSec * 1000)
|
|
1412
1439
|
}
|
|
1413
1440
|
|
|
1414
1441
|
async waitForStalenessOf(locator, sec = null) {
|
|
1415
1442
|
console.log(`waitForStalenessOf deprecated.
|
|
1416
1443
|
* Use waitForDetached to wait for element to be removed from page
|
|
1417
|
-
* Use waitForInvisible to wait for element to be hidden on page`)
|
|
1418
|
-
return this.waitForInvisible(locator, sec)
|
|
1444
|
+
* Use waitForInvisible to wait for element to be hidden on page`)
|
|
1445
|
+
return this.waitForInvisible(locator, sec)
|
|
1419
1446
|
}
|
|
1420
1447
|
|
|
1421
1448
|
/**
|
|
@@ -1424,114 +1451,112 @@ class Protractor extends Helper {
|
|
|
1424
1451
|
async waitNumberOfVisibleElements(locator, num, sec = null) {
|
|
1425
1452
|
function visibilityCountOf(loc, expectedCount) {
|
|
1426
1453
|
return function () {
|
|
1427
|
-
return global.element
|
|
1428
|
-
.
|
|
1454
|
+
return global.element
|
|
1455
|
+
.all(loc)
|
|
1456
|
+
.filter((el) => el.isDisplayed())
|
|
1429
1457
|
.count()
|
|
1430
|
-
.then(count => count === expectedCount)
|
|
1431
|
-
}
|
|
1458
|
+
.then((count) => count === expectedCount)
|
|
1459
|
+
}
|
|
1432
1460
|
}
|
|
1433
1461
|
|
|
1434
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1435
|
-
const guessLoc = guessLocator(locator) || global.by.css(locator)
|
|
1462
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1463
|
+
const guessLoc = guessLocator(locator) || global.by.css(locator)
|
|
1436
1464
|
|
|
1437
|
-
return this.browser.wait(visibilityCountOf(guessLoc, num), aSec * 1000)
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
});
|
|
1465
|
+
return this.browser.wait(visibilityCountOf(guessLoc, num), aSec * 1000).catch(() => {
|
|
1466
|
+
throw Error(`The number of elements (${new Locator(locator)}) is not ${num} after ${aSec} sec`)
|
|
1467
|
+
})
|
|
1441
1468
|
}
|
|
1442
1469
|
|
|
1443
1470
|
/**
|
|
1444
1471
|
* {{> waitForEnabled }}
|
|
1445
1472
|
*/
|
|
1446
1473
|
async waitForEnabled(locator, sec = null) {
|
|
1447
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1448
|
-
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1474
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1475
|
+
const el = global.element(guessLocator(locator) || global.by.css(locator))
|
|
1449
1476
|
|
|
1450
|
-
return this.browser.wait(EC.elementToBeClickable(el), aSec * 1000)
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
});
|
|
1477
|
+
return this.browser.wait(EC.elementToBeClickable(el), aSec * 1000).catch(() => {
|
|
1478
|
+
throw Error(`element (${new Locator(locator)}) still not enabled after ${aSec} sec`)
|
|
1479
|
+
})
|
|
1454
1480
|
}
|
|
1455
1481
|
|
|
1456
1482
|
/**
|
|
1457
1483
|
* {{> waitForValue }}
|
|
1458
1484
|
*/
|
|
1459
1485
|
async waitForValue(field, value, sec = null) {
|
|
1460
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1486
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1461
1487
|
|
|
1462
1488
|
const valueToBeInElementValue = (loc) => {
|
|
1463
1489
|
return async () => {
|
|
1464
|
-
const els = await findFields(this.browser, loc)
|
|
1490
|
+
const els = await findFields(this.browser, loc)
|
|
1465
1491
|
|
|
1466
1492
|
if (!els) {
|
|
1467
|
-
return false
|
|
1493
|
+
return false
|
|
1468
1494
|
}
|
|
1469
|
-
const values = await Promise.all(els.map(el => el.getAttribute('value')))
|
|
1470
|
-
return values.filter(part => part.indexOf(value) >= 0).length > 0
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1495
|
+
const values = await Promise.all(els.map((el) => el.getAttribute('value')))
|
|
1496
|
+
return values.filter((part) => part.indexOf(value) >= 0).length > 0
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1473
1499
|
|
|
1474
|
-
return this.browser.wait(valueToBeInElementValue(field, value), aSec * 1000)
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1500
|
+
return this.browser.wait(valueToBeInElementValue(field, value), aSec * 1000).catch(() => {
|
|
1501
|
+
throw Error(
|
|
1502
|
+
`element (${field}) is not in DOM or there is no element(${field}) with value "${value}" after ${aSec} sec`,
|
|
1503
|
+
)
|
|
1504
|
+
})
|
|
1478
1505
|
}
|
|
1479
1506
|
|
|
1480
1507
|
/**
|
|
1481
1508
|
* {{> waitForFunction }}
|
|
1482
1509
|
*/
|
|
1483
1510
|
async waitForFunction(fn, argsOrSec = null, sec = null) {
|
|
1484
|
-
let args = []
|
|
1511
|
+
let args = []
|
|
1485
1512
|
if (argsOrSec) {
|
|
1486
1513
|
if (Array.isArray(argsOrSec)) {
|
|
1487
|
-
args = argsOrSec
|
|
1514
|
+
args = argsOrSec
|
|
1488
1515
|
} else if (typeof argsOrSec === 'number') {
|
|
1489
|
-
sec = argsOrSec
|
|
1516
|
+
sec = argsOrSec
|
|
1490
1517
|
}
|
|
1491
1518
|
}
|
|
1492
1519
|
|
|
1493
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1494
|
-
return this.browser.wait(() => this.browser.executeScript.call(this.browser, fn, ...args), aSec * 1000)
|
|
1520
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1521
|
+
return this.browser.wait(() => this.browser.executeScript.call(this.browser, fn, ...args), aSec * 1000)
|
|
1495
1522
|
}
|
|
1496
1523
|
|
|
1497
1524
|
/**
|
|
1498
1525
|
* {{> waitInUrl }}
|
|
1499
1526
|
*/
|
|
1500
1527
|
async waitInUrl(urlPart, sec = null) {
|
|
1501
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1502
|
-
const waitTimeout = aSec * 1000
|
|
1503
|
-
|
|
1504
|
-
return this.browser.wait(EC.urlContains(urlPart), waitTimeout)
|
|
1505
|
-
.
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
});
|
|
1528
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1529
|
+
const waitTimeout = aSec * 1000
|
|
1530
|
+
|
|
1531
|
+
return this.browser.wait(EC.urlContains(urlPart), waitTimeout).catch(async (e) => {
|
|
1532
|
+
const currUrl = await this.browser.getCurrentUrl()
|
|
1533
|
+
if (/wait timed out after/i.test(e.message)) {
|
|
1534
|
+
throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`)
|
|
1535
|
+
} else {
|
|
1536
|
+
throw e
|
|
1537
|
+
}
|
|
1538
|
+
})
|
|
1513
1539
|
}
|
|
1514
1540
|
|
|
1515
1541
|
/**
|
|
1516
1542
|
* {{> waitUrlEquals }}
|
|
1517
1543
|
*/
|
|
1518
1544
|
async waitUrlEquals(urlPart, sec = null) {
|
|
1519
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1520
|
-
const waitTimeout = aSec * 1000
|
|
1521
|
-
const baseUrl = this.options.url
|
|
1545
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1546
|
+
const waitTimeout = aSec * 1000
|
|
1547
|
+
const baseUrl = this.options.url
|
|
1522
1548
|
if (urlPart.indexOf('http') < 0) {
|
|
1523
|
-
urlPart = baseUrl + urlPart
|
|
1549
|
+
urlPart = baseUrl + urlPart
|
|
1524
1550
|
}
|
|
1525
1551
|
|
|
1526
|
-
return this.browser.wait(EC.urlIs(urlPart), waitTimeout)
|
|
1527
|
-
.
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
});
|
|
1552
|
+
return this.browser.wait(EC.urlIs(urlPart), waitTimeout).catch(async (e) => {
|
|
1553
|
+
const currUrl = await this.browser.getCurrentUrl()
|
|
1554
|
+
if (/wait timed out after/i.test(e.message)) {
|
|
1555
|
+
throw new Error(`expected url to be ${urlPart}, but found ${currUrl}`)
|
|
1556
|
+
} else {
|
|
1557
|
+
throw e
|
|
1558
|
+
}
|
|
1559
|
+
})
|
|
1535
1560
|
}
|
|
1536
1561
|
|
|
1537
1562
|
/**
|
|
@@ -1539,11 +1564,11 @@ class Protractor extends Helper {
|
|
|
1539
1564
|
*/
|
|
1540
1565
|
async waitForText(text, sec = null, context = null) {
|
|
1541
1566
|
if (!context) {
|
|
1542
|
-
context = this.context
|
|
1567
|
+
context = this.context
|
|
1543
1568
|
}
|
|
1544
|
-
const el = global.element(guessLocator(context) || global.by.css(context))
|
|
1545
|
-
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1546
|
-
return this.browser.wait(EC.textToBePresentInElement(el, text), aSec * 1000)
|
|
1569
|
+
const el = global.element(guessLocator(context) || global.by.css(context))
|
|
1570
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds
|
|
1571
|
+
return this.browser.wait(EC.textToBePresentInElement(el, text), aSec * 1000)
|
|
1547
1572
|
}
|
|
1548
1573
|
|
|
1549
1574
|
// ANGULAR SPECIFIC
|
|
@@ -1552,22 +1577,22 @@ class Protractor extends Helper {
|
|
|
1552
1577
|
* Moves to url
|
|
1553
1578
|
*/
|
|
1554
1579
|
moveTo(path) {
|
|
1555
|
-
return this.browser.setLocation(path)
|
|
1580
|
+
return this.browser.setLocation(path)
|
|
1556
1581
|
}
|
|
1557
1582
|
|
|
1558
1583
|
/**
|
|
1559
1584
|
* {{> refreshPage }}
|
|
1560
1585
|
*/
|
|
1561
1586
|
refreshPage() {
|
|
1562
|
-
return this.browser.refresh()
|
|
1587
|
+
return this.browser.refresh()
|
|
1563
1588
|
}
|
|
1564
1589
|
|
|
1565
1590
|
/**
|
|
1566
1591
|
* Reloads page
|
|
1567
1592
|
*/
|
|
1568
1593
|
refresh() {
|
|
1569
|
-
console.log('Deprecated in favor of refreshPage')
|
|
1570
|
-
return this.browser.refresh()
|
|
1594
|
+
console.log('Deprecated in favor of refreshPage')
|
|
1595
|
+
return this.browser.refresh()
|
|
1571
1596
|
}
|
|
1572
1597
|
|
|
1573
1598
|
/**
|
|
@@ -1575,67 +1600,70 @@ class Protractor extends Helper {
|
|
|
1575
1600
|
*/
|
|
1576
1601
|
async scrollTo(locator, offsetX = 0, offsetY = 0) {
|
|
1577
1602
|
if (typeof locator === 'number' && typeof offsetX === 'number') {
|
|
1578
|
-
offsetY = offsetX
|
|
1579
|
-
offsetX = locator
|
|
1580
|
-
locator = null
|
|
1603
|
+
offsetY = offsetX
|
|
1604
|
+
offsetX = locator
|
|
1605
|
+
locator = null
|
|
1581
1606
|
}
|
|
1582
1607
|
|
|
1583
1608
|
if (locator) {
|
|
1584
|
-
const res = await this._locate(locator, true)
|
|
1609
|
+
const res = await this._locate(locator, true)
|
|
1585
1610
|
if (!res || res.length === 0) {
|
|
1586
|
-
return truth(`elements of ${
|
|
1611
|
+
return truth(`elements of ${new Locator(locator)}`, 'to be seen').assert(false)
|
|
1587
1612
|
}
|
|
1588
|
-
const elem = res[0]
|
|
1589
|
-
const location = await elem.getLocation()
|
|
1590
|
-
|
|
1591
|
-
return this.executeScript(
|
|
1592
|
-
|
|
1613
|
+
const elem = res[0]
|
|
1614
|
+
const location = await elem.getLocation()
|
|
1615
|
+
|
|
1616
|
+
return this.executeScript(
|
|
1617
|
+
function (x, y) {
|
|
1618
|
+
return window.scrollTo(x, y)
|
|
1619
|
+
},
|
|
1620
|
+
location.x + offsetX,
|
|
1621
|
+
location.y + offsetY,
|
|
1622
|
+
)
|
|
1593
1623
|
}
|
|
1594
1624
|
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1625
|
+
return this.executeScript(
|
|
1626
|
+
function (x, y) {
|
|
1627
|
+
return window.scrollTo(x, y)
|
|
1628
|
+
},
|
|
1629
|
+
offsetX,
|
|
1630
|
+
offsetY,
|
|
1631
|
+
)
|
|
1598
1632
|
}
|
|
1599
1633
|
|
|
1600
1634
|
/**
|
|
1601
1635
|
* {{> scrollPageToTop }}
|
|
1602
1636
|
*/
|
|
1603
1637
|
async scrollPageToTop() {
|
|
1604
|
-
return this.executeScript('window.scrollTo(0, 0);')
|
|
1638
|
+
return this.executeScript('window.scrollTo(0, 0);')
|
|
1605
1639
|
}
|
|
1606
1640
|
|
|
1607
1641
|
/**
|
|
1608
1642
|
* {{> scrollPageToBottom }}
|
|
1609
1643
|
*/
|
|
1610
1644
|
async scrollPageToBottom() {
|
|
1611
|
-
/* eslint-disable prefer-arrow-callback, comma-dangle */
|
|
1612
1645
|
return this.executeScript(function () {
|
|
1613
|
-
const body = document.body
|
|
1614
|
-
const html = document.documentElement
|
|
1615
|
-
window.scrollTo(
|
|
1616
|
-
|
|
1617
|
-
body.offsetHeight,
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
html.offsetHeight
|
|
1621
|
-
));
|
|
1622
|
-
});
|
|
1623
|
-
/* eslint-enable */
|
|
1646
|
+
const body = document.body
|
|
1647
|
+
const html = document.documentElement
|
|
1648
|
+
window.scrollTo(
|
|
1649
|
+
0,
|
|
1650
|
+
Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
|
|
1651
|
+
)
|
|
1652
|
+
})
|
|
1624
1653
|
}
|
|
1625
1654
|
|
|
1626
1655
|
/**
|
|
1627
1656
|
* {{> grabPageScrollPosition }}
|
|
1628
1657
|
*/
|
|
1629
1658
|
async grabPageScrollPosition() {
|
|
1630
|
-
/* eslint-disable comma-dangle */
|
|
1631
1659
|
function getScrollPosition() {
|
|
1632
1660
|
return {
|
|
1633
1661
|
x: window.pageXOffset,
|
|
1634
|
-
y: window.pageYOffset
|
|
1635
|
-
}
|
|
1662
|
+
y: window.pageYOffset,
|
|
1663
|
+
}
|
|
1636
1664
|
}
|
|
1637
|
-
|
|
1638
|
-
return this.executeScript(getScrollPosition)
|
|
1665
|
+
|
|
1666
|
+
return this.executeScript(getScrollPosition)
|
|
1639
1667
|
}
|
|
1640
1668
|
|
|
1641
1669
|
/**
|
|
@@ -1648,7 +1676,7 @@ class Protractor extends Helper {
|
|
|
1648
1676
|
* ```
|
|
1649
1677
|
*/
|
|
1650
1678
|
haveModule(modName, fn) {
|
|
1651
|
-
return this.browser.addMockModule(modName, fn)
|
|
1679
|
+
return this.browser.addMockModule(modName, fn)
|
|
1652
1680
|
}
|
|
1653
1681
|
|
|
1654
1682
|
/**
|
|
@@ -1661,175 +1689,175 @@ class Protractor extends Helper {
|
|
|
1661
1689
|
*/
|
|
1662
1690
|
resetModule(modName) {
|
|
1663
1691
|
if (!modName) {
|
|
1664
|
-
return this.browser.clearMockModules()
|
|
1692
|
+
return this.browser.clearMockModules()
|
|
1665
1693
|
}
|
|
1666
|
-
return this.browser.removeMockModule(modName)
|
|
1694
|
+
return this.browser.removeMockModule(modName)
|
|
1667
1695
|
}
|
|
1668
1696
|
|
|
1669
1697
|
/**
|
|
1670
1698
|
* {{> setCookie }}
|
|
1671
1699
|
*/
|
|
1672
1700
|
setCookie(cookie) {
|
|
1673
|
-
return this.browser.manage().addCookie(cookie)
|
|
1701
|
+
return this.browser.manage().addCookie(cookie)
|
|
1674
1702
|
}
|
|
1675
1703
|
}
|
|
1676
1704
|
|
|
1677
|
-
|
|
1705
|
+
module.exports = Protractor
|
|
1678
1706
|
|
|
1679
1707
|
async function findCheckable(client, locator) {
|
|
1680
|
-
const matchedLocator = guessLocator(locator)
|
|
1708
|
+
const matchedLocator = guessLocator(locator)
|
|
1681
1709
|
if (matchedLocator) {
|
|
1682
|
-
return client.findElements(matchedLocator)
|
|
1710
|
+
return client.findElements(matchedLocator)
|
|
1683
1711
|
}
|
|
1684
|
-
const literal = xpathLocator.literal(locator)
|
|
1685
|
-
let els = await client.findElements(global.by.xpath(Locator.checkable.byText(literal)))
|
|
1712
|
+
const literal = xpathLocator.literal(locator)
|
|
1713
|
+
let els = await client.findElements(global.by.xpath(Locator.checkable.byText(literal)))
|
|
1686
1714
|
if (els.length) {
|
|
1687
|
-
return els
|
|
1715
|
+
return els
|
|
1688
1716
|
}
|
|
1689
|
-
els = await client.findElements(global.by.xpath(Locator.checkable.byName(literal)))
|
|
1717
|
+
els = await client.findElements(global.by.xpath(Locator.checkable.byName(literal)))
|
|
1690
1718
|
if (els.length) {
|
|
1691
|
-
return els
|
|
1719
|
+
return els
|
|
1692
1720
|
}
|
|
1693
|
-
return client.findElements(global.by.css(locator))
|
|
1721
|
+
return client.findElements(global.by.css(locator))
|
|
1694
1722
|
}
|
|
1695
1723
|
|
|
1696
1724
|
function withStrictLocator(locator) {
|
|
1697
|
-
locator = new Locator(locator)
|
|
1698
|
-
if (locator.isAccessibilityId()) return withAccessiblitiyLocator.call(this, locator.value)
|
|
1699
|
-
return locator.simplify()
|
|
1725
|
+
locator = new Locator(locator)
|
|
1726
|
+
if (locator.isAccessibilityId()) return withAccessiblitiyLocator.call(this, locator.value)
|
|
1727
|
+
return locator.simplify()
|
|
1700
1728
|
}
|
|
1701
1729
|
|
|
1702
1730
|
function withAccessiblitiyLocator(locator) {
|
|
1703
1731
|
if (this.isWeb === false) {
|
|
1704
|
-
return `accessibility id:${locator.slice(1)}
|
|
1732
|
+
return `accessibility id:${locator.slice(1)}`
|
|
1705
1733
|
}
|
|
1706
|
-
return `[aria-label="${locator.slice(1)}"]
|
|
1734
|
+
return `[aria-label="${locator.slice(1)}"]`
|
|
1707
1735
|
// hook before webdriverio supports native ~ locators in web
|
|
1708
1736
|
}
|
|
1709
1737
|
|
|
1710
1738
|
async function findFields(client, locator) {
|
|
1711
|
-
const matchedLocator = guessLocator(locator)
|
|
1739
|
+
const matchedLocator = guessLocator(locator)
|
|
1712
1740
|
if (matchedLocator) {
|
|
1713
|
-
return client.findElements(matchedLocator)
|
|
1741
|
+
return client.findElements(matchedLocator)
|
|
1714
1742
|
}
|
|
1715
|
-
const literal = xpathLocator.literal(locator)
|
|
1743
|
+
const literal = xpathLocator.literal(locator)
|
|
1716
1744
|
|
|
1717
|
-
let els = await client.findElements(global.by.xpath(Locator.field.labelEquals(literal)))
|
|
1745
|
+
let els = await client.findElements(global.by.xpath(Locator.field.labelEquals(literal)))
|
|
1718
1746
|
if (els.length) {
|
|
1719
|
-
return els
|
|
1747
|
+
return els
|
|
1720
1748
|
}
|
|
1721
1749
|
|
|
1722
|
-
els = await client.findElements(global.by.xpath(Locator.field.labelContains(literal)))
|
|
1750
|
+
els = await client.findElements(global.by.xpath(Locator.field.labelContains(literal)))
|
|
1723
1751
|
if (els.length) {
|
|
1724
|
-
return els
|
|
1752
|
+
return els
|
|
1725
1753
|
}
|
|
1726
|
-
els = await client.findElements(global.by.xpath(Locator.field.byName(literal)))
|
|
1754
|
+
els = await client.findElements(global.by.xpath(Locator.field.byName(literal)))
|
|
1727
1755
|
if (els.length) {
|
|
1728
|
-
return els
|
|
1756
|
+
return els
|
|
1729
1757
|
}
|
|
1730
|
-
return client.findElements(global.by.css(locator))
|
|
1758
|
+
return client.findElements(global.by.css(locator))
|
|
1731
1759
|
}
|
|
1732
1760
|
|
|
1733
1761
|
async function proceedSee(assertType, text, context) {
|
|
1734
|
-
let description
|
|
1735
|
-
let locator
|
|
1762
|
+
let description
|
|
1763
|
+
let locator
|
|
1736
1764
|
if (!context) {
|
|
1737
1765
|
if (this.context === this.options.rootElement) {
|
|
1738
|
-
locator = guessLocator(this.context) || global.by.css(this.context)
|
|
1739
|
-
description = 'web application'
|
|
1766
|
+
locator = guessLocator(this.context) || global.by.css(this.context)
|
|
1767
|
+
description = 'web application'
|
|
1740
1768
|
} else {
|
|
1741
1769
|
// inside within block
|
|
1742
|
-
locator = global.by.xpath('.//*')
|
|
1743
|
-
description = `current context ${
|
|
1770
|
+
locator = global.by.xpath('.//*')
|
|
1771
|
+
description = `current context ${new Locator(context).toString()}`
|
|
1744
1772
|
}
|
|
1745
1773
|
} else {
|
|
1746
|
-
locator = guessLocator(context) || global.by.css(context)
|
|
1747
|
-
description = `element ${
|
|
1748
|
-
}
|
|
1749
|
-
const enableSmartWait = !!this.context && assertType === 'assert'
|
|
1750
|
-
const els = await this._smartWait(() => this.browser.findElements(locator), enableSmartWait)
|
|
1751
|
-
const promises = []
|
|
1752
|
-
let source = ''
|
|
1753
|
-
els.forEach(el => promises.push(el.getText().then(elText => source += `| ${elText}`)))
|
|
1754
|
-
await Promise.all(promises)
|
|
1755
|
-
return stringIncludes(description)[assertType](text, source)
|
|
1774
|
+
locator = guessLocator(context) || global.by.css(context)
|
|
1775
|
+
description = `element ${new Locator(context).toString()}`
|
|
1776
|
+
}
|
|
1777
|
+
const enableSmartWait = !!this.context && assertType === 'assert'
|
|
1778
|
+
const els = await this._smartWait(() => this.browser.findElements(locator), enableSmartWait)
|
|
1779
|
+
const promises = []
|
|
1780
|
+
let source = ''
|
|
1781
|
+
els.forEach((el) => promises.push(el.getText().then((elText) => (source += `| ${elText}`))))
|
|
1782
|
+
await Promise.all(promises)
|
|
1783
|
+
return stringIncludes(description)[assertType](text, source)
|
|
1756
1784
|
}
|
|
1757
1785
|
|
|
1758
1786
|
async function proceedSeeInField(assertType, field, value) {
|
|
1759
|
-
const els = await findFields(this.browser, field)
|
|
1760
|
-
assertElementExists(els, field, 'Field')
|
|
1761
|
-
const el = els[0]
|
|
1762
|
-
const tag = await el.getTagName()
|
|
1763
|
-
const fieldVal = await el.getAttribute('value')
|
|
1787
|
+
const els = await findFields(this.browser, field)
|
|
1788
|
+
assertElementExists(els, field, 'Field')
|
|
1789
|
+
const el = els[0]
|
|
1790
|
+
const tag = await el.getTagName()
|
|
1791
|
+
const fieldVal = await el.getAttribute('value')
|
|
1764
1792
|
if (tag === 'select') {
|
|
1765
1793
|
// locate option by values and check them
|
|
1766
|
-
const literal = xpathLocator.literal(fieldVal)
|
|
1767
|
-
const textEl = await el.findElement(global.by.xpath(Locator.select.byValue(literal)))
|
|
1768
|
-
const text = await textEl.getText()
|
|
1769
|
-
return equals(`select option by ${field}`)[assertType](value, text)
|
|
1794
|
+
const literal = xpathLocator.literal(fieldVal)
|
|
1795
|
+
const textEl = await el.findElement(global.by.xpath(Locator.select.byValue(literal)))
|
|
1796
|
+
const text = await textEl.getText()
|
|
1797
|
+
return equals(`select option by ${field}`)[assertType](value, text)
|
|
1770
1798
|
}
|
|
1771
|
-
return stringIncludes(`field by ${field}`)[assertType](value, fieldVal)
|
|
1799
|
+
return stringIncludes(`field by ${field}`)[assertType](value, fieldVal)
|
|
1772
1800
|
}
|
|
1773
1801
|
|
|
1774
1802
|
async function proceedIsChecked(assertType, option) {
|
|
1775
|
-
const els = await findCheckable(this.browser, option)
|
|
1776
|
-
assertElementExists(els, option, 'Option')
|
|
1777
|
-
const elsSelected = []
|
|
1778
|
-
els.forEach(el => elsSelected.push(el.isSelected()))
|
|
1779
|
-
const values = await Promise.all(elsSelected)
|
|
1780
|
-
const selected = values.reduce((prev, cur) => prev || cur)
|
|
1781
|
-
return truth(`checkable ${option}`, 'to be checked')[assertType](selected)
|
|
1803
|
+
const els = await findCheckable(this.browser, option)
|
|
1804
|
+
assertElementExists(els, option, 'Option')
|
|
1805
|
+
const elsSelected = []
|
|
1806
|
+
els.forEach((el) => elsSelected.push(el.isSelected()))
|
|
1807
|
+
const values = await Promise.all(elsSelected)
|
|
1808
|
+
const selected = values.reduce((prev, cur) => prev || cur)
|
|
1809
|
+
return truth(`checkable ${option}`, 'to be checked')[assertType](selected)
|
|
1782
1810
|
}
|
|
1783
1811
|
|
|
1784
1812
|
async function findClickable(matcher, locator) {
|
|
1785
|
-
locator = new Locator(locator)
|
|
1813
|
+
locator = new Locator(locator)
|
|
1786
1814
|
if (!locator.isFuzzy()) {
|
|
1787
|
-
const els = await this._locate(locator, true)
|
|
1788
|
-
assertElementExists(els, locator.value)
|
|
1789
|
-
return els[0]
|
|
1815
|
+
const els = await this._locate(locator, true)
|
|
1816
|
+
assertElementExists(els, locator.value)
|
|
1817
|
+
return els[0]
|
|
1790
1818
|
}
|
|
1791
|
-
const literal = xpathLocator.literal(locator.value)
|
|
1792
|
-
const narrowLocator = Locator.clickable.narrow(literal)
|
|
1793
|
-
let els = await matcher.findElements(global.by.xpath(narrowLocator))
|
|
1819
|
+
const literal = xpathLocator.literal(locator.value)
|
|
1820
|
+
const narrowLocator = Locator.clickable.narrow(literal)
|
|
1821
|
+
let els = await matcher.findElements(global.by.xpath(narrowLocator))
|
|
1794
1822
|
if (els.length) {
|
|
1795
|
-
return els[0]
|
|
1823
|
+
return els[0]
|
|
1796
1824
|
}
|
|
1797
1825
|
|
|
1798
|
-
els = await matcher.findElements(global.by.xpath(Locator.clickable.wide(literal)))
|
|
1826
|
+
els = await matcher.findElements(global.by.xpath(Locator.clickable.wide(literal)))
|
|
1799
1827
|
if (els.length) {
|
|
1800
|
-
return els[0]
|
|
1828
|
+
return els[0]
|
|
1801
1829
|
}
|
|
1802
|
-
return matcher.findElement(global.by.css(locator.value))
|
|
1830
|
+
return matcher.findElement(global.by.css(locator.value))
|
|
1803
1831
|
}
|
|
1804
1832
|
|
|
1805
1833
|
function guessLocator(locator) {
|
|
1806
|
-
const l = new Locator(locator)
|
|
1807
|
-
if (l.isFuzzy()) return false
|
|
1808
|
-
if (l.type) return global.by[l.type](l.value)
|
|
1809
|
-
return false
|
|
1834
|
+
const l = new Locator(locator)
|
|
1835
|
+
if (l.isFuzzy()) return false
|
|
1836
|
+
if (l.type) return global.by[l.type](l.value)
|
|
1837
|
+
return false
|
|
1810
1838
|
}
|
|
1811
1839
|
|
|
1812
1840
|
function assertElementExists(res, locator, prefix, suffix) {
|
|
1813
1841
|
if (!res.length) {
|
|
1814
|
-
throw new ElementNotFound(locator, prefix, suffix)
|
|
1842
|
+
throw new ElementNotFound(locator, prefix, suffix)
|
|
1815
1843
|
}
|
|
1816
1844
|
}
|
|
1817
1845
|
|
|
1818
1846
|
function isFrameLocator(locator) {
|
|
1819
|
-
locator = new Locator(locator)
|
|
1820
|
-
if (locator.isFrame()) return locator.value
|
|
1821
|
-
return false
|
|
1847
|
+
locator = new Locator(locator)
|
|
1848
|
+
if (locator.isFrame()) return locator.value
|
|
1849
|
+
return false
|
|
1822
1850
|
}
|
|
1823
1851
|
|
|
1824
1852
|
function isWithin() {
|
|
1825
|
-
return Object.keys(withinStore).length !== 0
|
|
1853
|
+
return Object.keys(withinStore).length !== 0
|
|
1826
1854
|
}
|
|
1827
1855
|
|
|
1828
1856
|
function loadGlobals(browser) {
|
|
1829
|
-
global.browser = browser
|
|
1830
|
-
global.$ = browser
|
|
1831
|
-
global.$$ = browser
|
|
1832
|
-
global.element = browser.element
|
|
1833
|
-
global.by = global.By = new ProtractorBy()
|
|
1834
|
-
global.ExpectedConditions = EC = new ProtractorExpectedConditions(browser)
|
|
1857
|
+
global.browser = browser
|
|
1858
|
+
global.$ = browser.$
|
|
1859
|
+
global.$$ = browser.$$
|
|
1860
|
+
global.element = browser.element
|
|
1861
|
+
global.by = global.By = new ProtractorBy()
|
|
1862
|
+
global.ExpectedConditions = EC = new ProtractorExpectedConditions(browser)
|
|
1835
1863
|
}
|