codeceptjs 4.0.0-beta.4 → 4.0.0-beta.6.esm-aria
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -119
- package/bin/codecept.js +53 -54
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +70 -102
- package/lib/ai.js +131 -121
- package/lib/assert/empty.js +11 -12
- package/lib/assert/equal.js +16 -21
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +11 -15
- package/lib/assert/throws.js +3 -5
- package/lib/assert/truth.js +10 -7
- package/lib/assert.js +18 -18
- package/lib/codecept.js +112 -101
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +13 -14
- package/lib/command/definitions.js +24 -36
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +38 -39
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +49 -15
- package/lib/command/init.js +41 -37
- package/lib/command/interactive.js +22 -13
- package/lib/command/list.js +11 -10
- package/lib/command/run-multiple/chunk.js +50 -47
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +27 -47
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +15 -66
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +22 -21
- package/lib/command/workers/runTests.js +131 -241
- package/lib/config.js +111 -49
- package/lib/container.js +589 -244
- package/lib/data/context.js +16 -18
- package/lib/data/dataScenarioConfig.js +9 -9
- package/lib/data/dataTableArgument.js +7 -7
- package/lib/data/table.js +6 -12
- package/lib/effects.js +307 -0
- package/lib/els.js +160 -0
- package/lib/event.js +24 -19
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -81
- package/lib/helper/AI.js +3 -2
- package/lib/helper/ApiDataFactory.js +19 -19
- package/lib/helper/Appium.js +47 -51
- package/lib/helper/FileSystem.js +35 -15
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +4 -4
- package/lib/helper/JSONResponse.js +72 -45
- package/lib/helper/Mochawesome.js +14 -11
- package/lib/helper/Playwright.js +832 -434
- package/lib/helper/Puppeteer.js +393 -292
- package/lib/helper/REST.js +32 -27
- package/lib/helper/WebDriver.js +320 -219
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +33 -48
- package/lib/helper/network/utils.js +76 -83
- package/lib/helper/scripts/blurElement.js +6 -6
- package/lib/helper/scripts/focusElement.js +6 -6
- package/lib/helper/scripts/highlightElement.js +9 -9
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -1
- package/lib/history.js +23 -20
- package/lib/hooks.js +10 -10
- package/lib/html.js +90 -100
- package/lib/index.js +48 -21
- package/lib/listener/config.js +8 -9
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/exit.js +10 -12
- package/lib/listener/{retry.js → globalRetry.js} +10 -10
- package/lib/listener/globalTimeout.js +166 -0
- package/lib/listener/helpers.js +43 -24
- package/lib/listener/mocha.js +4 -5
- package/lib/listener/result.js +11 -0
- package/lib/listener/steps.js +26 -23
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +264 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +160 -0
- package/lib/{interfaces → mocha}/featureConfig.js +33 -13
- package/lib/{interfaces → mocha}/gherkin.js +75 -45
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +32 -8
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +178 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +229 -0
- package/lib/output.js +86 -64
- package/lib/parser.js +44 -44
- package/lib/pause.js +160 -139
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +137 -43
- package/lib/plugin/autoDelay.js +19 -15
- package/lib/plugin/coverage.js +22 -27
- package/lib/plugin/customLocator.js +5 -5
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/heal.js +49 -17
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +60 -19
- package/lib/plugin/screenshotOnFail.js +80 -83
- package/lib/plugin/stepByStepReport.js +70 -31
- package/lib/plugin/stepTimeout.js +7 -13
- package/lib/plugin/subtitles.js +10 -9
- package/lib/recorder.js +167 -126
- package/lib/rerun.js +94 -50
- package/lib/result.js +161 -0
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -332
- package/lib/steps.js +54 -0
- package/lib/store.js +37 -5
- package/lib/template/heal.js +2 -11
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +354 -250
- package/lib/workerStorage.js +16 -16
- package/lib/workers.js +366 -282
- package/package.json +107 -95
- package/translations/de-DE.js +5 -4
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +23 -9
- package/translations/it-IT.js +5 -4
- package/translations/ja-JP.js +5 -4
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +5 -4
- package/translations/pt-BR.js +5 -4
- package/translations/ru-RU.js +5 -4
- package/translations/utils.js +18 -0
- package/translations/zh-CN.js +5 -4
- package/translations/zh-TW.js +5 -4
- package/typings/index.d.ts +177 -186
- package/typings/promiseBasedTypes.d.ts +3573 -5941
- package/typings/types.d.ts +4042 -6370
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/Nightmare.js +0 -1504
- package/lib/helper/Protractor.js +0 -1863
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1414
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -62
- package/lib/interfaces/bdd.js +0 -81
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -113
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -127
- package/lib/plugin/selenoid.js +0 -384
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/plugin/tryTo.js +0 -115
- package/lib/plugin/wdio.js +0 -249
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
- package/lib/within.js +0 -70
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const REST = require('./REST')
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import Helper from '@codeceptjs/helper'
|
|
3
|
+
import REST from './REST.js'
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Helper for managing remote data using REST API.
|
|
@@ -217,15 +216,16 @@ class ApiDataFactory extends Helper {
|
|
|
217
216
|
}
|
|
218
217
|
|
|
219
218
|
this.created = {}
|
|
220
|
-
Object.keys(this.factories).forEach(
|
|
219
|
+
Object.keys(this.factories).forEach(f => (this.created[f] = []))
|
|
221
220
|
}
|
|
222
221
|
|
|
223
222
|
static _checkRequirements() {
|
|
224
223
|
try {
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
// In ESM, dependencies are already imported at the top
|
|
225
|
+
// The import will fail at module load time if dependencies are missing
|
|
226
|
+
return null
|
|
227
227
|
} catch (e) {
|
|
228
|
-
return ['axios'
|
|
228
|
+
return ['axios']
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
@@ -265,8 +265,8 @@ class ApiDataFactory extends Helper {
|
|
|
265
265
|
* @param {*} [options] options for programmatically generate the attributes
|
|
266
266
|
* @returns {Promise<*>}
|
|
267
267
|
*/
|
|
268
|
-
have(factory, params, options) {
|
|
269
|
-
const item = this._createItem(factory, params, options)
|
|
268
|
+
async have(factory, params, options) {
|
|
269
|
+
const item = await this._createItem(factory, params, options)
|
|
270
270
|
this.debug(`Creating ${factory} ${JSON.stringify(item)}`)
|
|
271
271
|
return this._requestCreate(factory, item)
|
|
272
272
|
}
|
|
@@ -298,19 +298,22 @@ class ApiDataFactory extends Helper {
|
|
|
298
298
|
return Promise.all(promises)
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
_createItem(model, data, options) {
|
|
301
|
+
async _createItem(model, data, options) {
|
|
302
302
|
if (!this.factories[model]) {
|
|
303
303
|
throw new Error(`Factory ${model} is not defined in config`)
|
|
304
304
|
}
|
|
305
305
|
let modulePath = this.factories[model].factory
|
|
306
306
|
try {
|
|
307
307
|
try {
|
|
308
|
-
|
|
308
|
+
// Try to resolve the path as-is first
|
|
309
|
+
await import.meta.resolve(modulePath)
|
|
309
310
|
} catch (e) {
|
|
311
|
+
// If not found, try relative to codecept_dir
|
|
310
312
|
modulePath = path.join(global.codecept_dir, modulePath)
|
|
311
313
|
}
|
|
312
314
|
// check if the new syntax `export default new Factory()` is used and loads the builder, otherwise loads the module that used old syntax `module.exports = new Factory()`.
|
|
313
|
-
const
|
|
315
|
+
const module = await import(modulePath)
|
|
316
|
+
const builder = module.default || module
|
|
314
317
|
return builder.build(data, options)
|
|
315
318
|
} catch (err) {
|
|
316
319
|
throw new Error(`Couldn't load factory file from ${modulePath}, check that
|
|
@@ -357,7 +360,7 @@ Current file error: ${err.message}`)
|
|
|
357
360
|
|
|
358
361
|
request.baseURL = this.config.endpoint
|
|
359
362
|
|
|
360
|
-
return this.restHelper._executeRequest(request).then(
|
|
363
|
+
return this.restHelper._executeRequest(request).then(resp => {
|
|
361
364
|
const id = this._fetchId(resp.data, factory)
|
|
362
365
|
this.created[factory].push(id)
|
|
363
366
|
this.debugSection('Created', `Id: ${id}`)
|
|
@@ -391,10 +394,7 @@ Current file error: ${err.message}`)
|
|
|
391
394
|
request.baseURL = this.config.endpoint
|
|
392
395
|
|
|
393
396
|
if (request.url.match(/^undefined/)) {
|
|
394
|
-
return this.debugSection(
|
|
395
|
-
'Please configure the delete request in your ApiDataFactory helper',
|
|
396
|
-
"delete: () => ({ method: 'DELETE', url: '/api/users' })",
|
|
397
|
-
)
|
|
397
|
+
return this.debugSection('Please configure the delete request in your ApiDataFactory helper', "delete: () => ({ method: 'DELETE', url: '/api/users' })")
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
return this.restHelper._executeRequest(request).then(() => {
|
|
@@ -405,7 +405,7 @@ Current file error: ${err.message}`)
|
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
|
|
408
|
+
export { ApiDataFactory as default }
|
|
409
409
|
|
|
410
410
|
function createRequestFromFunction(param, data) {
|
|
411
411
|
if (typeof param !== 'function') return
|
package/lib/helper/Appium.js
CHANGED
|
@@ -44,7 +44,7 @@ const vendorPrefix = {
|
|
|
44
44
|
*
|
|
45
45
|
* This helper should be configured in codecept.conf.ts or codecept.conf.js
|
|
46
46
|
*
|
|
47
|
-
* * `appiumV2`: set this to
|
|
47
|
+
* * `appiumV2`: by default is true, set this to false if you want to run tests with AppiumV1. See more how to setup [here](https://codecept.io/mobile/#setting-up)
|
|
48
48
|
* * `app`: Application path. Local path or remote URL to an .ipa or .apk file, or a .zip containing one of these. Alias to desiredCapabilities.appPackage
|
|
49
49
|
* * `host`: (default: 'localhost') Appium host
|
|
50
50
|
* * `port`: (default: '4723') Appium port
|
|
@@ -124,7 +124,7 @@ const vendorPrefix = {
|
|
|
124
124
|
* {
|
|
125
125
|
* helpers: {
|
|
126
126
|
* Appium: {
|
|
127
|
-
* appiumV2: true,
|
|
127
|
+
* appiumV2: true, // By default is true, set to false if you want to run against Appium v1
|
|
128
128
|
* host: "hub-cloud.browserstack.com",
|
|
129
129
|
* port: 4444,
|
|
130
130
|
* user: process.env.BROWSERSTACK_USER,
|
|
@@ -178,16 +178,12 @@ class Appium extends Webdriver {
|
|
|
178
178
|
super(config)
|
|
179
179
|
|
|
180
180
|
this.isRunning = false
|
|
181
|
-
|
|
182
|
-
this.appiumV2 = true
|
|
183
|
-
}
|
|
181
|
+
this.appiumV2 = config.appiumV2 || true
|
|
184
182
|
this.axios = axios.create()
|
|
185
183
|
|
|
186
184
|
webdriverio = require('webdriverio')
|
|
187
185
|
if (!config.appiumV2) {
|
|
188
|
-
console.log(
|
|
189
|
-
'The Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. Please migrating to Appium 2.x by adding appiumV2: true to your config.',
|
|
190
|
-
)
|
|
186
|
+
console.log('The Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. Appium 2.x is used by default.')
|
|
191
187
|
console.log('More info: https://bit.ly/appium-v2-migration')
|
|
192
188
|
console.log('This Appium 1.x support will be removed in next major release.')
|
|
193
189
|
}
|
|
@@ -234,20 +230,14 @@ class Appium extends Webdriver {
|
|
|
234
230
|
|
|
235
231
|
config.baseUrl = config.url || config.baseUrl
|
|
236
232
|
if (config.desiredCapabilities && Object.keys(config.desiredCapabilities).length) {
|
|
237
|
-
config.capabilities =
|
|
238
|
-
this.appiumV2 === true ? this._convertAppiumV2Caps(config.desiredCapabilities) : config.desiredCapabilities
|
|
233
|
+
config.capabilities = this.appiumV2 === true ? this._convertAppiumV2Caps(config.desiredCapabilities) : config.desiredCapabilities
|
|
239
234
|
}
|
|
240
235
|
|
|
241
236
|
if (this.appiumV2) {
|
|
242
|
-
config.capabilities[`${vendorPrefix.appium}:deviceName`] =
|
|
243
|
-
|
|
244
|
-
config.capabilities[`${vendorPrefix.appium}:
|
|
245
|
-
|
|
246
|
-
config.capabilities[`${vendorPrefix.appium}:app`] =
|
|
247
|
-
config[`${vendorPrefix.appium}:app`] || config.capabilities[`${vendorPrefix.appium}:app`]
|
|
248
|
-
config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] =
|
|
249
|
-
config[`${vendorPrefix.appium}:tunnelIdentifier`] ||
|
|
250
|
-
config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] // Adding the code to connect to sauce labs via sauce tunnel
|
|
237
|
+
config.capabilities[`${vendorPrefix.appium}:deviceName`] = config[`${vendorPrefix.appium}:device`] || config.capabilities[`${vendorPrefix.appium}:deviceName`]
|
|
238
|
+
config.capabilities[`${vendorPrefix.appium}:browserName`] = config[`${vendorPrefix.appium}:browser`] || config.capabilities[`${vendorPrefix.appium}:browserName`]
|
|
239
|
+
config.capabilities[`${vendorPrefix.appium}:app`] = config[`${vendorPrefix.appium}:app`] || config.capabilities[`${vendorPrefix.appium}:app`]
|
|
240
|
+
config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] = config[`${vendorPrefix.appium}:tunnelIdentifier`] || config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] // Adding the code to connect to sauce labs via sauce tunnel
|
|
251
241
|
} else {
|
|
252
242
|
config.capabilities.deviceName = config.device || config.capabilities.deviceName
|
|
253
243
|
config.capabilities.browserName = config.browser || config.capabilities.browserName
|
|
@@ -393,8 +383,10 @@ class Appium extends Webdriver {
|
|
|
393
383
|
|
|
394
384
|
_buildAppiumEndpoint() {
|
|
395
385
|
const { protocol, port, hostname, path } = this.browser.options
|
|
386
|
+
// Ensure path does NOT end with a slash to prevent double slashes
|
|
387
|
+
const normalizedPath = path.replace(/\/$/, '')
|
|
396
388
|
// Build path to Appium REST API endpoint
|
|
397
|
-
return `${protocol}://${hostname}:${port}${
|
|
389
|
+
return `${protocol}://${hostname}:${port}${normalizedPath}/session/${this.browser.sessionId}`
|
|
398
390
|
}
|
|
399
391
|
|
|
400
392
|
/**
|
|
@@ -610,7 +602,7 @@ class Appium extends Webdriver {
|
|
|
610
602
|
|
|
611
603
|
return this.axios({
|
|
612
604
|
method: 'post',
|
|
613
|
-
url: `${this._buildAppiumEndpoint()}/
|
|
605
|
+
url: `${this._buildAppiumEndpoint()}/appium/device/remove_app`,
|
|
614
606
|
data: { appId, bundleId },
|
|
615
607
|
})
|
|
616
608
|
}
|
|
@@ -627,7 +619,7 @@ class Appium extends Webdriver {
|
|
|
627
619
|
onlyForApps.call(this)
|
|
628
620
|
return this.axios({
|
|
629
621
|
method: 'post',
|
|
630
|
-
url: `${this._buildAppiumEndpoint()}/
|
|
622
|
+
url: `${this._buildAppiumEndpoint()}/appium/app/reset`,
|
|
631
623
|
})
|
|
632
624
|
}
|
|
633
625
|
|
|
@@ -701,7 +693,7 @@ class Appium extends Webdriver {
|
|
|
701
693
|
|
|
702
694
|
const res = await this.axios({
|
|
703
695
|
method: 'get',
|
|
704
|
-
url: `${this._buildAppiumEndpoint()}/
|
|
696
|
+
url: `${this._buildAppiumEndpoint()}/orientation`,
|
|
705
697
|
})
|
|
706
698
|
|
|
707
699
|
const currentOrientation = res.data.value
|
|
@@ -725,7 +717,7 @@ class Appium extends Webdriver {
|
|
|
725
717
|
|
|
726
718
|
return this.axios({
|
|
727
719
|
method: 'post',
|
|
728
|
-
url: `${this._buildAppiumEndpoint()}/
|
|
720
|
+
url: `${this._buildAppiumEndpoint()}/orientation`,
|
|
729
721
|
data: { orientation },
|
|
730
722
|
})
|
|
731
723
|
}
|
|
@@ -964,21 +956,19 @@ class Appium extends Webdriver {
|
|
|
964
956
|
* ```js
|
|
965
957
|
* // taps outside to hide keyboard per default
|
|
966
958
|
* I.hideDeviceKeyboard();
|
|
967
|
-
* I.hideDeviceKeyboard('tapOutside');
|
|
968
|
-
*
|
|
969
|
-
* // or by pressing key
|
|
970
|
-
* I.hideDeviceKeyboard('pressKey', 'Done');
|
|
971
959
|
* ```
|
|
972
960
|
*
|
|
973
961
|
* Appium: support Android and iOS
|
|
974
962
|
*
|
|
975
|
-
* @param {'tapOutside' | 'pressKey'} [strategy] Desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
|
|
976
|
-
* @param {string} [key] Optional key
|
|
977
963
|
*/
|
|
978
|
-
async hideDeviceKeyboard(
|
|
964
|
+
async hideDeviceKeyboard() {
|
|
979
965
|
onlyForApps.call(this)
|
|
980
|
-
|
|
981
|
-
return this.
|
|
966
|
+
|
|
967
|
+
return this.axios({
|
|
968
|
+
method: 'post',
|
|
969
|
+
url: `${this._buildAppiumEndpoint()}/appium/device/hide_keyboard`,
|
|
970
|
+
data: {},
|
|
971
|
+
})
|
|
982
972
|
}
|
|
983
973
|
|
|
984
974
|
/**
|
|
@@ -1054,7 +1044,13 @@ class Appium extends Webdriver {
|
|
|
1054
1044
|
* @param {*} locator
|
|
1055
1045
|
*/
|
|
1056
1046
|
async tap(locator) {
|
|
1057
|
-
|
|
1047
|
+
const { elementId } = await this.browser.$(parseLocator.call(this, locator))
|
|
1048
|
+
|
|
1049
|
+
return this.axios({
|
|
1050
|
+
method: 'post',
|
|
1051
|
+
url: `${this._buildAppiumEndpoint()}/element/${elementId}/click`,
|
|
1052
|
+
data: {},
|
|
1053
|
+
})
|
|
1058
1054
|
}
|
|
1059
1055
|
|
|
1060
1056
|
/**
|
|
@@ -1304,14 +1300,14 @@ class Appium extends Webdriver {
|
|
|
1304
1300
|
}
|
|
1305
1301
|
return browser
|
|
1306
1302
|
.$$(parseLocator.call(this, searchableLocator))
|
|
1307
|
-
.then(
|
|
1308
|
-
.then(
|
|
1303
|
+
.then(els => els.length && els[0].isDisplayed())
|
|
1304
|
+
.then(res => {
|
|
1309
1305
|
if (res) {
|
|
1310
1306
|
return true
|
|
1311
1307
|
}
|
|
1312
1308
|
return this[direction](scrollLocator, offset, speed)
|
|
1313
1309
|
.getSource()
|
|
1314
|
-
.then(
|
|
1310
|
+
.then(source => {
|
|
1315
1311
|
if (source === currentSource) {
|
|
1316
1312
|
err = true
|
|
1317
1313
|
} else {
|
|
@@ -1324,12 +1320,9 @@ class Appium extends Webdriver {
|
|
|
1324
1320
|
timeout * 1000,
|
|
1325
1321
|
errorMsg,
|
|
1326
1322
|
)
|
|
1327
|
-
.catch(
|
|
1323
|
+
.catch(e => {
|
|
1328
1324
|
if (e.message.indexOf('timeout') && e.type !== 'NoSuchElement') {
|
|
1329
|
-
throw new AssertionFailedError(
|
|
1330
|
-
{ customMessage: `Scroll to the end and element ${searchableLocator} was not found` },
|
|
1331
|
-
'',
|
|
1332
|
-
)
|
|
1325
|
+
throw new AssertionFailedError({ customMessage: `Scroll to the end and element ${searchableLocator} was not found` }, '')
|
|
1333
1326
|
} else {
|
|
1334
1327
|
throw e
|
|
1335
1328
|
}
|
|
@@ -1386,8 +1379,8 @@ class Appium extends Webdriver {
|
|
|
1386
1379
|
*/
|
|
1387
1380
|
async pullFile(path, dest) {
|
|
1388
1381
|
onlyForApps.call(this)
|
|
1389
|
-
return this.browser.pullFile(path).then(
|
|
1390
|
-
fs.writeFile(dest, Buffer.from(res, 'base64'),
|
|
1382
|
+
return this.browser.pullFile(path).then(res =>
|
|
1383
|
+
fs.writeFile(dest, Buffer.from(res, 'base64'), err => {
|
|
1391
1384
|
if (err) {
|
|
1392
1385
|
return false
|
|
1393
1386
|
}
|
|
@@ -1504,7 +1497,14 @@ class Appium extends Webdriver {
|
|
|
1504
1497
|
*/
|
|
1505
1498
|
async click(locator, context) {
|
|
1506
1499
|
if (this.isWeb) return super.click(locator, context)
|
|
1507
|
-
|
|
1500
|
+
|
|
1501
|
+
const { elementId } = await this.browser.$(parseLocator.call(this, locator), parseLocator.call(this, context))
|
|
1502
|
+
|
|
1503
|
+
return this.axios({
|
|
1504
|
+
method: 'post',
|
|
1505
|
+
url: `${this._buildAppiumEndpoint()}/element/${elementId}/click`,
|
|
1506
|
+
data: {},
|
|
1507
|
+
})
|
|
1508
1508
|
}
|
|
1509
1509
|
|
|
1510
1510
|
/**
|
|
@@ -1759,12 +1759,8 @@ function parseLocator(locator) {
|
|
|
1759
1759
|
}
|
|
1760
1760
|
|
|
1761
1761
|
locator = new Locator(locator, 'xpath')
|
|
1762
|
-
if (locator.type === 'css' && !this.isWeb)
|
|
1763
|
-
|
|
1764
|
-
'Unable to use css locators in apps. Locator strategies for this request: xpath, id, class name or accessibility id',
|
|
1765
|
-
)
|
|
1766
|
-
if (locator.type === 'name' && !this.isWeb)
|
|
1767
|
-
throw new Error("Can't locate element by name in Native context. Use either ID, class name or accessibility id")
|
|
1762
|
+
if (locator.type === 'css' && !this.isWeb) throw new Error('Unable to use css locators in apps. Locator strategies for this request: xpath, id, class name or accessibility id')
|
|
1763
|
+
if (locator.type === 'name' && !this.isWeb) throw new Error("Can't locate element by name in Native context. Use either ID, class name or accessibility id")
|
|
1768
1764
|
if (locator.type === 'id' && !this.isWeb && this.platform === 'android') return `//*[@resource-id='${locator.value}']`
|
|
1769
1765
|
return locator.simplify()
|
|
1770
1766
|
}
|
package/lib/helper/FileSystem.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import fs from 'fs'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import Helper from '@codeceptjs/helper'
|
|
6
|
+
import { fileExists } from '../utils.js'
|
|
7
|
+
import { fileIncludes } from '../assert/include.js'
|
|
8
|
+
import { fileEquals } from '../assert/equal.js'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Helper for testing filesystem.
|
|
@@ -38,7 +38,12 @@ class FileSystem extends Helper {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
_before() {
|
|
41
|
-
|
|
41
|
+
try {
|
|
42
|
+
this.debugSection('Dir', this.dir)
|
|
43
|
+
} catch (e) {
|
|
44
|
+
// Fallback debug for ESM transition
|
|
45
|
+
console.log(`[Dir] ${this.dir}`)
|
|
46
|
+
}
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
/**
|
|
@@ -48,7 +53,12 @@ class FileSystem extends Helper {
|
|
|
48
53
|
*/
|
|
49
54
|
amInPath(openPath) {
|
|
50
55
|
this.dir = path.join(global.codecept_dir, openPath)
|
|
51
|
-
|
|
56
|
+
try {
|
|
57
|
+
this.debugSection('Dir', this.dir)
|
|
58
|
+
} catch (e) {
|
|
59
|
+
// Fallback debug for ESM transition
|
|
60
|
+
console.log(`[Dir] ${this.dir}`)
|
|
61
|
+
}
|
|
52
62
|
}
|
|
53
63
|
|
|
54
64
|
/**
|
|
@@ -66,7 +76,12 @@ class FileSystem extends Helper {
|
|
|
66
76
|
*/
|
|
67
77
|
seeFile(name) {
|
|
68
78
|
this.file = path.join(this.dir, name)
|
|
69
|
-
|
|
79
|
+
try {
|
|
80
|
+
this.debugSection('File', this.file)
|
|
81
|
+
} catch (e) {
|
|
82
|
+
// Fallback debug for ESM transition
|
|
83
|
+
console.log(`[File] ${this.file}`)
|
|
84
|
+
}
|
|
70
85
|
assert.ok(fileExists(this.file), `File ${name} not found in ${this.dir}`)
|
|
71
86
|
}
|
|
72
87
|
|
|
@@ -86,7 +101,12 @@ class FileSystem extends Helper {
|
|
|
86
101
|
if (sec === 0) assert.fail('Use `seeFile` instead of waiting 0 seconds!')
|
|
87
102
|
const waitTimeout = sec * 1000
|
|
88
103
|
this.file = path.join(this.dir, name)
|
|
89
|
-
|
|
104
|
+
try {
|
|
105
|
+
this.debugSection('File', this.file)
|
|
106
|
+
} catch (e) {
|
|
107
|
+
// Fallback debug for ESM transition
|
|
108
|
+
console.log(`[File] ${this.file}`)
|
|
109
|
+
}
|
|
90
110
|
return isFileExists(this.file, waitTimeout).catch(() => {
|
|
91
111
|
throw new Error(`file (${name}) still not present in directory ${this.dir} after ${waitTimeout / 1000} sec`)
|
|
92
112
|
})
|
|
@@ -105,7 +125,7 @@ class FileSystem extends Helper {
|
|
|
105
125
|
*/
|
|
106
126
|
seeFileNameMatching(text) {
|
|
107
127
|
assert.ok(
|
|
108
|
-
this.grabFileNames().some(
|
|
128
|
+
this.grabFileNames().some(file => file.includes(text)),
|
|
109
129
|
`File name which contains ${text} not found in ${this.dir}`,
|
|
110
130
|
)
|
|
111
131
|
}
|
|
@@ -175,11 +195,11 @@ class FileSystem extends Helper {
|
|
|
175
195
|
* ```
|
|
176
196
|
*/
|
|
177
197
|
grabFileNames() {
|
|
178
|
-
return fs.readdirSync(this.dir).filter(
|
|
198
|
+
return fs.readdirSync(this.dir).filter(item => !fs.lstatSync(path.join(this.dir, item)).isDirectory())
|
|
179
199
|
}
|
|
180
200
|
}
|
|
181
201
|
|
|
182
|
-
|
|
202
|
+
export { FileSystem as default }
|
|
183
203
|
|
|
184
204
|
/**
|
|
185
205
|
* @param {string} file
|
|
@@ -216,7 +236,7 @@ function isFileExists(file, timeout) {
|
|
|
216
236
|
}
|
|
217
237
|
})
|
|
218
238
|
|
|
219
|
-
fs.access(file, fs.constants.R_OK,
|
|
239
|
+
fs.access(file, fs.constants.R_OK, err => {
|
|
220
240
|
if (!err) {
|
|
221
241
|
clearTimeout(timer)
|
|
222
242
|
watcher.close()
|
package/lib/helper/GraphQL.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const HelperModule = require('@codeceptjs/helper')
|
|
4
4
|
const GraphQL = require('./GraphQL')
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -170,7 +170,7 @@ class GraphQLDataFactory extends Helper {
|
|
|
170
170
|
this.factories = this.config.factories
|
|
171
171
|
|
|
172
172
|
this.created = {}
|
|
173
|
-
Object.keys(this.factories).forEach(
|
|
173
|
+
Object.keys(this.factories).forEach(f => (this.created[f] = []))
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
static _checkRequirements() {
|
|
@@ -278,7 +278,7 @@ class GraphQLDataFactory extends Helper {
|
|
|
278
278
|
*/
|
|
279
279
|
_requestCreate(operation, variables) {
|
|
280
280
|
const { query } = this.factories[operation]
|
|
281
|
-
return this.graphqlHelper.sendMutation(query, variables).then(
|
|
281
|
+
return this.graphqlHelper.sendMutation(query, variables).then(response => {
|
|
282
282
|
const data = response.data.data[operation]
|
|
283
283
|
this.created[operation].push(data)
|
|
284
284
|
this.debugSection('Created', `record: ${data}`)
|
|
@@ -297,7 +297,7 @@ class GraphQLDataFactory extends Helper {
|
|
|
297
297
|
const deleteOperation = this.factories[operation].revert(data)
|
|
298
298
|
const { query, variables } = deleteOperation
|
|
299
299
|
|
|
300
|
-
return this.graphqlHelper.sendMutation(query, variables).then(
|
|
300
|
+
return this.graphqlHelper.sendMutation(query, variables).then(response => {
|
|
301
301
|
const idx = this.created[operation].indexOf(data)
|
|
302
302
|
this.debugSection('Deleted', `record: ${response.data.data}`)
|
|
303
303
|
this.created[operation].splice(idx, 1)
|