@testomatio/reporter 2.0.1-beta.5-timestamp → 2.0.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/lib/adapter/codecept.d.ts +2 -0
- package/lib/adapter/codecept.js +293 -335
- package/lib/adapter/cucumber/current.d.ts +14 -0
- package/lib/adapter/cucumber/current.js +195 -203
- package/lib/adapter/cucumber/legacy.d.ts +0 -0
- package/lib/adapter/cucumber/legacy.js +130 -155
- package/lib/adapter/cucumber.d.ts +2 -0
- package/lib/adapter/cucumber.js +5 -16
- package/lib/adapter/cypress-plugin/index.d.ts +2 -0
- package/lib/adapter/cypress-plugin/index.js +91 -105
- package/lib/adapter/jasmine.d.ts +11 -0
- package/lib/adapter/jasmine.js +54 -53
- package/lib/adapter/jest.d.ts +13 -0
- package/lib/adapter/jest.js +97 -99
- package/lib/adapter/mocha.d.ts +2 -0
- package/lib/adapter/mocha.js +112 -141
- package/lib/adapter/nightwatch.d.ts +4 -0
- package/lib/adapter/nightwatch.js +80 -0
- package/lib/adapter/playwright.d.ts +14 -0
- package/lib/adapter/playwright.js +199 -231
- package/lib/adapter/vitest.d.ts +35 -0
- package/lib/adapter/vitest.js +150 -149
- package/lib/adapter/webdriver.d.ts +24 -0
- package/lib/adapter/webdriver.js +144 -121
- package/lib/bin/cli.d.ts +2 -0
- package/lib/bin/cli.js +229 -211
- package/lib/bin/reportXml.d.ts +2 -0
- package/lib/bin/reportXml.js +51 -52
- package/lib/bin/startTest.d.ts +2 -0
- package/lib/bin/startTest.js +83 -95
- package/lib/bin/uploadArtifacts.d.ts +2 -0
- package/lib/bin/uploadArtifacts.js +56 -61
- package/lib/client.d.ts +76 -0
- package/lib/client.js +429 -465
- package/lib/config.d.ts +1 -0
- package/lib/config.js +18 -23
- package/lib/constants.d.ts +25 -0
- package/lib/constants.js +50 -44
- package/lib/data-storage.d.ts +34 -0
- package/lib/data-storage.js +216 -188
- package/lib/junit-adapter/adapter.d.ts +9 -0
- package/lib/junit-adapter/adapter.js +17 -20
- package/lib/junit-adapter/csharp.d.ts +5 -0
- package/lib/junit-adapter/csharp.js +28 -14
- package/lib/junit-adapter/index.d.ts +3 -0
- package/lib/junit-adapter/index.js +27 -25
- package/lib/junit-adapter/java.d.ts +5 -0
- package/lib/junit-adapter/java.js +41 -53
- package/lib/junit-adapter/javascript.d.ts +4 -0
- package/lib/junit-adapter/javascript.js +30 -27
- package/lib/junit-adapter/python.d.ts +5 -0
- package/lib/junit-adapter/python.js +38 -37
- package/lib/junit-adapter/ruby.d.ts +4 -0
- package/lib/junit-adapter/ruby.js +11 -8
- package/lib/output.d.ts +11 -0
- package/lib/output.js +44 -52
- package/lib/package.json +3 -0
- package/lib/pipe/bitbucket.d.ts +25 -0
- package/lib/pipe/bitbucket.js +223 -230
- package/lib/pipe/csv.d.ts +47 -0
- package/lib/pipe/csv.js +113 -126
- package/lib/pipe/debug.d.ts +29 -0
- package/lib/pipe/debug.js +125 -99
- package/lib/pipe/github.d.ts +30 -0
- package/lib/pipe/github.js +218 -213
- package/lib/pipe/gitlab.d.ts +25 -0
- package/lib/pipe/gitlab.js +183 -206
- package/lib/pipe/html.d.ts +35 -0
- package/lib/pipe/html.js +258 -321
- package/lib/pipe/index.d.ts +1 -0
- package/lib/pipe/index.js +94 -66
- package/lib/pipe/testomatio.d.ts +71 -0
- package/lib/pipe/testomatio.js +429 -474
- package/lib/replay.d.ts +31 -0
- package/lib/replay.js +255 -0
- package/lib/reporter-functions.d.ts +34 -0
- package/lib/reporter-functions.js +28 -26
- package/lib/reporter.d.ts +232 -0
- package/lib/reporter.js +34 -29
- package/lib/services/artifacts.d.ts +33 -0
- package/lib/services/artifacts.js +55 -51
- package/lib/services/index.d.ts +9 -0
- package/lib/services/index.js +14 -12
- package/lib/services/key-values.d.ts +27 -0
- package/lib/services/key-values.js +56 -53
- package/lib/services/logger.d.ts +64 -0
- package/lib/services/logger.js +226 -245
- package/lib/template/testomatio.hbs +1026 -1366
- package/lib/uploader.d.ts +60 -0
- package/lib/uploader.js +295 -364
- package/lib/utils/pipe_utils.d.ts +41 -0
- package/lib/utils/pipe_utils.js +89 -85
- package/lib/utils/utils.d.ts +54 -0
- package/lib/utils/utils.js +398 -307
- package/lib/xmlReader.d.ts +92 -0
- package/lib/xmlReader.js +525 -532
- package/package.json +64 -21
- package/src/adapter/codecept.js +373 -0
- package/src/adapter/cucumber/current.js +228 -0
- package/src/adapter/cucumber/legacy.js +158 -0
- package/src/adapter/cucumber.js +4 -0
- package/src/adapter/cypress-plugin/index.js +110 -0
- package/src/adapter/jasmine.js +60 -0
- package/src/adapter/jest.js +107 -0
- package/src/adapter/mocha.cjs +2 -0
- package/src/adapter/mocha.js +156 -0
- package/src/adapter/nightwatch.js +88 -0
- package/src/adapter/playwright.js +254 -0
- package/src/adapter/vitest.js +183 -0
- package/src/adapter/webdriver.js +142 -0
- package/src/bin/cli.js +348 -0
- package/src/bin/reportXml.js +77 -0
- package/src/bin/startTest.js +124 -0
- package/src/bin/uploadArtifacts.js +91 -0
- package/src/client.js +515 -0
- package/src/config.js +30 -0
- package/src/constants.js +53 -0
- package/src/data-storage.js +204 -0
- package/src/junit-adapter/adapter.js +23 -0
- package/src/junit-adapter/csharp.js +28 -0
- package/src/junit-adapter/index.js +28 -0
- package/src/junit-adapter/java.js +58 -0
- package/src/junit-adapter/javascript.js +31 -0
- package/src/junit-adapter/python.js +42 -0
- package/src/junit-adapter/ruby.js +10 -0
- package/src/output.js +57 -0
- package/src/pipe/bitbucket.js +252 -0
- package/src/pipe/csv.js +140 -0
- package/src/pipe/debug.js +125 -0
- package/src/pipe/github.js +232 -0
- package/src/pipe/gitlab.js +247 -0
- package/src/pipe/html.js +373 -0
- package/src/pipe/index.js +71 -0
- package/src/pipe/testomatio.js +504 -0
- package/src/replay.js +262 -0
- package/src/reporter-functions.js +55 -0
- package/src/reporter.cjs_decprecated +21 -0
- package/src/reporter.js +33 -0
- package/src/services/artifacts.js +59 -0
- package/src/services/index.js +13 -0
- package/src/services/key-values.js +59 -0
- package/src/services/logger.js +315 -0
- package/src/template/emptyData.svg +23 -0
- package/src/template/testomatio.hbs +1081 -0
- package/src/uploader.js +376 -0
- package/src/utils/pipe_utils.js +119 -0
- package/src/utils/utils.js +416 -0
- package/src/xmlReader.js +614 -0
package/package.json
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testomatio/reporter",
|
|
3
|
-
"version": "2.0.1-beta.
|
|
3
|
+
"version": "2.0.1-beta.6",
|
|
4
4
|
"description": "Testomatio Reporter Client",
|
|
5
|
-
"
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=18"
|
|
7
|
+
},
|
|
6
8
|
"typings": "typings/index.d.ts",
|
|
7
9
|
"repository": "git@github.com:testomatio/reporter.git",
|
|
8
10
|
"author": "Michael Bodnarchuk <davert@testomat.io>,Koushik Mohan <koushikmohan1996@gmail.com>",
|
|
9
11
|
"license": "MIT",
|
|
12
|
+
"type": "module",
|
|
10
13
|
"dependencies": {
|
|
11
14
|
"@aws-sdk/client-s3": "^3.279.0",
|
|
12
15
|
"@aws-sdk/lib-storage": "^3.279.0",
|
|
13
|
-
"@
|
|
16
|
+
"@cucumber/cucumber": "^10.9.0",
|
|
17
|
+
"@octokit/rest": "^21.1.1",
|
|
14
18
|
"aws-sdk": "^2.1072.0",
|
|
15
|
-
"
|
|
16
|
-
"axios-retry": "^3.9.1",
|
|
19
|
+
"gaxios": ">=6.0 || >=7.0.0-rc.4 || <8",
|
|
17
20
|
"callsite-record": "^4.1.4",
|
|
18
|
-
"chalk": "^4.1.0",
|
|
19
21
|
"commander": "^12",
|
|
20
22
|
"cross-spawn": "^7.0.3",
|
|
21
23
|
"csv-writer": "^1.6.0",
|
|
@@ -33,6 +35,7 @@
|
|
|
33
35
|
"lodash.memoize": "^4.1.2",
|
|
34
36
|
"lodash.merge": "^4.6.2",
|
|
35
37
|
"minimatch": "^9.0.3",
|
|
38
|
+
"picocolors": "^1.0.1",
|
|
36
39
|
"pretty-ms": "^7.0.1",
|
|
37
40
|
"promise-retry": "^2.0.1",
|
|
38
41
|
"strip-ansi": "^7.1.0",
|
|
@@ -41,51 +44,91 @@
|
|
|
41
44
|
"files": [
|
|
42
45
|
"bin",
|
|
43
46
|
"lib",
|
|
47
|
+
"src",
|
|
44
48
|
"testcafe"
|
|
45
49
|
],
|
|
46
50
|
"scripts": {
|
|
47
51
|
"clear-exportdir": "rm -rf export/",
|
|
48
52
|
"pretty": "npx prettier --check .",
|
|
49
53
|
"pretty:fix": "prettier --write .",
|
|
50
|
-
"lint": "eslint
|
|
51
|
-
"lint:fix": "eslint
|
|
54
|
+
"lint": "eslint src",
|
|
55
|
+
"lint:fix": "eslint src --fix",
|
|
52
56
|
"format": "npm run lint:fix && npm run pretty:fix",
|
|
53
|
-
"test": "mocha tests/**",
|
|
57
|
+
"test": "mocha tests/** --ignore tests/adapter/playwright.test.js --ignore tests/adapter/codecept.test.js",
|
|
58
|
+
"test:frameworks": "mocha tests/adapter/playwright.test.js tests/adapter/codecept.test.js",
|
|
59
|
+
"install-example-deps": "cd example/playwright && npm install && cd ../codecept && npm install",
|
|
54
60
|
"init": "cd ./tests/adapter/examples/cucumber && npm i",
|
|
55
|
-
"test:adapter": "mocha './tests/adapter/index.test.js'",
|
|
61
|
+
"test:adapter": "node node_modules/mocha/bin/mocha './tests/adapter/index.test.js'",
|
|
56
62
|
"test:pipes": "mocha './tests/pipes/*_test.js'",
|
|
57
63
|
"test:adapter:jest:example": "jest './tests/adapter/examples/jest/index.test.js' --config='./tests/adapter/examples/jest/jest.config.js'",
|
|
58
|
-
"test:adapter:mocha:example": "mocha './tests/adapter/examples/mocha/index.test.js' --config='./tests/adapter/examples/mocha/mocha.config.
|
|
59
|
-
"test:adapter:jasmine:example": "
|
|
64
|
+
"test:adapter:mocha:example": "mocha './tests/adapter/examples/mocha/index.test.js' --config='./tests/adapter/examples/mocha/mocha.config.cjs'",
|
|
65
|
+
"test:adapter:jasmine:example": "jasmine './tests/adapter/examples/jasmine/index.test.js' --reporter=./lib/adapter/jasmine.js",
|
|
60
66
|
"test:adapter:codecept:example": "codeceptjs run --config='./tests/adapter/examples/codecept/codecept.conf.js'",
|
|
61
67
|
"test:adapter:cucumber:example": "cd ./tests/adapter/examples/cucumber && npx cucumber-js",
|
|
62
|
-
"test:adapter:
|
|
63
|
-
"test:
|
|
68
|
+
"test:adapter:playwright:example": "npx playwright test --config='./tests/adapter/examples/playwright/playwright.config.ts'",
|
|
69
|
+
"test:adapter:vitest:example": "npx vitest --config='./tests/adapter/examples/vitest/vitest.config.ts'",
|
|
70
|
+
"test:storage": "npx mocha tests-storage/artifact-storage.test.js && npx mocha tests-storage/data-storage.test.js && TESTOMATIO_INTERCEPT_CONSOLE_LOGS=true npx mocha tests-storage/logger.test.js && npx mocha tests-storage/logger-2.test.js && npx mocha tests-storage/reporter-functions.test.js",
|
|
71
|
+
"build": "rm -rf ./cjs && tsc --module commonjs && npx tsx build/scripts/edit-js-files.js && npx tsx build/scripts/edit-package-json.js && chmod +x ./build/scripts/copy-tesmplate.sh && ./build/scripts/copy-tesmplate.sh",
|
|
72
|
+
"build:bun": "rm -rf ./cjs && bun build ./src/reporter.js ./src/bin/reportXml.js ./src/bin/startTest.js ./src/bin/uploadArtifacts.js --outdir ./cjs --target node && bun build/scripts/edit-js-files.js && bun build/scripts/edit-package-json.js && chmod +x ./build/scripts/copy-tesmplate.sh && ./build/scripts/copy-tesmplate.sh",
|
|
73
|
+
"build:watch:bun": "rm -rf ./cjs && bun build ./src/bin/reportXml.js ./src/bin/startTest.js ./src/bin/uploadArtifacts.js --outdir ./cjs --target node --watch --onSuccess \"build/scripts/post-build.js\""
|
|
64
74
|
},
|
|
65
75
|
"devDependencies": {
|
|
66
|
-
"@
|
|
76
|
+
"@playwright/test": "^1.49.1",
|
|
67
77
|
"@redocly/cli": "^1.0.0-beta.125",
|
|
78
|
+
"@types/cross-spawn": "^6.0.6",
|
|
79
|
+
"@types/cucumber": "^7.0.0",
|
|
80
|
+
"@types/mocha": "^10.0.7",
|
|
68
81
|
"@wdio/reporter": "^7.16.13",
|
|
69
82
|
"chai": "^4.3.6",
|
|
70
|
-
"codeceptjs": "^3.5
|
|
83
|
+
"codeceptjs": "^3.6.5",
|
|
71
84
|
"cucumber": "^6.0.7",
|
|
72
|
-
"eslint": "^
|
|
73
|
-
"eslint-config-airbnb-base": "^15.0.0",
|
|
85
|
+
"eslint": "^9.24.0",
|
|
74
86
|
"eslint-config-prettier": "^8.3.0",
|
|
75
87
|
"eslint-plugin-import": "^2.25.4",
|
|
76
|
-
"jasmine": "^
|
|
88
|
+
"jasmine": "^5.2.0",
|
|
77
89
|
"jest": "^27.4.7",
|
|
78
90
|
"jsdom": "^22.1.0",
|
|
79
|
-
"mocha": "^
|
|
91
|
+
"mocha": "^9.2.0",
|
|
80
92
|
"mock-http-server": "^1.4.5",
|
|
81
93
|
"pino": "^8.15.0",
|
|
82
94
|
"prettier": "^3.2.5",
|
|
83
|
-
"puppeteer": "^22.15.0"
|
|
95
|
+
"puppeteer": "^22.15.0",
|
|
96
|
+
"typescript": "^5.5.4",
|
|
97
|
+
"vitest": "^1.6.0"
|
|
84
98
|
},
|
|
85
99
|
"bin": {
|
|
86
100
|
"@testomatio/reporter": "./lib/bin/cli.js",
|
|
87
101
|
"report-xml": "./lib/bin/reportXml.js",
|
|
88
102
|
"start-test-run": "./lib/bin/startTest.js",
|
|
89
103
|
"upload-artifacts": "./lib/bin/uploadArtifacts.js"
|
|
104
|
+
},
|
|
105
|
+
"exports": {
|
|
106
|
+
".": {
|
|
107
|
+
"import": "./src/reporter.js",
|
|
108
|
+
"require": "./lib/reporter.js",
|
|
109
|
+
"types": "./types/types.d.ts"
|
|
110
|
+
},
|
|
111
|
+
"./lib/adapter/codecept/codecept.js": "./lib/adapter/codecept.js",
|
|
112
|
+
"./lib/adapter/codecept": "./lib/adapter/codecept.js",
|
|
113
|
+
"./codecept": "./lib/adapter/codecept.js",
|
|
114
|
+
"./lib/adapter/cucumber/cucumber.js": "./lib/adapter/cucumber/current.js",
|
|
115
|
+
"./cucumber": "./lib/adapter/cucumber/current.js",
|
|
116
|
+
"./lib/adapter/cypress-plugin": "./lib/adapter/cypress-plugin/index.js",
|
|
117
|
+
"./cypress-plugin": "./lib/adapter/cypress-plugin/index.js",
|
|
118
|
+
"./cypress": "./lib/adapter/cypress-plugin/index.js",
|
|
119
|
+
"./lib/adapter/jasmine.js": "./lib/adapter/jasmine.js",
|
|
120
|
+
"./jasmine": "./lib/adapter/jasmine.js",
|
|
121
|
+
"./lib/adapter/jest.js": "./lib/adapter/jest.js",
|
|
122
|
+
"./jest": "./lib/adapter/jest.js",
|
|
123
|
+
"./lib/adapter/mocha/mocha.js": "./lib/adapter/mocha.js",
|
|
124
|
+
"./mocha": "./lib/adapter/mocha.js",
|
|
125
|
+
"./lib/adapter/playwright.js": "./lib/adapter/playwright.js",
|
|
126
|
+
"./nightwatch": "./lib/adapter/nightwatch.js",
|
|
127
|
+
"./playwright": "./lib/adapter/playwright.js",
|
|
128
|
+
"./vitest": "./lib/adapter/vitest.js",
|
|
129
|
+
"./lib/adapter/webdriver.js": "./lib/adapter/webdriver.js",
|
|
130
|
+
"./lib/adapter/webdriver": "./lib/adapter/webdriver.js",
|
|
131
|
+
"./webdriver": "./lib/adapter/webdriver.js",
|
|
132
|
+
"./wdio": "./lib/adapter/webdriver.js"
|
|
90
133
|
}
|
|
91
134
|
}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import createDebugMessages from 'debug';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import TestomatClient from '../client.js';
|
|
4
|
+
import { STATUS, APP_PREFIX, TESTOMAT_TMP_STORAGE_DIR } from '../constants.js';
|
|
5
|
+
import { getTestomatIdFromTestTitle, fileSystem } from '../utils/utils.js';
|
|
6
|
+
import { services } from '../services/index.js';
|
|
7
|
+
import codeceptjs from 'codeceptjs';
|
|
8
|
+
|
|
9
|
+
const debug = createDebugMessages('@testomatio/reporter:adapter:codeceptjs');
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
if (!global.codeceptjs) {
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
global.codeceptjs = codeceptjs;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
const { event, recorder, codecept } = global.codeceptjs;
|
|
18
|
+
|
|
19
|
+
let currentMetaStep = [];
|
|
20
|
+
let error;
|
|
21
|
+
let stepShift = 0;
|
|
22
|
+
|
|
23
|
+
// const output = new Output({
|
|
24
|
+
// filterFn: stack => !stack.includes('codeceptjs/lib/output'), // output from codeceptjs
|
|
25
|
+
// });
|
|
26
|
+
|
|
27
|
+
let stepStart = new Date();
|
|
28
|
+
|
|
29
|
+
const MAJOR_VERSION = parseInt(codecept.version().match(/\d/)[0], 10);
|
|
30
|
+
|
|
31
|
+
const DATA_REGEXP = /[|\s]+?(\{".*\}|\[.*\])/;
|
|
32
|
+
|
|
33
|
+
if (MAJOR_VERSION < 3) {
|
|
34
|
+
console.log('🔴 This reporter works with CodeceptJS 3+, please update your tests');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function CodeceptReporter(config) {
|
|
38
|
+
let failedTests = [];
|
|
39
|
+
let videos = [];
|
|
40
|
+
let traces = [];
|
|
41
|
+
const reportTestPromises = [];
|
|
42
|
+
|
|
43
|
+
const testTimeMap = {};
|
|
44
|
+
const { apiKey } = config;
|
|
45
|
+
|
|
46
|
+
const getDuration = test => {
|
|
47
|
+
if (!test.uid) return 0;
|
|
48
|
+
if (testTimeMap[test.uid]) {
|
|
49
|
+
return Date.now() - testTimeMap[test.uid];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return 0;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const client = new TestomatClient({ apiKey });
|
|
56
|
+
|
|
57
|
+
recorder.startUnlessRunning();
|
|
58
|
+
|
|
59
|
+
// Listening to events
|
|
60
|
+
event.dispatcher.on(event.all.before, () => {
|
|
61
|
+
// clear tmp dir
|
|
62
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
63
|
+
|
|
64
|
+
// recorder.add('Creating new run', () => );
|
|
65
|
+
client.createRun();
|
|
66
|
+
videos = [];
|
|
67
|
+
traces = [];
|
|
68
|
+
|
|
69
|
+
if (!global.testomatioDataStore) global.testomatioDataStore = {};
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
let hookSteps = [];
|
|
73
|
+
let suiteHookRunning = false;
|
|
74
|
+
|
|
75
|
+
event.dispatcher.on(event.suite.before, suite => {
|
|
76
|
+
suiteHookRunning = true;
|
|
77
|
+
hookSteps = [];
|
|
78
|
+
global.testomatioDataStore.steps = [];
|
|
79
|
+
|
|
80
|
+
services.setContext(suite.fullTitle());
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
event.dispatcher.on(event.suite.after, () => {
|
|
84
|
+
services.setContext(null);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
event.dispatcher.on(event.hook.started, () => {
|
|
88
|
+
// global.testomatioDataStore.steps = [];
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
event.dispatcher.on(event.hook.passed, () => {
|
|
92
|
+
if (suiteHookRunning) {
|
|
93
|
+
hookSteps.push(...global.testomatioDataStore.steps);
|
|
94
|
+
services.setContext(null);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
event.dispatcher.on(event.hook.failed, () => {
|
|
99
|
+
if (suiteHookRunning) {
|
|
100
|
+
hookSteps.push(...global.testomatioDataStore.steps);
|
|
101
|
+
services.setContext(null);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
event.dispatcher.on(event.test.before, test => {
|
|
106
|
+
suiteHookRunning = false;
|
|
107
|
+
global.testomatioDataStore.steps = [];
|
|
108
|
+
|
|
109
|
+
recorder.add(() => {
|
|
110
|
+
currentMetaStep = [];
|
|
111
|
+
// output.reset();
|
|
112
|
+
// output.start();
|
|
113
|
+
stepShift = 0;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
if (!global.testomatioDataStore) global.testomatioDataStore = {};
|
|
117
|
+
// reset steps
|
|
118
|
+
global.testomatioDataStore.steps = [];
|
|
119
|
+
|
|
120
|
+
services.setContext(test.fullTitle());
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
event.dispatcher.on(event.test.started, test => {
|
|
124
|
+
services.setContext(test.fullTitle());
|
|
125
|
+
|
|
126
|
+
testTimeMap[test.id] = Date.now();
|
|
127
|
+
if (!test.uid) return;
|
|
128
|
+
testTimeMap[test.uid] = Date.now();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
event.dispatcher.on(event.all.result, async () => {
|
|
132
|
+
debug('waiting for all tests to be reported');
|
|
133
|
+
// all tests were reported and we can upload videos
|
|
134
|
+
await Promise.all(reportTestPromises);
|
|
135
|
+
|
|
136
|
+
await uploadAttachments(client, videos, '🎞️ Uploading', 'video');
|
|
137
|
+
await uploadAttachments(client, traces, '📁 Uploading', 'trace');
|
|
138
|
+
|
|
139
|
+
const status = failedTests.length === 0 ? STATUS.PASSED : STATUS.FAILED;
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
client.updateRunStatus(status);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
event.dispatcher.on(event.test.passed, test => {
|
|
145
|
+
const { uid, tags, title } = test;
|
|
146
|
+
if (uid && failedTests.includes(uid)) {
|
|
147
|
+
failedTests = failedTests.filter(failed => uid !== failed);
|
|
148
|
+
}
|
|
149
|
+
const testObj = getTestAndMessage(title);
|
|
150
|
+
|
|
151
|
+
const logs = getTestLogs(test);
|
|
152
|
+
const manuallyAttachedArtifacts = services.artifacts.get(test.fullTitle());
|
|
153
|
+
const keyValues = services.keyValues.get(test.fullTitle());
|
|
154
|
+
services.setContext(null);
|
|
155
|
+
|
|
156
|
+
client.addTestRun(STATUS.PASSED, {
|
|
157
|
+
...stripExampleFromTitle(title),
|
|
158
|
+
rid: uid,
|
|
159
|
+
suite_title: test.parent && test.parent.title,
|
|
160
|
+
message: testObj.message,
|
|
161
|
+
time: getDuration(test),
|
|
162
|
+
steps: global.testomatioDataStore.steps.join('\n') || null,
|
|
163
|
+
test_id: getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`),
|
|
164
|
+
logs,
|
|
165
|
+
manuallyAttachedArtifacts,
|
|
166
|
+
meta: keyValues,
|
|
167
|
+
});
|
|
168
|
+
// output.stop();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
event.dispatcher.on(event.test.failed, (test, err) => {
|
|
172
|
+
error = err;
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
event.dispatcher.on(event.hook.failed, (suite, err) => {
|
|
176
|
+
error = err;
|
|
177
|
+
|
|
178
|
+
if (!suite) return;
|
|
179
|
+
if (!suite.tests) return;
|
|
180
|
+
for (const test of suite.tests) {
|
|
181
|
+
const { uid, tags, title } = test;
|
|
182
|
+
failedTests.push(uid || title);
|
|
183
|
+
const testId = getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`);
|
|
184
|
+
|
|
185
|
+
client.addTestRun(STATUS.FAILED, {
|
|
186
|
+
rid: uid,
|
|
187
|
+
...stripExampleFromTitle(title),
|
|
188
|
+
suite_title: suite.title,
|
|
189
|
+
test_id: testId,
|
|
190
|
+
error,
|
|
191
|
+
time: 0,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
// output.stop();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
event.dispatcher.on(event.test.after, test => {
|
|
198
|
+
if (test.state && test.state !== STATUS.FAILED) return;
|
|
199
|
+
if (test.err) error = test.err;
|
|
200
|
+
const { uid, tags, title, artifacts } = test;
|
|
201
|
+
failedTests.push(uid || title);
|
|
202
|
+
const testObj = getTestAndMessage(title);
|
|
203
|
+
|
|
204
|
+
const files = [];
|
|
205
|
+
if (artifacts.screenshot) files.push({ path: artifacts.screenshot, type: 'image/png' });
|
|
206
|
+
// todo: video must be uploaded later....
|
|
207
|
+
|
|
208
|
+
const logs = getTestLogs(test);
|
|
209
|
+
const manuallyAttachedArtifacts = services.artifacts.get(test.fullTitle());
|
|
210
|
+
const keyValues = services.keyValues.get(test.fullTitle());
|
|
211
|
+
services.setContext(null);
|
|
212
|
+
|
|
213
|
+
client.addTestRun(STATUS.FAILED, {
|
|
214
|
+
...stripExampleFromTitle(title),
|
|
215
|
+
rid: uid,
|
|
216
|
+
test_id: getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`),
|
|
217
|
+
suite_title: test.parent && test.parent.title,
|
|
218
|
+
error,
|
|
219
|
+
message: testObj.message,
|
|
220
|
+
time: getDuration(test),
|
|
221
|
+
files,
|
|
222
|
+
steps: global.testomatioDataStore?.steps?.join('\n') || null,
|
|
223
|
+
logs,
|
|
224
|
+
manuallyAttachedArtifacts,
|
|
225
|
+
meta: keyValues,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
debug('artifacts', artifacts);
|
|
229
|
+
|
|
230
|
+
for (const aid in artifacts) {
|
|
231
|
+
if (aid.startsWith('video')) videos.push({ rid: uid, title, path: artifacts[aid], type: 'video/webm' });
|
|
232
|
+
if (aid.startsWith('trace')) traces.push({ rid: uid, title, path: artifacts[aid], type: 'application/zip' });
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// output.stop();
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
event.dispatcher.on(event.test.skipped, test => {
|
|
239
|
+
const { uid, tags, title } = test;
|
|
240
|
+
if (failedTests.includes(uid || title)) return;
|
|
241
|
+
|
|
242
|
+
const testObj = getTestAndMessage(title);
|
|
243
|
+
client.addTestRun(STATUS.SKIPPED, {
|
|
244
|
+
rid: uid,
|
|
245
|
+
...stripExampleFromTitle(title),
|
|
246
|
+
test_id: getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`),
|
|
247
|
+
suite_title: test.parent && test.parent.title,
|
|
248
|
+
message: testObj.message,
|
|
249
|
+
time: getDuration(test),
|
|
250
|
+
});
|
|
251
|
+
// output.stop();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
event.dispatcher.on(event.step.started, step => {
|
|
255
|
+
stepShift = 0;
|
|
256
|
+
step.started = true;
|
|
257
|
+
stepStart = new Date();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
event.dispatcher.on(event.step.finished, step => {
|
|
261
|
+
if (!step.started) return;
|
|
262
|
+
let processingStep = step;
|
|
263
|
+
const metaSteps = [];
|
|
264
|
+
while (processingStep.metaStep) {
|
|
265
|
+
metaSteps.unshift(processingStep.metaStep);
|
|
266
|
+
processingStep = processingStep.metaStep;
|
|
267
|
+
}
|
|
268
|
+
const shift = metaSteps.length;
|
|
269
|
+
|
|
270
|
+
for (let i = 0; i < Math.max(currentMetaStep.length, metaSteps.length); i++) {
|
|
271
|
+
if (currentMetaStep[i] !== metaSteps[i]) {
|
|
272
|
+
stepShift = 2 * i;
|
|
273
|
+
if (!metaSteps[i]) continue;
|
|
274
|
+
if (metaSteps[i].isBDD()) {
|
|
275
|
+
// output.push(repeat(stepShift) + pc.bold(metaSteps[i].toString()) + metaSteps[i].comment);
|
|
276
|
+
global.testomatioDataStore?.steps?.push(
|
|
277
|
+
repeat(stepShift) + pc.bold(metaSteps[i].toString()) + metaSteps[i].comment,
|
|
278
|
+
);
|
|
279
|
+
} else {
|
|
280
|
+
// output.push(repeat(stepShift) + pc.green.bold(metaSteps[i].toString()));
|
|
281
|
+
global.testomatioDataStore?.steps?.push(repeat(stepShift) + pc.green(pc.bold(metaSteps[i].toString())));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
currentMetaStep = metaSteps;
|
|
286
|
+
stepShift = 2 * shift;
|
|
287
|
+
|
|
288
|
+
const durationMs = +new Date() - +stepStart;
|
|
289
|
+
let duration = '';
|
|
290
|
+
if (durationMs) {
|
|
291
|
+
duration = repeat(1) + pc.gray(`(${durationMs}ms)`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (step.status === STATUS.FAILED) {
|
|
295
|
+
// output.push(repeat(stepShift) + pc.red(step.toString()) + duration);
|
|
296
|
+
global.testomatioDataStore?.steps?.push(repeat(stepShift) + pc.red(step.toString()) + duration);
|
|
297
|
+
} else {
|
|
298
|
+
// output.push(repeat(stepShift) + step.toString() + duration);
|
|
299
|
+
global.testomatioDataStore?.steps?.push(repeat(stepShift) + step.toString() + duration);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
event.dispatcher.on(event.step.comment, step => {
|
|
304
|
+
// output.push(pc.cyan.bold(step.toString()));
|
|
305
|
+
global.testomatioDataStore?.steps?.push(pc.cyan(pc.bold(step.toString())));
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async function uploadAttachments(client, attachments, messagePrefix, attachmentType) {
|
|
310
|
+
if (!attachments?.length) return;
|
|
311
|
+
|
|
312
|
+
if (client.uploader.isEnabled) {
|
|
313
|
+
console.log(APP_PREFIX, `Attachments: ${messagePrefix} ${attachments.length} ${attachmentType} ...`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const promises = attachments.map(async attachment => {
|
|
317
|
+
const { rid, title, path, type } = attachment;
|
|
318
|
+
const file = { path, type, title };
|
|
319
|
+
|
|
320
|
+
// we are storing file if upload is disabled
|
|
321
|
+
if (!client.uploader.isEnabled) return client.uploader.storeUploadedFile(path, client.runId, rid, false);
|
|
322
|
+
|
|
323
|
+
return client.addTestRun(undefined, {
|
|
324
|
+
...stripExampleFromTitle(title),
|
|
325
|
+
rid,
|
|
326
|
+
files: [file],
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
await Promise.all(promises);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function getTestAndMessage(title) {
|
|
334
|
+
const testObj = { message: '' };
|
|
335
|
+
const testArr = title.split(/\s(\|\s\{.*?\})/);
|
|
336
|
+
testObj.title = testArr[0];
|
|
337
|
+
|
|
338
|
+
return testObj;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function stripExampleFromTitle(title) {
|
|
342
|
+
const res = title.match(DATA_REGEXP);
|
|
343
|
+
if (!res) return { title, example: null };
|
|
344
|
+
|
|
345
|
+
const example = JSON.parse(res[1]);
|
|
346
|
+
title = title.replace(DATA_REGEXP, '').trim();
|
|
347
|
+
|
|
348
|
+
return { title, example };
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function repeat(num) {
|
|
352
|
+
return ''.padStart(num, ' ');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// TODO: think about moving to some common utils
|
|
356
|
+
function getTestLogs(test) {
|
|
357
|
+
const suiteLogsArr = services.logger.getLogs(test.parent.fullTitle());
|
|
358
|
+
const suiteLogs = suiteLogsArr ? suiteLogsArr.join('\n').trim() : '';
|
|
359
|
+
const testLogsArr = services.logger.getLogs(test.fullTitle());
|
|
360
|
+
const testLogs = testLogsArr ? testLogsArr.join('\n').trim() : '';
|
|
361
|
+
|
|
362
|
+
let logs = '';
|
|
363
|
+
if (suiteLogs) {
|
|
364
|
+
logs += `${pc.bold('\t--- BeforeSuite ---')}\n${suiteLogs}`;
|
|
365
|
+
}
|
|
366
|
+
if (testLogs) {
|
|
367
|
+
logs += `\n${pc.bold('\t--- Test ---')}\n${testLogs}`;
|
|
368
|
+
}
|
|
369
|
+
return logs;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export { CodeceptReporter };
|
|
373
|
+
export default CodeceptReporter;
|