wdio-qase-reporter 1.1.1 → 1.1.3

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 CHANGED
@@ -20,6 +20,8 @@ from Qase.io before executing tests. It's a more reliable way to bind
20
20
  autotests to test cases, that persists when you rename, move, or
21
21
  parameterize your tests.
22
22
 
23
+ For more information, see the [Usage Guide](docs/usage.md).
24
+
23
25
  For example:
24
26
 
25
27
  ### Mocha/Jasmine
@@ -28,14 +30,12 @@ For example:
28
30
  import {qase} from "wdio-qase-reporter";
29
31
 
30
32
  describe('My First Test', () => {
31
- it('Several ids', () => {
32
- qase.id(1);
33
+ it(qase(1, 'Several ids'), () => {
33
34
  expect(true).to.equal(true);
34
35
  });
35
36
 
36
37
  // a test can check multiple test cases
37
- it('Correct test', () => {
38
- qase.id([2, 3]);
38
+ it(qase([2,3], 'Correct test'), () => {
39
39
  expect(true).to.equal(true);
40
40
  });
41
41
 
package/changelog.md CHANGED
@@ -1,3 +1,11 @@
1
+ # qase-wdio@1.1.2
2
+
3
+ ## What's new
4
+
5
+ - Fixed an issue where the test result was not uploaded to the Qase TMS when the test has skipped status.
6
+ - Added a new function `qase` to set the test case ID.
7
+ - Marked the function `qase.id` as deprecated.
8
+
1
9
  # qase-wdio@1.1.0
2
10
 
3
11
  ## What's new
@@ -2,6 +2,10 @@ import WDIOReporter, { AfterCommandArgs, BeforeCommandArgs, RunnerStats, SuiteSt
2
2
  import { TestStatusEnum, TestStepType } from 'qase-javascript-commons';
3
3
  import { AddAttachmentEventArgs, AddQaseIdEventArgs, AddRecordsEventArgs, AddSuiteEventArgs, AddTitleEventArgs } from './models';
4
4
  export default class WDIOQaseReporter extends WDIOReporter {
5
+ /**
6
+ * @type {RegExp}
7
+ */
8
+ static qaseIdRegExp: RegExp;
5
9
  /**
6
10
  * @type {Record<string, TestStatusEnum>}
7
11
  */
@@ -56,4 +60,16 @@ export default class WDIOQaseReporter extends WDIOReporter {
56
60
  private attachFile;
57
61
  private _endStep;
58
62
  private parseTag;
63
+ /**
64
+ * @param {string} title
65
+ * @returns {number[]}
66
+ * @private
67
+ */
68
+ private static extractQaseIdsFromTitle;
69
+ /**
70
+ * @param {string} title
71
+ * @returns {string}
72
+ * @private
73
+ */
74
+ private removeQaseIdsFromTitle;
59
75
  }
package/dist/reporter.js CHANGED
@@ -12,6 +12,10 @@ const utils_1 = require("./utils");
12
12
  const path_1 = __importDefault(require("path"));
13
13
  const events_1 = require("./events");
14
14
  class WDIOQaseReporter extends reporter_1.default {
15
+ /**
16
+ * @type {RegExp}
17
+ */
18
+ static qaseIdRegExp = /\(Qase ID:? ([\d,]+)\)/;
15
19
  /**
16
20
  * @type {Record<string, TestStatusEnum>}
17
21
  */
@@ -188,6 +192,9 @@ class WDIOQaseReporter extends reporter_1.default {
188
192
  this._endStep(qase_javascript_commons_1.TestStatusEnum.skipped);
189
193
  return;
190
194
  }
195
+ if (this.storage.getCurrentTest()?.title !== test.title) {
196
+ this._startTest(test.title, test.cid, test.start.valueOf() / 1000);
197
+ }
191
198
  await this._endTest(WDIOQaseReporter.statusMap[test.state] ?? qase_javascript_commons_1.TestStatusEnum.skipped, null);
192
199
  }
193
200
  async _endTest(status, err, end_time = Date.now().valueOf() / 1000) {
@@ -218,6 +225,11 @@ class WDIOQaseReporter extends reporter_1.default {
218
225
  null : err.message === undefined ?
219
226
  null : err.message;
220
227
  testResult.signature = (0, qase_javascript_commons_1.generateSignature)(Array.isArray(testResult.testops_id) ? testResult.testops_id : testResult.testops_id ? [testResult.testops_id] : null, [...this.storage.suites, testResult.title], testResult.params);
228
+ const ids = WDIOQaseReporter.extractQaseIdsFromTitle(testResult.title);
229
+ if (ids.length > 0) {
230
+ testResult.testops_id = ids;
231
+ }
232
+ testResult.title = this.removeQaseIdsFromTitle(testResult.title);
221
233
  await this.reporter.addTestResult(testResult);
222
234
  }
223
235
  onBeforeCommand(command) {
@@ -441,5 +453,26 @@ class WDIOQaseReporter extends reporter_1.default {
441
453
  }
442
454
  return { key, value };
443
455
  }
456
+ /**
457
+ * @param {string} title
458
+ * @returns {number[]}
459
+ * @private
460
+ */
461
+ static extractQaseIdsFromTitle(title) {
462
+ const [, ids] = title.match(WDIOQaseReporter.qaseIdRegExp) ?? [];
463
+ return ids ? ids.split(',').map((id) => Number(id)) : [];
464
+ }
465
+ /**
466
+ * @param {string} title
467
+ * @returns {string}
468
+ * @private
469
+ */
470
+ removeQaseIdsFromTitle(title) {
471
+ const matches = title.match(WDIOQaseReporter.qaseIdRegExp);
472
+ if (matches) {
473
+ return title.replace(matches[0], '').trimEnd();
474
+ }
475
+ return title;
476
+ }
444
477
  }
445
478
  exports.default = WDIOQaseReporter;
package/dist/wdio.d.ts CHANGED
@@ -1,61 +1,135 @@
1
1
  import { StepFunction } from 'qase-javascript-commons';
2
- export declare class qase {
2
+ /**
3
+ * Set IDs for the test case
4
+ *
5
+ * @param qaseId
6
+ * @param name
7
+ * @example
8
+ * describe('suite', () => {
9
+ * it(qase(1, 'should work'), () => {
10
+ * // test code
11
+ * });
12
+ * });
13
+ * @returns {string}
14
+ */
15
+ export declare const qase: {
16
+ (qaseId: number | string | number[] | string[], name: string): string;
3
17
  /**
4
- * Assign QaseID to test
5
- * @name id
6
- * @param {number | number[]} value
18
+ * Set IDs for the test case.
19
+ * Deprecated: Use qase(qaseId, name) instead.
20
+ *
21
+ * @param value
22
+ * @returns {string}
23
+ * @example
24
+ * describe('suite', () => {
25
+ * it('should work', () => {
26
+ * qase.id(1);
27
+ * // test code
28
+ * });
29
+ * });
7
30
  */
8
- static id(value: number | number[]): typeof qase;
31
+ id(value: number | number[]): undefined;
9
32
  /**
10
- * Assign title to test
11
- * @name title
33
+ * Set a title for the test case
12
34
  * @param {string} value
35
+ * @example
36
+ * describe('suite', () => {
37
+ * it('should work', () => {
38
+ * qase.title("Title");
39
+ * // test code
40
+ * });
41
+ * });
13
42
  */
14
- static title(value: string): typeof qase;
43
+ title(value: string): undefined;
15
44
  /**
16
- * Assign parameters to test
17
- * @name parameters
45
+ * Set parameters for the test case
18
46
  * @param {Record<string, string>} values
47
+ * @example
48
+ * describe('suite', () => {
49
+ * it('should work', () => {
50
+ * qase.parameters({ param1: 'value1', param2: 'value2' });
51
+ * // test code
52
+ * });
53
+ * });
19
54
  */
20
- static parameters(values: Record<string, string>): typeof qase;
55
+ parameters(values: Record<string, string>): undefined;
21
56
  /**
22
- * Assign group parameters to test
23
- * @name groupParameters
57
+ * Set group parameters for the test case
24
58
  * @param {Record<string, string>} values
59
+ * @example
60
+ * describe('suite', () => {
61
+ * it('should work', () => {
62
+ * qase.groupParameters({ param1: 'value1', param2: 'value2' });
63
+ * // test code
64
+ * });
65
+ * });
25
66
  */
26
- static groupParameters(values: Record<string, string>): typeof qase;
67
+ groupParameters(values: Record<string, string>): undefined;
27
68
  /**
28
- * Assign fields to test
29
- * @name fields
69
+ * Set fields for the test case
30
70
  * @param {Record<string, string>} values
71
+ * @example
72
+ * describe('suite', () => {
73
+ * it('should work', () => {
74
+ * qase.fields({ field1: 'value1', field2: 'value2' });
75
+ * // test code
76
+ * });
77
+ * });
31
78
  */
32
- static fields(values: Record<string, string>): typeof qase;
79
+ fields(values: Record<string, string>): undefined;
33
80
  /**
34
- * Assign suite to test
35
- * @name suite
81
+ * Set suite for the test case
36
82
  * @param {string} value
83
+ * @example
84
+ * describe('suite', () => {
85
+ * it('should work', () => {
86
+ * qase.suite('Suite');
87
+ * // test code
88
+ * });
89
+ * });
37
90
  */
38
- static suite(value: string): typeof qase;
91
+ suite(value: string): undefined;
39
92
  /**
40
- * Assign ignore mark to test
41
- * @name ignore
93
+ * Set ignore for the test case
94
+ * @example
95
+ * describe('suite', () => {
96
+ * it('should work', () => {
97
+ * qase.ignore();
98
+ * // test code
99
+ * });
100
+ * });
42
101
  */
43
- static ignore(): typeof qase;
102
+ ignore(): undefined;
44
103
  /**
45
- * Assign attachment to test
46
- * @name attach
47
- * @param attach
104
+ * Set attachment for the test case
105
+ * @param {object} attach
106
+ * @example
107
+ * describe('suite', () => {
108
+ * it('should work', () => {
109
+ * qase.attach({ name: 'attachment', type: 'text/plain', content: 'attachment content' });
110
+ * // test code
111
+ * });
112
+ * });
48
113
  */
49
- static attach(attach: {
114
+ attach(attach: {
50
115
  name?: string;
51
116
  type?: string;
52
117
  content?: string;
53
118
  paths?: string[];
54
- }): typeof qase;
119
+ }): undefined;
55
120
  /**
56
- * Starts step
57
- * @param {string} name - the step name
58
- * @param {StepFunction} body - the step content function
121
+ * Set step for the test case
122
+ * @param {string} name
123
+ * @param {StepFunction} body
124
+ * @example
125
+ * describe('suite', () => {
126
+ * it('should work', () => {
127
+ * qase.step('step', async () => {
128
+ * // step code
129
+ * });
130
+ * // test code
131
+ * });
132
+ * });
59
133
  */
60
- static step(name: string, body: StepFunction): Promise<void>;
61
- }
134
+ step(name: string, body: StepFunction): Promise<undefined>;
135
+ };
package/dist/wdio.js CHANGED
@@ -14,88 +14,177 @@ const sendEvent = (event, msg = {}) => {
14
14
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
15
15
  process.emit(event, msg);
16
16
  };
17
- // eslint-disable-next-line @typescript-eslint/no-extraneous-class
18
- class qase {
19
- /**
20
- * Assign QaseID to test
21
- * @name id
22
- * @param {number | number[]} value
23
- */
24
- static id(value) {
25
- sendEvent(events_1.events.addQaseID, { ids: Array.isArray(value) ? value : [value] });
26
- return this;
27
- }
28
- /**
29
- * Assign title to test
30
- * @name title
31
- * @param {string} value
32
- */
33
- static title(value) {
34
- sendEvent(events_1.events.addTitle, { title: value });
35
- return this;
36
- }
37
- /**
38
- * Assign parameters to test
39
- * @name parameters
40
- * @param {Record<string, string>} values
41
- */
42
- static parameters(values) {
43
- sendEvent(events_1.events.addParameters, { records: values });
44
- return this;
45
- }
46
- /**
47
- * Assign group parameters to test
48
- * @name groupParameters
49
- * @param {Record<string, string>} values
50
- */
51
- static groupParameters(values) {
52
- sendEvent(events_1.events.addGroupParameters, { records: values });
53
- return this;
54
- }
55
- /**
56
- * Assign fields to test
57
- * @name fields
58
- * @param {Record<string, string>} values
59
- */
60
- static fields(values) {
61
- sendEvent(events_1.events.addFields, { records: values });
62
- return this;
63
- }
64
- /**
65
- * Assign suite to test
66
- * @name suite
67
- * @param {string} value
68
- */
69
- static suite(value) {
70
- sendEvent(events_1.events.addSuite, { suite: value });
71
- return this;
72
- }
73
- /**
74
- * Assign ignore mark to test
75
- * @name ignore
76
- */
77
- static ignore() {
78
- sendEvent(events_1.events.addIgnore, {});
79
- return this;
80
- }
81
- /**
82
- * Assign attachment to test
83
- * @name attach
84
- * @param attach
85
- */
86
- static attach(attach) {
87
- sendEvent(events_1.events.addAttachment, attach);
88
- return this;
89
- }
90
- /**
91
- * Starts step
92
- * @param {string} name - the step name
93
- * @param {StepFunction} body - the step content function
94
- */
95
- static async step(name, body) {
96
- const runningStep = new qase_javascript_commons_1.QaseStep(name);
97
- // eslint-disable-next-line @typescript-eslint/require-await
98
- await runningStep.run(body, async (message) => sendEvent(events_1.events.addStep, message));
17
+ /**
18
+ * Set IDs for the test case
19
+ *
20
+ * @param qaseId
21
+ * @param name
22
+ * @example
23
+ * describe('suite', () => {
24
+ * it(qase(1, 'should work'), () => {
25
+ * // test code
26
+ * });
27
+ * });
28
+ * @returns {string}
29
+ */
30
+ const qase = (qaseId, name) => {
31
+ const caseIds = Array.isArray(qaseId) ? qaseId : [qaseId];
32
+ const ids = [];
33
+ for (const id of caseIds) {
34
+ if (typeof id === 'number') {
35
+ ids.push(id);
36
+ continue;
37
+ }
38
+ const parsedId = parseInt(id);
39
+ if (!isNaN(parsedId)) {
40
+ ids.push(parsedId);
41
+ continue;
42
+ }
43
+ console.log(`qase: qase ID ${id} should be a number`);
99
44
  }
100
- }
45
+ const newName = `${name} (Qase ID: ${caseIds.join(',')})`;
46
+ return newName;
47
+ };
101
48
  exports.qase = qase;
49
+ /**
50
+ * Set IDs for the test case.
51
+ * Deprecated: Use qase(qaseId, name) instead.
52
+ *
53
+ * @param value
54
+ * @returns {string}
55
+ * @example
56
+ * describe('suite', () => {
57
+ * it('should work', () => {
58
+ * qase.id(1);
59
+ * // test code
60
+ * });
61
+ * });
62
+ */
63
+ exports.qase.id = (value) => {
64
+ sendEvent(events_1.events.addQaseID, { ids: Array.isArray(value) ? value : [value] });
65
+ return this;
66
+ };
67
+ /**
68
+ * Set a title for the test case
69
+ * @param {string} value
70
+ * @example
71
+ * describe('suite', () => {
72
+ * it('should work', () => {
73
+ * qase.title("Title");
74
+ * // test code
75
+ * });
76
+ * });
77
+ */
78
+ exports.qase.title = (value) => {
79
+ sendEvent(events_1.events.addTitle, { title: value });
80
+ return this;
81
+ };
82
+ /**
83
+ * Set parameters for the test case
84
+ * @param {Record<string, string>} values
85
+ * @example
86
+ * describe('suite', () => {
87
+ * it('should work', () => {
88
+ * qase.parameters({ param1: 'value1', param2: 'value2' });
89
+ * // test code
90
+ * });
91
+ * });
92
+ */
93
+ exports.qase.parameters = (values) => {
94
+ sendEvent(events_1.events.addParameters, { records: values });
95
+ return this;
96
+ };
97
+ /**
98
+ * Set group parameters for the test case
99
+ * @param {Record<string, string>} values
100
+ * @example
101
+ * describe('suite', () => {
102
+ * it('should work', () => {
103
+ * qase.groupParameters({ param1: 'value1', param2: 'value2' });
104
+ * // test code
105
+ * });
106
+ * });
107
+ */
108
+ exports.qase.groupParameters = (values) => {
109
+ sendEvent(events_1.events.addGroupParameters, { records: values });
110
+ return this;
111
+ };
112
+ /**
113
+ * Set fields for the test case
114
+ * @param {Record<string, string>} values
115
+ * @example
116
+ * describe('suite', () => {
117
+ * it('should work', () => {
118
+ * qase.fields({ field1: 'value1', field2: 'value2' });
119
+ * // test code
120
+ * });
121
+ * });
122
+ */
123
+ exports.qase.fields = (values) => {
124
+ sendEvent(events_1.events.addFields, { records: values });
125
+ return this;
126
+ };
127
+ /**
128
+ * Set suite for the test case
129
+ * @param {string} value
130
+ * @example
131
+ * describe('suite', () => {
132
+ * it('should work', () => {
133
+ * qase.suite('Suite');
134
+ * // test code
135
+ * });
136
+ * });
137
+ */
138
+ exports.qase.suite = (value) => {
139
+ sendEvent(events_1.events.addSuite, { suite: value });
140
+ return this;
141
+ };
142
+ /**
143
+ * Set ignore for the test case
144
+ * @example
145
+ * describe('suite', () => {
146
+ * it('should work', () => {
147
+ * qase.ignore();
148
+ * // test code
149
+ * });
150
+ * });
151
+ */
152
+ exports.qase.ignore = () => {
153
+ sendEvent(events_1.events.addIgnore, {});
154
+ return this;
155
+ };
156
+ /**
157
+ * Set attachment for the test case
158
+ * @param {object} attach
159
+ * @example
160
+ * describe('suite', () => {
161
+ * it('should work', () => {
162
+ * qase.attach({ name: 'attachment', type: 'text/plain', content: 'attachment content' });
163
+ * // test code
164
+ * });
165
+ * });
166
+ */
167
+ exports.qase.attach = (attach) => {
168
+ sendEvent(events_1.events.addAttachment, attach);
169
+ return this;
170
+ };
171
+ /**
172
+ * Set step for the test case
173
+ * @param {string} name
174
+ * @param {StepFunction} body
175
+ * @example
176
+ * describe('suite', () => {
177
+ * it('should work', () => {
178
+ * qase.step('step', async () => {
179
+ * // step code
180
+ * });
181
+ * // test code
182
+ * });
183
+ * });
184
+ */
185
+ exports.qase.step = async (name, body) => {
186
+ const runningStep = new qase_javascript_commons_1.QaseStep(name);
187
+ // eslint-disable-next-line @typescript-eslint/require-await
188
+ await runningStep.run(body, async (message) => sendEvent(events_1.events.addStep, message));
189
+ return this;
190
+ };
package/docs/usage.md ADDED
@@ -0,0 +1,247 @@
1
+ # Qase Integration in WebdriverIO
2
+
3
+ This guide demonstrates how to integrate Qase with WebdriverIO, providing instructions on how to add Qase IDs, titles,
4
+ fields, suites, comments, and file attachments to your test cases.
5
+
6
+ ---
7
+
8
+ ## Adding QaseID to a Test
9
+
10
+ To associate a QaseID with a test in WebdriverIO, use the `qase` function. This function accepts a single integer
11
+ representing the test's ID in Qase.
12
+
13
+ ### Example
14
+
15
+ ```javascript
16
+ import { qase } from 'wdio-qase-reporter';
17
+
18
+ it(qase(1, 'test'), () => {
19
+ browser.url('https://example.com');
20
+ });
21
+
22
+ it(qase([1, 2, 3], 'test'), () => {
23
+ browser.url('https://example.com');
24
+ });
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Adding a Title to a Test
30
+
31
+ You can provide a title for your test using the `qase.title` function. The function accepts a string, which will be
32
+ used as the test's title in Qase. If no title is provided, the test method name will be used by default.
33
+
34
+ ### Example
35
+
36
+ ```javascript
37
+ import { qase } from 'wdio-qase-reporter';
38
+
39
+ it('test', () => {
40
+ qase.title('Title');
41
+ browser.url('https://example.com');
42
+ });
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Adding Fields to a Test
48
+
49
+ The `qase.fields` function allows you to add additional metadata to a test case. You can specify multiple fields to
50
+ enhance test case information in Qase.
51
+
52
+ ### System Fields
53
+
54
+ - `description` — Description of the test case.
55
+ - `preconditions` — Preconditions for the test case.
56
+ - `postconditions` — Postconditions for the test case.
57
+ - `severity` — Severity of the test case (e.g., `critical`, `major`).
58
+ - `priority` — Priority of the test case (e.g., `high`, `low`).
59
+ - `layer` — Test layer (e.g., `UI`, `API`).
60
+
61
+ ### Example
62
+
63
+ ```javascript
64
+ import { qase } from 'wdio-qase-reporter';
65
+
66
+ it('test', () => {
67
+ qase.fields({ description: "Description", preconditions: "Preconditions" });
68
+ browser.url('https://example.com');
69
+ });
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Adding a Suite to a Test
75
+
76
+ To assign a suite or sub-suite to a test, use the `qase.suite` function. It can receive a suite name, and optionally a
77
+ sub-suite, both as strings.
78
+
79
+ ### Example
80
+
81
+ ```javascript
82
+ import { qase } from 'wdio-qase-reporter';
83
+
84
+ it('test', () => {
85
+ qase.suite("Suite 01");
86
+ browser.url('https://example.com');
87
+ });
88
+
89
+ it('test', () => {
90
+ qase.suite("Suite 01\tSuite 02");
91
+ browser.url('https://example.com');
92
+ });
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Ignoring a Test in Qase
98
+
99
+ To exclude a test from being reported to Qase (while still executing the test in WebdriverIO), use the `qase.ignore`
100
+ function. The test will run, but its result will not be sent to Qase.
101
+
102
+ ### Example
103
+
104
+ ```javascript
105
+ import { qase } from 'wdio-qase-reporter';
106
+
107
+ it('test', () => {
108
+ qase.ignore();
109
+ browser.url('https://example.com');
110
+ });
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Adding a Comment to a Test
116
+
117
+ You can attach comments to the test results in Qase using the `qase.comment` function. The comment will be displayed
118
+ alongside the test execution details in Qase.
119
+
120
+ ### Example
121
+
122
+ ```javascript
123
+ import { qase } from 'wdio-qase-reporter';
124
+
125
+ it('test', () => {
126
+ qase.comment("Some comment");
127
+ browser.url('https://example.com');
128
+ });
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Attaching Files to a Test
134
+
135
+ To attach files to a test result, use the `qase.attach` function. This method supports attaching one or multiple files,
136
+ along with optional file names, comments, and file types.
137
+
138
+ ### Example
139
+
140
+ ```javascript
141
+ import { qase } from 'wdio-qase-reporter';
142
+
143
+ it('test', () => {
144
+ qase.attach({ name: 'attachment.txt', content: 'Hello, world!', type: 'text/plain' });
145
+ qase.attach({ paths: '/path/to/file' });
146
+ qase.attach({ paths: ['/path/to/file', '/path/to/another/file'] });
147
+ browser.url('https://example.com');
148
+ });
149
+ ```
150
+
151
+ ## Adding Parameters to a Test
152
+
153
+ You can add parameters to a test case using the `qase.parameters` function. This function accepts an object with
154
+ parameter names and values.
155
+
156
+ ### Example
157
+
158
+ ```javascript
159
+ import { qase } from 'wdio-qase-reporter';
160
+
161
+ it('test', () => {
162
+ qase.parameters({ param1: 'value1', param2: 'value2' });
163
+ browser.url('https://example.com');
164
+ });
165
+ ```
166
+
167
+ ## Adding Group Parameters to a Test
168
+
169
+ To add group parameters to a test case, use the `qase.groupParameters` function. This function accepts an object with
170
+ group parameter names and values.
171
+
172
+ ### Example
173
+
174
+ ```javascript
175
+ import { qase } from 'wdio-qase-reporter';
176
+
177
+ it('test', () => {
178
+ qase.parameters({ param1: 'value1', param2: 'value2' });
179
+ qase.groupParameters({ param3: 'value3', param4: 'value4' });
180
+ browser.url('https://example.com');
181
+ });
182
+ ```
183
+
184
+ ## Adding Steps to a Test
185
+
186
+ You can add steps to a test case using the `qase.step` function. This function accepts a string and a callback function,
187
+ which will be used as the step description and actions in Qase.
188
+
189
+ ### Example
190
+
191
+ ```javascript
192
+ import { qase } from 'wdio-qase-reporter';
193
+
194
+ it('test', async () => {
195
+ await qase.step('Some step', async (step) => {
196
+ // some actions
197
+ step.attach({ name: 'screenshot.png', type: 'image/png', content: await browser.takeScreenshot() });
198
+ });
199
+ browser.url('https://example.com');
200
+ });
201
+ ```
202
+
203
+ ## Cucumber Integration
204
+
205
+ WebdriverIO Qase reporter supports Cucumber integration. When using Cucumber, you can annotate your scenarios with Qase IDs using tags.
206
+
207
+ ### Feature file example
208
+
209
+ ```gherkin
210
+ Feature: Test user role
211
+
212
+ @QaseId=3
213
+ Scenario: Login
214
+ Given I test login
215
+ When I enter credentials
216
+ Then I should be logged in
217
+
218
+ @QaseId=4,5
219
+ @Title=Custom Test Title
220
+ @Suite=Authentication
221
+ Scenario: Logout
222
+ Given I am logged in
223
+ When I click logout
224
+ Then I should be logged out
225
+ ```
226
+
227
+ ### Supported Cucumber tags
228
+
229
+ - `@QaseId=<id>` - Set Qase test case ID(s). Multiple IDs can be separated by commas
230
+ - `@Title=<title>` - Set custom test title
231
+ - `@Suite=<suite>` - Set test suite name
232
+
233
+ ### Configuration for Cucumber
234
+
235
+ ```javascript
236
+ // wdio.conf.js
237
+ const WDIOQaseReporter = require('wdio-qase-reporter').default;
238
+
239
+ exports.config = {
240
+ reporters: [[WDIOQaseReporter, {
241
+ useCucumber: true, // Enable Cucumber support
242
+ disableWebdriverStepsReporting: true,
243
+ disableWebdriverScreenshotsReporting: false,
244
+ }]],
245
+ // ... other options
246
+ };
247
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wdio-qase-reporter",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Qase WebDriverIO Reporter",
5
5
  "homepage": "https://github.com/qase-tms/qase-javascript",
6
6
  "sideEffects": false,
@@ -32,7 +32,7 @@
32
32
  "author": "Qase Team <support@qase.io>",
33
33
  "license": "Apache-2.0",
34
34
  "dependencies": {
35
- "qase-javascript-commons": "~2.3.3",
35
+ "qase-javascript-commons": "~2.4.1",
36
36
  "uuid": "^9.0.1",
37
37
  "@types/node": "^20.1.0",
38
38
  "@wdio/reporter": "^8.39.0",