codeceptjs 3.7.5-beta.8 → 3.7.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.7.5-beta.8",
3
+ "version": "3.7.5",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -78,12 +78,12 @@
78
78
  "@codeceptjs/configure": "1.0.6",
79
79
  "@codeceptjs/helper": "2.0.4",
80
80
  "@cucumber/cucumber-expressions": "18",
81
- "@cucumber/gherkin": "32.1.2",
82
- "@cucumber/messages": "27.2.0",
81
+ "@cucumber/gherkin": "35.1.0",
82
+ "@cucumber/messages": "29.0.1",
83
83
  "@xmldom/xmldom": "0.9.8",
84
- "acorn": "8.14.1",
84
+ "acorn": "8.15.0",
85
85
  "arrify": "3.0.0",
86
- "axios": "1.11.0",
86
+ "axios": "1.12.2",
87
87
  "chalk": "4.1.2",
88
88
  "cheerio": "^1.0.0",
89
89
  "chokidar": "^4.0.3",
@@ -95,20 +95,20 @@
95
95
  "escape-string-regexp": "4.0.0",
96
96
  "figures": "3.2.0",
97
97
  "fn-args": "4.0.0",
98
- "fs-extra": "11.3.0",
98
+ "fs-extra": "11.3.2",
99
99
  "fuse.js": "^7.0.0",
100
100
  "glob": ">=9.0.0 <12",
101
101
  "html-minifier-terser": "7.2.0",
102
102
  "inquirer": "^8.2.7",
103
103
  "invisi-data": "^1.0.0",
104
- "joi": "17.13.3",
104
+ "joi": "18.0.1",
105
105
  "js-beautify": "1.15.4",
106
106
  "lodash.clonedeep": "4.5.0",
107
107
  "lodash.merge": "4.6.2",
108
108
  "lodash.shuffle": "4.2.0",
109
109
  "mkdirp": "3.0.1",
110
- "mocha": "11.6.0",
111
- "monocart-coverage-reports": "2.12.6",
110
+ "mocha": "11.7.2",
111
+ "monocart-coverage-reports": "2.12.9",
112
112
  "ms": "2.1.3",
113
113
  "multer": "^2.0.2",
114
114
  "ora-classic": "5.4.2",
@@ -120,20 +120,20 @@
120
120
  "uuid": "11.1.0"
121
121
  },
122
122
  "optionalDependencies": {
123
- "@codeceptjs/detox-helper": "1.1.8"
123
+ "@codeceptjs/detox-helper": "1.1.12"
124
124
  },
125
125
  "devDependencies": {
126
- "@apollo/server": "^4",
126
+ "@apollo/server": "^5",
127
127
  "@codeceptjs/expect-helper": "^1.0.2",
128
128
  "@codeceptjs/mock-request": "0.3.1",
129
129
  "@eslint/eslintrc": "3.3.1",
130
- "@eslint/js": "9.34.0",
130
+ "@eslint/js": "9.36.0",
131
131
  "@faker-js/faker": "9.8.0",
132
132
  "@pollyjs/adapter-puppeteer": "6.0.6",
133
133
  "@pollyjs/core": "6.0.6",
134
134
  "@types/chai": "5.2.2",
135
- "@types/inquirer": "9.0.7",
136
- "@types/node": "24.0.10",
135
+ "@types/inquirer": "9.0.9",
136
+ "@types/node": "24.5.2",
137
137
  "@wdio/sauce-service": "9.12.5",
138
138
  "@wdio/selenium-standalone-service": "8.15.0",
139
139
  "@wdio/utils": "9.15.0",
@@ -142,13 +142,13 @@
142
142
  "chai-as-promised": "7.1.2",
143
143
  "chai-subset": "1.6.0",
144
144
  "documentation": "14.0.3",
145
- "electron": "37.2.3",
146
- "eslint": "^9.24.0",
145
+ "electron": "38.1.2",
146
+ "eslint": "^9.36.0",
147
147
  "eslint-plugin-import": "2.32.0",
148
148
  "eslint-plugin-mocha": "11.1.0",
149
- "expect": "30.0.5",
149
+ "expect": "30.1.2",
150
150
  "express": "^5.1.0",
151
- "globals": "16.2.0",
151
+ "globals": "16.4.0",
152
152
  "graphql": "16.11.0",
153
153
  "graphql-tag": "^2.12.6",
154
154
  "husky": "9.1.7",
@@ -157,7 +157,7 @@
157
157
  "jsdoc-typeof-plugin": "1.0.0",
158
158
  "json-server": "0.17.4",
159
159
  "mochawesome": "^7.1.3",
160
- "playwright": "1.54.1",
160
+ "playwright": "1.55.0",
161
161
  "prettier": "^3.3.2",
162
162
  "puppeteer": "24.15.0",
163
163
  "qrcode-terminal": "0.12.0",
@@ -171,8 +171,8 @@
171
171
  "ts-node": "10.9.2",
172
172
  "tsd": "^0.33.0",
173
173
  "tsd-jsdoc": "2.5.0",
174
- "typedoc": "0.28.10",
175
- "typedoc-plugin-markdown": "4.8.1",
174
+ "typedoc": "0.28.13",
175
+ "typedoc-plugin-markdown": "4.9.0",
176
176
  "typescript": "5.8.3",
177
177
  "wdio-docker-service": "3.2.1",
178
178
  "webdriverio": "9.12.5",
@@ -189,5 +189,8 @@
189
189
  "compilerOptions": {
190
190
  "strict": false
191
191
  }
192
+ },
193
+ "overrides": {
194
+ "tmp": "0.2.5"
192
195
  }
193
196
  }
@@ -2735,9 +2735,6 @@ declare namespace CodeceptJS {
2735
2735
  * @property [testIdAttribute = data-testid] - locate elements based on the testIdAttribute. See more of [locate by test id](https://playwright.dev/docs/locators#locate-by-test-id).
2736
2736
  * @property [customLocatorStrategies] - custom locator strategies. An object with keys as strategy names and values as JavaScript functions. Example: `{ byRole: (selector, root) => { return root.querySelector(\`[role="\${selector}\"]\`) } }`
2737
2737
  */
2738
- // @ts-ignore
2739
- // @ts-ignore
2740
- // @ts-ignore
2741
2738
  type PlaywrightConfig = {
2742
2739
  url?: string;
2743
2740
  browser?: 'chromium' | 'firefox' | 'webkit' | 'electron';
@@ -6115,9 +6112,6 @@ declare namespace CodeceptJS {
6115
6112
  * @property [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
6116
6113
  * @property [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
6117
6114
  */
6118
- // @ts-ignore
6119
- // @ts-ignore
6120
- // @ts-ignore
6121
6115
  type PuppeteerConfig = {
6122
6116
  url: string;
6123
6117
  basicAuth?: any;
@@ -6541,6 +6535,17 @@ declare namespace CodeceptJS {
6541
6535
  * {{ react }}
6542
6536
  */
6543
6537
  _locate(): Promise<any>;
6538
+ /**
6539
+ * Get single element by different locator types, including strict locator
6540
+ * Should be used in custom helpers:
6541
+ *
6542
+ * ```js
6543
+ * const element = await this.helpers['Puppeteer']._locateElement({name: 'password'});
6544
+ * ```
6545
+ *
6546
+ * {{ react }}
6547
+ */
6548
+ _locateElement(): Promise<any>;
6544
6549
  /**
6545
6550
  * Find a checkbox by providing human-readable text:
6546
6551
  * NOTE: Assumes the checkable element exists
@@ -6577,6 +6582,17 @@ declare namespace CodeceptJS {
6577
6582
  * @returns WebElement of being used Web helper
6578
6583
  */
6579
6584
  grabWebElements(locator: CodeceptJS.LocatorOrString): Promise<any>;
6585
+ /**
6586
+ * Grab WebElement for given locator
6587
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
6588
+ *
6589
+ * ```js
6590
+ * const webElement = await I.grabWebElement('#button');
6591
+ * ```
6592
+ * @param locator - element located by CSS|XPath|strict locator.
6593
+ * @returns WebElement of being used Web helper
6594
+ */
6595
+ grabWebElement(locator: CodeceptJS.LocatorOrString): Promise<any>;
6580
6596
  /**
6581
6597
  * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab
6582
6598
  *
@@ -7912,6 +7928,22 @@ declare namespace CodeceptJS {
7912
7928
  */
7913
7929
  flushWebSocketMessages(): Promise<any>;
7914
7930
  }
7931
+ /**
7932
+ * Find elements using Puppeteer's native element discovery methods
7933
+ * Note: Unlike Playwright, Puppeteer's Locator API doesn't have .all() method for multiple elements
7934
+ * @param matcher - Puppeteer context to search within
7935
+ * @param locator - Locator specification
7936
+ * @returns Array of ElementHandle objects
7937
+ */
7938
+ function findElements(matcher: any, locator: any | string): Promise<any[]>;
7939
+ /**
7940
+ * Find a single element using Puppeteer's native element discovery methods
7941
+ * Note: Puppeteer Locator API doesn't have .first() method like Playwright
7942
+ * @param matcher - Puppeteer context to search within
7943
+ * @param locator - Locator specification
7944
+ * @returns Single ElementHandle object
7945
+ */
7946
+ function findElement(matcher: any, locator: any | string): Promise<object>;
7915
7947
  /**
7916
7948
  * ## Configuration
7917
7949
  * @property [endpoint] - API base URL
@@ -7924,9 +7956,6 @@ declare namespace CodeceptJS {
7924
7956
  * @property [onResponse] - an async function which can update response object.
7925
7957
  * @property [maxUploadFileSize] - set the max content file size in MB when performing api calls.
7926
7958
  */
7927
- // @ts-ignore
7928
- // @ts-ignore
7929
- // @ts-ignore
7930
7959
  type RESTConfig = {
7931
7960
  endpoint?: string;
7932
7961
  prettyPrintJson?: boolean;
@@ -9072,9 +9101,6 @@ declare namespace CodeceptJS {
9072
9101
  * @property [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
9073
9102
  * @property [logLevel = silent] - level of logging verbosity. Default: silent. Options: trace | debug | info | warn | error | silent. More info: https://webdriver.io/docs/configuration/#loglevel
9074
9103
  */
9075
- // @ts-ignore
9076
- // @ts-ignore
9077
- // @ts-ignore
9078
9104
  type WebDriverConfig = {
9079
9105
  url: string;
9080
9106
  browser: string;
@@ -9545,6 +9571,17 @@ declare namespace CodeceptJS {
9545
9571
  * @returns WebElement of being used Web helper
9546
9572
  */
9547
9573
  grabWebElements(locator: CodeceptJS.LocatorOrString): Promise<any>;
9574
+ /**
9575
+ * Grab WebElement for given locator
9576
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
9577
+ *
9578
+ * ```js
9579
+ * const webElement = await I.grabWebElement('#button');
9580
+ * ```
9581
+ * @param locator - element located by CSS|XPath|strict locator.
9582
+ * @returns WebElement of being used Web helper
9583
+ */
9584
+ grabWebElement(locator: CodeceptJS.LocatorOrString): Promise<any>;
9548
9585
  /**
9549
9586
  * Set [WebDriver timeouts](https://webdriver.io/docs/timeouts.html) in realtime.
9550
9587
  *
@@ -2825,9 +2825,6 @@ declare namespace CodeceptJS {
2825
2825
  * @property [testIdAttribute = data-testid] - locate elements based on the testIdAttribute. See more of [locate by test id](https://playwright.dev/docs/locators#locate-by-test-id).
2826
2826
  * @property [customLocatorStrategies] - custom locator strategies. An object with keys as strategy names and values as JavaScript functions. Example: `{ byRole: (selector, root) => { return root.querySelector(\`[role="\${selector}\"]\`) } }`
2827
2827
  */
2828
- // @ts-ignore
2829
- // @ts-ignore
2830
- // @ts-ignore
2831
2828
  type PlaywrightConfig = {
2832
2829
  url?: string;
2833
2830
  browser?: 'chromium' | 'firefox' | 'webkit' | 'electron';
@@ -6356,9 +6353,6 @@ declare namespace CodeceptJS {
6356
6353
  * @property [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
6357
6354
  * @property [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
6358
6355
  */
6359
- // @ts-ignore
6360
- // @ts-ignore
6361
- // @ts-ignore
6362
6356
  type PuppeteerConfig = {
6363
6357
  url: string;
6364
6358
  basicAuth?: any;
@@ -6798,6 +6792,17 @@ declare namespace CodeceptJS {
6798
6792
  * {{ react }}
6799
6793
  */
6800
6794
  _locate(): void;
6795
+ /**
6796
+ * Get single element by different locator types, including strict locator
6797
+ * Should be used in custom helpers:
6798
+ *
6799
+ * ```js
6800
+ * const element = await this.helpers['Puppeteer']._locateElement({name: 'password'});
6801
+ * ```
6802
+ *
6803
+ * {{ react }}
6804
+ */
6805
+ _locateElement(): void;
6801
6806
  /**
6802
6807
  * Find a checkbox by providing human-readable text:
6803
6808
  * NOTE: Assumes the checkable element exists
@@ -6834,6 +6839,17 @@ declare namespace CodeceptJS {
6834
6839
  * @returns WebElement of being used Web helper
6835
6840
  */
6836
6841
  grabWebElements(locator: CodeceptJS.LocatorOrString): Promise<any>;
6842
+ /**
6843
+ * Grab WebElement for given locator
6844
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
6845
+ *
6846
+ * ```js
6847
+ * const webElement = await I.grabWebElement('#button');
6848
+ * ```
6849
+ * @param locator - element located by CSS|XPath|strict locator.
6850
+ * @returns WebElement of being used Web helper
6851
+ */
6852
+ grabWebElement(locator: CodeceptJS.LocatorOrString): Promise<any>;
6837
6853
  /**
6838
6854
  * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab
6839
6855
  *
@@ -8289,6 +8305,22 @@ declare namespace CodeceptJS {
8289
8305
  */
8290
8306
  flushWebSocketMessages(): void;
8291
8307
  }
8308
+ /**
8309
+ * Find elements using Puppeteer's native element discovery methods
8310
+ * Note: Unlike Playwright, Puppeteer's Locator API doesn't have .all() method for multiple elements
8311
+ * @param matcher - Puppeteer context to search within
8312
+ * @param locator - Locator specification
8313
+ * @returns Array of ElementHandle objects
8314
+ */
8315
+ function findElements(matcher: any, locator: any | string): Promise<any[]>;
8316
+ /**
8317
+ * Find a single element using Puppeteer's native element discovery methods
8318
+ * Note: Puppeteer Locator API doesn't have .first() method like Playwright
8319
+ * @param matcher - Puppeteer context to search within
8320
+ * @param locator - Locator specification
8321
+ * @returns Single ElementHandle object
8322
+ */
8323
+ function findElement(matcher: any, locator: any | string): Promise<object>;
8292
8324
  /**
8293
8325
  * ## Configuration
8294
8326
  * @property [endpoint] - API base URL
@@ -8301,9 +8333,6 @@ declare namespace CodeceptJS {
8301
8333
  * @property [onResponse] - an async function which can update response object.
8302
8334
  * @property [maxUploadFileSize] - set the max content file size in MB when performing api calls.
8303
8335
  */
8304
- // @ts-ignore
8305
- // @ts-ignore
8306
- // @ts-ignore
8307
8336
  type RESTConfig = {
8308
8337
  endpoint?: string;
8309
8338
  prettyPrintJson?: boolean;
@@ -9509,9 +9538,6 @@ declare namespace CodeceptJS {
9509
9538
  * @property [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
9510
9539
  * @property [logLevel = silent] - level of logging verbosity. Default: silent. Options: trace | debug | info | warn | error | silent. More info: https://webdriver.io/docs/configuration/#loglevel
9511
9540
  */
9512
- // @ts-ignore
9513
- // @ts-ignore
9514
- // @ts-ignore
9515
9541
  type WebDriverConfig = {
9516
9542
  url: string;
9517
9543
  browser: string;
@@ -9982,6 +10008,17 @@ declare namespace CodeceptJS {
9982
10008
  * @returns WebElement of being used Web helper
9983
10009
  */
9984
10010
  grabWebElements(locator: CodeceptJS.LocatorOrString): Promise<any>;
10011
+ /**
10012
+ * Grab WebElement for given locator
10013
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
10014
+ *
10015
+ * ```js
10016
+ * const webElement = await I.grabWebElement('#button');
10017
+ * ```
10018
+ * @param locator - element located by CSS|XPath|strict locator.
10019
+ * @returns WebElement of being used Web helper
10020
+ */
10021
+ grabWebElement(locator: CodeceptJS.LocatorOrString): Promise<any>;
9985
10022
  /**
9986
10023
  * Set [WebDriver timeouts](https://webdriver.io/docs/timeouts.html) in realtime.
9987
10024
  *
@@ -11526,6 +11563,13 @@ declare namespace CodeceptJS {
11526
11563
  * Loads tests by pattern or by config.tests
11527
11564
  */
11528
11565
  loadTests(pattern?: string): void;
11566
+ /**
11567
+ * Apply sharding to test files based on shard configuration
11568
+ * @param testFiles - Array of test file paths
11569
+ * @param shardConfig - Shard configuration in format "index/total" (e.g., "1/4")
11570
+ * @returns - Filtered array of test files for this shard
11571
+ */
11572
+ _applySharding(testFiles: string[], shardConfig: string): string[];
11529
11573
  /**
11530
11574
  * Run a specific test or all loaded tests.
11531
11575
  */
@@ -12019,6 +12063,10 @@ declare namespace CodeceptJS {
12019
12063
  * Get a state of current queue and tasks
12020
12064
  */
12021
12065
  toString(): string;
12066
+ /**
12067
+ * Get current session ID
12068
+ */
12069
+ getCurrentSessionId(): string | null;
12022
12070
  }
12023
12071
  interface RecorderSession {
12024
12072
  running: boolean;
@@ -1,218 +0,0 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
- const { getConfig, printError, getTestRoot, createOutputDir } = require('./utils')
4
- const Config = require('../config')
5
- const store = require('../store')
6
- const Codecept = require('../codecept')
7
- const output = require('../output')
8
- const Workers = require('../workers')
9
- const { tryOrDefault } = require('../utils')
10
-
11
- module.exports = async function (options) {
12
- // registering options globally to use in config
13
- if (options.profile) {
14
- process.env.profile = options.profile
15
- }
16
- if (options.verbose || options.debug) store.debugMode = true
17
-
18
- const configFile = options.config
19
- let config = getConfig(configFile)
20
-
21
- if (options.override) {
22
- config = Config.append(JSON.parse(options.override))
23
- }
24
-
25
- const testRoot = getTestRoot(configFile)
26
- createOutputDir(config, testRoot)
27
-
28
- // Determine failed tests file path - respect CodeceptJS output directory
29
- const failedTestsFile = options.file || 'failed-tests.json'
30
- const failedTestsPath = path.isAbsolute(failedTestsFile)
31
- ? failedTestsFile
32
- : path.resolve(global.output_dir || './output', failedTestsFile)
33
-
34
- // Check if failed tests file exists
35
- if (!fs.existsSync(failedTestsPath)) {
36
- output.error(`Failed tests file not found: ${failedTestsPath}`)
37
- output.print('Run tests first to generate a failed tests file, or specify a different file with --file option')
38
- process.exitCode = 1
39
- return
40
- }
41
-
42
- let failedTestsData
43
- try {
44
- const fileContent = fs.readFileSync(failedTestsPath, 'utf8')
45
- failedTestsData = JSON.parse(fileContent)
46
- } catch (error) {
47
- output.error(`Failed to read or parse failed tests file: ${error.message}`)
48
- process.exitCode = 1
49
- return
50
- }
51
-
52
- if (!failedTestsData.tests || failedTestsData.tests.length === 0) {
53
- output.print('No failed tests found in the file')
54
- return
55
- }
56
-
57
- output.print(`Found ${failedTestsData.tests.length} failed tests from ${failedTestsData.timestamp}`)
58
-
59
- // Build test patterns from failed tests
60
- const testPatterns = []
61
- const testsByFile = new Map()
62
-
63
- // Group tests by file for more efficient execution
64
- failedTestsData.tests.forEach(test => {
65
- if (test.file) {
66
- if (!testsByFile.has(test.file)) {
67
- testsByFile.set(test.file, [])
68
- }
69
- testsByFile.get(test.file).push(test)
70
- }
71
- })
72
-
73
- // If we have specific test files, use them
74
- if (testsByFile.size > 0) {
75
- for (const [file, tests] of testsByFile) {
76
- if (options.grep) {
77
- // If grep is specified, combine with file pattern
78
- testPatterns.push(file)
79
- } else {
80
- // Try to be more specific with test titles if possible
81
- testPatterns.push(file)
82
- }
83
- }
84
- } else {
85
- // Fallback: use test titles with grep
86
- const testTitles = failedTestsData.tests.map(test => test.title).filter(Boolean)
87
- if (testTitles.length > 0) {
88
- // Create a regex pattern to match any of the failed test titles
89
- const grepPattern = testTitles.map(title => title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')
90
- options.grep = grepPattern
91
- }
92
- }
93
-
94
- // Check if user wants to run with workers
95
- if (options.workers) {
96
- await runWithWorkers(config, options, testPatterns, failedTestsData)
97
- } else {
98
- await runWithoutWorkers(config, options, testPatterns, failedTestsData, testRoot)
99
- }
100
- }
101
-
102
- async function runWithWorkers(config, options, testPatterns, failedTestsData) {
103
- const numberOfWorkers = parseInt(options.workers, 10)
104
- const overrideConfigs = tryOrDefault(() => JSON.parse(options.override || '{}'), {})
105
-
106
- // Determine test split strategy
107
- let by = 'test' // default for failed tests
108
- if (options.by) {
109
- by = options.by
110
- } else if (options.suites) {
111
- by = 'suite'
112
- }
113
-
114
- // Validate the by option
115
- const validStrategies = ['test', 'suite', 'pool']
116
- if (!validStrategies.includes(by)) {
117
- throw new Error(`Invalid --by strategy: ${by}. Valid options are: ${validStrategies.join(', ')}`)
118
- }
119
-
120
- const workerConfig = {
121
- by,
122
- testConfig: options.config,
123
- options,
124
- selectedRuns: undefined,
125
- }
126
-
127
- output.print(`CodeceptJS v${require('../codecept').version()}`)
128
- output.print(`Re-running ${failedTestsData.tests.length} failed tests in ${output.styles.bold(numberOfWorkers)} workers...`)
129
- output.print()
130
- store.hasWorkers = true
131
-
132
- const workers = new Workers(numberOfWorkers, workerConfig)
133
- workers.overrideConfig(overrideConfigs)
134
-
135
- // Set up event listeners for worker output
136
- workers.on('test.failed', test => {
137
- output.test.failed(test)
138
- })
139
-
140
- workers.on('test.passed', test => {
141
- output.test.passed(test)
142
- })
143
-
144
- workers.on('test.skipped', test => {
145
- output.test.skipped(test)
146
- })
147
-
148
- workers.on('all.result', result => {
149
- workers.printResults()
150
- })
151
-
152
- try {
153
- if (options.verbose || options.debug) store.debugMode = true
154
-
155
- if (options.verbose) {
156
- output.print('\nFailed tests to re-run with workers:')
157
- failedTestsData.tests.forEach((test, index) => {
158
- output.print(` ${index + 1}. ${test.fullTitle || test.title} (${test.file || 'unknown file'})`)
159
- if (test.error && test.error.message) {
160
- output.print(` Error: ${test.error.message}`)
161
- }
162
- })
163
- output.print('')
164
-
165
- const { getMachineInfo } = require('./info')
166
- await getMachineInfo()
167
- }
168
-
169
- await workers.bootstrapAll()
170
- await workers.run()
171
- } catch (err) {
172
- printError(err)
173
- process.exitCode = 1
174
- } finally {
175
- await workers.teardownAll()
176
- }
177
- }
178
-
179
- async function runWithoutWorkers(config, options, testPatterns, failedTestsData, testRoot) {
180
- const codecept = new Codecept(config, options)
181
-
182
- try {
183
- codecept.init(testRoot)
184
- await codecept.bootstrap()
185
-
186
- // Load tests - if we have specific patterns, use them, otherwise load all and filter with grep
187
- if (testPatterns.length > 0) {
188
- codecept.loadTests(testPatterns.join(' '))
189
- } else {
190
- codecept.loadTests()
191
- }
192
-
193
- if (options.verbose) {
194
- global.debugMode = true
195
- const { getMachineInfo } = require('./info')
196
- await getMachineInfo()
197
- }
198
-
199
- // Display information about what we're running
200
- if (options.verbose) {
201
- output.print('\nFailed tests to re-run:')
202
- failedTestsData.tests.forEach((test, index) => {
203
- output.print(` ${index + 1}. ${test.fullTitle || test.title} (${test.file || 'unknown file'})`)
204
- if (test.error && test.error.message) {
205
- output.print(` Error: ${test.error.message}`)
206
- }
207
- })
208
- output.print('')
209
- }
210
-
211
- await codecept.run()
212
- } catch (err) {
213
- printError(err)
214
- process.exitCode = 1
215
- } finally {
216
- await codecept.teardown()
217
- }
218
- }