testcafe-reporter-qase 2.0.0-beta.1 → 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/README.md +32 -28
- package/changelog.md +31 -0
- package/dist/factory.d.ts +4 -4
- package/dist/factory.js +9 -5
- package/dist/qase.d.ts +66 -0
- package/dist/qase.js +98 -0
- package/dist/reporter.d.ts +19 -20
- package/dist/reporter.js +88 -27
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
>
|
|
3
|
-
> Publish results simple and easy.
|
|
1
|
+
# Qase TMS TestCafe reporter
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
Publish results simple and easy.
|
|
6
4
|
|
|
5
|
+
To install the latest version, run:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install -D testcafe-reporter-qase
|
|
7
9
|
```
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
## Updating from v1
|
|
12
|
+
|
|
13
|
+
To update a test project using testcafe-reporter-qaser@v1 to version 2:
|
|
14
|
+
|
|
15
|
+
1. Update reporter configuration in `qase.config.json` and/or environment variables —
|
|
16
|
+
see the [configuration reference](#configuration) below.
|
|
10
17
|
|
|
11
18
|
## Example of usage
|
|
12
19
|
|
|
@@ -22,7 +29,12 @@ test.meta('CID', [1])('Text typing basics', async (t) => {
|
|
|
22
29
|
await t;
|
|
23
30
|
});
|
|
24
31
|
|
|
25
|
-
|
|
32
|
+
const q = qase.id(1)
|
|
33
|
+
.title('Text typing basics')
|
|
34
|
+
.field({ 'severity': 'high' })
|
|
35
|
+
.parameters({ 'browser': 'chrome' })
|
|
36
|
+
.create();
|
|
37
|
+
test.meta({ ...q })(
|
|
26
38
|
'Click check boxes and then verify their state',
|
|
27
39
|
async (t) => {
|
|
28
40
|
await t;
|
|
@@ -60,36 +72,28 @@ https://app.qase.io/run/QASE_PROJECT_CODE
|
|
|
60
72
|
|
|
61
73
|
## Configuration
|
|
62
74
|
|
|
63
|
-
Qase reporter
|
|
64
|
-
using `.qaserc`/`qase.config.json` file and using ENV variables.
|
|
75
|
+
Qase Testcafe reporter can be configured in multiple ways:
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
- using a separate config file `qase.config.json`,
|
|
78
|
+
- using environment variables (they override the values from the configuration files).
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `environment` - To execute with the sending of the envinroment information
|
|
71
|
-
- *`testops.api.token` - Token for API access, you can find more information
|
|
72
|
-
[here](https://developers.qase.io/#authentication)
|
|
73
|
-
- *`testops.project` - Code of your project (can be extracted from main
|
|
74
|
-
page of your project: `https://app.qase.io/project/DEMOTR` -
|
|
75
|
-
`DEMOTR` is project code here)
|
|
76
|
-
- `testops.uploadAttachments` - Permission to send screenshots to Qase TMS
|
|
77
|
-
- `testops.run.id` - Pass Run ID
|
|
78
|
-
- `testops.run.title` - Set custom Run name, when new run is created
|
|
79
|
-
- `testops.run.description` - Set custom Run description, when new run is created
|
|
80
|
-
- `testops.run.complete` - Whether the run should be completed
|
|
80
|
+
For a full list of configuration options, see
|
|
81
|
+
the [Configuration reference](../qase-javascript-commons/README.md#configuration).
|
|
81
82
|
|
|
82
|
-
Example
|
|
83
|
+
Example `qase.config.json` file:
|
|
83
84
|
|
|
84
85
|
```json
|
|
85
86
|
{
|
|
87
|
+
"mode": "testops",
|
|
86
88
|
"debug": true,
|
|
87
|
-
"environment": 1,
|
|
88
89
|
"testops": {
|
|
89
90
|
"api": {
|
|
90
91
|
"token": "api_key"
|
|
91
92
|
},
|
|
92
|
-
"project": "project_code"
|
|
93
|
+
"project": "project_code",
|
|
94
|
+
"run": {
|
|
95
|
+
"complete": true
|
|
96
|
+
}
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
```
|
|
@@ -98,7 +102,7 @@ Supported ENV variables:
|
|
|
98
102
|
|
|
99
103
|
- `QASE_MODE` - Same as `mode`
|
|
100
104
|
- `QASE_DEBUG` - Same as `debug`
|
|
101
|
-
- `QASE_ENVIRONMENT` - Same as `environment`
|
|
105
|
+
- `QASE_ENVIRONMENT` - Same as `environment`
|
|
102
106
|
- `QASE_TESTOPS_API_TOKEN` - Same as `testops.api.token`
|
|
103
107
|
- `QASE_TESTOPS_PROJECT` - Same as `testops.project`
|
|
104
108
|
- `QASE_TESTOPS_RUN_ID` - Pass Run ID from ENV and override reporter option `testops.run.id`
|
|
@@ -107,7 +111,7 @@ Supported ENV variables:
|
|
|
107
111
|
|
|
108
112
|
## Requirements
|
|
109
113
|
|
|
110
|
-
We maintain the reporter on LTS versions of Node
|
|
114
|
+
We maintain the reporter on [LTS versions of Node](https://nodejs.org/en/about/releases/).
|
|
111
115
|
|
|
112
116
|
`testcafe >= 2.0.0`
|
|
113
117
|
|
package/changelog.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# qase-testcafe@2.0.0
|
|
2
|
+
|
|
3
|
+
## What's new
|
|
4
|
+
|
|
5
|
+
This is the first release in the 2.x series of the TestCafe reporter.
|
|
6
|
+
It brings a new annotation syntax with test parametrization and field values,
|
|
7
|
+
new and more flexible configs, uploading results in parallel with running tests,
|
|
8
|
+
and other powerful features.
|
|
9
|
+
|
|
10
|
+
This changelog entry will be updated soon.
|
|
11
|
+
For more information about the new features and a guide for migration from v1, refer to the
|
|
12
|
+
[reporter documentation](https://github.com/qase-tms/qase-javascript/tree/main/qase-testcafe#readme)
|
|
13
|
+
|
|
14
|
+
# qase-testcafe@2.0.0-beta.2
|
|
15
|
+
|
|
16
|
+
## What's new
|
|
17
|
+
|
|
18
|
+
Add new syntax to annotate the following fields: `QaseID`, `QaseTitle`, `QaseFields`, `QaseParameters`:
|
|
19
|
+
|
|
20
|
+
```diff
|
|
21
|
+
+ import { qase } from 'testcafe-reporter-qase/qase';
|
|
22
|
+
- test.meta('CID', '2')('Test name', async t => {...});
|
|
23
|
+
+ const q = qase.id(2).title('Test name').fields('field1', 'field2').parameters('param1', 'param2').create();
|
|
24
|
+
+ test.meta(q)('Test name', async t => {...});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
# qase-testcafe@2.0.0-beta.1
|
|
28
|
+
|
|
29
|
+
## What's new
|
|
30
|
+
|
|
31
|
+
First major beta release for the version 2 series of the Qase TestCafe reporter.
|
package/dist/factory.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { TestcafeQaseOptionsType,
|
|
1
|
+
import { TestcafeQaseOptionsType, TestRunInfoType } from './reporter';
|
|
2
2
|
/**
|
|
3
3
|
* @param {TestcafeQaseOptionsType} options
|
|
4
|
-
* @returns
|
|
4
|
+
* @returns
|
|
5
5
|
*/
|
|
6
6
|
export declare const factory: (options: TestcafeQaseOptionsType) => {
|
|
7
|
+
noColors: boolean;
|
|
7
8
|
reportTaskStart: () => void;
|
|
8
9
|
reportFixtureStart: () => void;
|
|
9
|
-
reportTestDone: (
|
|
10
|
+
reportTestDone: (name: string, testRunInfo: TestRunInfoType, meta: Record<string, string>) => Promise<void>;
|
|
10
11
|
reportTaskDone: () => Promise<void>;
|
|
11
|
-
reporter: TestcafeQaseReporter;
|
|
12
12
|
};
|
package/dist/factory.js
CHANGED
|
@@ -4,20 +4,24 @@ exports.factory = void 0;
|
|
|
4
4
|
const reporter_1 = require("./reporter");
|
|
5
5
|
/**
|
|
6
6
|
* @param {TestcafeQaseOptionsType} options
|
|
7
|
-
* @returns
|
|
7
|
+
* @returns
|
|
8
8
|
*/
|
|
9
9
|
const factory = (options) => {
|
|
10
10
|
const reporter = new reporter_1.TestcafeQaseReporter(options);
|
|
11
11
|
return {
|
|
12
|
+
noColors: false,
|
|
12
13
|
reportTaskStart: () => {
|
|
13
|
-
|
|
14
|
+
reporter.startTestRun();
|
|
14
15
|
},
|
|
15
16
|
reportFixtureStart: () => {
|
|
16
17
|
/* empty */
|
|
17
18
|
},
|
|
18
|
-
reportTestDone:
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
reportTestDone: async (name, testRunInfo, meta) => {
|
|
20
|
+
await reporter.reportTestDone(name, testRunInfo, meta);
|
|
21
|
+
},
|
|
22
|
+
reportTaskDone: async () => {
|
|
23
|
+
await reporter.reportTaskDone();
|
|
24
|
+
},
|
|
21
25
|
};
|
|
22
26
|
};
|
|
23
27
|
exports.factory = factory;
|
package/dist/qase.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export declare class qase {
|
|
2
|
+
private static _qaseID;
|
|
3
|
+
private static _qaseTitle;
|
|
4
|
+
private static _qaseFields;
|
|
5
|
+
private static _qaseParameters;
|
|
6
|
+
/**
|
|
7
|
+
* Set a Qase ID for the test case
|
|
8
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
9
|
+
* @param {number | number[]} value
|
|
10
|
+
* @example
|
|
11
|
+
* const q = qase.id(1).create();
|
|
12
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
13
|
+
* or
|
|
14
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
15
|
+
*/
|
|
16
|
+
static id: (value: number | number[]) => typeof qase;
|
|
17
|
+
/**
|
|
18
|
+
* Set a title for the test case
|
|
19
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
20
|
+
* @param {string} value
|
|
21
|
+
* @example
|
|
22
|
+
* const q = qase.title('Test case title').create();
|
|
23
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
24
|
+
* or
|
|
25
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
26
|
+
*/
|
|
27
|
+
static title: (value: string) => typeof qase;
|
|
28
|
+
/**
|
|
29
|
+
* Set a fields for the test case
|
|
30
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
31
|
+
* @param {Record<string, string>} values
|
|
32
|
+
* @example
|
|
33
|
+
* const q = qase.fields({ 'severity': 'high', 'priority': 'medium' }).create();
|
|
34
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
35
|
+
* or
|
|
36
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
37
|
+
*/
|
|
38
|
+
static fields: (values: Record<string, string>) => typeof qase;
|
|
39
|
+
/**
|
|
40
|
+
* Set a parameters for the test case
|
|
41
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
42
|
+
* @param {Record<string, string>} values
|
|
43
|
+
* @example
|
|
44
|
+
* const q = qase.parameters({ 'severity': 'high', 'priority': 'medium' }).create();
|
|
45
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
46
|
+
* or
|
|
47
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
48
|
+
*/
|
|
49
|
+
static parameters: (values: Record<string, string>) => typeof qase;
|
|
50
|
+
/**
|
|
51
|
+
* Create a Qase metadata
|
|
52
|
+
* Call this method after setting all the necessary parameters
|
|
53
|
+
* @example
|
|
54
|
+
* const q = qase.id(1).title('Test case title').fields({ 'severity': 'high', 'priority': 'medium' }).create();
|
|
55
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
56
|
+
* or
|
|
57
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
58
|
+
*/
|
|
59
|
+
static create: () => {
|
|
60
|
+
QaseID: string;
|
|
61
|
+
QaseTitle: string;
|
|
62
|
+
QaseFields: string;
|
|
63
|
+
QaseParameters: string;
|
|
64
|
+
};
|
|
65
|
+
private static toNormalizeRecord;
|
|
66
|
+
}
|
package/dist/qase.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.qase = void 0;
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
6
|
+
class qase {
|
|
7
|
+
}
|
|
8
|
+
exports.qase = qase;
|
|
9
|
+
_a = qase;
|
|
10
|
+
qase._qaseID = '';
|
|
11
|
+
qase._qaseTitle = '';
|
|
12
|
+
qase._qaseFields = '';
|
|
13
|
+
qase._qaseParameters = '';
|
|
14
|
+
/**
|
|
15
|
+
* Set a Qase ID for the test case
|
|
16
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
17
|
+
* @param {number | number[]} value
|
|
18
|
+
* @example
|
|
19
|
+
* const q = qase.id(1).create();
|
|
20
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
21
|
+
* or
|
|
22
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
23
|
+
*/
|
|
24
|
+
qase.id = (value) => {
|
|
25
|
+
_a._qaseID = Array.isArray(value) ? value.join(',') : String(value);
|
|
26
|
+
return _a;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Set a title for the test case
|
|
30
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
31
|
+
* @param {string} value
|
|
32
|
+
* @example
|
|
33
|
+
* const q = qase.title('Test case title').create();
|
|
34
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
35
|
+
* or
|
|
36
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
37
|
+
*/
|
|
38
|
+
qase.title = (value) => {
|
|
39
|
+
_a._qaseTitle = value;
|
|
40
|
+
return _a;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Set a fields for the test case
|
|
44
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
45
|
+
* @param {Record<string, string>} values
|
|
46
|
+
* @example
|
|
47
|
+
* const q = qase.fields({ 'severity': 'high', 'priority': 'medium' }).create();
|
|
48
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
49
|
+
* or
|
|
50
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
51
|
+
*/
|
|
52
|
+
qase.fields = (values) => {
|
|
53
|
+
_a._qaseFields = _a.toNormalizeRecord(values);
|
|
54
|
+
return _a;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Set a parameters for the test case
|
|
58
|
+
* Don't forget to call `create` method after setting all the necessary parameters
|
|
59
|
+
* @param {Record<string, string>} values
|
|
60
|
+
* @example
|
|
61
|
+
* const q = qase.parameters({ 'severity': 'high', 'priority': 'medium' }).create();
|
|
62
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
63
|
+
* or
|
|
64
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
65
|
+
*/
|
|
66
|
+
qase.parameters = (values) => {
|
|
67
|
+
_a._qaseParameters = _a.toNormalizeRecord(values);
|
|
68
|
+
return _a;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Create a Qase metadata
|
|
72
|
+
* Call this method after setting all the necessary parameters
|
|
73
|
+
* @example
|
|
74
|
+
* const q = qase.id(1).title('Test case title').fields({ 'severity': 'high', 'priority': 'medium' }).create();
|
|
75
|
+
* test.meta(q)('Test case title', async t => { ... });
|
|
76
|
+
* or
|
|
77
|
+
* test.meta({userField: 123, ...q})('Test case title', async t => { ... });
|
|
78
|
+
*/
|
|
79
|
+
qase.create = () => {
|
|
80
|
+
const meta = {
|
|
81
|
+
QaseID: _a._qaseID,
|
|
82
|
+
QaseTitle: _a._qaseTitle,
|
|
83
|
+
QaseFields: _a._qaseFields,
|
|
84
|
+
QaseParameters: _a._qaseParameters,
|
|
85
|
+
};
|
|
86
|
+
_a._qaseID = '';
|
|
87
|
+
_a._qaseTitle = '';
|
|
88
|
+
_a._qaseFields = '';
|
|
89
|
+
_a._qaseParameters = '';
|
|
90
|
+
return meta;
|
|
91
|
+
};
|
|
92
|
+
qase.toNormalizeRecord = (record) => {
|
|
93
|
+
const stringRecord = {};
|
|
94
|
+
for (const [key, value] of Object.entries(record)) {
|
|
95
|
+
stringRecord[String(key)] = String(value);
|
|
96
|
+
}
|
|
97
|
+
return JSON.stringify(stringRecord);
|
|
98
|
+
};
|
package/dist/reporter.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ConfigLoader, ConfigType } from 'qase-javascript-commons';
|
|
2
|
-
|
|
2
|
+
interface CallsiteRecordType {
|
|
3
3
|
filename?: string;
|
|
4
4
|
lineNum?: number;
|
|
5
5
|
callsiteFrameIdx?: number;
|
|
6
|
-
stackFrames?:
|
|
6
|
+
stackFrames?: unknown[];
|
|
7
7
|
isV8Frames?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
8
|
+
}
|
|
9
|
+
interface TestRunErrorFormattableAdapterType {
|
|
10
10
|
userAgent: string;
|
|
11
11
|
screenshotPath: string;
|
|
12
12
|
testRunId: string;
|
|
@@ -17,21 +17,21 @@ type TestRunErrorFormattableAdapterType = {
|
|
|
17
17
|
errMsg?: string;
|
|
18
18
|
diff?: boolean;
|
|
19
19
|
id?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
20
|
+
}
|
|
21
|
+
interface ScreenshotType {
|
|
22
22
|
screenshotPath: string;
|
|
23
23
|
thumbnailPath: string;
|
|
24
24
|
userAgent: string;
|
|
25
25
|
quarantineAttempt: number;
|
|
26
26
|
takenOnFail: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
27
|
+
}
|
|
28
|
+
interface FixtureType {
|
|
29
29
|
id: string;
|
|
30
30
|
name: string;
|
|
31
31
|
path?: string;
|
|
32
32
|
meta: Record<string, unknown>;
|
|
33
|
-
}
|
|
34
|
-
export
|
|
33
|
+
}
|
|
34
|
+
export interface TestRunInfoType {
|
|
35
35
|
errs: TestRunErrorFormattableAdapterType[];
|
|
36
36
|
warnings: string[];
|
|
37
37
|
durationMs: number;
|
|
@@ -41,18 +41,12 @@ export type TestRunInfoType = {
|
|
|
41
41
|
quarantine: Record<string, Record<'passed', boolean>>;
|
|
42
42
|
skipped: boolean;
|
|
43
43
|
fixture: FixtureType;
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
export type TestcafeQaseOptionsType = ConfigType;
|
|
46
46
|
/**
|
|
47
47
|
* @class TestcafeQaseReporter
|
|
48
48
|
*/
|
|
49
49
|
export declare class TestcafeQaseReporter {
|
|
50
|
-
/**
|
|
51
|
-
* @param {Record<string, string>} meta
|
|
52
|
-
* @returns {number[]}
|
|
53
|
-
* @private
|
|
54
|
-
*/
|
|
55
|
-
private static getCaseId;
|
|
56
50
|
/**
|
|
57
51
|
* @param {TestRunInfoType} testRunInfo
|
|
58
52
|
* @returns {TestStatusEnum}
|
|
@@ -66,8 +60,8 @@ export declare class TestcafeQaseReporter {
|
|
|
66
60
|
*/
|
|
67
61
|
private static transformErrors;
|
|
68
62
|
/**
|
|
69
|
-
* @param {ScreenshotType[]}
|
|
70
|
-
* @returns {
|
|
63
|
+
* @param {ScreenshotType[]} screenshots
|
|
64
|
+
* @returns {Attachment[]}
|
|
71
65
|
* @private
|
|
72
66
|
*/
|
|
73
67
|
private static transformAttachments;
|
|
@@ -81,15 +75,20 @@ export declare class TestcafeQaseReporter {
|
|
|
81
75
|
* @param {ConfigLoaderInterface} configLoader
|
|
82
76
|
*/
|
|
83
77
|
constructor(options: TestcafeQaseOptionsType, configLoader?: ConfigLoader<Partial<ConfigType> & Record<string, unknown>>);
|
|
78
|
+
/**
|
|
79
|
+
* @returns {Promise<void>}
|
|
80
|
+
*/
|
|
81
|
+
startTestRun: () => void;
|
|
84
82
|
/**
|
|
85
83
|
* @param {string} title
|
|
86
84
|
* @param {TestRunInfoType} testRunInfo
|
|
87
85
|
* @param {Record<string, string>} meta
|
|
88
86
|
*/
|
|
89
|
-
reportTestDone: (title: string, testRunInfo: TestRunInfoType, meta: Record<string, string>) => void
|
|
87
|
+
reportTestDone: (title: string, testRunInfo: TestRunInfoType, meta: Record<string, string>) => Promise<void>;
|
|
90
88
|
/**
|
|
91
89
|
* @returns {Promise<void>}
|
|
92
90
|
*/
|
|
93
91
|
reportTaskDone: () => Promise<void>;
|
|
92
|
+
private getMeta;
|
|
94
93
|
}
|
|
95
94
|
export {};
|
package/dist/reporter.js
CHANGED
|
@@ -3,24 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TestcafeQaseReporter = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
const qase_javascript_commons_1 = require("qase-javascript-commons");
|
|
6
|
+
var metadataEnum;
|
|
7
|
+
(function (metadataEnum) {
|
|
8
|
+
metadataEnum["id"] = "QaseID";
|
|
9
|
+
metadataEnum["title"] = "QaseTitle";
|
|
10
|
+
metadataEnum["fields"] = "QaseFields";
|
|
11
|
+
metadataEnum["parameters"] = "QaseParameters";
|
|
12
|
+
metadataEnum["oldID"] = "CID";
|
|
13
|
+
})(metadataEnum || (metadataEnum = {}));
|
|
6
14
|
/**
|
|
7
15
|
* @class TestcafeQaseReporter
|
|
8
16
|
*/
|
|
9
17
|
class TestcafeQaseReporter {
|
|
10
|
-
/**
|
|
11
|
-
* @param {Record<string, string>} meta
|
|
12
|
-
* @returns {number[]}
|
|
13
|
-
* @private
|
|
14
|
-
*/
|
|
15
|
-
static getCaseId(meta) {
|
|
16
|
-
if (!meta['CID']) {
|
|
17
|
-
return [];
|
|
18
|
-
}
|
|
19
|
-
const ids = Array.isArray(meta['CID'])
|
|
20
|
-
? meta['CID']
|
|
21
|
-
: meta['CID'].split(',');
|
|
22
|
-
return ids.map((id) => Number(id));
|
|
23
|
-
}
|
|
24
18
|
/**
|
|
25
19
|
* @param {TestRunInfoType} testRunInfo
|
|
26
20
|
* @returns {TestStatusEnum}
|
|
@@ -52,32 +46,73 @@ class TestcafeQaseReporter {
|
|
|
52
46
|
return error;
|
|
53
47
|
}
|
|
54
48
|
/**
|
|
55
|
-
* @param {ScreenshotType[]}
|
|
56
|
-
* @returns {
|
|
49
|
+
* @param {ScreenshotType[]} screenshots
|
|
50
|
+
* @returns {Attachment[]}
|
|
57
51
|
* @private
|
|
58
52
|
*/
|
|
59
|
-
static transformAttachments(
|
|
60
|
-
|
|
53
|
+
static transformAttachments(screenshots) {
|
|
54
|
+
const attachments = [];
|
|
55
|
+
for (const screenshot of screenshots) {
|
|
56
|
+
attachments.push({
|
|
57
|
+
file_name: screenshot.screenshotPath,
|
|
58
|
+
file_path: screenshot.screenshotPath,
|
|
59
|
+
mime_type: '',
|
|
60
|
+
content: '',
|
|
61
|
+
size: 0,
|
|
62
|
+
id: (0, uuid_1.v4)(),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return attachments;
|
|
61
66
|
}
|
|
62
67
|
/**
|
|
63
68
|
* @param {TestcafeQaseOptionsType} options
|
|
64
69
|
* @param {ConfigLoaderInterface} configLoader
|
|
65
70
|
*/
|
|
66
71
|
constructor(options, configLoader = new qase_javascript_commons_1.ConfigLoader()) {
|
|
72
|
+
/**
|
|
73
|
+
* @returns {Promise<void>}
|
|
74
|
+
*/
|
|
75
|
+
this.startTestRun = () => {
|
|
76
|
+
this.reporter.startTestRun();
|
|
77
|
+
};
|
|
67
78
|
/**
|
|
68
79
|
* @param {string} title
|
|
69
80
|
* @param {TestRunInfoType} testRunInfo
|
|
70
81
|
* @param {Record<string, string>} meta
|
|
71
82
|
*/
|
|
72
|
-
this.reportTestDone = (title, testRunInfo, meta) => {
|
|
73
|
-
|
|
83
|
+
this.reportTestDone = async (title, testRunInfo, meta) => {
|
|
84
|
+
const error = TestcafeQaseReporter.transformErrors(testRunInfo.errs);
|
|
85
|
+
const metadata = this.getMeta(meta);
|
|
86
|
+
await this.reporter.addTestResult({
|
|
87
|
+
author: null,
|
|
88
|
+
execution: {
|
|
89
|
+
status: TestcafeQaseReporter.getStatus(testRunInfo),
|
|
90
|
+
start_time: null,
|
|
91
|
+
end_time: null,
|
|
92
|
+
duration: testRunInfo.durationMs,
|
|
93
|
+
stacktrace: error.stack ?? null,
|
|
94
|
+
thread: null,
|
|
95
|
+
},
|
|
96
|
+
fields: metadata[metadataEnum.fields],
|
|
97
|
+
message: error.message,
|
|
98
|
+
muted: false,
|
|
99
|
+
params: metadata[metadataEnum.parameters],
|
|
100
|
+
relations: {
|
|
101
|
+
suite: {
|
|
102
|
+
data: [
|
|
103
|
+
{
|
|
104
|
+
title: testRunInfo.fixture.name,
|
|
105
|
+
public_id: null,
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
run_id: null,
|
|
111
|
+
signature: `${testRunInfo.fixture.name}::${title}`,
|
|
112
|
+
steps: [],
|
|
74
113
|
id: (0, uuid_1.v4)(),
|
|
75
|
-
|
|
76
|
-
title: title,
|
|
77
|
-
suiteTitle: testRunInfo.fixture.name,
|
|
78
|
-
status: TestcafeQaseReporter.getStatus(testRunInfo),
|
|
79
|
-
error: TestcafeQaseReporter.transformErrors(testRunInfo.errs),
|
|
80
|
-
duration: testRunInfo.durationMs,
|
|
114
|
+
testops_id: metadata[metadataEnum.id].length > 0 ? metadata[metadataEnum.id] : null,
|
|
115
|
+
title: metadata[metadataEnum.title] != undefined ? metadata[metadataEnum.title] : title,
|
|
81
116
|
attachments: TestcafeQaseReporter.transformAttachments(testRunInfo.screenshots),
|
|
82
117
|
});
|
|
83
118
|
};
|
|
@@ -88,12 +123,38 @@ class TestcafeQaseReporter {
|
|
|
88
123
|
await this.reporter.publish();
|
|
89
124
|
};
|
|
90
125
|
const config = configLoader.load();
|
|
91
|
-
this.reporter =
|
|
126
|
+
this.reporter = qase_javascript_commons_1.QaseReporter.getInstance({
|
|
92
127
|
...(0, qase_javascript_commons_1.composeOptions)(options, config),
|
|
93
128
|
frameworkPackage: 'testcafe',
|
|
94
129
|
frameworkName: 'testcafe',
|
|
95
130
|
reporterName: 'testcafe-reporter-qase',
|
|
96
131
|
});
|
|
97
132
|
}
|
|
133
|
+
getMeta(meta) {
|
|
134
|
+
const metadata = {
|
|
135
|
+
QaseID: [],
|
|
136
|
+
QaseTitle: undefined,
|
|
137
|
+
QaseFields: {},
|
|
138
|
+
QaseParameters: {},
|
|
139
|
+
};
|
|
140
|
+
if (meta[metadataEnum.oldID] !== undefined && meta[metadataEnum.oldID] !== '') {
|
|
141
|
+
const v = meta[metadataEnum.oldID].split(',');
|
|
142
|
+
metadata.QaseID = Array.isArray(v) ? v.map(Number) : [Number(v)];
|
|
143
|
+
}
|
|
144
|
+
if (meta[metadataEnum.id] !== undefined && meta[metadataEnum.id] !== '') {
|
|
145
|
+
const v = meta[metadataEnum.id].split(',');
|
|
146
|
+
metadata.QaseID = Array.isArray(v) ? v.map(Number) : [Number(v)];
|
|
147
|
+
}
|
|
148
|
+
if (meta[metadataEnum.title] !== undefined && meta[metadataEnum.title] !== '') {
|
|
149
|
+
metadata.QaseTitle = meta[metadataEnum.title];
|
|
150
|
+
}
|
|
151
|
+
if (meta[metadataEnum.fields] !== undefined && meta[metadataEnum.fields] !== '') {
|
|
152
|
+
metadata.QaseFields = JSON.parse(meta[metadataEnum.fields]);
|
|
153
|
+
}
|
|
154
|
+
if (meta[metadataEnum.parameters] !== undefined && meta[metadataEnum.parameters] !== '') {
|
|
155
|
+
metadata.QaseParameters = JSON.parse(meta[metadataEnum.parameters]);
|
|
156
|
+
}
|
|
157
|
+
return metadata;
|
|
158
|
+
}
|
|
98
159
|
}
|
|
99
160
|
exports.TestcafeQaseReporter = TestcafeQaseReporter;
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testcafe-reporter-qase",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Qase TMS TestCafe Reporter",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./dist/index.js",
|
|
9
|
+
"./qase": "./dist/qase.js",
|
|
9
10
|
"./reporter": "./dist/reporter.js",
|
|
10
11
|
"./package.json": "./package.json"
|
|
11
12
|
},
|
|
@@ -36,10 +37,10 @@
|
|
|
36
37
|
"test": "jest --passWithNoTests",
|
|
37
38
|
"clean": "rm -rf dist"
|
|
38
39
|
},
|
|
39
|
-
"author": "
|
|
40
|
+
"author": "Qase Team <support@qase.io>",
|
|
40
41
|
"license": "Apache-2.0",
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"qase-javascript-commons": "^2.0.
|
|
43
|
+
"qase-javascript-commons": "^2.0.9",
|
|
43
44
|
"uuid": "^9.0.0"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|