wdio-rerun-service 2.0.7 → 2.1.0
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/CHANGELOG.md +29 -0
- package/README.md +44 -11
- package/build/cjs/index.d.ts +6 -2
- package/build/cjs/index.js +55 -36
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.d.ts +6 -2
- package/build/esm/index.js +43 -16
- package/build/esm/index.js.map +1 -1
- package/package.json +67 -54
- package/vitest.config.ts +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,35 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
|
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
+
## v2.1.0 (2025-12-22)
|
|
17
|
+
#### :rocket: New Feature
|
|
18
|
+
* Support for Cucumber scenarios nested inside `Rule:` blocks - line numbers are now correctly extracted for reruns
|
|
19
|
+
|
|
20
|
+
#### :bug: Bug Fix
|
|
21
|
+
* Fixed WebdriverIO v9 compatibility - updated `@cucumber/messages` enum comparison to work with both v8 and v9
|
|
22
|
+
|
|
23
|
+
#### :house: Internal
|
|
24
|
+
* Migrated from Jest to Vitest - faster test execution, no experimental flags needed
|
|
25
|
+
* Switched to pnpm for development (enforced via `packageManager` field)
|
|
26
|
+
* Updated all dependencies to latest versions
|
|
27
|
+
* Removed deprecated `@types/uuid` - uuid v13 includes its own types
|
|
28
|
+
* Achieved 100% test coverage with 56 tests
|
|
29
|
+
* Node.js 18+ required (compatible with both WDIO v8 and v9)
|
|
30
|
+
|
|
31
|
+
#### Committers: 1
|
|
32
|
+
- [@esaari](https://github.com/esaari)
|
|
33
|
+
|
|
34
|
+
## v2.0.7 (2023-7-24)
|
|
35
|
+
#### :bug: Bug Fix
|
|
36
|
+
* [[#67]](https://github.com/webdriverio-community/wdio-rerun-service/pull/67) Update some dependencies ([@esaari](https://github.com/esaari))
|
|
37
|
+
|
|
38
|
+
#### :memo: Documentation
|
|
39
|
+
* [[#63]](https://github.com/webdriverio-community/wdio-rerun-service/pull/63) Update Readme ([@mikesalvia](https://github.com/mikesalvia))
|
|
40
|
+
|
|
41
|
+
#### Committers: 3
|
|
42
|
+
- [@esaari](https://github.com/esaari)
|
|
43
|
+
- [@mikesalvia](https://github.com/mikesalvia)
|
|
44
|
+
|
|
16
45
|
## v2.0.6 (2023-1-19)
|
|
17
46
|
#### :bug: Bug Fix
|
|
18
47
|
* [[#56]](https://github.com/webdriverio-community/wdio-rerun-service/pull/56) [v8] Generate failure line number at Example data line ([@cesar-rivera](https://github.com/cesar-rivera), [@wenzhhu](https://github.com/wenzhhu))
|
package/README.md
CHANGED
|
@@ -2,13 +2,30 @@ WebdriverIO Re-run Service
|
|
|
2
2
|
==========================
|
|
3
3
|
|
|
4
4
|
[](https://github.com/webdriverio-community/wdio-rerun-service/actions/workflows/test.yml)
|
|
5
|
+
[](https://codecov.io/gh/webdriverio-community/wdio-rerun-service)
|
|
5
6
|

|
|
6
7
|

|
|
7
8
|

|
|
8
9
|
|
|
9
10
|
This service tracks failing Mocha or Jasmine tests and Cucumber scenarios executed within the [WebdriverIO](https://webdriver.io) test framework. It will allow failing or unstable tests or scenarios to be re-run.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- 🔄 Re-run failed Mocha, Jasmine, or Cucumber tests after the main test run completes
|
|
15
|
+
- 🥒 Full Cucumber support including scenarios inside `Rule:` blocks
|
|
16
|
+
- 🏷️ Filter out scenarios with specific tags from re-runs
|
|
17
|
+
- 🪟 Cross-platform support (generates `rerun.sh` on Unix, `rerun.bat` on Windows)
|
|
18
|
+
- ⚙️ Configurable command prefix and custom parameters
|
|
19
|
+
|
|
20
|
+
## Compatibility
|
|
21
|
+
|
|
22
|
+
| wdio-rerun-service | WebdriverIO |
|
|
23
|
+
|--------------------|-------------|
|
|
24
|
+
| `^2.1.0` | `^8.0.0 \|\| ^9.0.0` |
|
|
25
|
+
| `^2.0.0` | `^8.0.0` |
|
|
26
|
+
| `^1.7.0` | `^7.0.0` |
|
|
27
|
+
|
|
28
|
+
**Note:** Version `2.1.0` is backward compatible with WebdriverIO v8 and adds support for v9. All users on v8 or v9 should use the latest `2.x.x` version.
|
|
12
29
|
|
|
13
30
|
## Re-run vs. Retry
|
|
14
31
|
|
|
@@ -33,12 +50,18 @@ Using `npm`:
|
|
|
33
50
|
npm install wdio-rerun-service
|
|
34
51
|
```
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
Using `yarn`:
|
|
37
54
|
|
|
38
55
|
```bash
|
|
39
56
|
yarn add wdio-rerun-service
|
|
40
57
|
```
|
|
41
58
|
|
|
59
|
+
Using `pnpm`:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pnpm add wdio-rerun-service
|
|
63
|
+
```
|
|
64
|
+
|
|
42
65
|
After package installation is complete, add it to `services` array in `wdio.conf.js`:
|
|
43
66
|
|
|
44
67
|
```js
|
|
@@ -46,29 +69,39 @@ After package installation is complete, add it to `services` array in `wdio.conf
|
|
|
46
69
|
import RerunService from 'wdio-rerun-service';
|
|
47
70
|
export const config = {
|
|
48
71
|
// ...
|
|
49
|
-
services: [
|
|
50
|
-
|
|
51
|
-
|
|
72
|
+
services: [
|
|
73
|
+
[RerunService, {
|
|
74
|
+
// Re-run service options here...
|
|
75
|
+
}]
|
|
76
|
+
],
|
|
77
|
+
// ...
|
|
52
78
|
};
|
|
53
79
|
```
|
|
54
80
|
|
|
55
81
|
Instructions on how to install `WebdriverIO` can be found [here.](https://webdriver.io/docs/gettingstarted.html)
|
|
56
82
|
|
|
57
83
|
## Usage
|
|
84
|
+
|
|
58
85
|
By design, this service does not automatically re-run failed tests.
|
|
59
86
|
|
|
60
|
-
After
|
|
87
|
+
After WebdriverIO has completed execution, if failures are found, a re-run script will be generated at **rerunScriptPath** (default: `./rerun.sh` on Unix, `./rerun.bat` on Windows).
|
|
88
|
+
|
|
89
|
+
You can then execute this script manually or integrate it into your CI pipeline.
|
|
90
|
+
|
|
91
|
+
### Disabling Re-run
|
|
92
|
+
|
|
93
|
+
Set the environment variable `DISABLE_RERUN=true` to disable the service (useful during re-run execution to prevent infinite loops).
|
|
61
94
|
|
|
62
95
|
### Conditional Re-run
|
|
63
96
|
Every teams re-run needs will differ execution could be based on any number of factors, this is an example of how to accomplish a conditional re-run based on # of failures.
|
|
64
97
|
|
|
65
98
|
##### attemptRerun.sh
|
|
66
|
-
Executes `./rerun.sh` if less than 25 failures have been found in last execution of
|
|
99
|
+
Executes `./rerun.sh` if less than 25 failures have been found in the last execution of WebdriverIO.
|
|
67
100
|
```sh
|
|
68
101
|
#!/usr/bin/env bash
|
|
69
102
|
MAX_TO_RERUN=${MAX_TO_RERUN:=25}
|
|
70
103
|
if [ -f "rerun.sh" ]; then
|
|
71
|
-
echo "[rerun.sh] file
|
|
104
|
+
echo "[rerun.sh] file exists, checking total failures."
|
|
72
105
|
NUMBER_OF_FAILURES=$(grep "\-\-spec" -o rerun.sh | wc -l | xargs)
|
|
73
106
|
if [ "$MAX_TO_RERUN" -gt "$NUMBER_OF_FAILURES" ]; then
|
|
74
107
|
echo "Re-running $NUMBER_OF_FAILURES failed scenarios!"
|
|
@@ -77,7 +110,7 @@ if [ -f "rerun.sh" ]; then
|
|
|
77
110
|
echo "Skipping re-run, expected < $MAX_TO_RERUN failures to qualify execution for re-run, got $NUMBER_OF_FAILURES failures."
|
|
78
111
|
fi
|
|
79
112
|
else
|
|
80
|
-
echo "No [rerun.sh] file
|
|
113
|
+
echo "No [rerun.sh] file exists, skipping re-run!"
|
|
81
114
|
fi
|
|
82
115
|
```
|
|
83
116
|
##### Bash Re-run Command
|
|
@@ -136,11 +169,11 @@ export const config = {
|
|
|
136
169
|
```
|
|
137
170
|
|
|
138
171
|
### rerunScriptPath
|
|
139
|
-
Path to write re-run
|
|
172
|
+
Path to write the re-run script.
|
|
140
173
|
|
|
141
174
|
Type: `String`
|
|
142
175
|
|
|
143
|
-
Default: `./rerun.sh`
|
|
176
|
+
Default: `./rerun.sh` (Unix) or `./rerun.bat` (Windows)
|
|
144
177
|
|
|
145
178
|
Example:
|
|
146
179
|
```js
|
package/build/cjs/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Logger } from '@wdio/logger';
|
|
2
|
+
import type { Frameworks, Services } from '@wdio/types';
|
|
2
3
|
type AfterScenario = NonNullable<WebdriverIO.HookFunctionExtension['afterScenario']>;
|
|
3
4
|
type AfterScenarioParameters = Parameters<AfterScenario>;
|
|
4
5
|
type World = AfterScenarioParameters[0];
|
|
@@ -12,6 +13,7 @@ interface RerunServiceOptions {
|
|
|
12
13
|
rerunScriptPath?: string;
|
|
13
14
|
commandPrefix?: string;
|
|
14
15
|
customParameters?: string;
|
|
16
|
+
platformName?: NodeJS.Platform;
|
|
15
17
|
}
|
|
16
18
|
export default class RerunService implements Services.ServiceInstance {
|
|
17
19
|
nonPassingItems: NonPassingItem[];
|
|
@@ -23,8 +25,10 @@ export default class RerunService implements Services.ServiceInstance {
|
|
|
23
25
|
customParameters: string;
|
|
24
26
|
specFile: string;
|
|
25
27
|
disabled: boolean;
|
|
28
|
+
platformName: NodeJS.Platform;
|
|
29
|
+
log: Logger;
|
|
26
30
|
constructor(options?: RerunServiceOptions);
|
|
27
|
-
before(_capabilities: Capabilities
|
|
31
|
+
before(_capabilities: WebdriverIO.Capabilities, specs: string[]): Promise<void>;
|
|
28
32
|
afterTest(_test: Frameworks.Test, _context: any, results: Frameworks.TestResult): void;
|
|
29
33
|
afterScenario(world: World): void;
|
|
30
34
|
after(): Promise<void>;
|
package/build/cjs/index.js
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const node_path_1 = require("node:path");
|
|
9
|
-
const node_process_1 = require("node:process");
|
|
10
|
-
const uuid_1 = require("uuid");
|
|
11
|
-
class RerunService {
|
|
1
|
+
import logger from '@wdio/logger';
|
|
2
|
+
import minimist from 'minimist';
|
|
3
|
+
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { argv, env, platform } from 'node:process';
|
|
6
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
7
|
+
export default class RerunService {
|
|
12
8
|
constructor(options = {}) {
|
|
13
|
-
const { ignoredTags, rerunDataDir, rerunScriptPath, commandPrefix, customParameters, } = options;
|
|
9
|
+
const { ignoredTags, rerunDataDir, rerunScriptPath, commandPrefix, customParameters, platformName, } = options;
|
|
14
10
|
this.nonPassingItems = [];
|
|
15
11
|
this.serviceWorkerId = '';
|
|
16
12
|
this.ignoredTags = ignoredTags ?? [];
|
|
17
13
|
this.rerunDataDir = rerunDataDir ?? './results/rerun';
|
|
14
|
+
this.platformName = platformName ?? platform;
|
|
18
15
|
this.rerunScriptPath =
|
|
19
|
-
rerunScriptPath ??
|
|
16
|
+
rerunScriptPath ??
|
|
17
|
+
(this.platformName === 'win32' ? 'rerun.bat' : 'rerun.sh');
|
|
20
18
|
this.commandPrefix = commandPrefix ?? '';
|
|
21
19
|
this.customParameters = customParameters ?? '';
|
|
22
20
|
this.specFile = '';
|
|
23
|
-
this.disabled =
|
|
21
|
+
this.disabled = env['DISABLE_RERUN'] === 'true';
|
|
22
|
+
this.log = logger('@wdio/wdio-rerun-service');
|
|
24
23
|
}
|
|
25
24
|
async before(_capabilities, specs) {
|
|
26
25
|
if (this.disabled) {
|
|
27
26
|
return;
|
|
28
27
|
}
|
|
29
28
|
this.specFile = specs[0] ?? '';
|
|
30
|
-
|
|
31
|
-
await
|
|
32
|
-
this.serviceWorkerId = (
|
|
29
|
+
this.log.debug(`Re-run service is activated. Data directory: ${this.rerunDataDir}`);
|
|
30
|
+
await mkdir(this.rerunDataDir, { recursive: true });
|
|
31
|
+
this.serviceWorkerId = uuidv4();
|
|
33
32
|
}
|
|
34
33
|
afterTest(_test, _context, results) {
|
|
35
34
|
if (this.disabled) {
|
|
@@ -40,8 +39,8 @@ class RerunService {
|
|
|
40
39
|
if (passed || config.framework === 'cucumber') {
|
|
41
40
|
return;
|
|
42
41
|
}
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
this.log.debug(`Re-run service is inspecting non-passing test.`);
|
|
43
|
+
this.log.debug(`Test location: ${this.specFile}`);
|
|
45
44
|
const error = results.error;
|
|
46
45
|
if (error?.message) {
|
|
47
46
|
this.nonPassingItems.push({
|
|
@@ -50,7 +49,7 @@ class RerunService {
|
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
else {
|
|
53
|
-
|
|
52
|
+
this.log.debug('The non-passing test did not contain any error message, it could not be added for re-run.');
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
// Executed after a Cucumber scenario ends.
|
|
@@ -65,14 +64,34 @@ class RerunService {
|
|
|
65
64
|
status === 'SKIPPED') {
|
|
66
65
|
return;
|
|
67
66
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
const { gherkinDocument, pickle } = world;
|
|
68
|
+
const featureChildren = gherkinDocument.feature?.children ?? [];
|
|
69
|
+
// Locate the matching scenario by searching feature children
|
|
70
|
+
// Scenarios can be at top-level OR nested within Rule blocks
|
|
71
|
+
const findMatchingScenario = () => {
|
|
72
|
+
for (const featureChild of featureChildren) {
|
|
73
|
+
// Direct scenario under feature
|
|
74
|
+
if (featureChild.scenario) {
|
|
75
|
+
if (pickle.astNodeIds.includes(featureChild.scenario.id)) {
|
|
76
|
+
return featureChild.scenario;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Scenario nested inside a Rule block
|
|
80
|
+
if (featureChild.rule?.children) {
|
|
81
|
+
const ruleScenario = featureChild.rule.children.find((ruleChild) => ruleChild.scenario &&
|
|
82
|
+
pickle.astNodeIds.includes(ruleChild.scenario.id))?.scenario;
|
|
83
|
+
if (ruleScenario)
|
|
84
|
+
return ruleScenario;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
};
|
|
89
|
+
const scenario = findMatchingScenario();
|
|
71
90
|
let scenarioLineNumber = scenario?.location.line ?? 0;
|
|
72
91
|
if (scenario && scenario.examples.length > 0) {
|
|
73
92
|
let exampleLineNumber = 0;
|
|
74
93
|
scenario.examples.find((example) => example.tableBody.find((row) => {
|
|
75
|
-
if (row.id ===
|
|
94
|
+
if (row.id === pickle.astNodeIds[1]) {
|
|
76
95
|
exampleLineNumber = row.location.line;
|
|
77
96
|
return true;
|
|
78
97
|
}
|
|
@@ -80,8 +99,8 @@ class RerunService {
|
|
|
80
99
|
}));
|
|
81
100
|
scenarioLineNumber = exampleLineNumber;
|
|
82
101
|
}
|
|
83
|
-
const scenarioLocation = `${
|
|
84
|
-
const tagsList =
|
|
102
|
+
const scenarioLocation = `${pickle.uri}:${scenarioLineNumber}`;
|
|
103
|
+
const tagsList = pickle.tags.map((tag) => tag.name);
|
|
85
104
|
if (!Array.isArray(this.ignoredTags) ||
|
|
86
105
|
!tagsList.some((ignoredTag) => this.ignoredTags.includes(ignoredTag))) {
|
|
87
106
|
this.nonPassingItems.push({
|
|
@@ -95,30 +114,31 @@ class RerunService {
|
|
|
95
114
|
return;
|
|
96
115
|
}
|
|
97
116
|
if (this.nonPassingItems.length === 0) {
|
|
98
|
-
|
|
117
|
+
this.log.debug('Re-run service did not detect any non-passing scenarios or tests.');
|
|
118
|
+
return;
|
|
99
119
|
}
|
|
100
|
-
await
|
|
120
|
+
await writeFile(join(this.rerunDataDir, `rerun-${this.serviceWorkerId}.json`), JSON.stringify(this.nonPassingItems));
|
|
101
121
|
}
|
|
102
122
|
async onComplete() {
|
|
103
123
|
if (this.disabled) {
|
|
104
124
|
return;
|
|
105
125
|
}
|
|
106
126
|
try {
|
|
107
|
-
const files = await
|
|
127
|
+
const files = await readdir(this.rerunDataDir);
|
|
108
128
|
const rerunFiles = files.filter((file) => file.endsWith('.json'));
|
|
109
129
|
if (rerunFiles.length === 0) {
|
|
110
130
|
return;
|
|
111
131
|
}
|
|
112
|
-
const parsedArgs = (
|
|
132
|
+
const parsedArgs = minimist(argv.slice(2));
|
|
113
133
|
const args = parsedArgs._[0] ? parsedArgs._[0] + ' ' : '';
|
|
114
134
|
const prefix = this.commandPrefix ? this.commandPrefix + ' ' : '';
|
|
115
|
-
const disableRerun =
|
|
135
|
+
const disableRerun = this.platformName === 'win32'
|
|
116
136
|
? 'set DISABLE_RERUN=true &&'
|
|
117
137
|
: 'DISABLE_RERUN=true';
|
|
118
138
|
let rerunCommand = `${prefix}${disableRerun} npx wdio ${args}${this.customParameters}`;
|
|
119
139
|
const failureLocations = new Set();
|
|
120
140
|
for (const file of rerunFiles) {
|
|
121
|
-
const json = JSON.parse(await
|
|
141
|
+
const json = JSON.parse(await readFile(join(this.rerunDataDir, file), 'utf8'));
|
|
122
142
|
json.forEach((failure) => {
|
|
123
143
|
failureLocations.add(failure.location.replace(/\\/g, '/'));
|
|
124
144
|
});
|
|
@@ -126,13 +146,12 @@ class RerunService {
|
|
|
126
146
|
failureLocations.forEach((failureLocation) => {
|
|
127
147
|
rerunCommand += ` --spec=${failureLocation}`;
|
|
128
148
|
});
|
|
129
|
-
await
|
|
130
|
-
|
|
149
|
+
await writeFile(this.rerunScriptPath, rerunCommand, { mode: 0o755 });
|
|
150
|
+
this.log.debug(`Re-run script has been generated @ ${this.rerunScriptPath}`);
|
|
131
151
|
}
|
|
132
152
|
catch (err) {
|
|
133
|
-
|
|
153
|
+
this.log.debug(`Re-run service failed to generate re-run script: ${JSON.stringify(err)}`);
|
|
134
154
|
}
|
|
135
155
|
}
|
|
136
156
|
}
|
|
137
|
-
exports.default = RerunService;
|
|
138
157
|
//# sourceMappingURL=index.js.map
|
package/build/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/build/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Logger } from '@wdio/logger';
|
|
2
|
+
import type { Frameworks, Services } from '@wdio/types';
|
|
2
3
|
type AfterScenario = NonNullable<WebdriverIO.HookFunctionExtension['afterScenario']>;
|
|
3
4
|
type AfterScenarioParameters = Parameters<AfterScenario>;
|
|
4
5
|
type World = AfterScenarioParameters[0];
|
|
@@ -12,6 +13,7 @@ interface RerunServiceOptions {
|
|
|
12
13
|
rerunScriptPath?: string;
|
|
13
14
|
commandPrefix?: string;
|
|
14
15
|
customParameters?: string;
|
|
16
|
+
platformName?: NodeJS.Platform;
|
|
15
17
|
}
|
|
16
18
|
export default class RerunService implements Services.ServiceInstance {
|
|
17
19
|
nonPassingItems: NonPassingItem[];
|
|
@@ -23,8 +25,10 @@ export default class RerunService implements Services.ServiceInstance {
|
|
|
23
25
|
customParameters: string;
|
|
24
26
|
specFile: string;
|
|
25
27
|
disabled: boolean;
|
|
28
|
+
platformName: NodeJS.Platform;
|
|
29
|
+
log: Logger;
|
|
26
30
|
constructor(options?: RerunServiceOptions);
|
|
27
|
-
before(_capabilities: Capabilities
|
|
31
|
+
before(_capabilities: WebdriverIO.Capabilities, specs: string[]): Promise<void>;
|
|
28
32
|
afterTest(_test: Frameworks.Test, _context: any, results: Frameworks.TestResult): void;
|
|
29
33
|
afterScenario(world: World): void;
|
|
30
34
|
after(): Promise<void>;
|
package/build/esm/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logger from '@wdio/logger';
|
|
1
2
|
import minimist from 'minimist';
|
|
2
3
|
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
4
|
import { join } from 'node:path';
|
|
@@ -13,25 +14,30 @@ export default class RerunService {
|
|
|
13
14
|
customParameters;
|
|
14
15
|
specFile;
|
|
15
16
|
disabled;
|
|
17
|
+
platformName;
|
|
18
|
+
log;
|
|
16
19
|
constructor(options = {}) {
|
|
17
|
-
const { ignoredTags, rerunDataDir, rerunScriptPath, commandPrefix, customParameters, } = options;
|
|
20
|
+
const { ignoredTags, rerunDataDir, rerunScriptPath, commandPrefix, customParameters, platformName, } = options;
|
|
18
21
|
this.nonPassingItems = [];
|
|
19
22
|
this.serviceWorkerId = '';
|
|
20
23
|
this.ignoredTags = ignoredTags ?? [];
|
|
21
24
|
this.rerunDataDir = rerunDataDir ?? './results/rerun';
|
|
25
|
+
this.platformName = platformName ?? platform;
|
|
22
26
|
this.rerunScriptPath =
|
|
23
|
-
rerunScriptPath ??
|
|
27
|
+
rerunScriptPath ??
|
|
28
|
+
(this.platformName === 'win32' ? 'rerun.bat' : 'rerun.sh');
|
|
24
29
|
this.commandPrefix = commandPrefix ?? '';
|
|
25
30
|
this.customParameters = customParameters ?? '';
|
|
26
31
|
this.specFile = '';
|
|
27
32
|
this.disabled = env['DISABLE_RERUN'] === 'true';
|
|
33
|
+
this.log = logger('@wdio/wdio-rerun-service');
|
|
28
34
|
}
|
|
29
35
|
async before(_capabilities, specs) {
|
|
30
36
|
if (this.disabled) {
|
|
31
37
|
return;
|
|
32
38
|
}
|
|
33
39
|
this.specFile = specs[0] ?? '';
|
|
34
|
-
|
|
40
|
+
this.log.debug(`Re-run service is activated. Data directory: ${this.rerunDataDir}`);
|
|
35
41
|
await mkdir(this.rerunDataDir, { recursive: true });
|
|
36
42
|
this.serviceWorkerId = uuidv4();
|
|
37
43
|
}
|
|
@@ -44,8 +50,8 @@ export default class RerunService {
|
|
|
44
50
|
if (passed || config.framework === 'cucumber') {
|
|
45
51
|
return;
|
|
46
52
|
}
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
this.log.debug(`Re-run service is inspecting non-passing test.`);
|
|
54
|
+
this.log.debug(`Test location: ${this.specFile}`);
|
|
49
55
|
const error = results.error;
|
|
50
56
|
if (error?.message) {
|
|
51
57
|
this.nonPassingItems.push({
|
|
@@ -54,7 +60,7 @@ export default class RerunService {
|
|
|
54
60
|
});
|
|
55
61
|
}
|
|
56
62
|
else {
|
|
57
|
-
|
|
63
|
+
this.log.debug('The non-passing test did not contain any error message, it could not be added for re-run.');
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
// Executed after a Cucumber scenario ends.
|
|
@@ -69,14 +75,34 @@ export default class RerunService {
|
|
|
69
75
|
status === 'SKIPPED') {
|
|
70
76
|
return;
|
|
71
77
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
const { gherkinDocument, pickle } = world;
|
|
79
|
+
const featureChildren = gherkinDocument.feature?.children ?? [];
|
|
80
|
+
// Locate the matching scenario by searching feature children
|
|
81
|
+
// Scenarios can be at top-level OR nested within Rule blocks
|
|
82
|
+
const findMatchingScenario = () => {
|
|
83
|
+
for (const featureChild of featureChildren) {
|
|
84
|
+
// Direct scenario under feature
|
|
85
|
+
if (featureChild.scenario) {
|
|
86
|
+
if (pickle.astNodeIds.includes(featureChild.scenario.id)) {
|
|
87
|
+
return featureChild.scenario;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Scenario nested inside a Rule block
|
|
91
|
+
if (featureChild.rule?.children) {
|
|
92
|
+
const ruleScenario = featureChild.rule.children.find((ruleChild) => ruleChild.scenario &&
|
|
93
|
+
pickle.astNodeIds.includes(ruleChild.scenario.id))?.scenario;
|
|
94
|
+
if (ruleScenario)
|
|
95
|
+
return ruleScenario;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
};
|
|
100
|
+
const scenario = findMatchingScenario();
|
|
75
101
|
let scenarioLineNumber = scenario?.location.line ?? 0;
|
|
76
102
|
if (scenario && scenario.examples.length > 0) {
|
|
77
103
|
let exampleLineNumber = 0;
|
|
78
104
|
scenario.examples.find((example) => example.tableBody.find((row) => {
|
|
79
|
-
if (row.id ===
|
|
105
|
+
if (row.id === pickle.astNodeIds[1]) {
|
|
80
106
|
exampleLineNumber = row.location.line;
|
|
81
107
|
return true;
|
|
82
108
|
}
|
|
@@ -84,8 +110,8 @@ export default class RerunService {
|
|
|
84
110
|
}));
|
|
85
111
|
scenarioLineNumber = exampleLineNumber;
|
|
86
112
|
}
|
|
87
|
-
const scenarioLocation = `${
|
|
88
|
-
const tagsList =
|
|
113
|
+
const scenarioLocation = `${pickle.uri}:${scenarioLineNumber}`;
|
|
114
|
+
const tagsList = pickle.tags.map((tag) => tag.name);
|
|
89
115
|
if (!Array.isArray(this.ignoredTags) ||
|
|
90
116
|
!tagsList.some((ignoredTag) => this.ignoredTags.includes(ignoredTag))) {
|
|
91
117
|
this.nonPassingItems.push({
|
|
@@ -99,7 +125,8 @@ export default class RerunService {
|
|
|
99
125
|
return;
|
|
100
126
|
}
|
|
101
127
|
if (this.nonPassingItems.length === 0) {
|
|
102
|
-
|
|
128
|
+
this.log.debug('Re-run service did not detect any non-passing scenarios or tests.');
|
|
129
|
+
return;
|
|
103
130
|
}
|
|
104
131
|
await writeFile(join(this.rerunDataDir, `rerun-${this.serviceWorkerId}.json`), JSON.stringify(this.nonPassingItems));
|
|
105
132
|
}
|
|
@@ -116,7 +143,7 @@ export default class RerunService {
|
|
|
116
143
|
const parsedArgs = minimist(argv.slice(2));
|
|
117
144
|
const args = parsedArgs._[0] ? parsedArgs._[0] + ' ' : '';
|
|
118
145
|
const prefix = this.commandPrefix ? this.commandPrefix + ' ' : '';
|
|
119
|
-
const disableRerun =
|
|
146
|
+
const disableRerun = this.platformName === 'win32'
|
|
120
147
|
? 'set DISABLE_RERUN=true &&'
|
|
121
148
|
: 'DISABLE_RERUN=true';
|
|
122
149
|
let rerunCommand = `${prefix}${disableRerun} npx wdio ${args}${this.customParameters}`;
|
|
@@ -131,10 +158,10 @@ export default class RerunService {
|
|
|
131
158
|
rerunCommand += ` --spec=${failureLocation}`;
|
|
132
159
|
});
|
|
133
160
|
await writeFile(this.rerunScriptPath, rerunCommand, { mode: 0o755 });
|
|
134
|
-
|
|
161
|
+
this.log.debug(`Re-run script has been generated @ ${this.rerunScriptPath}`);
|
|
135
162
|
}
|
|
136
163
|
catch (err) {
|
|
137
|
-
|
|
164
|
+
this.log.debug(`Re-run service failed to generate re-run script: ${JSON.stringify(err)}`);
|
|
138
165
|
}
|
|
139
166
|
}
|
|
140
167
|
}
|
package/build/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wdio-rerun-service",
|
|
3
|
-
"version": "2.0
|
|
4
|
-
"description": "A WebdriverIO service to track and
|
|
5
|
-
"author": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "A WebdriverIO service to track and stage for re-running failed or flaky Jasmine/Mocha tests or Cucumber Scenarios.",
|
|
5
|
+
"author": "Eric Saari <esaari@gmail.com>",
|
|
6
|
+
"contributors": [
|
|
7
|
+
"Mike Salvia <mike.salvia@icloud.com>"
|
|
8
|
+
],
|
|
6
9
|
"homepage": "https://github.com/webdriverio-community/wdio-rerun-service",
|
|
7
10
|
"license": "MIT",
|
|
8
11
|
"publishConfig": {
|
|
@@ -25,8 +28,9 @@
|
|
|
25
28
|
}
|
|
26
29
|
},
|
|
27
30
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
31
|
+
"node": ">=20.0.0"
|
|
29
32
|
},
|
|
33
|
+
"packageManager": "pnpm@10.11.0",
|
|
30
34
|
"scripts": {
|
|
31
35
|
"build": "run-s clean compile",
|
|
32
36
|
"clean": "rimraf ./build",
|
|
@@ -34,12 +38,12 @@
|
|
|
34
38
|
"compile:cjs": "tsc -p tsconfig.cjs.json",
|
|
35
39
|
"compile:esm": "tsc -p tsconfig.esm.json",
|
|
36
40
|
"generate:cjs:package": "shx echo \"{\\\"type\\\":\\\"commonjs\\\"}\" > ./build/cjs/package.json",
|
|
37
|
-
"prepare": "
|
|
41
|
+
"prepare": "pnpm run build",
|
|
38
42
|
"test": "run-s test:*",
|
|
39
43
|
"test:clean": "rimraf ./results ./coverage rerun.sh rerun.bat",
|
|
40
44
|
"test:eslint": "eslint src tests",
|
|
41
45
|
"test:tsc": "tsc -p tsconfig.json --noEmit",
|
|
42
|
-
"test:unit": "
|
|
46
|
+
"test:unit": "vitest run --coverage",
|
|
43
47
|
"watch": "npm-watch"
|
|
44
48
|
},
|
|
45
49
|
"watch": {
|
|
@@ -50,68 +54,77 @@
|
|
|
50
54
|
"url": "git://github.com/webdriverio-community/wdio-rerun-service.git"
|
|
51
55
|
},
|
|
52
56
|
"keywords": [
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
57
|
+
"automation",
|
|
58
|
+
"auto-rerun",
|
|
59
|
+
"bdd",
|
|
60
|
+
"ci",
|
|
61
|
+
"continuous-integration",
|
|
62
|
+
"cucumber",
|
|
63
|
+
"cucumberjs",
|
|
64
|
+
"flaky",
|
|
65
|
+
"flaky-tests",
|
|
66
|
+
"gherkin",
|
|
67
|
+
"jasmine",
|
|
68
|
+
"jasmine-tests",
|
|
69
|
+
"javascript",
|
|
70
|
+
"javascript-testing",
|
|
71
|
+
"mocha",
|
|
72
|
+
"mocha-tests",
|
|
73
|
+
"nodejs",
|
|
74
|
+
"parallel-testing",
|
|
58
75
|
"re-run",
|
|
76
|
+
"rerun",
|
|
77
|
+
"rerun-failures",
|
|
59
78
|
"retry",
|
|
60
|
-
"
|
|
61
|
-
"
|
|
79
|
+
"retry-failures",
|
|
80
|
+
"retry-runner",
|
|
62
81
|
"scenario",
|
|
63
|
-
"cucumber",
|
|
64
|
-
"mocha",
|
|
65
|
-
"jasmine",
|
|
66
|
-
"flaky",
|
|
67
82
|
"selenium",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
83
|
+
"test",
|
|
84
|
+
"test-retry",
|
|
85
|
+
"tests",
|
|
86
|
+
"typescript",
|
|
87
|
+
"wdio",
|
|
88
|
+
"wdio-service",
|
|
89
|
+
"wdio-service-plugin",
|
|
90
|
+
"webdriver",
|
|
91
|
+
"webdriver.io",
|
|
92
|
+
"webdriverio",
|
|
93
|
+
"webdriverio-plugin"
|
|
71
94
|
],
|
|
72
95
|
"bugs": {
|
|
73
96
|
"url": "https://github.com/webdriverio-community/wdio-rerun-service/issues"
|
|
74
97
|
},
|
|
75
98
|
"dependencies": {
|
|
76
|
-
"@wdio/
|
|
99
|
+
"@wdio/logger": "^9.18.0",
|
|
100
|
+
"@wdio/types": "^9.20.0",
|
|
77
101
|
"minimist": "^1.2.7",
|
|
78
|
-
"uuid": "^
|
|
102
|
+
"uuid": "^13.0.0"
|
|
79
103
|
},
|
|
80
104
|
"devDependencies": {
|
|
81
|
-
"@
|
|
82
|
-
"@
|
|
105
|
+
"@cucumber/cucumber": "^11.2.0",
|
|
106
|
+
"@cucumber/messages": "^27.0.0",
|
|
107
|
+
"@tsconfig/node16": "^16.1.8",
|
|
83
108
|
"@tsconfig/node18-strictest-esm": "^1.0.1",
|
|
84
|
-
"@types/minimist": "^1.2.
|
|
85
|
-
"@types/node": "^
|
|
86
|
-
"@
|
|
87
|
-
"@typescript-eslint/
|
|
88
|
-
"@
|
|
89
|
-
"@wdio/cucumber-framework": "^
|
|
90
|
-
"@wdio/globals": "^
|
|
91
|
-
"cross-env": "^7.0.3",
|
|
109
|
+
"@types/minimist": "^1.2.5",
|
|
110
|
+
"@types/node": "^22.19.0",
|
|
111
|
+
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
112
|
+
"@typescript-eslint/parser": "^8.50.0",
|
|
113
|
+
"@vitest/coverage-v8": "^3.2.2",
|
|
114
|
+
"@wdio/cucumber-framework": "^9.21.0",
|
|
115
|
+
"@wdio/globals": "^9.17.0",
|
|
92
116
|
"eslint": "^8.30.0",
|
|
93
|
-
"eslint-config-prettier": "^
|
|
94
|
-
"eslint-plugin-prettier": "^
|
|
95
|
-
"jest": "^29.3.1",
|
|
117
|
+
"eslint-config-prettier": "^10.1.8",
|
|
118
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
96
119
|
"npm-run-all": "4.1.5",
|
|
97
|
-
"npm-watch": "0.
|
|
98
|
-
"prettier": "^
|
|
99
|
-
"prettier-plugin-organize-imports": "^3.
|
|
100
|
-
"release-it": "^
|
|
101
|
-
"rimraf": "^
|
|
102
|
-
"shx": "^0.
|
|
103
|
-
"ts-
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
},
|
|
107
|
-
"jest": {
|
|
108
|
-
"preset": "ts-jest/presets/default-esm",
|
|
109
|
-
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
|
|
110
|
-
"moduleNameMapper": {
|
|
111
|
-
"^(\\.{1,2}/.*)\\.js$": "$1"
|
|
112
|
-
},
|
|
113
|
-
"collectCoverageFrom": [
|
|
114
|
-
"src/index.ts"
|
|
115
|
-
]
|
|
120
|
+
"npm-watch": "0.13.0",
|
|
121
|
+
"prettier": "^3.7.4",
|
|
122
|
+
"prettier-plugin-organize-imports": "^4.3.0",
|
|
123
|
+
"release-it": "^19.1.0",
|
|
124
|
+
"rimraf": "^6.1.2",
|
|
125
|
+
"shx": "^0.4.0",
|
|
126
|
+
"ts-node": "^10.9.2",
|
|
127
|
+
"typescript": "^5.8.3",
|
|
128
|
+
"vitest": "^3.2.2"
|
|
116
129
|
}
|
|
117
130
|
}
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
include: ['tests/**/*.test.ts'],
|
|
6
|
+
coverage: {
|
|
7
|
+
provider: 'v8',
|
|
8
|
+
include: ['src/index.ts'],
|
|
9
|
+
reporter: ['text', 'lcov', 'clover', 'json'],
|
|
10
|
+
thresholds: {
|
|
11
|
+
statements: 100,
|
|
12
|
+
branches: 100,
|
|
13
|
+
functions: 100,
|
|
14
|
+
lines: 100,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
})
|