@testomatio/reporter 1.3.5-beta → 1.4.1-beta-1
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 +4 -4
- package/lib/adapter/codecept.js +11 -9
- package/lib/adapter/cucumber/current.js +4 -4
- package/lib/adapter/cucumber/legacy.js +3 -3
- package/lib/adapter/cypress-plugin/index.js +1 -1
- package/lib/adapter/jasmine.js +1 -1
- package/lib/adapter/jest.js +12 -17
- package/lib/adapter/mocha.js +22 -50
- package/lib/adapter/playwright.js +34 -22
- package/lib/adapter/webdriver.js +1 -1
- package/lib/bin/reportXml.js +1 -0
- package/lib/bin/startTest.js +25 -4
- package/lib/client.js +93 -27
- package/lib/constants.js +4 -6
- package/lib/fileUploader.js +106 -38
- package/lib/junit-adapter/java.js +27 -9
- package/lib/pipe/csv.js +4 -1
- package/lib/pipe/github.js +5 -16
- package/lib/pipe/gitlab.js +5 -16
- package/lib/pipe/testomatio.js +136 -34
- package/lib/reporter-functions.js +43 -0
- package/lib/reporter.js +11 -5
- package/lib/storages/artifact-storage.js +70 -0
- package/lib/storages/data-storage.js +307 -0
- package/lib/storages/key-value-storage.js +58 -0
- package/lib/{logger.js → storages/logger.js} +103 -114
- package/lib/utils/pipe_utils.js +135 -0
- package/lib/{util.js → utils/utils.js} +129 -12
- package/lib/xmlReader.js +132 -44
- package/package.json +9 -7
- package/lib/_ArtifactStorageOld.js +0 -142
- package/lib/artifactStorage.js +0 -25
- package/lib/dataStorage.js +0 -244
package/README.md
CHANGED
|
@@ -11,12 +11,12 @@ Testomat.io Reporter (this npm package) supports:
|
|
|
11
11
|
|
|
12
12
|
* 🏄 Integarion with all popular [JavaScript/TypeScript frameworks](./docs/frameworks.md)
|
|
13
13
|
* 🗄️ Screenshots, videos, traces [uploaded into S3 bucket](./docs/artifacts.md)
|
|
14
|
-
* 🔎 Stack traces and error messages
|
|
15
|
-
* 🐙 [GitHub](./docs/pipes/github.
|
|
14
|
+
* 🔎 [Stack traces](./docs/stacktrace.md) and error messages
|
|
15
|
+
* 🐙 [GitHub](./docs/pipes/github.md) & [GitLab](./docs/pipes/gitlab.md) integration
|
|
16
16
|
* 🚅 Realtime reports
|
|
17
17
|
* 🗃️ Other test frameworks supported via [JUNit XML](./docs/junit.md)
|
|
18
18
|
* 🚶♀️ Steps *(work in progress)*
|
|
19
|
-
* 📄 Logger *(work in progress, supports Jest for now)*
|
|
19
|
+
* 📄 [Logger](./docs/logger.md) *(work in progress, supports Jest for now)*
|
|
20
20
|
* ☁️ Custom properties and metadata *(work in progress)*
|
|
21
21
|
* 💯 Free & open-source.
|
|
22
22
|
* 📊 Public and private Run reports on cloud via [Testomat.io App](https://testomat.io) 👇
|
|
@@ -128,7 +128,7 @@ Bring this reporter on CI and never lose test results again!
|
|
|
128
128
|
* 📓 [JUnit](./docs/junit.md)
|
|
129
129
|
* 🗄️ [Artifacts](./docs/artifacts.md)
|
|
130
130
|
* 🔂 [Workflows](./docs/workflows.md)
|
|
131
|
-
*
|
|
131
|
+
* 🖊️ [Logger](./docs/logger.md)
|
|
132
132
|
|
|
133
133
|
## Development
|
|
134
134
|
|
package/lib/adapter/codecept.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const debug = require('debug')('@testomatio/reporter:adapter:codeceptjs');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const TestomatClient = require('../client');
|
|
4
|
-
const { STATUS, APP_PREFIX,
|
|
4
|
+
const { STATUS, APP_PREFIX, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
|
|
5
5
|
const upload = require('../fileUploader');
|
|
6
|
-
const { parseTest: getIdFromTestTitle, fileSystem } = require('../
|
|
6
|
+
const { parseTest: getIdFromTestTitle, fileSystem } = require('../utils/utils');
|
|
7
7
|
|
|
8
8
|
if (!global.codeceptjs) {
|
|
9
9
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
@@ -56,7 +56,7 @@ function CodeceptReporter(config) {
|
|
|
56
56
|
// Listening to events
|
|
57
57
|
event.dispatcher.on(event.all.before, () => {
|
|
58
58
|
// clear tmp dir
|
|
59
|
-
fileSystem.clearDir(
|
|
59
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
60
60
|
|
|
61
61
|
recorder.add('Creating new run', () => client.createRun());
|
|
62
62
|
videos = [];
|
|
@@ -73,6 +73,8 @@ function CodeceptReporter(config) {
|
|
|
73
73
|
stepShift = 0;
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
if (!global.testomatioDataStore) global.testomatioDataStore = {};
|
|
77
|
+
// reset steps
|
|
76
78
|
global.testomatioDataStore.steps = [];
|
|
77
79
|
});
|
|
78
80
|
|
|
@@ -162,7 +164,7 @@ function CodeceptReporter(config) {
|
|
|
162
164
|
message: testObj.message,
|
|
163
165
|
time: getDuration(test),
|
|
164
166
|
files,
|
|
165
|
-
steps: global.testomatioDataStore
|
|
167
|
+
steps: global.testomatioDataStore?.steps?.join('\n') || null,
|
|
166
168
|
})
|
|
167
169
|
.then(pipes => {
|
|
168
170
|
testId = pipes.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
|
|
@@ -219,12 +221,12 @@ function CodeceptReporter(config) {
|
|
|
219
221
|
if (!metaSteps[i]) continue;
|
|
220
222
|
if (metaSteps[i].isBDD()) {
|
|
221
223
|
// output.push(repeat(stepShift) + chalk.bold(metaSteps[i].toString()) + metaSteps[i].comment);
|
|
222
|
-
global.testomatioDataStore
|
|
224
|
+
global.testomatioDataStore?.steps?.push(
|
|
223
225
|
repeat(stepShift) + chalk.bold(metaSteps[i].toString()) + metaSteps[i].comment,
|
|
224
226
|
);
|
|
225
227
|
} else {
|
|
226
228
|
// output.push(repeat(stepShift) + chalk.green.bold(metaSteps[i].toString()));
|
|
227
|
-
global.testomatioDataStore
|
|
229
|
+
global.testomatioDataStore?.steps?.push(repeat(stepShift) + chalk.green.bold(metaSteps[i].toString()));
|
|
228
230
|
}
|
|
229
231
|
}
|
|
230
232
|
}
|
|
@@ -239,16 +241,16 @@ function CodeceptReporter(config) {
|
|
|
239
241
|
|
|
240
242
|
if (step.status === STATUS.FAILED) {
|
|
241
243
|
// output.push(repeat(stepShift) + chalk.red(step.toString()) + duration);
|
|
242
|
-
global.testomatioDataStore
|
|
244
|
+
global.testomatioDataStore?.steps?.push(repeat(stepShift) + chalk.red(step.toString()) + duration);
|
|
243
245
|
} else {
|
|
244
246
|
// output.push(repeat(stepShift) + step.toString() + duration);
|
|
245
|
-
global.testomatioDataStore
|
|
247
|
+
global.testomatioDataStore?.steps?.push(repeat(stepShift) + step.toString() + duration);
|
|
246
248
|
}
|
|
247
249
|
});
|
|
248
250
|
|
|
249
251
|
event.dispatcher.on(event.step.comment, step => {
|
|
250
252
|
// output.push(chalk.cyan.bold(step.toString()));
|
|
251
|
-
global.testomatioDataStore
|
|
253
|
+
global.testomatioDataStore?.steps?.push(chalk.cyan.bold(step.toString()));
|
|
252
254
|
});
|
|
253
255
|
}
|
|
254
256
|
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
const { Formatter, formatterHelpers } = require('@cucumber/cucumber');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const fs = require('fs');
|
|
5
|
-
const { STATUS,
|
|
5
|
+
const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../../constants');
|
|
6
6
|
const TestomatClient = require('../../client');
|
|
7
|
-
const logger = require('../../logger');
|
|
8
|
-
const { parseTest, fileSystem } = require('../../
|
|
7
|
+
const logger = require('../../storages/logger');
|
|
8
|
+
const { parseTest, fileSystem } = require('../../utils/utils');
|
|
9
9
|
|
|
10
10
|
const { GherkinDocumentParser, PickleParser } = formatterHelpers;
|
|
11
11
|
const { getGherkinScenarioLocationMap, getGherkinStepMap } = GherkinDocumentParser;
|
|
@@ -37,7 +37,7 @@ class CucumberReporter extends Formatter {
|
|
|
37
37
|
|
|
38
38
|
parseEnvelope(envelope) {
|
|
39
39
|
if (envelope.testRunStarted) {
|
|
40
|
-
fileSystem.clearDir(
|
|
40
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
41
41
|
}
|
|
42
42
|
if (envelope.testCaseStarted && this.client) {
|
|
43
43
|
this.client.createRun();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies, import/no-unresolved
|
|
2
2
|
const { Formatter } = require('cucumber');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
|
-
const { parseTest, fileSystem } = require('../../
|
|
5
|
-
const { STATUS,
|
|
4
|
+
const { parseTest, fileSystem } = require('../../utils/utils');
|
|
5
|
+
const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../../constants');
|
|
6
6
|
const TestomatClient = require('../../client');
|
|
7
7
|
|
|
8
8
|
const createTestomatFormatter = apiKey => {
|
|
@@ -97,7 +97,7 @@ const createTestomatFormatter = apiKey => {
|
|
|
97
97
|
|
|
98
98
|
options.eventBroadcaster.on('gherkin-document', addDocument);
|
|
99
99
|
options.eventBroadcaster.on('test-run-started', () => {
|
|
100
|
-
fileSystem.clearDir(
|
|
100
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
101
101
|
this?.client?.createRun();
|
|
102
102
|
});
|
|
103
103
|
options.eventBroadcaster.on('test-case-finished', this.onTestCaseFinished.bind(this));
|
package/lib/adapter/jasmine.js
CHANGED
package/lib/adapter/jest.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const TestomatClient = require('../client');
|
|
2
|
-
const { STATUS,
|
|
3
|
-
const { parseTest, ansiRegExp, fileSystem } = require('../
|
|
2
|
+
const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
|
|
3
|
+
const { parseTest, ansiRegExp, fileSystem } = require('../utils/utils');
|
|
4
4
|
|
|
5
5
|
class JestReporter {
|
|
6
6
|
constructor(globalConfig, options) {
|
|
@@ -11,20 +11,9 @@ class JestReporter {
|
|
|
11
11
|
this.client.createRun();
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
static getIdOfCurrentlyRunningTest() {
|
|
15
|
-
if (!process.env.JEST_WORKER_ID) return null;
|
|
16
|
-
try {
|
|
17
|
-
// @ts-expect-error "expect" could only be defined inside Jest environement (forbidden to import it outside)
|
|
18
|
-
// eslint-disable-next-line no-undef
|
|
19
|
-
if (expect && expect?.getState()?.currentTestName) return parseTest(expect?.getState()?.currentTestName);
|
|
20
|
-
} catch (e) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
14
|
onRunStart() {
|
|
26
15
|
// clear tmp dir
|
|
27
|
-
fileSystem.clearDir(
|
|
16
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
28
17
|
}
|
|
29
18
|
|
|
30
19
|
onTestResult(test, testResult) {
|
|
@@ -42,12 +31,21 @@ class JestReporter {
|
|
|
42
31
|
steps = failureMessages[0];
|
|
43
32
|
}
|
|
44
33
|
const testId = parseTest(title);
|
|
34
|
+
let suite_title;
|
|
35
|
+
// this is test without a suite
|
|
36
|
+
if (result.fullName === result.title) {
|
|
37
|
+
suite_title = testResult.testFilePath.split('/').pop();
|
|
38
|
+
} else {
|
|
39
|
+
suite_title = result.fullName.replace(result.title, '');
|
|
40
|
+
}
|
|
41
|
+
|
|
45
42
|
const deducedStatus = status === 'pending' ? 'skipped' : status;
|
|
46
43
|
// In jest if test is not matched with test name pattern it is considered as skipped.
|
|
47
44
|
// So adding a check if it is skipped for real or because of test pattern
|
|
48
45
|
if (!this._globalConfig.testNamePattern || deducedStatus !== 'skipped') {
|
|
49
46
|
this.client.addTestRun(deducedStatus, {
|
|
50
47
|
test_id: testId,
|
|
48
|
+
suite_title,
|
|
51
49
|
error,
|
|
52
50
|
steps,
|
|
53
51
|
title,
|
|
@@ -63,9 +61,6 @@ class JestReporter {
|
|
|
63
61
|
const { numFailedTests } = results;
|
|
64
62
|
const status = numFailedTests === 0 ? STATUS.PASSED : STATUS.FAILED;
|
|
65
63
|
this.client.updateRunStatus(status);
|
|
66
|
-
|
|
67
|
-
// clear tmp dir
|
|
68
|
-
fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
|
|
69
64
|
}
|
|
70
65
|
}
|
|
71
66
|
|
package/lib/adapter/mocha.js
CHANGED
|
@@ -1,58 +1,40 @@
|
|
|
1
1
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
2
2
|
const Mocha = require('mocha');
|
|
3
|
-
const debug = require('debug')('@testomatio/reporter:adapter:mocha');
|
|
4
3
|
const chalk = require('chalk');
|
|
5
4
|
const TestomatClient = require('../client');
|
|
6
|
-
const { STATUS } = require('../constants');
|
|
7
|
-
const { parseTest,
|
|
8
|
-
const ArtifactStorage = require('../_ArtifactStorageOld');
|
|
5
|
+
const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
|
|
6
|
+
const { parseTest, fileSystem } = require('../utils/utils');
|
|
9
7
|
|
|
10
|
-
const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } =
|
|
8
|
+
const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } =
|
|
9
|
+
Mocha.Runner.constants;
|
|
11
10
|
|
|
12
11
|
function MochaReporter(runner, opts) {
|
|
13
12
|
Mocha.reporters.Base.call(this, runner);
|
|
14
|
-
let passes = 0;
|
|
15
|
-
let
|
|
13
|
+
let passes = 0;
|
|
14
|
+
let failures = 0;
|
|
15
|
+
let skipped = 0;
|
|
16
|
+
// let artifactStore;
|
|
16
17
|
|
|
17
18
|
const apiKey = opts?.reporterOptions?.apiKey || process.env.TESTOMATIO;
|
|
18
19
|
|
|
19
|
-
if (!apiKey) {
|
|
20
|
-
debug('TESTOMATIO key is empty, ignoring reports');
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
20
|
const client = new TestomatClient({ apiKey });
|
|
24
21
|
|
|
25
22
|
runner.on(EVENT_RUN_BEGIN, () => {
|
|
26
23
|
client.createRun();
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
toFile: true
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
artifactStore = runner._workerReporter !== undefined
|
|
33
|
-
? new ArtifactStorage(params)
|
|
34
|
-
: new ArtifactStorage();
|
|
25
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
35
26
|
});
|
|
36
27
|
|
|
37
|
-
runner.on(EVENT_TEST_PASS, async
|
|
28
|
+
runner.on(EVENT_TEST_PASS, async test => {
|
|
38
29
|
passes += 1;
|
|
39
30
|
console.log(chalk.bold.green('✔'), test.fullTitle());
|
|
40
31
|
const testId = parseTest(test.title);
|
|
41
32
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
client.addTestRun(
|
|
48
|
-
STATUS.PASSED,
|
|
49
|
-
{
|
|
50
|
-
test_id: testId,
|
|
51
|
-
title: test.title,
|
|
52
|
-
time: test.duration,
|
|
53
|
-
},
|
|
54
|
-
content
|
|
55
|
-
);
|
|
33
|
+
client.addTestRun(STATUS.PASSED, {
|
|
34
|
+
test_id: testId,
|
|
35
|
+
title: test.title,
|
|
36
|
+
time: test.duration,
|
|
37
|
+
});
|
|
56
38
|
});
|
|
57
39
|
|
|
58
40
|
runner.on(EVENT_TEST_PENDING, test => {
|
|
@@ -66,33 +48,23 @@ function MochaReporter(runner, opts) {
|
|
|
66
48
|
});
|
|
67
49
|
});
|
|
68
50
|
|
|
69
|
-
runner.on(EVENT_TEST_FAIL, async(test, err) => {
|
|
51
|
+
runner.on(EVENT_TEST_FAIL, async (test, err) => {
|
|
70
52
|
failures += 1;
|
|
71
53
|
console.log(chalk.bold.red('✖'), test.fullTitle(), chalk.gray(err.message));
|
|
72
54
|
const testId = parseTest(test.title);
|
|
73
55
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
STATUS.FAILED, {
|
|
81
|
-
error: err,
|
|
82
|
-
test_id: testId,
|
|
83
|
-
title: test.title,
|
|
84
|
-
time: test.duration,
|
|
85
|
-
},
|
|
86
|
-
content
|
|
87
|
-
);
|
|
56
|
+
client.addTestRun(STATUS.FAILED, {
|
|
57
|
+
error: err,
|
|
58
|
+
test_id: testId,
|
|
59
|
+
title: test.title,
|
|
60
|
+
time: test.duration,
|
|
61
|
+
});
|
|
88
62
|
});
|
|
89
63
|
|
|
90
64
|
runner.on(EVENT_RUN_END, () => {
|
|
91
65
|
const status = failures === 0 ? STATUS.PASSED : STATUS.FAILED;
|
|
92
66
|
console.log(chalk.bold(status), `${passes} passed, ${failures} failed, ${skipped} skipped`);
|
|
93
67
|
client.updateRunStatus(status);
|
|
94
|
-
|
|
95
|
-
artifactStore.cleanup();
|
|
96
68
|
});
|
|
97
69
|
}
|
|
98
70
|
|
|
@@ -3,10 +3,10 @@ const crypto = require('crypto');
|
|
|
3
3
|
const os = require('os');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
|
-
const { APP_PREFIX, STATUS: Status,
|
|
6
|
+
const { APP_PREFIX, STATUS: Status, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
|
|
7
7
|
const TestomatioClient = require('../client');
|
|
8
8
|
const { isArtifactsEnabled } = require('../fileUploader');
|
|
9
|
-
const { parseTest, fileSystem } = require('../
|
|
9
|
+
const { parseTest, fileSystem } = require('../utils/utils');
|
|
10
10
|
|
|
11
11
|
const reportTestPromises = [];
|
|
12
12
|
|
|
@@ -19,15 +19,17 @@ class PlaywrightReporter {
|
|
|
19
19
|
|
|
20
20
|
onBegin(_config, suite) {
|
|
21
21
|
// clean data storage
|
|
22
|
-
fileSystem.clearDir(
|
|
22
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
23
23
|
if (!this.client) return;
|
|
24
24
|
this.suite = suite;
|
|
25
25
|
this.client.createRun();
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
/*
|
|
29
|
+
onTestBegin(test) {
|
|
30
|
+
// does not work; value is not to the storage context
|
|
31
|
+
global.testTitle = test.title;
|
|
32
|
+
} */
|
|
31
33
|
|
|
32
34
|
onTestEnd(test, result) {
|
|
33
35
|
if (!this.client) return;
|
|
@@ -44,23 +46,33 @@ class PlaywrightReporter {
|
|
|
44
46
|
appendStep(step, steps);
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
let logs = '';
|
|
50
|
+
if (result.stderr.length || result.stdout.length) {
|
|
51
|
+
logs = `\n\n${chalk.bold('Logs:')}\n${chalk.red(result.stderr.join(''))}\n${result.stdout.join('')}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const reportTestPromise = this.client
|
|
55
|
+
.addTestRun(checkStatus(result.status), {
|
|
56
|
+
error,
|
|
57
|
+
test_id: testId,
|
|
58
|
+
suite_title,
|
|
59
|
+
title,
|
|
60
|
+
steps: steps.join('\n'),
|
|
61
|
+
time: duration,
|
|
62
|
+
stack: logs,
|
|
63
|
+
})
|
|
64
|
+
.then(pipes => {
|
|
65
|
+
testId = pipes?.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
|
|
66
|
+
|
|
67
|
+
this.uploads.push({
|
|
68
|
+
testId,
|
|
69
|
+
title,
|
|
70
|
+
suite_title,
|
|
71
|
+
files: result.attachments.filter(a => a.body || a.path),
|
|
72
|
+
});
|
|
73
|
+
// remove empty uploads
|
|
74
|
+
this.uploads = this.uploads.filter(upload => upload.files.length);
|
|
62
75
|
});
|
|
63
|
-
});
|
|
64
76
|
|
|
65
77
|
reportTestPromises.push(reportTestPromise);
|
|
66
78
|
}
|
package/lib/adapter/webdriver.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
2
2
|
const WDIOReporter = require('@wdio/reporter').default;
|
|
3
3
|
const TestomatClient = require('../client');
|
|
4
|
-
const { parseTest } = require('../
|
|
4
|
+
const { parseTest } = require('../utils/utils');
|
|
5
5
|
|
|
6
6
|
class WebdriverReporter extends WDIOReporter {
|
|
7
7
|
constructor(options) {
|
package/lib/bin/reportXml.js
CHANGED
package/lib/bin/startTest.js
CHANGED
|
@@ -13,9 +13,11 @@ program
|
|
|
13
13
|
.option('--launch', 'Start a new run and return its ID')
|
|
14
14
|
.option('--finish', 'Finish Run by its ID')
|
|
15
15
|
.option("--env-file <envfile>", "Load environment variables from env file")
|
|
16
|
-
.
|
|
16
|
+
.option("--filter <filter>", "Additional execution filter")
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
const { launch, finish, filter } = opts;
|
|
19
|
+
let { command } = opts;
|
|
17
20
|
|
|
18
|
-
const { command, launch, finish } = opts;
|
|
19
21
|
if (opts.envFile) require('dotenv').config(opts.envFile); // eslint-disable-line
|
|
20
22
|
|
|
21
23
|
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || process.env.TESTOMATIO;
|
|
@@ -57,6 +59,27 @@ program
|
|
|
57
59
|
return;
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
const client = new TestomatClient({ apiKey, title, parallel: true });
|
|
63
|
+
|
|
64
|
+
if(filter) {
|
|
65
|
+
const [pipe, ...optsArray] = filter.split(":");
|
|
66
|
+
const pipeOptions = optsArray.join(":");
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const tests = await client.prepareRun({pipe, pipeOptions});
|
|
70
|
+
|
|
71
|
+
if(!tests || tests.length === 0) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const grep = ` --grep (${tests.join('|')})`;
|
|
76
|
+
command += grep;
|
|
77
|
+
}
|
|
78
|
+
catch(err) {
|
|
79
|
+
console.log(APP_PREFIX, err);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
60
83
|
const testCmds = command.split(' ');
|
|
61
84
|
console.log(APP_PREFIX, `🚀 Running`, chalk.green(command));
|
|
62
85
|
|
|
@@ -73,8 +96,6 @@ program
|
|
|
73
96
|
return;
|
|
74
97
|
}
|
|
75
98
|
|
|
76
|
-
const client = new TestomatClient({ apiKey, title, parallel: true });
|
|
77
|
-
|
|
78
99
|
client.createRun().then(() => {
|
|
79
100
|
const cmd = spawn(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
80
101
|
|