codeceptjs 4.0.0-beta.2 → 4.0.0-beta.20
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 +133 -120
- package/bin/codecept.js +107 -96
- package/bin/test-server.js +64 -0
- package/docs/webapi/clearCookie.mustache +1 -1
- package/docs/webapi/click.mustache +5 -1
- package/lib/actor.js +71 -103
- package/lib/ai.js +159 -188
- package/lib/assert/empty.js +22 -24
- package/lib/assert/equal.js +30 -37
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +43 -48
- package/lib/assert/throws.js +11 -11
- package/lib/assert/truth.js +22 -22
- package/lib/assert.js +20 -18
- package/lib/codecept.js +262 -162
- package/lib/colorUtils.js +50 -52
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +56 -51
- package/lib/command/definitions.js +96 -109
- package/lib/command/dryRun.js +77 -79
- package/lib/command/generate.js +234 -194
- package/lib/command/gherkin/init.js +42 -33
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +20 -17
- package/lib/command/info.js +74 -38
- package/lib/command/init.js +301 -290
- package/lib/command/interactive.js +41 -32
- package/lib/command/list.js +28 -27
- package/lib/command/run-multiple/chunk.js +51 -48
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +5 -1
- package/lib/command/run-multiple.js +97 -97
- package/lib/command/run-rerun.js +19 -25
- package/lib/command/run-workers.js +68 -92
- package/lib/command/run.js +39 -27
- package/lib/command/utils.js +80 -64
- package/lib/command/workers/runTests.js +388 -226
- package/lib/config.js +109 -50
- package/lib/container.js +641 -261
- package/lib/data/context.js +60 -61
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +32 -32
- package/lib/data/table.js +22 -22
- package/lib/effects.js +307 -0
- package/lib/element/WebElement.js +327 -0
- package/lib/els.js +160 -0
- package/lib/event.js +173 -163
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -85
- package/lib/helper/AI.js +131 -41
- package/lib/helper/ApiDataFactory.js +107 -75
- package/lib/helper/Appium.js +542 -404
- package/lib/helper/FileSystem.js +100 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +52 -52
- package/lib/helper/JSONResponse.js +126 -88
- package/lib/helper/Mochawesome.js +54 -29
- package/lib/helper/Playwright.js +2547 -1316
- package/lib/helper/Puppeteer.js +1578 -1181
- package/lib/helper/REST.js +209 -68
- package/lib/helper/WebDriver.js +1482 -1342
- 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/PlaywrightReactVueLocator.js +17 -8
- package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +27 -28
- package/lib/helper/network/actions.js +36 -42
- package/lib/helper/network/utils.js +78 -84
- package/lib/helper/scripts/blurElement.js +5 -5
- package/lib/helper/scripts/focusElement.js +5 -5
- package/lib/helper/scripts/highlightElement.js +8 -8
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -3
- package/lib/history.js +23 -19
- package/lib/hooks.js +8 -8
- package/lib/html.js +94 -104
- package/lib/index.js +38 -27
- package/lib/listener/config.js +30 -23
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/enhancedGlobalRetry.js +110 -0
- package/lib/listener/exit.js +16 -18
- package/lib/listener/globalRetry.js +70 -0
- package/lib/listener/globalTimeout.js +181 -0
- package/lib/listener/helpers.js +76 -51
- package/lib/listener/mocha.js +10 -11
- package/lib/listener/result.js +11 -0
- package/lib/listener/retryEnhancer.js +85 -0
- package/lib/listener/steps.js +71 -59
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +214 -197
- package/lib/mocha/asyncWrapper.js +274 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +163 -0
- package/lib/mocha/featureConfig.js +89 -0
- package/lib/mocha/gherkin.js +231 -0
- 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 +58 -34
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +184 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +242 -0
- package/lib/output.js +141 -71
- package/lib/parser.js +47 -44
- package/lib/pause.js +173 -145
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +178 -79
- package/lib/plugin/autoDelay.js +36 -40
- package/lib/plugin/coverage.js +131 -78
- package/lib/plugin/customLocator.js +22 -21
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/enhancedRetryFailedStep.js +99 -0
- package/lib/plugin/heal.js +101 -110
- package/lib/plugin/htmlReporter.js +3648 -0
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +12 -11
- package/lib/plugin/retryFailedStep.js +82 -47
- package/lib/plugin/screenshotOnFail.js +111 -92
- package/lib/plugin/stepByStepReport.js +159 -101
- package/lib/plugin/stepTimeout.js +20 -25
- package/lib/plugin/subtitles.js +38 -38
- package/lib/recorder.js +193 -130
- package/lib/rerun.js +94 -49
- package/lib/result.js +238 -0
- package/lib/retryCoordinator.js +207 -0
- package/lib/secret.js +20 -18
- 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 -329
- package/lib/steps.js +54 -0
- package/lib/store.js +38 -7
- package/lib/template/heal.js +3 -12
- package/lib/template/prompts/generatePageObject.js +31 -0
- package/lib/template/prompts/healStep.js +13 -0
- package/lib/template/prompts/writeStep.js +9 -0
- package/lib/test-server.js +334 -0
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +34 -21
- package/lib/utils/loaderCheck.js +124 -0
- package/lib/utils/mask_data.js +47 -0
- package/lib/utils/typescript.js +237 -0
- package/lib/utils.js +411 -228
- package/lib/workerStorage.js +37 -34
- package/lib/workers.js +532 -296
- package/package.json +124 -95
- package/translations/de-DE.js +5 -3
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +22 -12
- package/translations/it-IT.js +4 -3
- package/translations/ja-JP.js +4 -3
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +4 -3
- package/translations/pt-BR.js +4 -3
- package/translations/ru-RU.js +4 -3
- package/translations/utils.js +10 -0
- package/translations/zh-CN.js +4 -3
- package/translations/zh-TW.js +4 -3
- package/typings/index.d.ts +546 -185
- package/typings/promiseBasedTypes.d.ts +150 -875
- package/typings/types.d.ts +547 -992
- package/lib/cli.js +0 -249
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
- package/lib/helper/ExpectHelper.js +0 -399
- package/lib/helper/MockServer.js +0 -223
- package/lib/helper/Nightmare.js +0 -1411
- package/lib/helper/Protractor.js +0 -1835
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1410
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -63
- package/lib/interfaces/bdd.js +0 -98
- package/lib/interfaces/featureConfig.js +0 -69
- package/lib/interfaces/gherkin.js +0 -195
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/retry.js +0 -68
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -110
- 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 -121
- package/lib/plugin/selenoid.js +0 -371
- package/lib/plugin/standardActingHelpers.js +0 -9
- package/lib/plugin/tryTo.js +0 -105
- package/lib/plugin/wdio.js +0 -246
- package/lib/scenario.js +0 -222
- package/lib/ui.js +0 -238
- package/lib/within.js +0 -70
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import { fileExists, isAsyncFunction } from '../utils.js'
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { fileExists, isAsyncFunction } from '../utils.js'
|
|
4
|
+
import CommentStep from '../step/comment.js'
|
|
5
|
+
import Section from '../step/section.js'
|
|
6
|
+
import container from '../container.js'
|
|
7
|
+
import store from '../store.js'
|
|
8
|
+
import event from '../event.js'
|
|
9
|
+
import recorder from '../recorder.js'
|
|
10
|
+
import output from '../output.js'
|
|
8
11
|
|
|
9
12
|
const defaultUser = {
|
|
10
13
|
fetch: I => I.grabCookie(),
|
|
11
14
|
check: () => {},
|
|
12
15
|
restore: (I, cookies) => {
|
|
13
|
-
I.amOnPage('/')
|
|
14
|
-
I.setCookie(cookies)
|
|
16
|
+
I.amOnPage('/') // open a page
|
|
17
|
+
I.setCookie(cookies)
|
|
15
18
|
},
|
|
16
|
-
}
|
|
19
|
+
}
|
|
17
20
|
|
|
18
21
|
const defaultConfig = {
|
|
19
22
|
saveToFile: false,
|
|
20
23
|
inject: 'login',
|
|
21
|
-
}
|
|
24
|
+
}
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Logs user in for the first test and reuses session for next tests.
|
|
@@ -71,7 +74,7 @@ const defaultConfig = {
|
|
|
71
74
|
* #### Example: Simple login
|
|
72
75
|
*
|
|
73
76
|
* ```js
|
|
74
|
-
*
|
|
77
|
+
* auth: {
|
|
75
78
|
* enabled: true,
|
|
76
79
|
* saveToFile: true,
|
|
77
80
|
* inject: 'login',
|
|
@@ -92,7 +95,7 @@ const defaultConfig = {
|
|
|
92
95
|
* #### Example: Multiple users
|
|
93
96
|
*
|
|
94
97
|
* ```js
|
|
95
|
-
*
|
|
98
|
+
* auth: {
|
|
96
99
|
* enabled: true,
|
|
97
100
|
* saveToFile: true,
|
|
98
101
|
* inject: 'loginAs', // use `loginAs` instead of login
|
|
@@ -139,7 +142,7 @@ const defaultConfig = {
|
|
|
139
142
|
* }
|
|
140
143
|
* },
|
|
141
144
|
* plugins: {
|
|
142
|
-
*
|
|
145
|
+
* auth: {
|
|
143
146
|
* users: {
|
|
144
147
|
* admin: {
|
|
145
148
|
* login: (I) => {
|
|
@@ -166,7 +169,7 @@ const defaultConfig = {
|
|
|
166
169
|
*
|
|
167
170
|
* ```js
|
|
168
171
|
* plugins: {
|
|
169
|
-
*
|
|
172
|
+
* auth: {
|
|
170
173
|
* admin: {
|
|
171
174
|
* login: (I) => I.loginAsAdmin(),
|
|
172
175
|
* check: (I) => I.see('Admin', '.navbar'),
|
|
@@ -182,18 +185,18 @@ const defaultConfig = {
|
|
|
182
185
|
* }
|
|
183
186
|
* ```
|
|
184
187
|
*
|
|
185
|
-
* #### Tips: Using async function in the
|
|
188
|
+
* #### Tips: Using async function in the auth
|
|
186
189
|
*
|
|
187
|
-
* If you use async functions in the
|
|
190
|
+
* If you use async functions in the auth plugin, login function should be used with `await` keyword.
|
|
188
191
|
*
|
|
189
192
|
* ```js
|
|
190
|
-
*
|
|
193
|
+
* auth: {
|
|
191
194
|
* enabled: true,
|
|
192
195
|
* saveToFile: true,
|
|
193
196
|
* inject: 'login',
|
|
194
197
|
* users: {
|
|
195
198
|
* admin: {
|
|
196
|
-
* login: async (I) => { // If you use async function in the
|
|
199
|
+
* login: async (I) => { // If you use async function in the auth plugin
|
|
197
200
|
* const phrase = await I.grabTextFrom('#phrase')
|
|
198
201
|
* I.fillField('username', 'admin'),
|
|
199
202
|
* I.fillField('password', 'password')
|
|
@@ -219,13 +222,13 @@ const defaultConfig = {
|
|
|
219
222
|
* Instead of asserting on page elements for the current user in `check`, you can use the `session` you saved in `fetch`
|
|
220
223
|
*
|
|
221
224
|
* ```js
|
|
222
|
-
*
|
|
225
|
+
* auth: {
|
|
223
226
|
* enabled: true,
|
|
224
227
|
* saveToFile: true,
|
|
225
228
|
* inject: 'login',
|
|
226
229
|
* users: {
|
|
227
230
|
* admin: {
|
|
228
|
-
* login: async (I) => { // If you use async function in the
|
|
231
|
+
* login: async (I) => { // If you use async function in the auth plugin
|
|
229
232
|
* const phrase = await I.grabTextFrom('#phrase')
|
|
230
233
|
* I.fillField('username', 'admin'),
|
|
231
234
|
* I.fillField('password', 'password')
|
|
@@ -248,88 +251,184 @@ const defaultConfig = {
|
|
|
248
251
|
* })
|
|
249
252
|
*
|
|
250
253
|
*
|
|
251
|
-
*/
|
|
254
|
+
*/
|
|
252
255
|
export default function (config) {
|
|
253
|
-
config = Object.assign(defaultConfig, config)
|
|
254
|
-
Object.keys(config.users).map(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
config = Object.assign(defaultConfig, config)
|
|
257
|
+
Object.keys(config.users).map(
|
|
258
|
+
u =>
|
|
259
|
+
(config.users[u] = {
|
|
260
|
+
...defaultUser,
|
|
261
|
+
...config.users[u],
|
|
262
|
+
}),
|
|
263
|
+
)
|
|
258
264
|
|
|
259
265
|
if (config.saveToFile) {
|
|
260
266
|
// loading from file
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
loadCookiesFromFile(config)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const loginFunction = async name => {
|
|
271
|
+
const I = container.support('I')
|
|
272
|
+
const userSession = config.users[name]
|
|
273
|
+
|
|
274
|
+
if (!userSession) {
|
|
275
|
+
throw new Error(`User '${name}' was not configured for authorization in auth plugin. Add it to the plugin config`)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const test = store.currentTest
|
|
279
|
+
|
|
280
|
+
// we are in BeforeSuite hook
|
|
281
|
+
if (!test) {
|
|
282
|
+
enableAuthBeforeEachTest(name)
|
|
283
|
+
return
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const section = new Section(`I am logged in as ${name}`)
|
|
287
|
+
|
|
288
|
+
if (config.saveToFile && !store[`${name}_session`]) {
|
|
289
|
+
loadCookiesFromFile(config)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (isPlaywrightSession() && test?.opts?.cookies) {
|
|
293
|
+
if (test.opts.user == name) {
|
|
294
|
+
output.debug(`Cookies already loaded for ${name}`)
|
|
295
|
+
|
|
296
|
+
alreadyLoggedIn(name)
|
|
297
|
+
return
|
|
298
|
+
} else {
|
|
299
|
+
output.debug(`Cookies already loaded for ${test.opts.user}, but not for ${name}`)
|
|
300
|
+
await I.deleteCookie()
|
|
269
301
|
}
|
|
270
|
-
debug(`Loaded user session for ${name}`);
|
|
271
302
|
}
|
|
272
|
-
}
|
|
273
303
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
const shouldAwait = isAsyncFunction(userSession.login)
|
|
279
|
-
|| isAsyncFunction(userSession.restore)
|
|
280
|
-
|| isAsyncFunction(userSession.check);
|
|
304
|
+
section.start()
|
|
305
|
+
|
|
306
|
+
const cookies = store[`${name}_session`]
|
|
307
|
+
const shouldAwait = isAsyncFunction(userSession.login) || isAsyncFunction(userSession.restore) || isAsyncFunction(userSession.check)
|
|
281
308
|
|
|
282
309
|
const loginAndSave = async () => {
|
|
283
310
|
if (shouldAwait) {
|
|
284
|
-
await userSession.login(I)
|
|
311
|
+
await userSession.login(I)
|
|
285
312
|
} else {
|
|
286
|
-
userSession.login(I)
|
|
313
|
+
userSession.login(I)
|
|
287
314
|
}
|
|
288
315
|
|
|
289
|
-
|
|
316
|
+
section.end()
|
|
317
|
+
const cookies = await userSession.fetch(I)
|
|
290
318
|
if (!cookies) {
|
|
291
|
-
debug(
|
|
292
|
-
return
|
|
319
|
+
output.debug("Cannot save user session with empty cookies from auto login's fetch method")
|
|
320
|
+
return
|
|
293
321
|
}
|
|
294
322
|
if (config.saveToFile) {
|
|
295
|
-
debug(`Saved user session into file for ${name}`)
|
|
296
|
-
fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies))
|
|
323
|
+
output.debug(`Saved user session into file for ${name}`)
|
|
324
|
+
fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies))
|
|
297
325
|
}
|
|
298
|
-
store[`${name}_session`] = cookies
|
|
299
|
-
}
|
|
326
|
+
store[`${name}_session`] = cookies
|
|
327
|
+
}
|
|
300
328
|
|
|
301
|
-
if (!cookies) return loginAndSave()
|
|
329
|
+
if (!cookies) return loginAndSave()
|
|
302
330
|
|
|
303
|
-
recorder.session.start('check login')
|
|
331
|
+
recorder.session.start('check login')
|
|
304
332
|
if (shouldAwait) {
|
|
305
|
-
await userSession.restore(I, cookies)
|
|
306
|
-
await userSession.check(I, cookies)
|
|
333
|
+
await userSession.restore(I, cookies)
|
|
334
|
+
await userSession.check(I, cookies)
|
|
307
335
|
} else {
|
|
308
|
-
userSession.restore(I, cookies)
|
|
309
|
-
userSession.check(I, cookies)
|
|
336
|
+
userSession.restore(I, cookies)
|
|
337
|
+
userSession.check(I, cookies)
|
|
310
338
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
debug(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
339
|
+
section.end()
|
|
340
|
+
recorder.session.catch(err => {
|
|
341
|
+
output.debug(`Failed auto login for ${name} due to ${err}`)
|
|
342
|
+
output.debug('Logging in again')
|
|
343
|
+
recorder.session.start('auto login')
|
|
344
|
+
return loginAndSave()
|
|
345
|
+
.then(() => {
|
|
346
|
+
recorder.add(() => recorder.session.restore('auto login'))
|
|
347
|
+
recorder.catch(() => output.debug('continue'))
|
|
348
|
+
})
|
|
349
|
+
.catch(err => {
|
|
350
|
+
recorder.session.restore('auto login')
|
|
351
|
+
recorder.session.restore('check login')
|
|
352
|
+
section.end()
|
|
353
|
+
recorder.throw(err)
|
|
354
|
+
})
|
|
355
|
+
})
|
|
324
356
|
recorder.add(() => {
|
|
325
|
-
recorder.session.restore('check login')
|
|
326
|
-
})
|
|
357
|
+
recorder.session.restore('check login')
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
return recorder.promise()
|
|
361
|
+
}
|
|
327
362
|
|
|
328
|
-
|
|
329
|
-
|
|
363
|
+
function enableAuthBeforeEachTest(name) {
|
|
364
|
+
const suite = store.currentSuite
|
|
365
|
+
if (!suite) return
|
|
366
|
+
|
|
367
|
+
output.debug(`enabling auth as ${name} for each test of suite ${suite.title}`)
|
|
368
|
+
|
|
369
|
+
// we are setting test opts so they can be picked up by Playwright if it starts browser for this test
|
|
370
|
+
suite.eachTest(test => {
|
|
371
|
+
// preload from store
|
|
372
|
+
if (store[`${name}_session`]) {
|
|
373
|
+
test.opts.cookies = store[`${name}_session`]
|
|
374
|
+
test.opts.user = name
|
|
375
|
+
return
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (!config.saveToFile) return
|
|
379
|
+
const cookieFile = path.join(global.output_dir, `${name}_session.json`)
|
|
380
|
+
|
|
381
|
+
if (!fileExists(cookieFile)) {
|
|
382
|
+
return
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const context = fs.readFileSync(cookieFile).toString()
|
|
386
|
+
test.opts.cookies = JSON.parse(context)
|
|
387
|
+
test.opts.user = name
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
function runLoginFunctionForTest(test) {
|
|
391
|
+
if (!suite.tests.includes(test)) return
|
|
392
|
+
// let's call this function to ensure that authorization happened
|
|
393
|
+
// if no cookies, it will login and save them
|
|
394
|
+
loginFunction(name)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// we are in BeforeSuite hook
|
|
398
|
+
event.dispatcher.on(event.test.started, runLoginFunctionForTest)
|
|
399
|
+
event.dispatcher.on(event.suite.after, () => {
|
|
400
|
+
event.dispatcher.off(event.test.started, runLoginFunctionForTest)
|
|
401
|
+
})
|
|
402
|
+
}
|
|
330
403
|
|
|
331
404
|
// adding this to DI container
|
|
332
|
-
const support = {}
|
|
333
|
-
support[config.inject] = loginFunction
|
|
334
|
-
container.append({ support })
|
|
405
|
+
const support = {}
|
|
406
|
+
support[config.inject] = loginFunction
|
|
407
|
+
container.append({ support })
|
|
408
|
+
|
|
409
|
+
return loginFunction
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function loadCookiesFromFile(config) {
|
|
413
|
+
for (const name in config.users) {
|
|
414
|
+
const fileName = path.join(global.output_dir, `${name}_session.json`)
|
|
415
|
+
if (!fileExists(fileName)) continue
|
|
416
|
+
const data = fs.readFileSync(fileName).toString()
|
|
417
|
+
try {
|
|
418
|
+
store[`${name}_session`] = JSON.parse(data)
|
|
419
|
+
} catch (err) {
|
|
420
|
+
throw new Error(`Could not load session from ${fileName}\n${err}`)
|
|
421
|
+
}
|
|
422
|
+
output.debug(`Loaded user session for ${name}`)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function isPlaywrightSession() {
|
|
427
|
+
return !!container.helpers('Playwright')
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function alreadyLoggedIn(name) {
|
|
431
|
+
const step = new CommentStep('am logged in as')
|
|
432
|
+
step.actor = 'I'
|
|
433
|
+
return step.addToRecorder([name])
|
|
335
434
|
}
|
package/lib/plugin/autoDelay.js
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
import Container from '../container.js'
|
|
2
|
-
import { store } from '../store.js';
|
|
3
|
-
import recorder from '../recorder.js';
|
|
4
|
-
import * as event from '../event.js';
|
|
5
|
-
import { log } from '../output.js';
|
|
1
|
+
import Container from '../container.js'
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
import store from '../store.js'
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
]
|
|
5
|
+
import recorder from '../recorder.js'
|
|
6
|
+
|
|
7
|
+
import event from '../event.js'
|
|
8
|
+
|
|
9
|
+
import output from '../output.js'
|
|
10
|
+
const standardActingHelpers = Container.STANDARD_ACTING_HELPERS
|
|
11
|
+
|
|
12
|
+
const methodsToDelay = ['click', 'fillField', 'checkOption', 'pressKey', 'doubleClick', 'rightClick']
|
|
17
13
|
|
|
18
14
|
const defaultConfig = {
|
|
19
15
|
methods: methodsToDelay,
|
|
20
16
|
delayBefore: 100,
|
|
21
17
|
delayAfter: 200,
|
|
22
|
-
}
|
|
18
|
+
}
|
|
23
19
|
|
|
24
20
|
/**
|
|
25
21
|
*
|
|
@@ -60,41 +56,41 @@ const defaultConfig = {
|
|
|
60
56
|
*
|
|
61
57
|
*/
|
|
62
58
|
export default function (config) {
|
|
63
|
-
|
|
64
|
-
const helpers = Container.helpers()
|
|
65
|
-
let helper
|
|
59
|
+
const affectedHelpers = [...standardActingHelpers, 'REST']
|
|
60
|
+
const helpers = Container.helpers()
|
|
61
|
+
let helper
|
|
66
62
|
|
|
67
|
-
config = Object.assign(defaultConfig, config)
|
|
63
|
+
config = Object.assign(defaultConfig, config)
|
|
68
64
|
|
|
69
|
-
for (const helperName of
|
|
65
|
+
for (const helperName of affectedHelpers) {
|
|
70
66
|
if (Object.keys(helpers).indexOf(helperName) > -1) {
|
|
71
|
-
helper = helpers[helperName]
|
|
67
|
+
helper = helpers[helperName]
|
|
72
68
|
}
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
if (!helper) return
|
|
71
|
+
if (!helper) return // no helpers for auto-delay
|
|
76
72
|
|
|
77
|
-
event.dispatcher.on(event.step.before,
|
|
78
|
-
if (config.methods.indexOf(step.helperMethod) < 0) return
|
|
73
|
+
event.dispatcher.on(event.step.before, step => {
|
|
74
|
+
if (config.methods.indexOf(step.helperMethod) < 0) return // skip non-actions
|
|
79
75
|
|
|
80
76
|
recorder.add('auto-delay', async () => {
|
|
81
|
-
if (store.debugMode) return
|
|
82
|
-
log(`Delaying for ${config.delayBefore}ms`)
|
|
83
|
-
return new Promise(
|
|
84
|
-
setTimeout(resolve, config.delayBefore)
|
|
85
|
-
})
|
|
86
|
-
})
|
|
87
|
-
})
|
|
77
|
+
if (store.debugMode) return // no need to delay in debug
|
|
78
|
+
output.log(`Delaying for ${config.delayBefore}ms`)
|
|
79
|
+
return new Promise(resolve => {
|
|
80
|
+
setTimeout(resolve, config.delayBefore)
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
})
|
|
88
84
|
|
|
89
|
-
event.dispatcher.on(event.step.after,
|
|
90
|
-
if (config.methods.indexOf(step.helperMethod) < 0) return
|
|
85
|
+
event.dispatcher.on(event.step.after, step => {
|
|
86
|
+
if (config.methods.indexOf(step.helperMethod) < 0) return // skip non-actions
|
|
91
87
|
|
|
92
88
|
recorder.add('auto-delay', async () => {
|
|
93
|
-
if (store.debugMode) return
|
|
94
|
-
log(`Delaying for ${config.delayAfter}ms`)
|
|
95
|
-
return new Promise(
|
|
96
|
-
setTimeout(resolve, config.delayAfter)
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
})
|
|
89
|
+
if (store.debugMode) return // no need to delay in debug
|
|
90
|
+
output.log(`Delaying for ${config.delayAfter}ms`)
|
|
91
|
+
return new Promise(resolve => {
|
|
92
|
+
setTimeout(resolve, config.delayAfter)
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})
|
|
100
96
|
}
|