jest-qase-reporter 2.2.0 → 2.2.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 +187 -134
- package/changelog.md +7 -0
- package/dist/reporter.d.ts +10 -0
- package/dist/reporter.js +31 -1
- package/docs/ATTACHMENTS.md +311 -0
- package/docs/MULTI_PROJECT.md +126 -8
- package/docs/STEPS.md +371 -0
- package/docs/UPGRADE.md +260 -0
- package/docs/usage.md +812 -139
- package/package.json +2 -2
- package/tsconfig.build.json +2 -1
package/README.md
CHANGED
|
@@ -1,42 +1,109 @@
|
|
|
1
|
-
# Qase TestOps Jest
|
|
1
|
+
# [Qase TestOps](https://qase.io) Jest Reporter
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
4
|
+
[](https://www.npmjs.com/package/jest-qase-reporter)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
* Report Jest test results to existing test cases in Qase.
|
|
6
|
+
Qase Jest Reporter enables seamless integration between your Jest tests and [Qase TestOps](https://qase.io), providing automatic test result reporting, test case management, and comprehensive test analytics.
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
can also be used with Jest reporter.
|
|
8
|
+
## Features
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
- Link automated tests to Qase test cases by ID
|
|
11
|
+
- Auto-create test cases from your test code
|
|
12
|
+
- Report test results with rich metadata (fields, attachments, steps)
|
|
13
|
+
- Support for parameterized tests
|
|
14
|
+
- Multi-project reporting support
|
|
15
|
+
- Flexible configuration (file, environment variables, Jest config)
|
|
16
|
+
- Network Profiler for automatic HTTP request capture
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```sh
|
|
15
21
|
npm install --save-dev jest-qase-reporter
|
|
16
22
|
```
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
**1. Create `qase.config.json` in your project root:**
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mode": "testops",
|
|
31
|
+
"testops": {
|
|
32
|
+
"project": "YOUR_PROJECT_CODE",
|
|
33
|
+
"api": {
|
|
34
|
+
"token": "YOUR_API_TOKEN"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**2. Add Qase ID to your test:**
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
const { qase } = require('jest-qase-reporter/jest');
|
|
19
44
|
|
|
20
|
-
|
|
21
|
-
|
|
45
|
+
describe('User Authentication', () => {
|
|
46
|
+
test(qase(1, 'User can login with valid credentials'), () => {
|
|
47
|
+
expect(true).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
```
|
|
22
51
|
|
|
23
|
-
|
|
24
|
-
- [Using Reporter](#using-reporter)
|
|
25
|
-
- [Configuration](#configuration)
|
|
26
|
-
- [Requirements](#requirements)
|
|
52
|
+
**3. Run your tests:**
|
|
27
53
|
|
|
28
|
-
|
|
54
|
+
```sh
|
|
55
|
+
npx jest
|
|
56
|
+
```
|
|
29
57
|
|
|
30
|
-
##
|
|
58
|
+
## Configuration
|
|
31
59
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
60
|
+
The reporter is configured via (in order of priority):
|
|
61
|
+
|
|
62
|
+
1. **jest.config.js** (Jest-specific, highest priority)
|
|
63
|
+
2. **Environment variables** (`QASE_*`)
|
|
64
|
+
3. **Config file** (`qase.config.json`)
|
|
65
|
+
|
|
66
|
+
### Minimal Configuration
|
|
67
|
+
|
|
68
|
+
| Option | Environment Variable | Description |
|
|
69
|
+
|--------|---------------------|-------------|
|
|
70
|
+
| `mode` | `QASE_MODE` | Set to `testops` to enable reporting |
|
|
71
|
+
| `testops.project` | `QASE_TESTOPS_PROJECT` | Your Qase project code |
|
|
72
|
+
| `testops.api.token` | `QASE_TESTOPS_API_TOKEN` | Your Qase API token |
|
|
73
|
+
|
|
74
|
+
### Example `qase.config.json`
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mode": "testops",
|
|
79
|
+
"fallback": "report",
|
|
80
|
+
"testops": {
|
|
81
|
+
"project": "YOUR_PROJECT_CODE",
|
|
82
|
+
"api": {
|
|
83
|
+
"token": "YOUR_API_TOKEN"
|
|
84
|
+
},
|
|
85
|
+
"run": {
|
|
86
|
+
"title": "Jest Automated Run"
|
|
87
|
+
},
|
|
88
|
+
"batch": {
|
|
89
|
+
"size": 100
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"report": {
|
|
93
|
+
"driver": "local",
|
|
94
|
+
"connection": {
|
|
95
|
+
"local": {
|
|
96
|
+
"path": "./build/qase-report",
|
|
97
|
+
"format": "json"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
35
103
|
|
|
36
|
-
|
|
37
|
-
* Qase API token, created on the [Apps page](https://app.qase.io/apps?app=jest-reporter).
|
|
104
|
+
### Example `jest.config.js`
|
|
38
105
|
|
|
39
|
-
```
|
|
106
|
+
```javascript
|
|
40
107
|
module.exports = {
|
|
41
108
|
reporters: [
|
|
42
109
|
'default',
|
|
@@ -46,9 +113,12 @@ module.exports = {
|
|
|
46
113
|
mode: 'testops',
|
|
47
114
|
testops: {
|
|
48
115
|
api: {
|
|
49
|
-
token:
|
|
116
|
+
token: process.env.QASE_API_TOKEN,
|
|
117
|
+
},
|
|
118
|
+
project: 'YOUR_PROJECT_CODE',
|
|
119
|
+
run: {
|
|
120
|
+
complete: true,
|
|
50
121
|
},
|
|
51
|
-
project: 'project_code',
|
|
52
122
|
},
|
|
53
123
|
},
|
|
54
124
|
],
|
|
@@ -56,152 +126,135 @@ module.exports = {
|
|
|
56
126
|
};
|
|
57
127
|
```
|
|
58
128
|
|
|
59
|
-
|
|
60
|
-
Test results will be reported to a new test run in Qase.
|
|
61
|
-
|
|
62
|
-
```console
|
|
63
|
-
$ npx jest
|
|
64
|
-
Determining test suites to run...
|
|
65
|
-
...
|
|
66
|
-
qase: Project DEMO exists
|
|
67
|
-
qase: Using run 42 to publish test results
|
|
68
|
-
...
|
|
69
|
-
|
|
70
|
-
Ran all test suites.
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Using Reporter
|
|
74
|
-
|
|
75
|
-
The Jest reporter has the ability to auto-generate test cases
|
|
76
|
-
and suites from your test data.
|
|
129
|
+
> **Full configuration reference:** See [qase-javascript-commons](../qase-javascript-commons/README.md) for all available options including logging, status mapping, execution plans, and more.
|
|
77
130
|
|
|
78
|
-
|
|
79
|
-
existing test cases from TMS before the executing tests. For example:
|
|
131
|
+
## Usage
|
|
80
132
|
|
|
81
|
-
###
|
|
133
|
+
### Link Tests with Test Cases
|
|
82
134
|
|
|
83
|
-
|
|
84
|
-
- `qase.fields` - set the fields of the test case
|
|
85
|
-
- `qase.suite` - set the suite of the test case
|
|
86
|
-
- `qase.comment` - set the comment of the test case
|
|
87
|
-
- `qase.parameters` - set the parameters of the test case
|
|
88
|
-
- `qase.groupParameters` - set the group parameters of the test case
|
|
89
|
-
- `qase.ignore` - ignore the test case in Qase. The test will be executed, but the results will not be sent to Qase.
|
|
90
|
-
- `qase.step` - create a step in the test case
|
|
91
|
-
- `qase.attach` - attach a file to the test case
|
|
135
|
+
Associate your tests with Qase test cases using test case IDs:
|
|
92
136
|
|
|
93
|
-
```
|
|
137
|
+
```javascript
|
|
94
138
|
const { qase } = require('jest-qase-reporter/jest');
|
|
95
139
|
|
|
96
|
-
describe('
|
|
97
|
-
|
|
140
|
+
describe('Test suite', () => {
|
|
141
|
+
// Single test case ID
|
|
142
|
+
test(qase(1, 'Test name'), () => {
|
|
98
143
|
expect(true).toBe(true);
|
|
99
144
|
});
|
|
100
145
|
|
|
101
|
-
|
|
102
|
-
|
|
146
|
+
// Multiple test case IDs
|
|
147
|
+
test(qase([1, 2, 3], 'Test covering multiple cases'), () => {
|
|
103
148
|
expect(true).toBe(true);
|
|
104
149
|
});
|
|
150
|
+
});
|
|
151
|
+
```
|
|
105
152
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
153
|
+
### Add Metadata
|
|
154
|
+
|
|
155
|
+
Enhance your tests with additional information:
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
const { qase } = require('jest-qase-reporter/jest');
|
|
109
159
|
|
|
110
|
-
|
|
111
|
-
|
|
160
|
+
test(qase(1, 'Test with metadata'), () => {
|
|
161
|
+
qase.title('User can successfully login');
|
|
162
|
+
qase.fields({
|
|
163
|
+
severity: 'critical',
|
|
164
|
+
priority: 'high',
|
|
165
|
+
layer: 'api',
|
|
112
166
|
});
|
|
167
|
+
qase.suite('Authentication / Login');
|
|
168
|
+
|
|
169
|
+
// Test logic
|
|
170
|
+
expect(true).toBe(true);
|
|
113
171
|
});
|
|
114
172
|
```
|
|
115
173
|
|
|
116
|
-
|
|
174
|
+
### Ignore Tests
|
|
117
175
|
|
|
118
|
-
|
|
119
|
-
QASE_MODE=testops npx jest --runInBand
|
|
120
|
-
```
|
|
176
|
+
Exclude specific tests from Qase reporting (test still runs, but results are not sent):
|
|
121
177
|
|
|
122
|
-
|
|
178
|
+
```javascript
|
|
179
|
+
const { qase } = require('jest-qase-reporter/jest');
|
|
123
180
|
|
|
124
|
-
|
|
125
|
-
|
|
181
|
+
test('This test runs but is not reported to Qase', () => {
|
|
182
|
+
qase.ignore();
|
|
183
|
+
expect(true).toBe(true);
|
|
184
|
+
});
|
|
126
185
|
```
|
|
127
186
|
|
|
128
|
-
|
|
129
|
-
<img width="65%" src="./screenshots/screenshot.png">
|
|
130
|
-
</p>
|
|
187
|
+
### Test Result Statuses
|
|
131
188
|
|
|
132
|
-
|
|
189
|
+
| Jest Result | Qase Status |
|
|
190
|
+
|-------------|-------------|
|
|
191
|
+
| passed | passed |
|
|
192
|
+
| failed | failed |
|
|
193
|
+
| skipped | skipped |
|
|
133
194
|
|
|
134
|
-
|
|
135
|
-
https://app.qase.io/run/QASE_PROJECT_CODE
|
|
136
|
-
```
|
|
195
|
+
> For more usage examples, see the [Usage Guide](docs/usage.md).
|
|
137
196
|
|
|
138
|
-
|
|
197
|
+
## Running Tests
|
|
139
198
|
|
|
140
|
-
|
|
199
|
+
```bash
|
|
200
|
+
# Run all tests with Qase reporting
|
|
201
|
+
QASE_MODE=testops npx jest
|
|
141
202
|
|
|
142
|
-
|
|
203
|
+
# Run specific test file
|
|
204
|
+
QASE_MODE=testops npx jest path/to/test.spec.js
|
|
143
205
|
|
|
144
|
-
|
|
206
|
+
# Run tests matching pattern
|
|
207
|
+
QASE_MODE=testops npx jest --testPathPattern="auth"
|
|
145
208
|
|
|
146
|
-
|
|
209
|
+
# Run with custom test run title
|
|
210
|
+
QASE_MODE=testops QASE_TESTOPS_RUN_TITLE="Nightly Regression" npx jest
|
|
211
|
+
```
|
|
147
212
|
|
|
148
|
-
|
|
149
|
-
- `debug` - Enables debug logging, default - `false`
|
|
150
|
-
- `environment` - To execute with the sending of the envinroment information
|
|
151
|
-
- *`testops.api.token` - Token for API access, you can generate it [here](https://developers.qase.io/#authentication).
|
|
152
|
-
- *`testops.project` - [Your project's code](https://help.qase.io/en/articles/9787250-how-do-i-find-my-project-code)
|
|
153
|
-
- `testops.run.id` - Qase test run ID, used when the test run was created earlier using CLI or API call.
|
|
154
|
-
- `testops.run.title` - Set custom Run name, when new run is created
|
|
155
|
-
- `testops.run.description` - Set custom Run description, when new run is created
|
|
156
|
-
- `testops.run.complete` - Whether the run should be completed
|
|
213
|
+
## Network Profiler
|
|
157
214
|
|
|
158
|
-
|
|
215
|
+
The Network Profiler automatically captures outgoing HTTP requests made during test execution and reports them as REQUEST-type steps in Qase TestOps.
|
|
159
216
|
|
|
160
|
-
|
|
161
|
-
module.exports = {
|
|
162
|
-
reporters: [
|
|
163
|
-
'default',
|
|
164
|
-
[
|
|
165
|
-
'jest-qase-reporter',
|
|
166
|
-
{
|
|
167
|
-
mode: 'testops',
|
|
168
|
-
testops: {
|
|
169
|
-
api: {
|
|
170
|
-
token: 'api_key'
|
|
171
|
-
},
|
|
172
|
-
project: 'project_code',
|
|
173
|
-
run: {
|
|
174
|
-
complete: true,
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
debug: true,
|
|
178
|
-
},
|
|
179
|
-
],
|
|
180
|
-
],
|
|
181
|
-
...
|
|
182
|
-
};
|
|
183
|
-
```
|
|
217
|
+
**Enable in `qase.config.json`:**
|
|
184
218
|
|
|
185
|
-
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"profilers": ["network"],
|
|
222
|
+
"networkProfiler": {
|
|
223
|
+
"skip_domains": ["analytics.example.com"],
|
|
224
|
+
"track_on_fail": true
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
186
228
|
|
|
187
|
-
|
|
229
|
+
| Option | Description | Default |
|
|
230
|
+
|--------|-------------|---------|
|
|
231
|
+
| `profilers` | Array of profilers to enable. Use `["network"]` for HTTP capture | `[]` |
|
|
232
|
+
| `networkProfiler.skip_domains` | Domains to exclude from profiling | `[]` |
|
|
233
|
+
| `networkProfiler.track_on_fail` | Capture response body for failed requests (status >= 400) | `true` |
|
|
188
234
|
|
|
189
|
-
|
|
190
|
-
- `QASE_DEBUG` - Same as `debug`
|
|
191
|
-
- `QASE_ENVIRONMENT` - Same as `environment`
|
|
192
|
-
- `QASE_TESTOPS_API_TOKEN` - Same as `testops.api.token`
|
|
193
|
-
- `QASE_TESTOPS_PROJECT` - Same as `testops.project`
|
|
194
|
-
- `QASE_TESTOPS_RUN_ID` - Pass Run ID from ENV and override reporter option `testops.run.id`
|
|
195
|
-
- `QASE_TESTOPS_RUN_TITLE` - Same as `testops.run.title`
|
|
196
|
-
- `QASE_TESTOPS_RUN_DESCRIPTION` - Same as `testops.run.description`
|
|
235
|
+
> Requests to `qase.io` are always excluded automatically.
|
|
197
236
|
|
|
198
237
|
## Requirements
|
|
199
238
|
|
|
200
|
-
|
|
201
|
-
|
|
239
|
+
- Node.js >= 14
|
|
240
|
+
- Jest >= 27.0.0
|
|
241
|
+
|
|
242
|
+
> **Note:** Testing frameworks that use Jest as a test runner, such as Puppeteer, Appium, and Detox, can also be used with Jest reporter.
|
|
243
|
+
|
|
244
|
+
## Documentation
|
|
245
|
+
|
|
246
|
+
| Guide | Description |
|
|
247
|
+
|-------|-------------|
|
|
248
|
+
| [Usage Guide](docs/usage.md) | Complete usage reference with all methods and options |
|
|
249
|
+
| [Attachments](docs/ATTACHMENTS.md) | Adding screenshots, logs, and files to test results |
|
|
250
|
+
| [Steps](docs/STEPS.md) | Defining test steps for detailed reporting |
|
|
251
|
+
| [Multi-Project Support](docs/MULTI_PROJECT.md) | Reporting to multiple Qase projects |
|
|
252
|
+
| [Upgrade Guide](docs/UPGRADE.md) | Migration guide for breaking changes |
|
|
253
|
+
|
|
254
|
+
## Examples
|
|
202
255
|
|
|
203
|
-
|
|
256
|
+
See the [examples directory](../examples/) for complete working examples.
|
|
204
257
|
|
|
205
|
-
|
|
258
|
+
## License
|
|
206
259
|
|
|
207
|
-
[
|
|
260
|
+
Apache License 2.0. See [LICENSE](LICENSE) for details.
|
package/changelog.md
CHANGED
package/dist/reporter.d.ts
CHANGED
|
@@ -26,6 +26,16 @@ export declare class JestQaseReporter implements Reporter {
|
|
|
26
26
|
* @private
|
|
27
27
|
*/
|
|
28
28
|
private reporter;
|
|
29
|
+
/**
|
|
30
|
+
* @type {NetworkProfiler | null}
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
private profiler;
|
|
34
|
+
/**
|
|
35
|
+
* Snapshot of fallback accumulator length — used for per-test step delta in --runInBand mode.
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
private _profilerStepSnapshot;
|
|
29
39
|
/**
|
|
30
40
|
* @type {Metadata}
|
|
31
41
|
* @private
|
package/dist/reporter.js
CHANGED
|
@@ -44,6 +44,16 @@ class JestQaseReporter {
|
|
|
44
44
|
* @private
|
|
45
45
|
*/
|
|
46
46
|
reporter;
|
|
47
|
+
/**
|
|
48
|
+
* @type {NetworkProfiler | null}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
profiler = null;
|
|
52
|
+
/**
|
|
53
|
+
* Snapshot of fallback accumulator length — used for per-test step delta in --runInBand mode.
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
_profilerStepSnapshot = 0;
|
|
47
57
|
/**
|
|
48
58
|
* @type {Metadata}
|
|
49
59
|
* @private
|
|
@@ -57,12 +67,19 @@ class JestQaseReporter {
|
|
|
57
67
|
*/
|
|
58
68
|
constructor(_, options, _state, configLoader = new qase_javascript_commons_1.ConfigLoader()) {
|
|
59
69
|
const config = configLoader.load();
|
|
70
|
+
const composedOptions = (0, qase_javascript_commons_1.composeOptions)(options, config);
|
|
60
71
|
this.reporter = qase_javascript_commons_1.QaseReporter.getInstance({
|
|
61
|
-
...
|
|
72
|
+
...composedOptions,
|
|
62
73
|
frameworkPackage: 'jest',
|
|
63
74
|
frameworkName: 'jest',
|
|
64
75
|
reporterName: 'jest-qase-reporter',
|
|
65
76
|
});
|
|
77
|
+
if (composedOptions.profilers?.includes('network')) {
|
|
78
|
+
this.profiler = new qase_javascript_commons_1.NetworkProfiler({
|
|
79
|
+
skipDomains: composedOptions.networkProfiler?.skip_domains,
|
|
80
|
+
trackOnFail: composedOptions.networkProfiler?.track_on_fail,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
66
83
|
// @ts-expect-error - global.Qase is dynamically added at runtime
|
|
67
84
|
global.Qase = new global_1.Qase(this);
|
|
68
85
|
this.metadata = this.createEmptyMetadata();
|
|
@@ -72,6 +89,8 @@ class JestQaseReporter {
|
|
|
72
89
|
*/
|
|
73
90
|
onRunStart() {
|
|
74
91
|
this.reporter.startTestRun();
|
|
92
|
+
// Enable profiler in main process for --runInBand mode
|
|
93
|
+
this.profiler?.enable();
|
|
75
94
|
}
|
|
76
95
|
onTestCaseResult(test, testCaseResult) {
|
|
77
96
|
if (this.metadata.ignore) {
|
|
@@ -116,6 +135,16 @@ class JestQaseReporter {
|
|
|
116
135
|
const ids = JestQaseReporter.getCaseId(testCaseResult.title);
|
|
117
136
|
result.signature = this.getSignature(test.path, testCaseResult.fullName, ids, this.metadata.parameters);
|
|
118
137
|
this.cleanMetadata();
|
|
138
|
+
// Collect profiler steps for --runInBand mode (reporter and tests share same process)
|
|
139
|
+
// In multi-worker mode, the reporter's profiler has no captured steps (different process).
|
|
140
|
+
if (this.profiler) {
|
|
141
|
+
const allSteps = this.profiler.getAllSteps();
|
|
142
|
+
const newSteps = allSteps.slice(this._profilerStepSnapshot);
|
|
143
|
+
this._profilerStepSnapshot = allSteps.length;
|
|
144
|
+
if (newSteps.length > 0) {
|
|
145
|
+
result.steps = [...result.steps, ...newSteps];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
119
148
|
void this.reporter.addTestResult(result);
|
|
120
149
|
}
|
|
121
150
|
/**
|
|
@@ -140,6 +169,7 @@ class JestQaseReporter {
|
|
|
140
169
|
* @see {Reporter.onRunComplete}
|
|
141
170
|
*/
|
|
142
171
|
onRunComplete() {
|
|
172
|
+
this.profiler?.restore();
|
|
143
173
|
void this.reporter.publish();
|
|
144
174
|
}
|
|
145
175
|
/**
|