wdio-rerun-service 1.7.6 → 2.0.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/.editorconfig ADDED
@@ -0,0 +1,20 @@
1
+ # EditorConfig helps developers define and maintain consistent
2
+ # coding styles between different editors and IDEs
3
+ # editorconfig.org
4
+
5
+ root = true
6
+
7
+ [*]
8
+ indent_style = space
9
+ indent_size = 4
10
+ end_of_line = lf
11
+ charset = utf-8
12
+ trim_trailing_whitespace = true
13
+ insert_final_newline = true
14
+
15
+ [*.md]
16
+ max_line_length = 0
17
+ trim_trailing_whitespace = false
18
+
19
+ [{*.json,*.yml}]
20
+ indent_size = 2
package/.eslintignore ADDED
@@ -0,0 +1,3 @@
1
+ build/
2
+ results/
3
+ coverage/
@@ -0,0 +1,68 @@
1
+ name: Manual NPM Publish
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ releaseType:
7
+ description: "Release type - major, minor or patch"
8
+ required: true
9
+ type: choice
10
+ default: "patch"
11
+ options:
12
+ - patch
13
+ - minor
14
+ - major
15
+ distTag:
16
+ description: 'NPM tag (e.g. use "next --preRelease=alpha --github.preRelease" to release a test version)'
17
+ required: true
18
+ default: 'latest'
19
+ preRelease:
20
+ description: If latest release was a pre-release (e.g. X.X.X-alpha.0) and you want to push another one, pick "yes"
21
+ required: true
22
+ type: choice
23
+ default: "no"
24
+ options:
25
+ - "yes"
26
+ - "no"
27
+
28
+ env:
29
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
30
+
31
+ jobs:
32
+ release:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v3
36
+ with:
37
+ ref: main
38
+ fetch-depth: 0
39
+ - uses: actions/setup-node@v3
40
+ with:
41
+ node-version: 18.x
42
+ - name: NPM Setup
43
+ run: |
44
+ npm set registry "https://registry.npmjs.org/"
45
+ npm set //registry.npmjs.org/:_authToken $NPM_TOKEN
46
+ npm whoami
47
+ - name: Git Setup
48
+ run: |
49
+ git config --global user.email "bot@webdriver.io"
50
+ git config --global user.name "WebdriverIO Release Bot"
51
+ - name: Install Dependencies
52
+ run: npm ci --ignore-scripts
53
+ - name: Build Project
54
+ run: npm run build --if-present
55
+ env:
56
+ NODE_ENV: production
57
+ - name: Release
58
+ run: npx release-it ${{github.event.inputs.releaseType}} --github.release --ci --npm.skipChecks --no-git.requireCleanWorkingDir --npm.tag=${{github.event.inputs.distTag}}
59
+ env:
60
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
61
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62
+ if: ${{ github.event.inputs.preRelease == 'no' }}
63
+ - name: Pre-Release
64
+ run: npx release-it ${{github.event.inputs.releaseType}} --github.release --ci --npm.skipChecks --no-git.requireCleanWorkingDir --preRelease=alpha --github.preRelease --npm.tag=next
65
+ env:
66
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
67
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68
+ if: ${{ github.event.inputs.preRelease == 'yes' }}
@@ -1,45 +1,50 @@
1
1
  # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
2
  # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
3
 
4
- name: wdio-rerun-service CI
4
+ name: Test
5
5
 
6
6
  on:
7
7
  push:
8
- branches: [ master, main ]
8
+ branches: [main]
9
9
  pull_request:
10
- branches: [ master, main ]
10
+ branches: [main]
11
+
12
+ permissions:
13
+ contents: read # to fetch code (actions/checkout)
11
14
 
12
15
  jobs:
13
16
  build:
14
17
  runs-on: ubuntu-latest
15
18
  strategy:
16
19
  matrix:
17
- node-version: [12.x, 13.x, 14.x]
18
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
20
+ node-version: [16.x, 18.x]
19
21
  steps:
20
- - uses: actions/checkout@v2
22
+ - uses: actions/checkout@v3
21
23
  - name: Use Node.js ${{ matrix.node-version }}
22
- uses: actions/setup-node@v1
24
+ uses: actions/setup-node@v3
23
25
  with:
24
26
  node-version: ${{ matrix.node-version }}
25
- - run: npm ci
26
- - run: npm install -g eslint
27
+ - run: npm i -g npm@latest
28
+ - run: npm ci --ignore-scripts
27
29
  - run: npm run build --if-present
28
- - run: npm run test
29
-
30
+ - run: npm test
31
+ env:
32
+ CI: true
33
+
30
34
  build-windows:
31
35
  runs-on: windows-latest
32
36
  strategy:
33
37
  matrix:
34
- node-version: [12.x]
35
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
38
+ node-version: [16.x]
36
39
  steps:
37
- - uses: actions/checkout@v2
40
+ - uses: actions/checkout@v3
38
41
  - name: Use Node.js ${{ matrix.node-version }}
39
- uses: actions/setup-node@v1
42
+ uses: actions/setup-node@v3
40
43
  with:
41
44
  node-version: ${{ matrix.node-version }}
42
- - run: npm ci
43
- - run: npm install -g eslint
45
+ - run: npm i -g npm@latest
46
+ - run: npm ci --ignore-scripts
44
47
  - run: npm run build --if-present
45
- - run: npm run test
48
+ - run: npm test
49
+ env:
50
+ CI: true
@@ -0,0 +1,30 @@
1
+ # this workflow merges requests from Dependabot if tests are passing
2
+ name: Merge me!
3
+
4
+ on:
5
+ workflow_run:
6
+ workflows:
7
+ - Test
8
+ types:
9
+ - completed
10
+
11
+ jobs:
12
+ merge-me:
13
+ name: Merge me!
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Merge me!
17
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
18
+ uses: ridedott/merge-me-action@v2
19
+ with:
20
+ # Depending on branch prodtection rules, a manually populated
21
+ # `GITHUB_TOKEN_WORKAROUND` secret with permissions to push to
22
+ # a protected branch must be used.
23
+ #
24
+ # When using a custom token, it is recommended to leave the following
25
+ # comment for other developers to be aware of the reasoning behind it:
26
+ #
27
+ # This must be used as GitHub Actions token does not support pushing
28
+ # to protected branches.
29
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30
+ PRESET: DEPENDABOT_MINOR
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ v18.12.1
package/README.md CHANGED
@@ -8,7 +8,7 @@ WebdriverIO Re-run Service
8
8
 
9
9
  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
10
 
11
- _NOTE_: Cucumber Framework users running WebdriverIO versions `5.x` and `6.x` should use version `1.6.x`. If you are on the latest major version of `7.x`, use the latest `1.7.x` version of this service.
11
+ _NOTE_: Cucumber Framework users running WebdriverIO versions `5.x.x` and `6.x.x` should use version `1.6.x`. If you are on `7.x.x`, use version `1.7.x` version of this service. If you are on the latest major version of `8.x.x`, use the latest `2.x.x` version of this service.
12
12
 
13
13
  ## Re-run vs. Retry
14
14
 
@@ -27,28 +27,24 @@ It is recommended to take some time to evaluate the options available. A hybrid
27
27
 
28
28
  ## Installation
29
29
 
30
- The easiest way is to add `wdio-rerun-service` to `devDependencies` in your `package.json`.
30
+ Using `npm`:
31
31
 
32
- ```json
33
- {
34
- "devDependencies": {
35
- "wdio-rerun-service": "^1.7.6"
36
- }
37
- }
32
+ ```bash
33
+ npm install wdio-rerun-service
38
34
  ```
39
35
 
40
- It can be installed by using `npm`:
36
+ or using `yarn`:
41
37
 
42
38
  ```bash
43
- npm install wdio-rerun-service
39
+ yarn add wdio-rerun-service
44
40
  ```
45
41
 
46
42
  After package installation is complete, add it to `services` array in `wdio.conf.js`:
47
43
 
48
44
  ```js
49
45
  // wdio.conf.js
50
- const RerunService = require('wdio-rerun-service');
51
- export.config = {
46
+ import RerunService from 'wdio-rerun-service';
47
+ export const config = {
52
48
  // ...
53
49
  services: [RerunService, {
54
50
  // ...
@@ -64,8 +60,8 @@ The following options may be added to the wdio.conf.js file. To define options f
64
60
 
65
61
  ```js
66
62
  // wdio.conf.js
67
- const RerunService = require('wdio-rerun-service');
68
- export.config = {
63
+ import RerunService from 'wdio-rerun-service';
64
+ export const config = {
69
65
  // ...
70
66
  services: [
71
67
  [RerunService, {
@@ -85,8 +81,8 @@ Default: `./results/rerun`
85
81
 
86
82
  Example:
87
83
  ```js
88
- const RerunService = require('wdio-rerun-service');
89
- export.config = {
84
+ import RerunService from 'wdio-rerun-service';
85
+ export const config = {
90
86
  // ...
91
87
  services: [
92
88
  [RerunService, {
@@ -106,8 +102,8 @@ Default: `./rerun.sh`
106
102
 
107
103
  Example:
108
104
  ```js
109
- const RerunService = require('wdio-rerun-service');
110
- export.config = {
105
+ import RerunService from 'wdio-rerun-service';
106
+ export const config = {
111
107
  // ...
112
108
  services: [
113
109
  [RerunService, {
@@ -127,8 +123,8 @@ Default: `[]`
127
123
 
128
124
  Example:
129
125
  ```js
130
- const RerunService = require('wdio-rerun-service');
131
- export.config = {
126
+ import RerunService from 'wdio-rerun-service';
127
+ export const config = {
132
128
  // ...
133
129
  services: [
134
130
  [RerunService, {
@@ -148,8 +144,8 @@ Default: `''`
148
144
 
149
145
  Example:
150
146
  ```js
151
- const RerunService = require('wdio-rerun-service');
152
- export.config = {
147
+ import RerunService from 'wdio-rerun-service';
148
+ export const config = {
153
149
  // ...
154
150
  services: [
155
151
  [RerunService, {
@@ -170,8 +166,8 @@ Default: `''`
170
166
 
171
167
  Example:
172
168
  ```js
173
- const RerunService = require('wdio-rerun-service');
174
- export.config = {
169
+ import RerunService from 'wdio-rerun-service';
170
+ export const config = {
175
171
  // ...
176
172
  services: [
177
173
  [RerunService, {
@@ -0,0 +1,33 @@
1
+ import type { Capabilities, Frameworks, Services } from '@wdio/types';
2
+ type AfterScenario = NonNullable<WebdriverIO.HookFunctionExtension['afterScenario']>;
3
+ type AfterScenarioParameters = Parameters<AfterScenario>;
4
+ type World = AfterScenarioParameters[0];
5
+ interface NonPassingItem {
6
+ location: string;
7
+ failure?: string | undefined;
8
+ }
9
+ interface RerunServiceOptions {
10
+ ignoredTags?: string[];
11
+ rerunDataDir?: string;
12
+ rerunScriptPath?: string;
13
+ commandPrefix?: string;
14
+ customParameters?: string;
15
+ }
16
+ export default class RerunService implements Services.ServiceInstance {
17
+ nonPassingItems: NonPassingItem[];
18
+ serviceWorkerId: string;
19
+ ignoredTags: string[];
20
+ rerunDataDir: string;
21
+ rerunScriptPath: string;
22
+ commandPrefix: string;
23
+ customParameters: string;
24
+ specFile: string;
25
+ disabled: boolean;
26
+ constructor(options?: RerunServiceOptions);
27
+ before(_capabilities: Capabilities.RemoteCapability, specs: string[]): Promise<void>;
28
+ afterTest(_test: Frameworks.Test, _context: any, results: Frameworks.TestResult): void;
29
+ afterScenario(world: World): void;
30
+ after(): Promise<void>;
31
+ onComplete(): Promise<void>;
32
+ }
33
+ export {};
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const minimist_1 = __importDefault(require("minimist"));
7
+ const promises_1 = require("node:fs/promises");
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 {
12
+ constructor(options = {}) {
13
+ const { ignoredTags, rerunDataDir, rerunScriptPath, commandPrefix, customParameters, } = options;
14
+ this.nonPassingItems = [];
15
+ this.serviceWorkerId = '';
16
+ this.ignoredTags = ignoredTags ?? [];
17
+ this.rerunDataDir = rerunDataDir ?? './results/rerun';
18
+ this.rerunScriptPath =
19
+ rerunScriptPath ?? (node_process_1.platform === 'win32' ? 'rerun.bat' : 'rerun.sh');
20
+ this.commandPrefix = commandPrefix ?? '';
21
+ this.customParameters = customParameters ?? '';
22
+ this.specFile = '';
23
+ this.disabled = node_process_1.env['DISABLE_RERUN'] === 'true';
24
+ }
25
+ async before(_capabilities, specs) {
26
+ if (this.disabled) {
27
+ return;
28
+ }
29
+ this.specFile = specs[0] ?? '';
30
+ // console.log(`Re-run service is activated. Data directory: ${this.rerunDataDir}`);
31
+ await (0, promises_1.mkdir)(this.rerunDataDir, { recursive: true });
32
+ this.serviceWorkerId = (0, uuid_1.v5)(String(Date.now()), uuid_1.v5.DNS);
33
+ }
34
+ afterTest(_test, _context, results) {
35
+ if (this.disabled) {
36
+ return;
37
+ }
38
+ const { passed } = results;
39
+ const config = browser.config;
40
+ if (passed || config.framework === 'cucumber') {
41
+ return;
42
+ }
43
+ // console.log(`Re-run service is inspecting non-passing test.`);
44
+ // console.log(`Test location: ${this.specFile}`);
45
+ const error = results.error;
46
+ if (error?.message) {
47
+ this.nonPassingItems.push({
48
+ location: this.specFile,
49
+ failure: error.message,
50
+ });
51
+ }
52
+ else {
53
+ // console.log("The non-passing test did not contain any error message, it could not be added for re-run.")
54
+ }
55
+ }
56
+ // Executed after a Cucumber scenario ends.
57
+ afterScenario(world) {
58
+ if (this.disabled) {
59
+ return;
60
+ }
61
+ const config = browser.config;
62
+ const status = world.result?.status;
63
+ if (config.framework !== 'cucumber' ||
64
+ status === 'PASSED' ||
65
+ status === 'SKIPPED') {
66
+ return;
67
+ }
68
+ const scenarioLineNumber = world.gherkinDocument.feature?.children.filter((child) => child.scenario
69
+ ? world.pickle.astNodeIds.includes(child.scenario.id.toString())
70
+ : false)?.[0]?.scenario?.location.line ?? 0;
71
+ const scenarioLocation = `${world.pickle.uri}:${scenarioLineNumber}`;
72
+ const tagsList = world.pickle.tags.map((tag) => tag.name);
73
+ if (!Array.isArray(this.ignoredTags) ||
74
+ !tagsList.some((ignoredTag) => this.ignoredTags.includes(ignoredTag))) {
75
+ this.nonPassingItems.push({
76
+ location: scenarioLocation,
77
+ failure: world.result?.message,
78
+ });
79
+ }
80
+ }
81
+ async after() {
82
+ if (this.disabled) {
83
+ return;
84
+ }
85
+ if (this.nonPassingItems.length === 0) {
86
+ return; // console.log('Re-run service did not detect any non-passing scenarios or tests.');
87
+ }
88
+ await (0, promises_1.writeFile)((0, node_path_1.join)(this.rerunDataDir, `rerun-${this.serviceWorkerId}.json`), JSON.stringify(this.nonPassingItems));
89
+ }
90
+ async onComplete() {
91
+ if (this.disabled) {
92
+ return;
93
+ }
94
+ try {
95
+ const files = await (0, promises_1.readdir)(this.rerunDataDir);
96
+ const rerunFiles = files.filter((file) => file.endsWith('.json'));
97
+ if (rerunFiles.length === 0) {
98
+ return;
99
+ }
100
+ const parsedArgs = (0, minimist_1.default)(node_process_1.argv.slice(2));
101
+ const args = parsedArgs._[0] ? parsedArgs._[0] + ' ' : '';
102
+ const prefix = this.commandPrefix ? this.commandPrefix + ' ' : '';
103
+ const disableRerun = node_process_1.platform === 'win32'
104
+ ? 'set DISABLE_RERUN=true &&'
105
+ : 'DISABLE_RERUN=true';
106
+ let rerunCommand = `${prefix}${disableRerun} npx wdio ${args}${this.customParameters}`;
107
+ const failureLocations = new Set();
108
+ for (const file of rerunFiles) {
109
+ const json = JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(this.rerunDataDir, file), 'utf8'));
110
+ json.forEach((failure) => {
111
+ failureLocations.add(failure.location.replace(/\\/g, '/'));
112
+ });
113
+ }
114
+ failureLocations.forEach((failureLocation) => {
115
+ rerunCommand += ` --spec=${failureLocation}`;
116
+ });
117
+ await (0, promises_1.writeFile)(this.rerunScriptPath, rerunCommand, { mode: 0o755 });
118
+ // console.log(`Re-run script has been generated @ ${this.rerunScriptPath}`);
119
+ }
120
+ catch (err) {
121
+ // console.log(`Re-run service failed to generate re-run script: ${err}`);
122
+ }
123
+ }
124
+ }
125
+ exports.default = RerunService;
126
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,33 @@
1
+ import type { Capabilities, Frameworks, Services } from '@wdio/types';
2
+ type AfterScenario = NonNullable<WebdriverIO.HookFunctionExtension['afterScenario']>;
3
+ type AfterScenarioParameters = Parameters<AfterScenario>;
4
+ type World = AfterScenarioParameters[0];
5
+ interface NonPassingItem {
6
+ location: string;
7
+ failure?: string | undefined;
8
+ }
9
+ interface RerunServiceOptions {
10
+ ignoredTags?: string[];
11
+ rerunDataDir?: string;
12
+ rerunScriptPath?: string;
13
+ commandPrefix?: string;
14
+ customParameters?: string;
15
+ }
16
+ export default class RerunService implements Services.ServiceInstance {
17
+ nonPassingItems: NonPassingItem[];
18
+ serviceWorkerId: string;
19
+ ignoredTags: string[];
20
+ rerunDataDir: string;
21
+ rerunScriptPath: string;
22
+ commandPrefix: string;
23
+ customParameters: string;
24
+ specFile: string;
25
+ disabled: boolean;
26
+ constructor(options?: RerunServiceOptions);
27
+ before(_capabilities: Capabilities.RemoteCapability, specs: string[]): Promise<void>;
28
+ afterTest(_test: Frameworks.Test, _context: any, results: Frameworks.TestResult): void;
29
+ afterScenario(world: World): void;
30
+ after(): Promise<void>;
31
+ onComplete(): Promise<void>;
32
+ }
33
+ export {};
@@ -0,0 +1,129 @@
1
+ import minimist from 'minimist';
2
+ import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { argv, env, platform } from 'node:process';
5
+ import { v5 as uuidv5 } from 'uuid';
6
+ export default class RerunService {
7
+ nonPassingItems;
8
+ serviceWorkerId;
9
+ ignoredTags;
10
+ rerunDataDir;
11
+ rerunScriptPath;
12
+ commandPrefix;
13
+ customParameters;
14
+ specFile;
15
+ disabled;
16
+ constructor(options = {}) {
17
+ const { ignoredTags, rerunDataDir, rerunScriptPath, commandPrefix, customParameters, } = options;
18
+ this.nonPassingItems = [];
19
+ this.serviceWorkerId = '';
20
+ this.ignoredTags = ignoredTags ?? [];
21
+ this.rerunDataDir = rerunDataDir ?? './results/rerun';
22
+ this.rerunScriptPath =
23
+ rerunScriptPath ?? (platform === 'win32' ? 'rerun.bat' : 'rerun.sh');
24
+ this.commandPrefix = commandPrefix ?? '';
25
+ this.customParameters = customParameters ?? '';
26
+ this.specFile = '';
27
+ this.disabled = env['DISABLE_RERUN'] === 'true';
28
+ }
29
+ async before(_capabilities, specs) {
30
+ if (this.disabled) {
31
+ return;
32
+ }
33
+ this.specFile = specs[0] ?? '';
34
+ // console.log(`Re-run service is activated. Data directory: ${this.rerunDataDir}`);
35
+ await mkdir(this.rerunDataDir, { recursive: true });
36
+ this.serviceWorkerId = uuidv5(String(Date.now()), uuidv5.DNS);
37
+ }
38
+ afterTest(_test, _context, results) {
39
+ if (this.disabled) {
40
+ return;
41
+ }
42
+ const { passed } = results;
43
+ const config = browser.config;
44
+ if (passed || config.framework === 'cucumber') {
45
+ return;
46
+ }
47
+ // console.log(`Re-run service is inspecting non-passing test.`);
48
+ // console.log(`Test location: ${this.specFile}`);
49
+ const error = results.error;
50
+ if (error?.message) {
51
+ this.nonPassingItems.push({
52
+ location: this.specFile,
53
+ failure: error.message,
54
+ });
55
+ }
56
+ else {
57
+ // console.log("The non-passing test did not contain any error message, it could not be added for re-run.")
58
+ }
59
+ }
60
+ // Executed after a Cucumber scenario ends.
61
+ afterScenario(world) {
62
+ if (this.disabled) {
63
+ return;
64
+ }
65
+ const config = browser.config;
66
+ const status = world.result?.status;
67
+ if (config.framework !== 'cucumber' ||
68
+ status === 'PASSED' ||
69
+ status === 'SKIPPED') {
70
+ return;
71
+ }
72
+ const scenarioLineNumber = world.gherkinDocument.feature?.children.filter((child) => child.scenario
73
+ ? world.pickle.astNodeIds.includes(child.scenario.id.toString())
74
+ : false)?.[0]?.scenario?.location.line ?? 0;
75
+ const scenarioLocation = `${world.pickle.uri}:${scenarioLineNumber}`;
76
+ const tagsList = world.pickle.tags.map((tag) => tag.name);
77
+ if (!Array.isArray(this.ignoredTags) ||
78
+ !tagsList.some((ignoredTag) => this.ignoredTags.includes(ignoredTag))) {
79
+ this.nonPassingItems.push({
80
+ location: scenarioLocation,
81
+ failure: world.result?.message,
82
+ });
83
+ }
84
+ }
85
+ async after() {
86
+ if (this.disabled) {
87
+ return;
88
+ }
89
+ if (this.nonPassingItems.length === 0) {
90
+ return; // console.log('Re-run service did not detect any non-passing scenarios or tests.');
91
+ }
92
+ await writeFile(join(this.rerunDataDir, `rerun-${this.serviceWorkerId}.json`), JSON.stringify(this.nonPassingItems));
93
+ }
94
+ async onComplete() {
95
+ if (this.disabled) {
96
+ return;
97
+ }
98
+ try {
99
+ const files = await readdir(this.rerunDataDir);
100
+ const rerunFiles = files.filter((file) => file.endsWith('.json'));
101
+ if (rerunFiles.length === 0) {
102
+ return;
103
+ }
104
+ const parsedArgs = minimist(argv.slice(2));
105
+ const args = parsedArgs._[0] ? parsedArgs._[0] + ' ' : '';
106
+ const prefix = this.commandPrefix ? this.commandPrefix + ' ' : '';
107
+ const disableRerun = platform === 'win32'
108
+ ? 'set DISABLE_RERUN=true &&'
109
+ : 'DISABLE_RERUN=true';
110
+ let rerunCommand = `${prefix}${disableRerun} npx wdio ${args}${this.customParameters}`;
111
+ const failureLocations = new Set();
112
+ for (const file of rerunFiles) {
113
+ const json = JSON.parse(await readFile(join(this.rerunDataDir, file), 'utf8'));
114
+ json.forEach((failure) => {
115
+ failureLocations.add(failure.location.replace(/\\/g, '/'));
116
+ });
117
+ }
118
+ failureLocations.forEach((failureLocation) => {
119
+ rerunCommand += ` --spec=${failureLocation}`;
120
+ });
121
+ await writeFile(this.rerunScriptPath, rerunCommand, { mode: 0o755 });
122
+ // console.log(`Re-run script has been generated @ ${this.rerunScriptPath}`);
123
+ }
124
+ catch (err) {
125
+ // console.log(`Re-run service failed to generate re-run script: ${err}`);
126
+ }
127
+ }
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,26 +1,49 @@
1
1
  {
2
2
  "name": "wdio-rerun-service",
3
- "version": "1.7.6",
3
+ "version": "2.0.0",
4
4
  "description": "A WebdriverIO service to track and prepare for re-running failing or flaky Jasmine/Mocha tests or Cucumber Scenarios.",
5
5
  "author": "Mike Salvia <msalvia@jwplayer.com>",
6
6
  "homepage": "https://github.com/webdriverio-community/wdio-rerun-service",
7
7
  "license": "MIT",
8
- "main": "./build/index",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "type": "module",
12
+ "main": "./build/cjs/index.js",
13
+ "types": "./build/cjs/index.d.ts",
14
+ "module": "./build/esm/index.js",
15
+ "exports": {
16
+ ".": {
17
+ "import": {
18
+ "types": "./build/esm/index.d.ts",
19
+ "default": "./build/esm/index.js"
20
+ },
21
+ "require": {
22
+ "types": "./build/cjs/index.d.ts",
23
+ "default": "./build/cjs/index.js"
24
+ }
25
+ }
26
+ },
9
27
  "engines": {
10
- "node": ">=12.0.0"
28
+ "node": ">=16.0.0"
11
29
  },
12
30
  "scripts": {
13
31
  "build": "run-s clean compile",
14
32
  "clean": "rimraf ./build",
15
- "compile": "babel src/ -d build/ --config-file ./babel.config.js",
16
- "watch": "npm-watch",
33
+ "compile": "run-s compile:esm compile:cjs generate:cjs:package",
34
+ "compile:cjs": "tsc -p tsconfig.cjs.json",
35
+ "compile:esm": "tsc -p tsconfig.esm.json",
36
+ "generate:cjs:package": "shx echo \"{\\\"type\\\":\\\"commonjs\\\"}\" > ./build/cjs/package.json",
37
+ "prepare": "npm run build",
17
38
  "test": "run-s test:*",
18
- "test:clean": "rimraf ./results ./coverage rerun.sh",
39
+ "test:clean": "rimraf ./results ./coverage rerun.sh rerun.bat",
19
40
  "test:eslint": "eslint src tests",
20
- "test:unit": "jest --collectCoverageFrom='[\"src/**/*.{js,jsx,ts,tsx}\"]' --coverage --collectCoverage=true --forceExit --detectOpenHandles tests/.*test.*"
41
+ "test:tsc": "tsc -p tsconfig.json --noEmit",
42
+ "test:unit": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage",
43
+ "watch": "npm-watch"
21
44
  },
22
45
  "watch": {
23
- "build": "{src,tests}/*.js"
46
+ "build": "{src,tests}/*.ts"
24
47
  },
25
48
  "repository": {
26
49
  "type": "git",
@@ -50,36 +73,45 @@
50
73
  "url": "https://github.com/webdriverio-community/wdio-rerun-service/issues"
51
74
  },
52
75
  "dependencies": {
53
- "@wdio/logger": "7.19.0",
54
- "minimist": "1.2.6",
55
- "npm-watch": "0.11.0",
56
- "uuid": "8.3.2"
57
- },
58
- "peerDependencies": {},
59
- "publishConfig": {
60
- "access": "public"
76
+ "@wdio/types": "^8.0.11",
77
+ "minimist": "^1.2.7",
78
+ "uuid": "^9.0.0"
61
79
  },
62
80
  "devDependencies": {
63
- "@babel/cli": "7.17.6",
64
- "@babel/core": "7.17.9",
65
- "@babel/node": "7.16.8",
66
- "@babel/plugin-proposal-class-properties": "7.16.7",
67
- "@babel/plugin-proposal-function-bind": "7.16.7",
68
- "@babel/plugin-proposal-optional-catch-binding": "7.16.7",
69
- "@babel/plugin-syntax-export-default-from": "7.16.7",
70
- "@babel/preset-env": "7.16.11",
71
- "@babel/register": "7.17.7",
72
- "@typescript-eslint/eslint-plugin": "5.20.0",
73
- "@typescript-eslint/parser": "5.20.0",
74
- "babel-cli": "6.26.0",
75
- "babel-core": "6.26.3",
76
- "babel-eslint": "10.1.0",
77
- "babel-jest": "27.5.1",
78
- "babel-plugin-source-map-support": "2.1.3",
79
- "eslint": "8.13.0",
80
- "jest": "27.5.1",
81
+ "@jest/globals": "^29.3.1",
82
+ "@tsconfig/node16": "^1.0.3",
83
+ "@tsconfig/node18-strictest-esm": "^1.0.1",
84
+ "@types/minimist": "^1.2.2",
85
+ "@types/node": "^18.11.16",
86
+ "@types/uuid": "^9.0.0",
87
+ "@typescript-eslint/eslint-plugin": "^5.46.1",
88
+ "@typescript-eslint/parser": "^5.46.1",
89
+ "@wdio/cucumber-framework": "^8.0.13",
90
+ "@wdio/globals": "^8.0.13",
91
+ "cross-env": "^7.0.3",
92
+ "eslint": "^8.30.0",
93
+ "eslint-config-prettier": "^8.5.0",
94
+ "eslint-plugin-prettier": "^4.2.1",
95
+ "jest": "^29.3.1",
81
96
  "npm-run-all": "4.1.5",
82
- "rimraf": "3.0.2",
83
- "typescript": "4.6.3"
97
+ "npm-watch": "0.11.0",
98
+ "prettier": "^2.8.1",
99
+ "prettier-plugin-organize-imports": "^3.2.1",
100
+ "release-it": "^15.5.1",
101
+ "rimraf": "^3.0.2",
102
+ "shx": "^0.3.4",
103
+ "ts-jest": "^29.0.3",
104
+ "ts-node": "^10.9.1",
105
+ "typescript": "^4.9.4"
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
+ ]
84
116
  }
85
117
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "@tsconfig/node16/tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "build/cjs",
5
+ "declaration": true,
6
+ "sourceMap": true,
7
+ "types": ["node", "@wdio/globals/types", "@wdio/cucumber-framework"]
8
+ },
9
+ "files": ["src/index.ts"]
10
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "build/esm",
5
+ "noEmit": false,
6
+ "declaration": true,
7
+ "sourceMap": true
8
+ },
9
+ "include": [],
10
+ "files": ["src/index.ts"]
11
+ }
package/.eslintrc.js DELETED
@@ -1,16 +0,0 @@
1
- module.exports = {
2
- "env": {
3
- "browser": true,
4
- "es2021": true
5
- },
6
- "parser": "@typescript-eslint/parser",
7
- "parserOptions": {
8
- "ecmaVersion": 12,
9
- "sourceType": "module"
10
- },
11
- "plugins": [
12
- "@typescript-eslint"
13
- ],
14
- "rules": {
15
- }
16
- };
package/babel.config.js DELETED
@@ -1,21 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- [
4
- '@babel/preset-env',
5
- {targets: {node: 'current'}},
6
- "@babel/preset-typescript"
7
- ]
8
- ],
9
- plugins: [
10
- '@babel/plugin-proposal-function-bind',
11
- '@babel/plugin-proposal-class-properties',
12
- '@babel/plugin-proposal-optional-catch-binding'
13
- ],
14
- env: {
15
- development: {
16
- sourceMaps: 'inline',
17
- plugins: ['source-map-support']
18
- }
19
- },
20
- comments: false
21
- }
package/build/index.js DELETED
@@ -1,115 +0,0 @@
1
- "use strict";
2
-
3
- require("source-map-support/register");
4
-
5
- const fs = require('fs');
6
-
7
- const path = require('path');
8
-
9
- const {
10
- v5: uuidv5
11
- } = require('uuid');
12
-
13
- const argv = require('minimist')(process.argv.slice(2));
14
-
15
- class RerunService {
16
- constructor({
17
- ignoredTags,
18
- rerunDataDir,
19
- rerunScriptPath,
20
- commandPrefix,
21
- customParameters
22
- } = {}) {
23
- this.nonPassingItems = [];
24
- this.serviceWorkerId;
25
- this.ignoredTags = ignoredTags || [];
26
- this.rerunDataDir = rerunDataDir || "./results/rerun";
27
- this.rerunScriptPath = rerunScriptPath || "./rerun.sh";
28
- this.commandPrefix = commandPrefix || "";
29
- this.customParameters = customParameters || "";
30
- this.specFile = "";
31
- }
32
-
33
- before(capabilities, specs) {
34
- this.specFile = specs[0];
35
- fs.mkdirSync(this.rerunDataDir, {
36
- recursive: true
37
- });
38
- this.serviceWorkerId = uuidv5(`${Date.now()}`, '6ba7b810-9dad-11d1-80b4-00c04fd430c8');
39
- }
40
-
41
- afterTest(test, context, {
42
- error,
43
- result,
44
- duration,
45
- passed,
46
- retries
47
- }) {
48
- if (browser.config.framework !== 'cucumber' && !passed) {
49
- if (error && error.message) {
50
- this.nonPassingItems.push({
51
- location: this.specFile,
52
- failure: error.message
53
- });
54
- } else {}
55
- }
56
- }
57
-
58
- afterScenario(world, result, context) {
59
- const CUCUMBER_STATUS_MAP = ['UNKNOWN', 'PASSED', 'SKIPPED', 'PENDING', 'UNDEFINED', 'AMBIGUOUS', 'FAILED'];
60
- const status = typeof world.result.status === 'number' ? CUCUMBER_STATUS_MAP[world.result.status || 0] : world.result.status;
61
- const scenarioLineNumber = world.gherkinDocument.feature.children.filter(child => {
62
- if (child.scenario) {
63
- return child.scenario && world.pickle.astNodeIds.includes(child.scenario.id.toString());
64
- }
65
- })[0].scenario.location.line;
66
-
67
- if (browser.config.framework === 'cucumber' && status !== 'PASSED' && status !== 'SKIPPED') {
68
- const scenarioLocation = `${world.pickle.uri}:${scenarioLineNumber}`;
69
- const tagsList = world.pickle.tags.map(tag => tag.name);
70
- const service = this;
71
-
72
- if (this.ignoredTags && !tagsList.some(ignoredTag => service.ignoredTags.includes(ignoredTag))) {
73
- this.nonPassingItems.push({
74
- location: scenarioLocation,
75
- failure: world.result.message
76
- });
77
- }
78
- }
79
- }
80
-
81
- after(result, capabilities, specs) {
82
- if (this.nonPassingItems.length > 0) {
83
- fs.writeFileSync(`${this.rerunDataDir}/rerun-${this.serviceWorkerId}.json`, JSON.stringify(this.nonPassingItems));
84
- } else {}
85
- }
86
-
87
- onComplete(exitCode, config, capabilities, results) {
88
- const directoryPath = path.join(process.cwd(), `${this.rerunDataDir}`);
89
-
90
- if (fs.existsSync(directoryPath)) {
91
- const rerunFiles = fs.readdirSync(directoryPath);
92
-
93
- if (rerunFiles.length > 0) {
94
- let rerunCommand = `${this.commandPrefix} DISABLE_RERUN=true node_modules/.bin/wdio ${argv._[0]} ${this.customParameters} `;
95
- let failureLocations = [];
96
- rerunFiles.forEach(file => {
97
- const json = JSON.parse(fs.readFileSync(`${this.rerunDataDir}/${file}`));
98
- json.forEach(failure => {
99
- failureLocations.push(failure.location.replace(/\\/g, "/"));
100
- });
101
- });
102
- const failureLocationsUnique = [...new Set(failureLocations)];
103
- failureLocationsUnique.forEach(failureLocation => {
104
- rerunCommand += ` --spec=${failureLocation}`;
105
- });
106
- fs.writeFileSync(this.rerunScriptPath, rerunCommand);
107
- }
108
- }
109
- }
110
-
111
- }
112
-
113
- ;
114
- module.exports = RerunService;
115
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJmcyIsInJlcXVpcmUiLCJwYXRoIiwidjUiLCJ1dWlkdjUiLCJhcmd2IiwicHJvY2VzcyIsInNsaWNlIiwiUmVydW5TZXJ2aWNlIiwiY29uc3RydWN0b3IiLCJpZ25vcmVkVGFncyIsInJlcnVuRGF0YURpciIsInJlcnVuU2NyaXB0UGF0aCIsImNvbW1hbmRQcmVmaXgiLCJjdXN0b21QYXJhbWV0ZXJzIiwibm9uUGFzc2luZ0l0ZW1zIiwic2VydmljZVdvcmtlcklkIiwic3BlY0ZpbGUiLCJiZWZvcmUiLCJjYXBhYmlsaXRpZXMiLCJzcGVjcyIsIm1rZGlyU3luYyIsInJlY3Vyc2l2ZSIsIkRhdGUiLCJub3ciLCJhZnRlclRlc3QiLCJ0ZXN0IiwiY29udGV4dCIsImVycm9yIiwicmVzdWx0IiwiZHVyYXRpb24iLCJwYXNzZWQiLCJyZXRyaWVzIiwiYnJvd3NlciIsImNvbmZpZyIsImZyYW1ld29yayIsIm1lc3NhZ2UiLCJwdXNoIiwibG9jYXRpb24iLCJmYWlsdXJlIiwiYWZ0ZXJTY2VuYXJpbyIsIndvcmxkIiwiQ1VDVU1CRVJfU1RBVFVTX01BUCIsInN0YXR1cyIsInNjZW5hcmlvTGluZU51bWJlciIsImdoZXJraW5Eb2N1bWVudCIsImZlYXR1cmUiLCJjaGlsZHJlbiIsImZpbHRlciIsImNoaWxkIiwic2NlbmFyaW8iLCJwaWNrbGUiLCJhc3ROb2RlSWRzIiwiaW5jbHVkZXMiLCJpZCIsInRvU3RyaW5nIiwibGluZSIsInNjZW5hcmlvTG9jYXRpb24iLCJ1cmkiLCJ0YWdzTGlzdCIsInRhZ3MiLCJtYXAiLCJ0YWciLCJuYW1lIiwic2VydmljZSIsInNvbWUiLCJpZ25vcmVkVGFnIiwiYWZ0ZXIiLCJsZW5ndGgiLCJ3cml0ZUZpbGVTeW5jIiwiSlNPTiIsInN0cmluZ2lmeSIsIm9uQ29tcGxldGUiLCJleGl0Q29kZSIsInJlc3VsdHMiLCJkaXJlY3RvcnlQYXRoIiwiam9pbiIsImN3ZCIsImV4aXN0c1N5bmMiLCJyZXJ1bkZpbGVzIiwicmVhZGRpclN5bmMiLCJyZXJ1bkNvbW1hbmQiLCJfIiwiZmFpbHVyZUxvY2F0aW9ucyIsImZvckVhY2giLCJmaWxlIiwianNvbiIsInBhcnNlIiwicmVhZEZpbGVTeW5jIiwicmVwbGFjZSIsImZhaWx1cmVMb2NhdGlvbnNVbmlxdWUiLCJTZXQiLCJmYWlsdXJlTG9jYXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUEsTUFBTUEsRUFBRSxHQUFHQyxPQUFPLENBQUMsSUFBRCxDQUFsQjs7QUFDQSxNQUFNQyxJQUFJLEdBQUdELE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLE1BQU07QUFBRUUsRUFBQUEsRUFBRSxFQUFFQztBQUFOLElBQWlCSCxPQUFPLENBQUMsTUFBRCxDQUE5Qjs7QUFFQSxNQUFNSSxJQUFJLEdBQUdKLE9BQU8sQ0FBQyxVQUFELENBQVAsQ0FBb0JLLE9BQU8sQ0FBQ0QsSUFBUixDQUFhRSxLQUFiLENBQW1CLENBQW5CLENBQXBCLENBQWI7O0FBRUEsTUFBTUMsWUFBTixDQUFtQjtBQUVmQyxFQUFBQSxXQUFXLENBQUM7QUFBRUMsSUFBQUEsV0FBRjtBQUFlQyxJQUFBQSxZQUFmO0FBQTZCQyxJQUFBQSxlQUE3QjtBQUE4Q0MsSUFBQUEsYUFBOUM7QUFBNkRDLElBQUFBO0FBQTdELE1BQWtGLEVBQW5GLEVBQXVGO0FBQzlGLFNBQUtDLGVBQUwsR0FBdUIsRUFBdkI7QUFDQSxTQUFLQyxlQUFMO0FBQ0EsU0FBS04sV0FBTCxHQUFtQkEsV0FBVyxJQUFJLEVBQWxDO0FBQ0EsU0FBS0MsWUFBTCxHQUFvQkEsWUFBWSxJQUFJLGlCQUFwQztBQUNBLFNBQUtDLGVBQUwsR0FBdUJBLGVBQWUsSUFBSSxZQUExQztBQUNBLFNBQUtDLGFBQUwsR0FBcUJBLGFBQWEsSUFBSSxFQUF0QztBQUNBLFNBQUtDLGdCQUFMLEdBQXdCQSxnQkFBZ0IsSUFBSSxFQUE1QztBQUNBLFNBQUtHLFFBQUwsR0FBZ0IsRUFBaEI7QUFDSDs7QUFF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QyxJQUFJLElBQUk7QUFDdkIsZ0JBQU1DLElBQUksR0FBR2hCLElBQUksQ0FBQ2lCLEtBQUwsQ0FBV3ZGLEVBQUUsQ0FBQ3dGLFlBQUgsQ0FBaUIsR0FBRSxLQUFLN0UsWUFBYSxJQUFHMEUsSUFBSyxFQUE3QyxDQUFYLENBQWI7QUFDQUMsVUFBQUEsSUFBSSxDQUFDRixPQUFMLENBQWE3QyxPQUFPLElBQUk7QUFDcEI0QyxZQUFBQSxnQkFBZ0IsQ0FBQzlDLElBQWpCLENBQXNCRSxPQUFPLENBQUNELFFBQVIsQ0FBaUJtRCxPQUFqQixDQUF5QixLQUF6QixFQUFnQyxHQUFoQyxDQUF0QjtBQUNILFdBRkQ7QUFHSCxTQUxEO0FBTUEsY0FBTUMsc0JBQXNCLEdBQUcsQ0FBQyxHQUFHLElBQUlDLEdBQUosQ0FBUVIsZ0JBQVIsQ0FBSixDQUEvQjtBQUNBTyxRQUFBQSxzQkFBc0IsQ0FBQ04sT0FBdkIsQ0FBK0JRLGVBQWUsSUFBSTtBQUM5Q1gsVUFBQUEsWUFBWSxJQUFLLFdBQVVXLGVBQWdCLEVBQTNDO0FBQ0gsU0FGRDtBQUdBNUYsUUFBQUEsRUFBRSxDQUFDcUUsYUFBSCxDQUFpQixLQUFLekQsZUFBdEIsRUFBdUNxRSxZQUF2QztBQUVIO0FBQ0o7QUFDSjs7QUFwRmM7O0FBcUZsQjtBQUVEWSxNQUFNLENBQUNDLE9BQVAsR0FBaUJ0RixZQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCB7IHY1OiB1dWlkdjUgfSA9IHJlcXVpcmUoJ3V1aWQnKTtcblxuY29uc3QgYXJndiA9IHJlcXVpcmUoJ21pbmltaXN0JykocHJvY2Vzcy5hcmd2LnNsaWNlKDIpKTtcblxuY2xhc3MgUmVydW5TZXJ2aWNlIHtcblxuICAgIGNvbnN0cnVjdG9yKHsgaWdub3JlZFRhZ3MsIHJlcnVuRGF0YURpciwgcmVydW5TY3JpcHRQYXRoLCBjb21tYW5kUHJlZml4LCBjdXN0b21QYXJhbWV0ZXJzIH0gPSB7fSkge1xuICAgICAgICB0aGlzLm5vblBhc3NpbmdJdGVtcyA9IFtdO1xuICAgICAgICB0aGlzLnNlcnZpY2VXb3JrZXJJZDtcbiAgICAgICAgdGhpcy5pZ25vcmVkVGFncyA9IGlnbm9yZWRUYWdzIHx8IFtdO1xuICAgICAgICB0aGlzLnJlcnVuRGF0YURpciA9IHJlcnVuRGF0YURpciB8fCBcIi4vcmVzdWx0cy9yZXJ1blwiO1xuICAgICAgICB0aGlzLnJlcnVuU2NyaXB0UGF0aCA9IHJlcnVuU2NyaXB0UGF0aCB8fCBcIi4vcmVydW4uc2hcIjtcbiAgICAgICAgdGhpcy5jb21tYW5kUHJlZml4ID0gY29tbWFuZFByZWZpeCB8fCBcIlwiO1xuICAgICAgICB0aGlzLmN1c3RvbVBhcmFtZXRlcnMgPSBjdXN0b21QYXJhbWV0ZXJzIHx8IFwiXCI7XG4gICAgICAgIHRoaXMuc3BlY0ZpbGUgPSBcIlwiO1xuICAgIH1cblxuICAgIGJlZm9yZShjYXBhYmlsaXRpZXMsIHNwZWNzKSB7XG4gICAgICAgIHRoaXMuc3BlY0ZpbGUgPSBzcGVjc1swXTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coYFJlLXJ1biBzZXJ2aWNlIGlzIGFjdGl2YXRlZC4gRGF0YSBkaXJlY3Rvcnk6ICR7dGhpcy5yZXJ1bkRhdGFEaXJ9YCk7XG4gICAgICAgIGZzLm1rZGlyU3luYyh0aGlzLnJlcnVuRGF0YURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIC8vIElORk86IGBuYW1lc3BhY2VgIGJlbG93IGNvcGllZCBmcm9tOiBodHRwczovL2dpdGh1Yi5jb20va2VsZWt0aXYvbm9kZS11dWlkL2Jsb2IvbWFzdGVyLy9saWIvdjM1LmpzI0w1NDoxNlxuICAgICAgICB0aGlzLnNlcnZpY2VXb3JrZXJJZCA9IHV1aWR2NShgJHtEYXRlLm5vdygpfWAsICc2YmE3YjgxMC05ZGFkLTExZDEtODBiNC0wMGMwNGZkNDMwYzgnKTtcbiAgICB9XG5cbiAgICBhZnRlclRlc3QodGVzdCwgY29udGV4dCwgeyBlcnJvciwgcmVzdWx0LCBkdXJhdGlvbiwgcGFzc2VkLCByZXRyaWVzIH0pIHtcbiAgICAgICAgaWYgKGJyb3dzZXIuY29uZmlnLmZyYW1ld29yayAhPT0gJ2N1Y3VtYmVyJyAmJiAhcGFzc2VkKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgUmUtcnVuIHNlcnZpY2UgaXMgaW5zcGVjdGluZyBub24tcGFzc2luZyB0ZXN0LmApO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFRlc3QgbG9jYXRpb246ICR7dGhpcy5zcGVjRmlsZX1gKTtcbiAgICAgICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub25QYXNzaW5nSXRlbXMucHVzaCh7IGxvY2F0aW9uOiB0aGlzLnNwZWNGaWxlLCBmYWlsdXJlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlRoZSBub24tcGFzc2luZyB0ZXN0IGRpZCBub3QgY29udGFpbiBhbnkgZXJyb3IgbWVzc2FnZSwgaXQgY291bGQgbm90IGJlIGFkZGVkIGZvciByZS1ydW4uXCIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlZCBhZnRlciBhIEN1Y3VtYmVyIHNjZW5hcmlvIGVuZHMuXG4gICAgYWZ0ZXJTY2VuYXJpbyh3b3JsZCwgcmVzdWx0LCBjb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IENVQ1VNQkVSX1NUQVRVU19NQVAgPSBbJ1VOS05PV04nLCAnUEFTU0VEJywgJ1NLSVBQRUQnLCAnUEVORElORycsICdVTkRFRklORUQnLCAnQU1CSUdVT1VTJywgJ0ZBSUxFRCddXG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHR5cGVvZiB3b3JsZC5yZXN1bHQuc3RhdHVzID09PSAnbnVtYmVyJyA/IENVQ1VNQkVSX1NUQVRVU19NQVBbd29ybGQucmVzdWx0LnN0YXR1cyB8fCAwXSA6IHdvcmxkLnJlc3VsdC5zdGF0dXM7XG4gICAgICAgIGNvbnN0IHNjZW5hcmlvTGluZU51bWJlciA9IHdvcmxkLmdoZXJraW5Eb2N1bWVudC5mZWF0dXJlLmNoaWxkcmVuLmZpbHRlcihjaGlsZCA9PiB7XG4gICAgICAgICAgICBpZiAoY2hpbGQuc2NlbmFyaW8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuc2NlbmFyaW8gJiYgd29ybGQucGlja2xlLmFzdE5vZGVJZHMuaW5jbHVkZXMoY2hpbGQuc2NlbmFyaW8uaWQudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pWzBdLnNjZW5hcmlvLmxvY2F0aW9uLmxpbmU7XG4gICAgICAgIGlmIChicm93c2VyLmNvbmZpZy5mcmFtZXdvcmsgPT09ICdjdWN1bWJlcicgJiYgKHN0YXR1cyAhPT0gJ1BBU1NFRCcgJiYgc3RhdHVzICE9PSAnU0tJUFBFRCcpKSB7XG4gICAgICAgICAgICBjb25zdCBzY2VuYXJpb0xvY2F0aW9uID0gYCR7d29ybGQucGlja2xlLnVyaX06JHtzY2VuYXJpb0xpbmVOdW1iZXJ9YDtcbiAgICAgICAgICAgIGNvbnN0IHRhZ3NMaXN0ID0gd29ybGQucGlja2xlLnRhZ3MubWFwKHRhZyA9PiB0YWcubmFtZSk7XG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlID0gdGhpcztcbiAgICAgICAgICAgIGlmICh0aGlzLmlnbm9yZWRUYWdzICYmICF0YWdzTGlzdC5zb21lKGlnbm9yZWRUYWcgPT4gc2VydmljZS5pZ25vcmVkVGFncy5pbmNsdWRlcyhpZ25vcmVkVGFnKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vblBhc3NpbmdJdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb246IHNjZW5hcmlvTG9jYXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGZhaWx1cmU6IHdvcmxkLnJlc3VsdC5tZXNzYWdlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZnRlcihyZXN1bHQsIGNhcGFiaWxpdGllcywgc3BlY3MpIHtcbiAgICAgICAgaWYgKHRoaXMubm9uUGFzc2luZ0l0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoYCR7dGhpcy5yZXJ1bkRhdGFEaXJ9L3JlcnVuLSR7dGhpcy5zZXJ2aWNlV29ya2VySWR9Lmpzb25gLCBKU09OLnN0cmluZ2lmeSh0aGlzLm5vblBhc3NpbmdJdGVtcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ1JlLXJ1biBzZXJ2aWNlIGRpZCBub3QgZGV0ZWN0IGFueSBub24tcGFzc2luZyBzY2VuYXJpb3Mgb3IgdGVzdHMuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkNvbXBsZXRlKGV4aXRDb2RlLCBjb25maWcsIGNhcGFiaWxpdGllcywgcmVzdWx0cykge1xuICAgICAgICBjb25zdCBkaXJlY3RvcnlQYXRoID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIGAke3RoaXMucmVydW5EYXRhRGlyfWApO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhkaXJlY3RvcnlQYXRoKSkge1xuICAgICAgICAgICAgY29uc3QgcmVydW5GaWxlcyA9IGZzLnJlYWRkaXJTeW5jKGRpcmVjdG9yeVBhdGgpO1xuICAgICAgICAgICAgaWYgKHJlcnVuRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCByZXJ1bkNvbW1hbmQgPSBgJHt0aGlzLmNvbW1hbmRQcmVmaXh9IERJU0FCTEVfUkVSVU49dHJ1ZSBub2RlX21vZHVsZXMvLmJpbi93ZGlvICR7YXJndi5fWzBdfSAke3RoaXMuY3VzdG9tUGFyYW1ldGVyc30gYDtcbiAgICAgICAgICAgICAgICBsZXQgZmFpbHVyZUxvY2F0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgIHJlcnVuRmlsZXMuZm9yRWFjaChmaWxlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QganNvbiA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGAke3RoaXMucmVydW5EYXRhRGlyfS8ke2ZpbGV9YCkpO1xuICAgICAgICAgICAgICAgICAgICBqc29uLmZvckVhY2goZmFpbHVyZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsdXJlTG9jYXRpb25zLnB1c2goZmFpbHVyZS5sb2NhdGlvbi5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZhaWx1cmVMb2NhdGlvbnNVbmlxdWUgPSBbLi4ubmV3IFNldChmYWlsdXJlTG9jYXRpb25zKV07XG4gICAgICAgICAgICAgICAgZmFpbHVyZUxvY2F0aW9uc1VuaXF1ZS5mb3JFYWNoKGZhaWx1cmVMb2NhdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlcnVuQ29tbWFuZCArPSBgIC0tc3BlYz0ke2ZhaWx1cmVMb2NhdGlvbn1gO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmModGhpcy5yZXJ1blNjcmlwdFBhdGgsIHJlcnVuQ29tbWFuZCk7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFJlLXJ1biBzY3JpcHQgaGFzIGJlZW4gZ2VuZXJhdGVkIEAgJHt0aGlzLnJlcnVuU2NyaXB0UGF0aH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVydW5TZXJ2aWNlO1xuIl19
package/rerun.sh DELETED
@@ -1 +0,0 @@
1
- CUSTOM_VAR=true DISABLE_RERUN=true node_modules/.bin/wdio undefined --spec=feature/sample.feature:1 --spec=feature/sample.feature:4