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