codeceptjs 4.2.0-beta.4 → 4.2.1-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/README.md +2 -0
- package/bin/codecept.js +11 -0
- package/docs/agents.md +26 -1
- package/docs/ai.md +57 -0
- package/docs/alternative-browsers.md +175 -148
- package/docs/assertions.md +74 -0
- package/docs/bootstrap.md +2 -0
- package/docs/commands.md +45 -0
- package/docs/configuration.md +37 -0
- package/docs/debugging.md +1 -1
- package/docs/helpers/ApiDataFactory.md +20 -20
- package/docs/helpers/Appium.md +1615 -670
- package/docs/helpers/Decision.md +146 -0
- package/docs/helpers/GraphQL.md +31 -31
- package/docs/helpers/GraphQLDataFactory.md +20 -20
- package/docs/helpers/Kitesurf.md +1808 -25
- package/docs/helpers/Lightpanda.md +139 -0
- package/docs/helpers/Obscura.md +1799 -74
- package/docs/helpers/Playwright.md +490 -428
- package/docs/helpers/Puppeteer.md +317 -255
- package/docs/helpers/REST.md +43 -43
- package/docs/helpers/WebDriver.md +237 -175
- package/docs/installation.md +16 -0
- package/docs/mcp.md +7 -1
- package/docs/parallel.md +35 -1
- package/docs/plugins/pause.md +2 -1
- package/docs/plugins/sitemap.md +48 -0
- package/docs/plugins.md +4 -0
- package/lib/ai.js +81 -2
- package/lib/codecept.js +32 -2
- package/lib/command/init.js +22 -0
- package/lib/command/initAgent.js +78 -0
- package/lib/command/run-multiple.js +3 -0
- package/lib/command/run-workers.js +10 -3
- package/lib/command/run.js +3 -2
- package/lib/command/utils.js +15 -0
- package/lib/command/workers/runTests.js +10 -10
- package/lib/container.js +4 -2
- package/lib/effects.js +19 -1
- package/lib/helper/Appium.js +23 -0
- package/lib/helper/CDPBrowser.js +387 -1338
- package/lib/helper/Decision.js +256 -0
- package/lib/helper/Kitesurf.js +3 -21
- package/lib/helper/Lightpanda.js +137 -0
- package/lib/helper/Obscura.js +21 -238
- package/lib/helper/Playwright.js +50 -4
- package/lib/helper/Puppeteer.js +62 -8
- package/lib/helper/WebDriver.js +45 -1
- package/lib/helper/extras/clipboard.js +31 -0
- package/lib/listener/result.js +4 -0
- package/lib/mocha/bdd.js +19 -1
- package/lib/plugin/junitReporter.js +4 -1
- package/lib/plugin/pause.js +4 -1
- package/lib/plugin/sitemap.js +228 -0
- package/lib/recorder.js +19 -18
- package/lib/result.js +16 -0
- package/lib/step/base.js +12 -0
- package/lib/utils.js +2 -10
- package/lib/webServer.js +193 -0
- package/lib/workers.js +118 -31
- package/package.json +4 -2
- package/typings/index.d.ts +60 -7
- package/typings/promiseBasedTypes.d.ts +985 -814
- package/typings/types.d.ts +1084 -815
- package/docs/helpers/CDPBrowser.md +0 -2138
package/lib/workers.js
CHANGED
|
@@ -20,9 +20,11 @@ import output from './output.js'
|
|
|
20
20
|
import event from './event.js'
|
|
21
21
|
import { deserializeTest } from './mocha/test.js'
|
|
22
22
|
import { deserializeSuite } from './mocha/suite.js'
|
|
23
|
+
import Step from './step/base.js'
|
|
23
24
|
import recorder from './recorder.js'
|
|
24
25
|
import store from './store.js'
|
|
25
26
|
import runHook from './hooks.js'
|
|
27
|
+
import WebServer from './webServer.js'
|
|
26
28
|
import WorkerStorage from './workerStorage.js'
|
|
27
29
|
import { createRuns } from './command/run-multiple/collection.js'
|
|
28
30
|
|
|
@@ -57,11 +59,23 @@ const populateGroups = numberOfWorkers => {
|
|
|
57
59
|
return groups
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
const
|
|
62
|
+
const matchesGrep = (mocha, test) => {
|
|
63
|
+
const { grep, invert } = mocha.options
|
|
64
|
+
if (!grep) return true
|
|
65
|
+
return grep.test(test.fullTitle()) !== Boolean(invert)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const withoutEmptyGroups = groups => {
|
|
69
|
+
const nonEmpty = groups.filter(group => group.length)
|
|
70
|
+
return nonEmpty.length ? nonEmpty : groups.slice(0, 1)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const createWorker = (workerObject, isPoolMode = false, skipTests = []) => {
|
|
61
74
|
const worker = new Worker(pathToWorker, {
|
|
62
75
|
workerData: {
|
|
63
76
|
options: simplifyObject(workerObject.options),
|
|
64
77
|
tests: workerObject.tests,
|
|
78
|
+
skipTests,
|
|
65
79
|
testRoot: workerObject.testRoot,
|
|
66
80
|
workerIndex: workerObject.workerIndex + 1,
|
|
67
81
|
poolMode: isPoolMode,
|
|
@@ -104,6 +118,8 @@ const simplifyObject = object => {
|
|
|
104
118
|
}, {})
|
|
105
119
|
}
|
|
106
120
|
|
|
121
|
+
const deserializeStep = data => Object.assign(new Step(data.title), data)
|
|
122
|
+
|
|
107
123
|
const createWorkerObjects = (testGroups, config, testRoot, options, selectedRuns) => {
|
|
108
124
|
selectedRuns = options && options.all && config.multiple ? Object.keys(config.multiple) : selectedRuns
|
|
109
125
|
if (selectedRuns === undefined || !selectedRuns.length || config.multiple === undefined) {
|
|
@@ -213,6 +229,7 @@ class WorkerObject {
|
|
|
213
229
|
*/
|
|
214
230
|
constructor(workerIndex) {
|
|
215
231
|
this.workerIndex = workerIndex
|
|
232
|
+
this.serial = false
|
|
216
233
|
this.options = {}
|
|
217
234
|
this.tests = []
|
|
218
235
|
this.testRoot = getTestRoot()
|
|
@@ -288,6 +305,7 @@ class Workers extends EventEmitter {
|
|
|
288
305
|
this.testGroups = []
|
|
289
306
|
this.testPool = []
|
|
290
307
|
this.testPoolInitialized = false
|
|
308
|
+
this.serialTests = []
|
|
291
309
|
this.isPoolMode = config.by === 'pool'
|
|
292
310
|
this.activeWorkers = new Map()
|
|
293
311
|
this.maxWorkers = numberOfWorkers // Track original worker count for pool mode
|
|
@@ -312,9 +330,21 @@ class Workers extends EventEmitter {
|
|
|
312
330
|
|
|
313
331
|
async _initWorkers(numberOfWorkers, config) {
|
|
314
332
|
await this.splitTestsByGroups(numberOfWorkers, config)
|
|
333
|
+
this.serialTests = await this.createGroupOfSerialTests()
|
|
334
|
+
if (this.serialTests.length && !this.isPoolMode) {
|
|
335
|
+
this.testGroups = this.testGroups.map(group => group.filter(uid => !this.serialTests.includes(uid))).filter(group => group.length)
|
|
336
|
+
}
|
|
315
337
|
// For function-based grouping, use the actual number of test groups created
|
|
316
338
|
const actualNumberOfWorkers = isFunction(config.by) ? this.testGroups.length : numberOfWorkers
|
|
317
339
|
this.workers = createWorkerObjects(this.testGroups, this.codecept.config, getTestRoot(config.testConfig), config.options, config.selectedRuns)
|
|
340
|
+
if (this.serialTests.length) {
|
|
341
|
+
const serialWorkers = createWorkerObjects([this.serialTests], this.codecept.config, getTestRoot(config.testConfig), config.options, config.selectedRuns)
|
|
342
|
+
for (const worker of serialWorkers) {
|
|
343
|
+
worker.workerIndex = this.workers.length
|
|
344
|
+
worker.serial = true
|
|
345
|
+
this.workers.push(worker)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
318
348
|
this.numberOfWorkers = this.workers.length
|
|
319
349
|
}
|
|
320
350
|
|
|
@@ -345,7 +375,8 @@ class Workers extends EventEmitter {
|
|
|
345
375
|
if (config.by === 'pool') {
|
|
346
376
|
this.createTestPool(numberOfWorkers)
|
|
347
377
|
} else {
|
|
348
|
-
|
|
378
|
+
const groups = config.by === 'suite' ? await this.createGroupsOfSuites(numberOfWorkers) : await this.createGroupsOfTests(numberOfWorkers)
|
|
379
|
+
this.testGroups = withoutEmptyGroups(groups)
|
|
349
380
|
}
|
|
350
381
|
}
|
|
351
382
|
}
|
|
@@ -375,17 +406,21 @@ class Workers extends EventEmitter {
|
|
|
375
406
|
const mocha = Container.mocha()
|
|
376
407
|
mocha.files = files
|
|
377
408
|
await loadTests(mocha)
|
|
409
|
+
this.codecept.filterLastFailedTests(mocha)
|
|
378
410
|
|
|
379
411
|
const groups = populateGroups(numberOfWorkers)
|
|
380
412
|
let groupCounter = 0
|
|
381
413
|
|
|
414
|
+
const tests = []
|
|
382
415
|
mocha.suite.eachTest(test => {
|
|
383
|
-
|
|
384
|
-
if (test) {
|
|
385
|
-
groups[i].push(test.uid)
|
|
386
|
-
groupCounter++
|
|
387
|
-
}
|
|
416
|
+
if (test) tests.push(test)
|
|
388
417
|
})
|
|
418
|
+
const selected = tests.filter(test => matchesGrep(mocha, test))
|
|
419
|
+
|
|
420
|
+
for (const test of selected.length ? selected : tests) {
|
|
421
|
+
groups[groupCounter % groups.length].push(test.uid)
|
|
422
|
+
groupCounter++
|
|
423
|
+
}
|
|
389
424
|
|
|
390
425
|
// Clean up after collecting test UIDs
|
|
391
426
|
mocha.unloadFiles()
|
|
@@ -393,6 +428,32 @@ class Workers extends EventEmitter {
|
|
|
393
428
|
return groups
|
|
394
429
|
}
|
|
395
430
|
|
|
431
|
+
/**
|
|
432
|
+
* Collects tests matching `--serial` option or `serial` config pattern.
|
|
433
|
+
* These tests are excluded from parallel workers and run one by one after them.
|
|
434
|
+
*
|
|
435
|
+
* @returns {Promise<string[]>}
|
|
436
|
+
*/
|
|
437
|
+
async createGroupOfSerialTests() {
|
|
438
|
+
const pattern = this.options.serial || this.codecept?.config.serial
|
|
439
|
+
if (!pattern) return []
|
|
440
|
+
const serial = new RegExp(pattern)
|
|
441
|
+
|
|
442
|
+
Container.createMocha(this.codecept.config.mocha || {}, this.options)
|
|
443
|
+
const mocha = Container.mocha()
|
|
444
|
+
mocha.files = this.codecept.testFiles
|
|
445
|
+
await loadTests(mocha, { reload: true })
|
|
446
|
+
|
|
447
|
+
const group = []
|
|
448
|
+
mocha.suite.eachTest(test => {
|
|
449
|
+
if (test && serial.test(test.fullTitle()) && matchesGrep(mocha, test)) group.push(test.uid)
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
mocha.unloadFiles()
|
|
453
|
+
|
|
454
|
+
return group
|
|
455
|
+
}
|
|
456
|
+
|
|
396
457
|
/**
|
|
397
458
|
* @param {Number} numberOfWorkers
|
|
398
459
|
*/
|
|
@@ -463,15 +524,15 @@ class Workers extends EventEmitter {
|
|
|
463
524
|
const mocha = Container.mocha()
|
|
464
525
|
mocha.files = files
|
|
465
526
|
await loadTests(mocha)
|
|
527
|
+
this.codecept.filterLastFailedTests(mocha)
|
|
466
528
|
|
|
467
|
-
mocha.suite.suites.
|
|
529
|
+
const suites = mocha.suite.suites.map(suite => suite.tests.filter(test => test))
|
|
530
|
+
const selected = suites.map(tests => tests.filter(test => matchesGrep(mocha, test))).filter(tests => tests.length)
|
|
531
|
+
|
|
532
|
+
for (const tests of selected.length ? selected : suites) {
|
|
468
533
|
const i = indexOfSmallestElement(groups)
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
groups[i].push(test.uid)
|
|
472
|
-
}
|
|
473
|
-
})
|
|
474
|
-
})
|
|
534
|
+
tests.forEach(test => groups[i].push(test.uid))
|
|
535
|
+
}
|
|
475
536
|
|
|
476
537
|
// Clean up after collecting test UIDs
|
|
477
538
|
mocha.unloadFiles()
|
|
@@ -490,12 +551,17 @@ class Workers extends EventEmitter {
|
|
|
490
551
|
|
|
491
552
|
async bootstrapAll() {
|
|
492
553
|
await this._ensureInitialized()
|
|
554
|
+
await WebServer.startAll(this.codecept.config.webServer)
|
|
493
555
|
return runHook(this.codecept.config.bootstrapAll, 'bootstrapAll')
|
|
494
556
|
}
|
|
495
557
|
|
|
496
558
|
async teardownAll() {
|
|
497
559
|
await this._ensureInitialized()
|
|
498
|
-
|
|
560
|
+
try {
|
|
561
|
+
return await runHook(this.codecept.config.teardownAll, 'teardownAll')
|
|
562
|
+
} finally {
|
|
563
|
+
await WebServer.stopAll()
|
|
564
|
+
}
|
|
499
565
|
}
|
|
500
566
|
|
|
501
567
|
async run() {
|
|
@@ -520,7 +586,8 @@ class Workers extends EventEmitter {
|
|
|
520
586
|
: 0
|
|
521
587
|
|
|
522
588
|
for (const worker of this.workers) {
|
|
523
|
-
|
|
589
|
+
if (worker.serial) continue
|
|
590
|
+
const workerThread = createWorker(worker, this.isPoolMode, this.serialTests)
|
|
524
591
|
this._listenWorkerEvents(workerThread)
|
|
525
592
|
workerThreads.push(workerThread)
|
|
526
593
|
|
|
@@ -531,6 +598,8 @@ class Workers extends EventEmitter {
|
|
|
531
598
|
}
|
|
532
599
|
}
|
|
533
600
|
|
|
601
|
+
if (!workerThreads.length) this._runSerialWorker()
|
|
602
|
+
|
|
534
603
|
recorder.add('workers started', () => {
|
|
535
604
|
// Workers are already running, this is just a placeholder step
|
|
536
605
|
})
|
|
@@ -542,6 +611,14 @@ class Workers extends EventEmitter {
|
|
|
542
611
|
})
|
|
543
612
|
}
|
|
544
613
|
|
|
614
|
+
_runSerialWorker() {
|
|
615
|
+
const parallelWorkers = this.workers.filter(worker => !worker.serial)
|
|
616
|
+
if (this.closedWorkers < parallelWorkers.length) return
|
|
617
|
+
const worker = this.workers[this.closedWorkers]
|
|
618
|
+
if (!worker) return
|
|
619
|
+
this._listenWorkerEvents(createWorker(worker))
|
|
620
|
+
}
|
|
621
|
+
|
|
545
622
|
/**
|
|
546
623
|
* @returns {Array<WorkerObject>}
|
|
547
624
|
*/
|
|
@@ -720,20 +797,32 @@ class Workers extends EventEmitter {
|
|
|
720
797
|
}
|
|
721
798
|
break
|
|
722
799
|
case event.step.finished:
|
|
723
|
-
|
|
724
|
-
|
|
800
|
+
{
|
|
801
|
+
const step = deserializeStep(message.data)
|
|
802
|
+
this.emit(event.step.finished, step)
|
|
803
|
+
event.dispatcher.emit(event.step.finished, step)
|
|
804
|
+
}
|
|
725
805
|
break
|
|
726
806
|
case event.step.started:
|
|
727
|
-
|
|
728
|
-
|
|
807
|
+
{
|
|
808
|
+
const step = deserializeStep(message.data)
|
|
809
|
+
this.emit(event.step.started, step)
|
|
810
|
+
event.dispatcher.emit(event.step.started, step)
|
|
811
|
+
}
|
|
729
812
|
break
|
|
730
813
|
case event.step.passed:
|
|
731
|
-
|
|
732
|
-
|
|
814
|
+
{
|
|
815
|
+
const step = deserializeStep(message.data)
|
|
816
|
+
this.emit(event.step.passed, step)
|
|
817
|
+
event.dispatcher.emit(event.step.passed, step)
|
|
818
|
+
}
|
|
733
819
|
break
|
|
734
820
|
case event.step.failed:
|
|
735
|
-
|
|
736
|
-
|
|
821
|
+
{
|
|
822
|
+
const step = deserializeStep(message.data)
|
|
823
|
+
this.emit(event.step.failed, step, step.error)
|
|
824
|
+
event.dispatcher.emit(event.step.failed, step, step.error)
|
|
825
|
+
}
|
|
737
826
|
break
|
|
738
827
|
case event.hook.failed:
|
|
739
828
|
// Hook failures are already reported as test failures by the worker
|
|
@@ -773,14 +862,10 @@ class Workers extends EventEmitter {
|
|
|
773
862
|
process.exitCode = 1
|
|
774
863
|
}
|
|
775
864
|
|
|
776
|
-
if (this.
|
|
777
|
-
// Pool mode: finish when all workers have exited and no more tests
|
|
778
|
-
if (this.closedWorkers === this.numberOfWorkers) {
|
|
779
|
-
this._finishRun()
|
|
780
|
-
}
|
|
781
|
-
} else if (this.closedWorkers === this.numberOfWorkers) {
|
|
782
|
-
// Regular mode: finish when all original workers have exited
|
|
865
|
+
if (this.closedWorkers === this.numberOfWorkers) {
|
|
783
866
|
this._finishRun()
|
|
867
|
+
} else {
|
|
868
|
+
this._runSerialWorker()
|
|
784
869
|
}
|
|
785
870
|
})
|
|
786
871
|
}
|
|
@@ -802,6 +887,7 @@ class Workers extends EventEmitter {
|
|
|
802
887
|
// For tests with retries configured, emit all failures + final success
|
|
803
888
|
// For tests without retries, emit only final state
|
|
804
889
|
const lastState = states[states.length - 1]
|
|
890
|
+
Container.result().addTest(deserializeTest(lastState.data))
|
|
805
891
|
|
|
806
892
|
// Check if this test had retries by looking for failure followed by success
|
|
807
893
|
const hasRetryPattern = states.length > 1 && states.some((s, i) => s.isFailed && i < states.length - 1 && !states[i + 1].isFailed)
|
|
@@ -829,6 +915,7 @@ class Workers extends EventEmitter {
|
|
|
829
915
|
|
|
830
916
|
this.emit(event.all.result, Container.result())
|
|
831
917
|
event.dispatcher.emit(event.workers.result, Container.result())
|
|
918
|
+
if (Container.result().tests.length) Container.result().save()
|
|
832
919
|
this.emit('end') // internal event
|
|
833
920
|
}
|
|
834
921
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.1-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
6
6
|
"keywords": [
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"test:unit:webbapi:webDriver:noSeleniumServer": "mocha test/helper/WebDriver.noSeleniumServer_test.js --timeout 10000 --reporter @testomatio/reporter/mocha",
|
|
81
81
|
"test:unit:webbapi:cdpbrowser": "mocha test/helper/CDPBrowser_chrome_test.js --timeout 30000 --reporter @testomatio/reporter/mocha",
|
|
82
82
|
"test:unit:webbapi:obscura": "mocha test/helper/CDPBrowser_obscura_test.js --timeout 30000 --reporter @testomatio/reporter/mocha",
|
|
83
|
+
"test:unit:webbapi:lightpanda": "mocha test/helper/CDPBrowser_lightpanda_test.js --timeout 30000 --reporter @testomatio/reporter/mocha",
|
|
83
84
|
"test:unit:expect": "mocha test/helper/Expect_test.js --reporter @testomatio/reporter/mocha",
|
|
84
85
|
"test:plugin": "mocha test/plugin/plugin_test.js --reporter @testomatio/reporter/mocha",
|
|
85
86
|
"def": "./runok.cjs def",
|
|
@@ -101,7 +102,7 @@
|
|
|
101
102
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
102
103
|
"@xmldom/xmldom": "0.9.10",
|
|
103
104
|
"acorn": "8.15.0",
|
|
104
|
-
"ai": "
|
|
105
|
+
"ai": "7.0.132",
|
|
105
106
|
"arrify": "3.0.0",
|
|
106
107
|
"axios": "1.16.1",
|
|
107
108
|
"chalk": "4.1.2",
|
|
@@ -149,6 +150,7 @@
|
|
|
149
150
|
"@eslint/js": "9.39.2",
|
|
150
151
|
"@faker-js/faker": "10.3.0",
|
|
151
152
|
"@inquirer/testing": "^3.0.3",
|
|
153
|
+
"@openrouter/ai-sdk-provider": "^3.1.0",
|
|
152
154
|
"@pollyjs/adapter-puppeteer": "6.0.6",
|
|
153
155
|
"@pollyjs/core": "6.0.6",
|
|
154
156
|
"@testomatio/reporter": "^2.3.1",
|
package/typings/index.d.ts
CHANGED
|
@@ -81,6 +81,21 @@ declare namespace CodeceptJS {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
type WebServerConfig = {
|
|
85
|
+
/** Shell command that starts the application, e.g. `npm run start` */
|
|
86
|
+
command: string
|
|
87
|
+
/** URL polled with GET until it responds; any HTTP status counts as ready */
|
|
88
|
+
url: string
|
|
89
|
+
/** Set to `false` to skip starting the server. Defaults to `true` */
|
|
90
|
+
enabled?: boolean
|
|
91
|
+
/** Milliseconds to wait for `url` to respond. Defaults to `60000` */
|
|
92
|
+
timeout?: number
|
|
93
|
+
/** Working directory for the command, relative to the config directory */
|
|
94
|
+
cwd?: string
|
|
95
|
+
/** Extra environment variables for the command */
|
|
96
|
+
env?: Record<string, string>
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
type MainConfig = {
|
|
85
100
|
/** Pattern to locate CodeceptJS tests.
|
|
86
101
|
* Allows to enter glob pattern or an Array<string> of patterns to match tests / test file names.
|
|
@@ -132,6 +147,15 @@ declare namespace CodeceptJS {
|
|
|
132
147
|
* ```
|
|
133
148
|
*/
|
|
134
149
|
grep?: string
|
|
150
|
+
/**
|
|
151
|
+
* Pattern for tests that must not run in parallel.
|
|
152
|
+
* In `run-workers` matching tests run one by one after all parallel workers finish.
|
|
153
|
+
*
|
|
154
|
+
* ```js
|
|
155
|
+
* serial: '@serial'
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
serial?: string | RegExp
|
|
135
159
|
/**
|
|
136
160
|
* Enable and configure helpers:
|
|
137
161
|
*
|
|
@@ -359,6 +383,17 @@ declare namespace CodeceptJS {
|
|
|
359
383
|
* [Execute JS code after finishing tests in parallel mode](https://codecept.io/bootstrap/#bootstrapall-teardownall)
|
|
360
384
|
*/
|
|
361
385
|
teardownAll?: (() => Promise<void>) | boolean | string
|
|
386
|
+
/**
|
|
387
|
+
* [Start the application under test](https://codecept.io/configuration/#web-server) before tests run and stop it after.
|
|
388
|
+
*
|
|
389
|
+
* ```js
|
|
390
|
+
* webServer: {
|
|
391
|
+
* command: 'npm run start',
|
|
392
|
+
* url: 'http://localhost:3000',
|
|
393
|
+
* }
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
webServer?: WebServerConfig | WebServerConfig[]
|
|
362
397
|
|
|
363
398
|
/** Enable [localized test commands](https://codecept.io/translation/) */
|
|
364
399
|
translation?: string
|
|
@@ -433,7 +468,12 @@ declare namespace CodeceptJS {
|
|
|
433
468
|
// Could get extended by user generated typings
|
|
434
469
|
interface Methods extends ActorStatic {}
|
|
435
470
|
interface I {}
|
|
436
|
-
interface IHook {
|
|
471
|
+
interface IHook {
|
|
472
|
+
(callback: HookCallback): HookConfig
|
|
473
|
+
}
|
|
474
|
+
interface IHookSuite {
|
|
475
|
+
(callback: HookSuiteCallback): HookConfig
|
|
476
|
+
}
|
|
437
477
|
interface IScenario {}
|
|
438
478
|
interface IFeature {
|
|
439
479
|
(title: string, opts?: { [key: string]: any }): FeatureConfig
|
|
@@ -473,8 +513,22 @@ declare namespace CodeceptJS {
|
|
|
473
513
|
|
|
474
514
|
type StringOrSecret = string | CodeceptJS.Secret
|
|
475
515
|
|
|
516
|
+
interface GherkinCallback {
|
|
517
|
+
(test: Test): void | Promise<void>
|
|
518
|
+
}
|
|
519
|
+
interface GherkinEventEmitter {}
|
|
520
|
+
interface GherkinHook {
|
|
521
|
+
(callback: GherkinCallback): GherkinEventEmitter
|
|
522
|
+
}
|
|
476
523
|
interface HookCallback {
|
|
477
|
-
(
|
|
524
|
+
// `suite` has type Mocha.Suite if hook (Background/Before/After) is called before `Feature()`
|
|
525
|
+
// `suite` has type CodeceptJS.Suite if hook is called after `Feature()`
|
|
526
|
+
(args: SupportObject & { suite: Mocha.Suite; test: Test }): void | Promise<void>
|
|
527
|
+
}
|
|
528
|
+
interface HookSuiteCallback {
|
|
529
|
+
// `suite` has type Mocha.Suite if hook (BeforeSuite/AfterSuite) is called before `Feature()`
|
|
530
|
+
// `suite` has type CodeceptJS.Suite if hook is called after `Feature()`
|
|
531
|
+
(args: SupportObject & { suite: Mocha.Suite }): void | Promise<void>
|
|
478
532
|
}
|
|
479
533
|
interface Scenario extends IScenario {
|
|
480
534
|
only: IScenario
|
|
@@ -495,9 +549,6 @@ declare namespace CodeceptJS {
|
|
|
495
549
|
(title: string, callback?: HookCallback): ScenarioConfig
|
|
496
550
|
(title: string, opts: { [key: string]: any }, callback: HookCallback): ScenarioConfig
|
|
497
551
|
}
|
|
498
|
-
interface IHook {
|
|
499
|
-
(callback: HookCallback): HookConfig
|
|
500
|
-
}
|
|
501
552
|
|
|
502
553
|
interface Globals {
|
|
503
554
|
codeceptjs: typeof codeceptjs
|
|
@@ -545,11 +596,13 @@ declare function xData(data: any): CodeceptJS.IData
|
|
|
545
596
|
declare function DefineParameterType(options: CodeceptJS.IParameterTypeDefinition<any>): void
|
|
546
597
|
|
|
547
598
|
// Hooks
|
|
548
|
-
declare const BeforeSuite: CodeceptJS.
|
|
549
|
-
declare const AfterSuite: CodeceptJS.
|
|
599
|
+
declare const BeforeSuite: CodeceptJS.IHookSuite
|
|
600
|
+
declare const AfterSuite: CodeceptJS.IHookSuite
|
|
550
601
|
declare const Background: CodeceptJS.IHook
|
|
551
602
|
declare const Before: CodeceptJS.IHook
|
|
552
603
|
declare const After: CodeceptJS.IHook
|
|
604
|
+
declare const GherkinBefore: CodeceptJS.GherkinHook
|
|
605
|
+
declare const GherkinAfter: CodeceptJS.GherkinHook
|
|
553
606
|
|
|
554
607
|
// Plugins
|
|
555
608
|
declare const __: any
|