wdio-rerun-service 1.7.3 → 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 +20 -0
- package/.eslintignore +3 -0
- package/.github/workflows/release.yml +68 -0
- package/.github/workflows/{node.js.yml → test.yml} +23 -18
- package/.github/workflows/update.yml +30 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.md +18 -11
- package/README.md +40 -22
- package/build/cjs/index.d.ts +33 -0
- package/build/cjs/index.js +126 -0
- package/build/cjs/index.js.map +1 -0
- package/build/cjs/package.json +1 -0
- package/build/esm/index.d.ts +33 -0
- package/build/esm/index.js +129 -0
- package/build/esm/index.js.map +1 -0
- package/package.json +68 -36
- package/tsconfig.cjs.json +10 -0
- package/tsconfig.esm.json +11 -0
- package/.eslintrc.js +0 -16
- package/babel.config.js +0 -21
- package/build/index.js +0 -117
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,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:
|
|
4
|
+
name: Test
|
|
5
5
|
|
|
6
6
|
on:
|
|
7
7
|
push:
|
|
8
|
-
branches: [
|
|
8
|
+
branches: [main]
|
|
9
9
|
pull_request:
|
|
10
|
-
branches: [
|
|
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: [
|
|
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@
|
|
22
|
+
- uses: actions/checkout@v3
|
|
21
23
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
22
|
-
uses: actions/setup-node@
|
|
24
|
+
uses: actions/setup-node@v3
|
|
23
25
|
with:
|
|
24
26
|
node-version: ${{ matrix.node-version }}
|
|
25
|
-
- run: npm
|
|
26
|
-
- run: npm
|
|
27
|
+
- run: npm i -g npm@latest
|
|
28
|
+
- run: npm ci --ignore-scripts
|
|
27
29
|
- run: npm run build --if-present
|
|
28
|
-
- run: npm
|
|
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: [
|
|
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@
|
|
40
|
+
- uses: actions/checkout@v3
|
|
38
41
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
39
|
-
uses: actions/setup-node@
|
|
42
|
+
uses: actions/setup-node@v3
|
|
40
43
|
with:
|
|
41
44
|
node-version: ${{ matrix.node-version }}
|
|
42
|
-
- run: npm
|
|
43
|
-
- run: npm
|
|
45
|
+
- run: npm i -g npm@latest
|
|
46
|
+
- run: npm ci --ignore-scripts
|
|
44
47
|
- run: npm run build --if-present
|
|
45
|
-
- run: npm
|
|
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/CHANGELOG.md
CHANGED
|
@@ -12,13 +12,20 @@
|
|
|
12
12
|
_Note: Gaps between patch versions are faulty, broken or test releases._
|
|
13
13
|
|
|
14
14
|
---
|
|
15
|
+
## v1.7.6 (2022-09-13)
|
|
16
|
+
#### :bug: Bug Fix
|
|
17
|
+
* [[#41]](https://github.com/webdriverio-community/wdio-rerun-service/pull/41) Update to work with newer versions of @wdio/cucumber-framework ([@mikesavia](https://github.com/mikesavia))
|
|
18
|
+
|
|
19
|
+
#### Committers: 1
|
|
20
|
+
- [@mikesalvia](https://github.com/mikesalvia)
|
|
21
|
+
|
|
15
22
|
## v1.7.3 (2022-04-19)
|
|
16
23
|
#### :bug: Bug Fix
|
|
17
|
-
* [[#31]](https://github.com/
|
|
18
|
-
* [[#26]](https://github.com/
|
|
24
|
+
* [[#31]](https://github.com/webdriverio-community/wdio-rerun-service/pull/31) Fixing WDIO v7 status code usage ([@ccristobal-skillz](https://github.com/ccristobal-skillz))
|
|
25
|
+
* [[#26]](https://github.com/webdriverio-community/wdio-rerun-service/pull/26) Ensure element contains scenario inside filter function ([@yopasa94](https://github.com/yopasa94))
|
|
19
26
|
|
|
20
27
|
#### :nail_care: Polish
|
|
21
|
-
* [[#32]](https://github.com/
|
|
28
|
+
* [[#32]](https://github.com/webdriverio-community/wdio-rerun-service/pull/32) Update dependencies, move to fixed static versions ([@esaari](https://github.com/esaari))
|
|
22
29
|
|
|
23
30
|
#### Committers: 3
|
|
24
31
|
- [@ccristobal-skillz](https://github.com/ccristobal-skillz)
|
|
@@ -37,9 +44,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
|
|
|
37
44
|
## v1.7.1 (2021-06-24)
|
|
38
45
|
|
|
39
46
|
#### :nail_care: Polish
|
|
40
|
-
* [[#20]](https://github.com/
|
|
41
|
-
* [[#20]](https://github.com/
|
|
42
|
-
* [[#20]](https://github.com/
|
|
47
|
+
* [[#20]](https://github.com/webdriverio-community/wdio-rerun-service/pull/20) Use lockfileVersion:2 ([@esaari](https://github.com/esaari))
|
|
48
|
+
* [[#20]](https://github.com/webdriverio-community/wdio-rerun-service/pull/20) Update `package.json` URLs to reflect webdriverio-community location ([@esaari](https://github.com/esaari))
|
|
49
|
+
* [[#20]](https://github.com/webdriverio-community/wdio-rerun-service/pull/20) Dependency bumps ([@esaari](https://github.com/esaari))
|
|
43
50
|
|
|
44
51
|
#### Committers: 1
|
|
45
52
|
- [@esaari](https://github.com/esaari)
|
|
@@ -47,11 +54,11 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
|
|
|
47
54
|
## v1.7.0 (2021-03-01)
|
|
48
55
|
|
|
49
56
|
#### :bug: Bug Fix
|
|
50
|
-
* [[#9]](https://github.com/
|
|
57
|
+
* [[#9]](https://github.com/webdriverio-community/wdio-rerun-service/pull/9) Fix Cucumber hooks, so we're now compatible with WDIO v7 ([@esaari](https://github.com/esaari))
|
|
51
58
|
#### :memo: Documentation
|
|
52
|
-
* [[#9]](https://github.com/
|
|
59
|
+
* [[#9]](https://github.com/webdriverio-community/wdio-rerun-service/pull/9) Readme updates for clarity ([@esaari](https://github.com/esaari))
|
|
53
60
|
#### ::nail_care:: Polish
|
|
54
|
-
* [[#9]](https://github.com/
|
|
61
|
+
* [[#9]](https://github.com/webdriverio-community/wdio-rerun-service/pull/9) Filter `skipped` Cucumber scenarios from being included in rerun ([@esaari](https://github.com/esaari))
|
|
55
62
|
|
|
56
63
|
#### Committers: 1
|
|
57
64
|
- [@esaari](https://github.com/esaari)
|
|
@@ -59,9 +66,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
|
|
|
59
66
|
## v1.6.0 (2021-02-26)
|
|
60
67
|
|
|
61
68
|
#### :rocket: New Feature
|
|
62
|
-
* [[#11]](https://github.com/
|
|
69
|
+
* [[#11]](https://github.com/webdriverio-community/wdio-rerun-service/pull/11) Fix issue with Windows-style separators, add CHANGELOG.md ([@mikesalvia](https://github.com/mikesalvia))*
|
|
63
70
|
#### :bug: Bug Fix
|
|
64
|
-
* [[#10]](https://github.com/
|
|
71
|
+
* [[#10]](https://github.com/webdriverio-community/wdio-rerun-service/pull/10) Ensure failure locations are unique so there are no duplicates created in re-run.sh ([@mikesalvia](https://github.com/mikesalvia))
|
|
65
72
|
#### :memo: Documentation
|
|
66
73
|
#### :house: Internal
|
|
67
74
|
|
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 `
|
|
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
|
-
|
|
30
|
+
Using `npm`:
|
|
31
31
|
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"wdio-rerun-service": "^1.7.3"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
32
|
+
```bash
|
|
33
|
+
npm install wdio-rerun-service
|
|
38
34
|
```
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
or using `yarn`:
|
|
41
37
|
|
|
42
38
|
```bash
|
|
43
|
-
|
|
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
|
-
|
|
51
|
-
export
|
|
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
|
-
|
|
68
|
-
export
|
|
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
|
-
|
|
89
|
-
export
|
|
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
|
-
|
|
110
|
-
export
|
|
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
|
-
|
|
131
|
-
export
|
|
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
|
-
|
|
152
|
-
export
|
|
147
|
+
import RerunService from 'wdio-rerun-service';
|
|
148
|
+
export const config = {
|
|
153
149
|
// ...
|
|
154
150
|
services: [
|
|
155
151
|
[RerunService, {
|
|
@@ -159,4 +155,26 @@ export.config = {
|
|
|
159
155
|
// ...
|
|
160
156
|
}
|
|
161
157
|
```
|
|
158
|
+
|
|
159
|
+
### customParameters
|
|
160
|
+
Parameters which will be added to the re-run command that is generated.
|
|
161
|
+
Can be used with `commandPrefix`.
|
|
162
|
+
|
|
163
|
+
Type: `String`
|
|
164
|
+
|
|
165
|
+
Default: `''`
|
|
166
|
+
|
|
167
|
+
Example:
|
|
168
|
+
```js
|
|
169
|
+
import RerunService from 'wdio-rerun-service';
|
|
170
|
+
export const config = {
|
|
171
|
+
// ...
|
|
172
|
+
services: [
|
|
173
|
+
[RerunService, {
|
|
174
|
+
customParameters: "--foobar"
|
|
175
|
+
}]
|
|
176
|
+
],
|
|
177
|
+
// ...
|
|
178
|
+
}
|
|
179
|
+
```
|
|
162
180
|
----
|
|
@@ -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":"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;AAqBnC,MAAM,CAAC,OAAO,OAAO,YAAY;IAC7B,eAAe,CAAkB;IACjC,eAAe,CAAQ;IACvB,WAAW,CAAU;IACrB,YAAY,CAAQ;IACpB,eAAe,CAAQ;IACvB,aAAa,CAAQ;IACrB,gBAAgB,CAAQ;IACxB,QAAQ,CAAQ;IAChB,QAAQ,CAAS;IAEjB,YAAY,UAA+B,EAAE;QACzC,MAAM,EACF,WAAW,EACX,YAAY,EACZ,eAAe,EACf,aAAa,EACb,gBAAgB,GACnB,GAAG,OAAO,CAAA;QACX,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QACzB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,EAAE,CAAA;QACpC,IAAI,CAAC,YAAY,GAAG,YAAY,IAAI,iBAAiB,CAAA;QACrD,IAAI,CAAC,eAAe;YAChB,eAAe,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QACxE,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,EAAE,CAAA;QACxC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,EAAE,CAAA;QAC9C,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAA;QAClB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,MAAM,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,MAAM,CACR,aAA4C,EAC5C,KAAe;QAEf,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,OAAM;SACT;QACD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC9B,oFAAoF;QACpF,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACnD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAA;IACjE,CAAC;IAED,SAAS,CACL,KAAsB,EACtB,QAAa,EACb,OAA8B;QAE9B,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,OAAM;SACT;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,MAA4B,CAAA;QACnD,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE;YAC3C,OAAM;SACT;QACD,iEAAiE;QACjE,kDAAkD;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAA0B,CAAA;QAChD,IAAI,KAAK,EAAE,OAAO,EAAE;YAChB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;gBACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,KAAK,CAAC,OAAO;aACzB,CAAC,CAAA;SACL;aAAM;YACH,2GAA2G;SAC9G;IACL,CAAC;IAED,2CAA2C;IAC3C,aAAa,CAAC,KAAY;QACtB,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,OAAM;SACT;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAA4B,CAAA;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAA;QACnC,IACI,MAAM,CAAC,SAAS,KAAK,UAAU;YAC/B,MAAM,KAAK,QAAQ;YACnB,MAAM,KAAK,SAAS,EACtB;YACE,OAAM;SACT;QACD,MAAM,kBAAkB,GACpB,KAAK,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CACrD,KAAK,CAAC,QAAQ;YACV,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAC5B,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAC/B;YACH,CAAC,CAAC,KAAK,CACd,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAA;QACxC,MAAM,gBAAgB,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,kBAAkB,EAAE,CAAA;QACpE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACzD,IACI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;YAChC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAC1B,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CACxC,EACH;YACE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;gBACtB,QAAQ,EAAE,gBAAgB;gBAC1B,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;aACjC,CAAC,CAAA;SACL;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACP,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,OAAM;SACT;QACD,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;YACnC,OAAM,CAAC,oFAAoF;SAC9F;QACD,MAAM,SAAS,CACX,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,IAAI,CAAC,eAAe,OAAO,CAAC,EAC7D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CACvC,CAAA;IACL,CAAC;IAED,KAAK,CAAC,UAAU;QACZ,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,OAAM;SACT;QACD,IAAI;YACA,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC9C,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;YACjE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzB,OAAM;aACT;YACD,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;YACzD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;YACjE,MAAM,YAAY,GACd,QAAQ,KAAK,OAAO;gBAChB,CAAC,CAAC,2BAA2B;gBAC7B,CAAC,CAAC,oBAAoB,CAAA;YAC9B,IAAI,YAAY,GAAG,GAAG,MAAM,GAAG,YAAY,aAAa,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACtF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;YAC1C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;gBAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACnB,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CACpC,CAAA;gBACrB,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACrB,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;gBAC9D,CAAC,CAAC,CAAA;aACL;YACD,gBAAgB,CAAC,OAAO,CAAC,CAAC,eAAe,EAAE,EAAE;gBACzC,YAAY,IAAI,WAAW,eAAe,EAAE,CAAA;YAChD,CAAC,CAAC,CAAA;YACF,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;YACpE,6EAA6E;SAChF;QAAC,OAAO,GAAG,EAAE;YACV,0EAA0E;SAC7E;IACL,CAAC;CACJ"}
|
package/package.json
CHANGED
|
@@ -1,26 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wdio-rerun-service",
|
|
3
|
-
"version": "
|
|
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
|
-
"
|
|
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": ">=
|
|
28
|
+
"node": ">=16.0.0"
|
|
11
29
|
},
|
|
12
30
|
"scripts": {
|
|
13
31
|
"build": "run-s clean compile",
|
|
14
32
|
"clean": "rimraf ./build",
|
|
15
|
-
"compile": "
|
|
16
|
-
"
|
|
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:
|
|
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}/*.
|
|
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/
|
|
54
|
-
"minimist": "1.2.
|
|
55
|
-
"
|
|
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
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@
|
|
66
|
-
"@
|
|
67
|
-
"@
|
|
68
|
-
"@
|
|
69
|
-
"@
|
|
70
|
-
"@
|
|
71
|
-
"@
|
|
72
|
-
"@
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
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
|
-
"
|
|
83
|
-
"
|
|
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
|
}
|
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,117 +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
|
-
} = {}) {
|
|
22
|
-
this.nonPassingItems = [];
|
|
23
|
-
this.serviceWorkerId;
|
|
24
|
-
this.ignoredTags = ignoredTags ? ignoredTags : [];
|
|
25
|
-
this.rerunDataDir = rerunDataDir ? rerunDataDir : "./results/rerun";
|
|
26
|
-
this.rerunScriptPath = rerunScriptPath ? rerunScriptPath : "./rerun.sh";
|
|
27
|
-
this.commandPrefix = commandPrefix ? commandPrefix : "";
|
|
28
|
-
this.specFile = "";
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
before(capabilities, specs) {
|
|
32
|
-
this.specFile = specs[0];
|
|
33
|
-
fs.mkdirSync(this.rerunDataDir, {
|
|
34
|
-
recursive: true
|
|
35
|
-
});
|
|
36
|
-
this.serviceWorkerId = uuidv5(`${Date.now()}`, '6ba7b810-9dad-11d1-80b4-00c04fd430c8');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
afterTest(test, context, {
|
|
40
|
-
error,
|
|
41
|
-
result,
|
|
42
|
-
duration,
|
|
43
|
-
passed,
|
|
44
|
-
retries
|
|
45
|
-
}) {
|
|
46
|
-
if (browser.config.framework !== 'cucumber' && !passed) {
|
|
47
|
-
if (error && error.message) {
|
|
48
|
-
this.nonPassingItems.push({
|
|
49
|
-
location: this.specFile,
|
|
50
|
-
failure: error.message
|
|
51
|
-
});
|
|
52
|
-
} else {}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
afterScenario(world) {
|
|
57
|
-
const status = world.result.status;
|
|
58
|
-
const scenarioLineNumber = world.gherkinDocument.feature.children.filter(child => {
|
|
59
|
-
if (child.scenario) {
|
|
60
|
-
return child.scenario && world.pickle.astNodeIds.includes(child.scenario.id.toString());
|
|
61
|
-
}
|
|
62
|
-
})[0].scenario.location.line;
|
|
63
|
-
|
|
64
|
-
if (browser.config.framework === 'cucumber' && status !== 'PASSED' && status !== 'SKIPPED') {
|
|
65
|
-
const scenarioLocation = `${world.pickle.uri}:${scenarioLineNumber}`;
|
|
66
|
-
const tagsList = world.pickle.tags.map(tag => tag.name);
|
|
67
|
-
const service = this;
|
|
68
|
-
|
|
69
|
-
if (this.ignoredTags && tagsList.some(ignoredTag => service.ignoredTags.includes(ignoredTag))) {} else {
|
|
70
|
-
this.nonPassingItems.push({
|
|
71
|
-
location: scenarioLocation,
|
|
72
|
-
failure: world.result.message
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
after(result, capabilities, specs) {
|
|
79
|
-
if (this.nonPassingItems.length > 0) {
|
|
80
|
-
fs.writeFileSync(`${this.rerunDataDir}/rerun-${this.serviceWorkerId}.json`, JSON.stringify(this.nonPassingItems));
|
|
81
|
-
} else {}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
onComplete(exitCode, config, capabilities, results) {
|
|
85
|
-
const directoryPath = path.join(process.cwd(), `${this.rerunDataDir}`);
|
|
86
|
-
|
|
87
|
-
if (fs.existsSync(directoryPath)) {
|
|
88
|
-
const rerunFiles = fs.readdirSync(directoryPath);
|
|
89
|
-
|
|
90
|
-
if (rerunFiles.length > 0) {
|
|
91
|
-
let rerunCommand = `DISABLE_RERUN=true node_modules/.bin/wdio ${argv._[0]} `;
|
|
92
|
-
|
|
93
|
-
if (this.commandPrefix) {
|
|
94
|
-
rerunCommand = `${this.commandPrefix} ${rerunCommand}`;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
let failureLocations = [];
|
|
98
|
-
rerunFiles.forEach(file => {
|
|
99
|
-
const json = JSON.parse(fs.readFileSync(`${this.rerunDataDir}/${file}`));
|
|
100
|
-
json.forEach(failure => {
|
|
101
|
-
failureLocations.push(failure.location.replace(/\\/g, "/"));
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
const failureLocationsUnique = [...new Set(failureLocations)];
|
|
105
|
-
failureLocationsUnique.forEach(failureLocation => {
|
|
106
|
-
rerunCommand += ` --spec=${failureLocation}`;
|
|
107
|
-
});
|
|
108
|
-
fs.writeFileSync(this.rerunScriptPath, rerunCommand);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
;
|
|
116
|
-
module.exports = RerunService;
|
|
117
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJmcyIsInJlcXVpcmUiLCJwYXRoIiwidjUiLCJ1dWlkdjUiLCJhcmd2IiwicHJvY2VzcyIsInNsaWNlIiwiUmVydW5TZXJ2aWNlIiwiY29uc3RydWN0b3IiLCJpZ25vcmVkVGFncyIsInJlcnVuRGF0YURpciIsInJlcnVuU2NyaXB0UGF0aCIsImNvbW1hbmRQcmVmaXgiLCJub25QYXNzaW5nSXRlbXMiLCJzZXJ2aWNlV29ya2VySWQiLCJzcGVjRmlsZSIsImJlZm9yZSIsImNhcGFiaWxpdGllcyIsInNwZWNzIiwibWtkaXJTeW5jIiwicmVjdXJzaXZlIiwiRGF0ZSIsIm5vdyIsImFmdGVyVGVzdCIsInRlc3QiLCJjb250ZXh0IiwiZXJyb3IiLCJyZXN1bHQiLCJkdXJhdGlvbiIsInBhc3NlZCIsInJldHJpZXMiLCJicm93c2VyIiwiY29uZmlnIiwiZnJhbWV3b3JrIiwibWVzc2FnZSIsInB1c2giLCJsb2NhdGlvbiIsImZhaWx1cmUiLCJhZnRlclNjZW5hcmlvIiwid29ybGQiLCJzdGF0dXMiLCJzY2VuYXJpb0xpbmVOdW1iZXIiLCJnaGVya2luRG9jdW1lbnQiLCJmZWF0dXJlIiwiY2hpbGRyZW4iLCJmaWx0ZXIiLCJjaGlsZCIsInNjZW5hcmlvIiwicGlja2xlIiwiYXN0Tm9kZUlkcyIsImluY2x1ZGVzIiwiaWQiLCJ0b1N0cmluZyIsImxpbmUiLCJzY2VuYXJpb0xvY2F0aW9uIiwidXJpIiwidGFnc0xpc3QiLCJ0YWdzIiwibWFwIiwidGFnIiwibmFtZSIsInNlcnZpY2UiLCJzb21lIiwiaWdub3JlZFRhZyIsImFmdGVyIiwibGVuZ3RoIiwid3JpdGVGaWxlU3luYyIsIkpTT04iLCJzdHJpbmdpZnkiLCJvbkNvbXBsZXRlIiwiZXhpdENvZGUiLCJyZXN1bHRzIiwiZGlyZWN0b3J5UGF0aCIsImpvaW4iLCJjd2QiLCJleGlzdHNTeW5jIiwicmVydW5GaWxlcyIsInJlYWRkaXJTeW5jIiwicmVydW5Db21tYW5kIiwiXyIsImZhaWx1cmVMb2NhdGlvbnMiLCJmb3JFYWNoIiwiZmlsZSIsImpzb24iLCJwYXJzZSIsInJlYWRGaWxlU3luYyIsInJlcGxhY2UiLCJmYWlsdXJlTG9jYXRpb25zVW5pcXVlIiwiU2V0IiwiZmFpbHVyZUxvY2F0aW9uIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE1BQU1BLEVBQUUsR0FBR0MsT0FBTyxDQUFDLElBQUQsQ0FBbEI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFDQSxNQUFNO0FBQUVFLEVBQUFBLEVBQUUsRUFBRUM7QUFBTixJQUFpQkgsT0FBTyxDQUFDLE1BQUQsQ0FBOUI7O0FBRUEsTUFBTUksSUFBSSxHQUFHSixPQUFPLENBQUMsVUFBRCxDQUFQLENBQW9CSyxPQUFPLENBQUNELElBQVIsQ0FBYUUsS0FBYixDQUFtQixDQUFuQixDQUFwQixDQUFiOztBQUVBLE1BQU1DLFlBQU4sQ0FBbUI7QUFFZkMsRUFBQUEsV0FBVyxDQUFDO0FBQUVDLElBQUFBLFdBQUY7QUFBZUMsSUFBQUEsWUFBZjtBQUE2QkMsSUFBQUEsZUFBN0I7QUFBOENDLElBQUFBO0FBQTlDLE1BQWdFLEVBQWpFLEVBQXFFO0FBQzVFLFNBQUtDLGVBQUwsR0FBdUIsRUFBdkI7QUFDQSxTQUFLQyxlQUFMO0FBQ0EsU0FBS0wsV0FBTCxHQUFtQkEsV0FBVyxHQUFHQSxXQUFILEdBQWlCLEVBQS9DO0FBQ0EsU0FBS0MsWUFBTCxHQUFvQkEsWUFBWSxHQUFHQSxZQUFILEdBQWtCLGlCQUFsRDtBQUNBLFNBQUtDLGVBQUwsR0FBdUJBLGVBQWUsR0FBR0EsZUFBSCxHQUFxQixZQUEzRDtBQUNBLFNBQUtDLGFBQUwsR0FBcUJBLGFBQWEsR0FBR0EsYUFBSCxHQUFtQixFQUFyRDtBQUNBLFNBQUtHLFFBQUwsR0FBZ0IsRUFBaEI7QUFDSDs7QUFFREMsRUFBQUEsTUFBTSxDQUFDQyxZQUFELEVBQWVDLEtBQWYsRUFBc0I7QUFDeEIsU0FBS0gs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T0FBakIsQ0FBeUIsS0FBekIsRUFBZ0MsR0FBaEMsQ0FBdEI7QUFDSCxXQUZEO0FBR0gsU0FMRDtBQU1BLGNBQU1DLHNCQUFzQixHQUFHLENBQUMsR0FBRyxJQUFJQyxHQUFKLENBQVFSLGdCQUFSLENBQUosQ0FBL0I7QUFDQU8sUUFBQUEsc0JBQXNCLENBQUNOLE9BQXZCLENBQStCUSxlQUFlLElBQUk7QUFDOUNYLFVBQUFBLFlBQVksSUFBSyxXQUFVVyxlQUFnQixFQUEzQztBQUNILFNBRkQ7QUFHQTFGLFFBQUFBLEVBQUUsQ0FBQ21FLGFBQUgsQ0FBaUIsS0FBS3ZELGVBQXRCLEVBQXVDbUUsWUFBdkM7QUFFSDtBQUNKO0FBQ0o7O0FBeEZjOztBQXlGbEI7QUFFRFksTUFBTSxDQUFDQyxPQUFQLEdBQWlCcEYsWUFBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5jb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuY29uc3QgeyB2NTogdXVpZHY1IH0gPSByZXF1aXJlKCd1dWlkJyk7XG5cbmNvbnN0IGFyZ3YgPSByZXF1aXJlKCdtaW5pbWlzdCcpKHByb2Nlc3MuYXJndi5zbGljZSgyKSk7XG5cbmNsYXNzIFJlcnVuU2VydmljZSB7XG5cbiAgICBjb25zdHJ1Y3Rvcih7IGlnbm9yZWRUYWdzLCByZXJ1bkRhdGFEaXIsIHJlcnVuU2NyaXB0UGF0aCwgY29tbWFuZFByZWZpeCB9ID0ge30pIHtcbiAgICAgICAgdGhpcy5ub25QYXNzaW5nSXRlbXMgPSBbXTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlV29ya2VySWQ7XG4gICAgICAgIHRoaXMuaWdub3JlZFRhZ3MgPSBpZ25vcmVkVGFncyA/IGlnbm9yZWRUYWdzIDogW107XG4gICAgICAgIHRoaXMucmVydW5EYXRhRGlyID0gcmVydW5EYXRhRGlyID8gcmVydW5EYXRhRGlyIDogXCIuL3Jlc3VsdHMvcmVydW5cIjtcbiAgICAgICAgdGhpcy5yZXJ1blNjcmlwdFBhdGggPSByZXJ1blNjcmlwdFBhdGggPyByZXJ1blNjcmlwdFBhdGggOiBcIi4vcmVydW4uc2hcIjtcbiAgICAgICAgdGhpcy5jb21tYW5kUHJlZml4ID0gY29tbWFuZFByZWZpeCA/IGNvbW1hbmRQcmVmaXggOiBcIlwiO1xuICAgICAgICB0aGlzLnNwZWNGaWxlID0gXCJcIjtcbiAgICB9XG5cbiAgICBiZWZvcmUoY2FwYWJpbGl0aWVzLCBzcGVjcykge1xuICAgICAgICB0aGlzLnNwZWNGaWxlID0gc3BlY3NbMF07XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGBSZS1ydW4gc2VydmljZSBpcyBhY3RpdmF0ZWQuIERhdGEgZGlyZWN0b3J5OiAke3RoaXMucmVydW5EYXRhRGlyfWApO1xuICAgICAgICBmcy5ta2RpclN5bmModGhpcy5yZXJ1bkRhdGFEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICAvLyBJTkZPOiBgbmFtZXNwYWNlYCBiZWxvdyBjb3BpZWQgZnJvbTogaHR0cHM6Ly9naXRodWIuY29tL2tlbGVrdGl2L25vZGUtdXVpZC9ibG9iL21hc3Rlci8vbGliL3YzNS5qcyNMNTQ6MTZcbiAgICAgICAgdGhpcy5zZXJ2aWNlV29ya2VySWQgPSB1dWlkdjUoYCR7RGF0ZS5ub3coKX1gLCAnNmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4Jyk7XG4gICAgfVxuXG4gICAgYWZ0ZXJUZXN0KHRlc3QsIGNvbnRleHQsIHsgZXJyb3IsIHJlc3VsdCwgZHVyYXRpb24sIHBhc3NlZCwgcmV0cmllcyB9KSB7XG4gICAgICAgIGlmIChicm93c2VyLmNvbmZpZy5mcmFtZXdvcmsgIT09ICdjdWN1bWJlcicgJiYgIXBhc3NlZCkge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFJlLXJ1biBzZXJ2aWNlIGlzIGluc3BlY3Rpbmcgbm9uLXBhc3NpbmcgdGVzdC5gKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBUZXN0IGxvY2F0aW9uOiAke3RoaXMuc3BlY0ZpbGV9YCk7XG4gICAgICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIHRoaXMubm9uUGFzc2luZ0l0ZW1zLnB1c2goeyBsb2NhdGlvbjogdGhpcy5zcGVjRmlsZSwgZmFpbHVyZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJUaGUgbm9uLXBhc3NpbmcgdGVzdCBkaWQgbm90IGNvbnRhaW4gYW55IGVycm9yIG1lc3NhZ2UsIGl0IGNvdWxkIG5vdCBiZSBhZGRlZCBmb3IgcmUtcnVuLlwiKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRXhlY3V0ZWQgYWZ0ZXIgYSBDdWN1bWJlciBzY2VuYXJpbyBlbmRzLlxuICAgIGFmdGVyU2NlbmFyaW8od29ybGQpIHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gd29ybGQucmVzdWx0LnN0YXR1cztcbiAgICAgICAgY29uc3Qgc2NlbmFyaW9MaW5lTnVtYmVyID0gd29ybGQuZ2hlcmtpbkRvY3VtZW50LmZlYXR1cmUuY2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4ge1xuICAgICAgICAgICAgaWYoY2hpbGQuc2NlbmFyaW8pe1xuICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5zY2VuYXJpbyAmJiB3b3JsZC5waWNrbGUuYXN0Tm9kZUlkcy5pbmNsdWRlcyhjaGlsZC5zY2VuYXJpby5pZC50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlbMF0uc2NlbmFyaW8ubG9jYXRpb24ubGluZTtcblxuICAgICAgICBpZiAoYnJvd3Nlci5jb25maWcuZnJhbWV3b3JrID09PSAnY3VjdW1iZXInICYmIChzdGF0dXMgIT09ICdQQVNTRUQnICYmIHN0YXR1cyAhPT0gJ1NLSVBQRUQnKSkge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFJlLXJ1biBzZXJ2aWNlIGlzIGluc3BlY3Rpbmcgbm9uLXBhc3Npbmcgc2NlbmFyaW8uYCk7XG4gICAgICAgICAgICBjb25zdCBzY2VuYXJpb0xvY2F0aW9uID0gYCR7d29ybGQucGlja2xlLnVyaX06JHtzY2VuYXJpb0xpbmVOdW1iZXJ9YDtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBTY2VuYXJpbyBsb2NhdGlvbjogJHtzY2VuYXJpb0xvY2F0aW9ufWApO1xuICAgICAgICAgICAgY29uc3QgdGFnc0xpc3QgPSB3b3JsZC5waWNrbGUudGFncy5tYXAodGFnID0+IHRhZy5uYW1lKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBTY2VuYXJpbyB0YWdzOiAke3RhZ3NMaXN0fWApO1xuICAgICAgICAgICAgY29uc3Qgc2VydmljZSA9IHRoaXM7XG4gICAgICAgICAgICBpZiAodGhpcy5pZ25vcmVkVGFncyAmJiB0YWdzTGlzdC5zb21lKGlnbm9yZWRUYWcgPT4gc2VydmljZS5pZ25vcmVkVGFncy5pbmNsdWRlcyhpZ25vcmVkVGFnKSkpIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgUmUtcnVuIHNlcnZpY2Ugd2lsbCBpZ25vcmUgdGhlIGN1cnJlbnQgc2NlbmFyaW8gc2luY2UgaXQgaW5jbHVkZXMgb25lIG9mIHRoZSBpZ25vcmVkIHRhZ3M6ICR7dGhpcy5pZ25vcmVkVGFnc31gKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub25QYXNzaW5nSXRlbXMucHVzaCh7IGxvY2F0aW9uOiBzY2VuYXJpb0xvY2F0aW9uLCBmYWlsdXJlOiB3b3JsZC5yZXN1bHQubWVzc2FnZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFmdGVyKHJlc3VsdCwgY2FwYWJpbGl0aWVzLCBzcGVjcykge1xuICAgICAgICBpZiAodGhpcy5ub25QYXNzaW5nSXRlbXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhgJHt0aGlzLnJlcnVuRGF0YURpcn0vcmVydW4tJHt0aGlzLnNlcnZpY2VXb3JrZXJJZH0uanNvbmAsIEpTT04uc3RyaW5naWZ5KHRoaXMubm9uUGFzc2luZ0l0ZW1zKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnUmUtcnVuIHNlcnZpY2UgZGlkIG5vdCBkZXRlY3QgYW55IG5vbi1wYXNzaW5nIHNjZW5hcmlvcyBvciB0ZXN0cy4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uQ29tcGxldGUoZXhpdENvZGUsIGNvbmZpZywgY2FwYWJpbGl0aWVzLCByZXN1bHRzKSB7XG4gICAgICAgIGNvbnN0IGRpcmVjdG9yeVBhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgYCR7dGhpcy5yZXJ1bkRhdGFEaXJ9YCk7XG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRpcmVjdG9yeVBhdGgpKSB7XG4gICAgICAgICAgICBjb25zdCByZXJ1bkZpbGVzID0gZnMucmVhZGRpclN5bmMoZGlyZWN0b3J5UGF0aCk7XG4gICAgICAgICAgICBpZiAocmVydW5GaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlcnVuQ29tbWFuZCA9IGBESVNBQkxFX1JFUlVOPXRydWUgbm9kZV9tb2R1bGVzLy5iaW4vd2RpbyAke2FyZ3YuX1swXX0gYDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb21tYW5kUHJlZml4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcnVuQ29tbWFuZCA9IGAke3RoaXMuY29tbWFuZFByZWZpeH0gJHtyZXJ1bkNvbW1hbmR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGZhaWx1cmVMb2NhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICByZXJ1bkZpbGVzLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhgJHt0aGlzLnJlcnVuRGF0YURpcn0vJHtmaWxlfWApKTtcbiAgICAgICAgICAgICAgICAgICAganNvbi5mb3JFYWNoKGZhaWx1cmUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFpbHVyZUxvY2F0aW9ucy5wdXNoKGZhaWx1cmUubG9jYXRpb24ucmVwbGFjZSgvXFxcXC9nLCBcIi9cIikpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBmYWlsdXJlTG9jYXRpb25zVW5pcXVlID0gWy4uLm5ldyBTZXQoZmFpbHVyZUxvY2F0aW9ucyldO1xuICAgICAgICAgICAgICAgIGZhaWx1cmVMb2NhdGlvbnNVbmlxdWUuZm9yRWFjaChmYWlsdXJlTG9jYXRpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXJ1bkNvbW1hbmQgKz0gYCAtLXNwZWM9JHtmYWlsdXJlTG9jYXRpb259YDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHRoaXMucmVydW5TY3JpcHRQYXRoLCByZXJ1bkNvbW1hbmQpO1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBSZS1ydW4gc2NyaXB0IGhhcyBiZWVuIGdlbmVyYXRlZCBAICR7dGhpcy5yZXJ1blNjcmlwdFBhdGh9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlcnVuU2VydmljZTtcbiJdfQ==
|