qase-javascript-commons 2.4.18 → 2.5.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 CHANGED
@@ -34,8 +34,8 @@ All configuration options are listed in the table below:
34
34
  | Description | Config file | Environment variable | Default value | Required | Possible values |
35
35
  |-----------------------------------------------------------------------------------------------------------------------|----------------------------|---------------------------------|-----------------------------------------|----------|----------------------------|
36
36
  | **Common** | | | | | |
37
- | Mode of reporter | `mode` | `QASE_MODE` | `off` | No | `testops`, `report`, `off` |
38
- | Fallback mode of reporter | `fallback` | `QASE_FALLBACK` | `off` | No | `testops`, `report`, `off` |
37
+ | Mode of reporter | `mode` | `QASE_MODE` | `off` | No | `testops`, `testops_multi`, `report`, `off` |
38
+ | Fallback mode of reporter | `fallback` | `QASE_FALLBACK` | `off` | No | `testops`, `testops_multi`, `report`, `off` |
39
39
  | Environment | `environment` | `QASE_ENVIRONMENT` | undefined | No | Any string |
40
40
  | Root suite | `rootSuite` | `QASE_ROOT_SUITE` | undefined | No | Any string |
41
41
  | Enable debug logs | `debug` | `QASE_DEBUG` | `False` | No | `True`, `False` |
@@ -67,6 +67,18 @@ All configuration options are listed in the table below:
67
67
  | Configuration values to create/find in groups (format: `group1=value1,group2=value2`) | `testops.configurations.values` | `QASE_TESTOPS_CONFIGURATIONS_VALUES` | undefined | No | Comma-separated key=value pairs |
68
68
  | Create configuration groups if they don't exist | `testops.configurations.createIfNotExists` | `QASE_TESTOPS_CONFIGURATIONS_CREATE_IF_NOT_EXISTS` | `false` | No | `True`, `False` |
69
69
  | Enable public report link generation and display after test run completion | `testops.showPublicReportLink` | `QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK` | `False` | No | `True`, `False` |
70
+ | **Qase TestOps Multi-Project configuration** | | | | | |
71
+ | Default project code for tests without explicit project mapping | `testops_multi.default_project` | N/A (use config file) | First project in `projects` | No | Any string (must match one of `projects[].code`) |
72
+ | Array of project configurations | `testops_multi.projects` | N/A (use config file) | `[]` | Yes\*\* | Array of objects |
73
+ | Project code | `testops_multi.projects[].code` | N/A | undefined | Yes\*\* | Any string |
74
+ | Project-specific test run title | `testops_multi.projects[].run.title` | N/A | Same as single-project default | No | Any string |
75
+ | Project-specific test run description | `testops_multi.projects[].run.description` | N/A | Same as single-project default | No | Any string |
76
+ | Project-specific test run complete | `testops_multi.projects[].run.complete` | N/A | `true` | No | `true`, `false` |
77
+ | Project-specific test run ID | `testops_multi.projects[].run.id` | N/A | undefined | No | Any integer |
78
+ | Project-specific test plan ID | `testops_multi.projects[].plan.id` | N/A | undefined | No | Any integer |
79
+ | Project-specific environment | `testops_multi.projects[].environment` | N/A | Uses global `environment` if not set | No | Any string |
80
+
81
+ \*\* Required when using `testops_multi` mode
70
82
 
71
83
  ### Example `qase.config.json` config
72
84
 
@@ -134,6 +146,64 @@ All configuration options are listed in the table below:
134
146
  }
135
147
  ```
136
148
 
149
+ ### Multi-Project Configuration (`testops_multi` mode)
150
+
151
+ Example `qase.config.json` for multi-project reporting:
152
+
153
+ ```json
154
+ {
155
+ "mode": "testops_multi",
156
+ "fallback": "report",
157
+ "debug": false,
158
+ "environment": "local",
159
+ "logging": {
160
+ "console": true,
161
+ "file": false
162
+ },
163
+ "report": {
164
+ "driver": "local",
165
+ "connection": {
166
+ "local": {
167
+ "path": "./build/qase-report",
168
+ "format": "json"
169
+ }
170
+ }
171
+ },
172
+ "testops": {
173
+ "api": {
174
+ "token": "<token>",
175
+ "host": "qase.io"
176
+ },
177
+ "batch": { "size": 100 },
178
+ "showPublicReportLink": true
179
+ },
180
+ "testops_multi": {
181
+ "default_project": "PROJ1",
182
+ "projects": [
183
+ {
184
+ "code": "PROJ1",
185
+ "run": {
186
+ "title": "PROJ1 Multi-Project Run",
187
+ "description": "Test run for PROJ1 project",
188
+ "complete": true
189
+ },
190
+ "plan": { "id": 1 },
191
+ "environment": "staging"
192
+ },
193
+ {
194
+ "code": "PROJ2",
195
+ "run": {
196
+ "title": "PROJ2 Multi-Project Run",
197
+ "description": "Test run for PROJ2 project",
198
+ "complete": true
199
+ },
200
+ "environment": "production"
201
+ }
202
+ ]
203
+ }
204
+ }
205
+ ```
206
+
137
207
  ### Environment Variables Example
138
208
 
139
209
  ```bash
@@ -156,3 +226,193 @@ export QASE_LOGGING_FILE=true # Enable file output
156
226
  # Enable public report link generation
157
227
  export QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK=true
158
228
  ```
229
+
230
+ ## Multi-Project Support
231
+
232
+ The multi-project feature allows you to send test results to multiple Qase projects simultaneously, with different test case IDs for each project. This is useful when:
233
+
234
+ * You need to report the same test to different projects
235
+ * Different projects track the same functionality with different test case IDs
236
+ * You want to maintain separate test runs for different environments or teams
237
+
238
+ ### How It Works
239
+
240
+ 1. Configure multiple projects in the `testops_multi.projects` array
241
+ 2. Each project can have its own run configuration (title, description, plan, environment)
242
+ 3. Use framework-specific helpers or markers to map test cases to projects (see table below)
243
+ 4. Tests without explicit project mapping are sent to `default_project` (or the first project). Results without any case ID are also sent to the default project without linking to a test case.
244
+
245
+ ### Framework-Specific Documentation
246
+
247
+ For detailed framework-specific documentation on multi-project support, see:
248
+
249
+ * **[Cypress Multi-Project Guide](../qase-cypress/docs/MULTI_PROJECT.md)** — `qase.projects(mapping, it(...))`, title markers
250
+ * **[Playwright Multi-Project Guide](../qase-playwright/docs/MULTI_PROJECT.md)** — `qase.projects(mapping)`, `qase.projectsTitle()`, annotations
251
+ * **[Jest Multi-Project Guide](../qase-jest/docs/MULTI_PROJECT.md)** — `qase.projects(mapping, name)`
252
+ * **[Vitest Multi-Project Guide](../qase-vitest/docs/MULTI_PROJECT.md)** — `addQaseProjects(name, mapping)`
253
+ * **[Mocha Multi-Project Guide](../qase-mocha/docs/MULTI_PROJECT.md)** — `qase.projects(mapping, name)`
254
+ * **[WDIO Multi-Project Guide](../qase-wdio/docs/MULTI_PROJECT.md)** — `qase.projects(mapping, name)`
255
+ * **[CucumberJS Multi-Project Guide](../qase-cucumberjs/docs/MULTI_PROJECT.md)** — tags `@qaseid.PROJ(ids)` in feature files
256
+ * **[Newman](../examples/multiProject/newman/README.md)** — comments in test script
257
+ * **[TestCafe](../examples/multiProject/testcafe/README.md)** — `qase.projects(mapping).create()` in `test.meta()`
258
+
259
+ ### Example Usage
260
+
261
+ For runnable examples, see the [multi-project examples directory](../examples/multiProject/).
262
+
263
+ ### Configuration
264
+
265
+ Set `mode` to `testops_multi` and add a `testops_multi` section with `default_project` and `projects`:
266
+
267
+ ```json
268
+ {
269
+ "mode": "testops_multi",
270
+ "testops": {
271
+ "api": { "token": "<token>", "host": "qase.io" },
272
+ "batch": { "size": 100 }
273
+ },
274
+ "testops_multi": {
275
+ "default_project": "PROJ1",
276
+ "projects": [
277
+ {
278
+ "code": "PROJ1",
279
+ "run": { "title": "Project 1 Run", "complete": true },
280
+ "plan": { "id": 1 },
281
+ "environment": "staging"
282
+ },
283
+ {
284
+ "code": "PROJ2",
285
+ "run": { "title": "Project 2 Run", "id": 123, "complete": true },
286
+ "environment": "production"
287
+ }
288
+ ]
289
+ }
290
+ }
291
+ ```
292
+
293
+ ### Test case mapping
294
+
295
+ For each result you can set `testops_project_mapping` (or use the helpers on `TestResultType`):
296
+
297
+ - **`testops_project_mapping`**: `Record<string, number[]>` — project code → list of test case IDs.
298
+ - **Backward compatibility**: if `testops_project_mapping` is empty or missing, the result uses `testops_id` and is sent to `default_project` (or the first project).
299
+
300
+ ### How to specify projects and IDs in tests
301
+
302
+ Use the syntax below **only when `mode` is `testops_multi`**. For single-project mode (`testops`), keep using the usual single-project syntax (e.g. `(Qase ID: 123)` or `qase(1, 'name')`).
303
+
304
+ Use the **helper methods** below so project codes and IDs are formatted correctly (same idea as `qase(id, name)` for single-project).
305
+
306
+ #### Vitest
307
+
308
+ - **Single project:** `addQaseId(name, caseIds)` → `"name (Qase ID: 1,2)"`.
309
+ - **Multi-project:** `addQaseProjects(name, mapping)` → `"name (Qase PROJ1: 1,2) (Qase PROJ2: 3)"`.
310
+
311
+ ```js
312
+ import { addQaseId, addQaseProjects } from 'vitest-qase-reporter/vitest';
313
+
314
+ // Single project (legacy)
315
+ it(addQaseId('login flow', [100]), async () => { ... });
316
+
317
+ // Multi-project — use helper so title is formatted correctly
318
+ it(addQaseProjects('login flow', { PROJ1: [100], PROJ2: [200] }), async () => { ... });
319
+
320
+ // Multiple IDs per project
321
+ it(addQaseProjects('checkout', { PROJ1: [10, 11], PROJ2: [20] }), async () => { ... });
322
+ ```
323
+
324
+ #### Jest
325
+
326
+ - **Single project:** `qase(caseId, name)`.
327
+ - **Multi-project:** `qase.projects(mapping, name)`.
328
+
329
+ ```js
330
+ const { qase } = require('jest-qase-reporter');
331
+
332
+ // Single project
333
+ test(qase(100, 'login flow'), () => { ... });
334
+
335
+ // Multi-project
336
+ test(qase.projects({ PROJ1: [100], PROJ2: [200] }, 'login flow'), () => { ... });
337
+ ```
338
+
339
+ #### Cypress
340
+
341
+ - **Single project:** `qase(caseId, test)` (mutates test title) or title string `(Qase ID: 100)`.
342
+ - **Multi-project:** `qase.projects(mapping, name)` returns the title string; use it as the first argument to `it()`.
343
+
344
+ ```js
345
+ const { qase } = require('cypress-qase-reporter');
346
+
347
+ // Single project
348
+ it(qase(100, 'login flow'), () => { ... }); // if qase receives test
349
+ it('login flow (Qase ID: 100)', () => { ... });
350
+
351
+ // Multi-project — use helper
352
+ it(qase.projects({ PROJ1: [100], PROJ2: [200] }, 'login flow'), () => { ... });
353
+ ```
354
+
355
+ **Tags (Cucumber/BDD):** `@qaseid.PROJ1(100) @qaseid.PROJ2(200)`.
356
+
357
+ #### Playwright
358
+
359
+ - **Single project:** `qase(caseId, name)` or `qase.id([1, 2])` in test.
360
+ - **Multi-project:** `qase.projects(mapping)` inside the test (metadata, not title).
361
+
362
+ ```js
363
+ const { test } = require('@playwright/test');
364
+ const { qase } = require('playwright-qase-reporter');
365
+
366
+ // Multi-project: set mapping inside the test
367
+ test('login and checkout', async ({ page }) => {
368
+ qase.projects({ PROJ1: [1, 2], PROJ2: [3] });
369
+ await page.goto('/login');
370
+ // ...
371
+ });
372
+
373
+ // Single project
374
+ test(qase(1, 'single project test'), async ({ page }) => { ... });
375
+ ```
376
+
377
+ #### Mocha
378
+
379
+ - **Single project:** `qase(caseId, name)`.
380
+ - **Multi-project:** `qase.projects(mapping, name)`.
381
+
382
+ ```js
383
+ const { qase } = require('mocha-qase-reporter');
384
+
385
+ it(qase(100, 'login flow'), function () { ... });
386
+ it(qase.projects({ PROJ1: [100], PROJ2: [200] }, 'login flow'), function () { ... });
387
+ ```
388
+
389
+ #### WDIO (WebdriverIO)
390
+
391
+ - **Single project:** `qase(qaseId, name)`.
392
+ - **Multi-project:** `qase.projects(mapping, name)`.
393
+
394
+ ```js
395
+ const { qase } = require('wdio-qase-reporter');
396
+
397
+ it(qase(1, 'should work'), async () => { ... });
398
+ it(qase.projects({ PROJ1: [100], PROJ2: [200] }, 'Login flow'), async () => { ... });
399
+ ```
400
+
401
+ You can still type markers manually in the title (e.g. `(Qase PROJ1: 100) (Qase PROJ2: 200)`); the helpers avoid typos and keep the format consistent.
402
+
403
+ #### Summary
404
+
405
+ | Framework | Single project (legacy) | Multi-project (project: IDs in title or API) |
406
+ |------------|-----------------------------|--------------------------------------------------|
407
+ | **Vitest** | `(Qase ID: 123)` in title | `(Qase PROJ1: 123) (Qase PROJ2: 456)` in title |
408
+ | **Jest** | `(Qase ID: 123)` in title | `(Qase PROJ1: 123) (Qase PROJ2: 456)` in title |
409
+ | **Cypress**| `(Qase ID: 123)` or `@qaseid(123)` | `(Qase PROJ1: 123) (Qase PROJ2: 456)` or `@qaseid.PROJ1(123) @qaseid.PROJ2(456)` |
410
+ | **Playwright** | `qase(1, 'name')` or metadata | `qase.projects({ PROJ1: [1, 2], PROJ2: [3] })` in test |
411
+ | **Mocha** | `(Qase ID: 123)` in title | `(Qase PROJ1: 123) (Qase PROJ2: 456)` in title |
412
+ | **WDIO** | `(Qase ID: 123)` in title | `(Qase PROJ1: 123) (Qase PROJ2: 456)` in title |
413
+
414
+ - **Title format:** `(Qase PROJECT_CODE: id1,id2,...)` — space after `Qase`, project code (letters, numbers, underscores), colon, then one or more IDs separated by commas. Several projects = several such blocks in one title.
415
+ - **Cypress tags:** `@qaseid.PROJECT_CODE(id1,id2,...)`.
416
+ - **Playwright:** `qase.projects({ PROJECT_CODE: [id1, id2, ...], ... })`; project codes must match `testops_multi.projects[].code`.
417
+
418
+ Tests that do not specify any multi-project mapping are sent to `default_project` (or the first project) using their usual single-project ID, if any.
package/changelog.md CHANGED
@@ -1,3 +1,20 @@
1
+ # qase-javascript-commons@2.5.1
2
+
3
+ ## What's new
4
+
5
+ Fixed issue with incorrect test status determination.
6
+
7
+ # qase-javascript-commons@2.5.0
8
+
9
+ ## What's new
10
+
11
+ Added **multi-project support** (`testops_multi` mode):
12
+
13
+ - New mode `testops_multi` sends results to multiple Qase projects in one run; each project gets its own run.
14
+ - New field `testops_project_mapping` on `TestResultType`: project code → list of test case IDs. Helpers: `setTestopsProjectMapping()`, `getTestopsProjectMapping()`, `getTestopsIdsForProject()`, `getProjects()`.
15
+ - New config: `testops_multi.default_project` and `testops_multi.projects[]` with `code`, `run`, `plan`, `environment` per project.
16
+ - New reporter `TestOpsMultiReporter`; selected when `mode` is `testops_multi`. Single-project behavior is unchanged.
17
+
1
18
  # qase-javascript-commons@2.4.18
2
19
 
3
20
  ## What's new
@@ -184,6 +184,88 @@ export declare const configValidationSchema: {
184
184
  };
185
185
  };
186
186
  };
187
+ testops_multi: {
188
+ type: string;
189
+ nullable: boolean;
190
+ properties: {
191
+ default_project: {
192
+ type: string;
193
+ nullable: boolean;
194
+ };
195
+ projects: {
196
+ type: string;
197
+ items: {
198
+ type: string;
199
+ properties: {
200
+ code: {
201
+ type: string;
202
+ nullable: boolean;
203
+ };
204
+ run: {
205
+ type: string;
206
+ nullable: boolean;
207
+ properties: {
208
+ id: {
209
+ type: string;
210
+ nullable: boolean;
211
+ };
212
+ title: {
213
+ type: string;
214
+ nullable: boolean;
215
+ };
216
+ description: {
217
+ type: string;
218
+ nullable: boolean;
219
+ };
220
+ complete: {
221
+ type: string;
222
+ nullable: boolean;
223
+ };
224
+ tags: {
225
+ type: string;
226
+ items: {
227
+ type: string;
228
+ };
229
+ nullable: boolean;
230
+ };
231
+ externalLink: {
232
+ type: string;
233
+ nullable: boolean;
234
+ properties: {
235
+ type: {
236
+ type: string;
237
+ enum: ExternalLinkType[];
238
+ };
239
+ link: {
240
+ type: string;
241
+ };
242
+ };
243
+ required: string[];
244
+ };
245
+ };
246
+ };
247
+ plan: {
248
+ type: string;
249
+ nullable: boolean;
250
+ properties: {
251
+ id: {
252
+ type: string;
253
+ nullable: boolean;
254
+ };
255
+ };
256
+ };
257
+ environment: {
258
+ type: string;
259
+ nullable: boolean;
260
+ };
261
+ };
262
+ required: string[];
263
+ };
264
+ nullable: boolean;
265
+ };
266
+ };
267
+ required: string[];
268
+ };
187
269
  report: {
188
270
  type: string;
189
271
  nullable: boolean;
@@ -12,12 +12,12 @@ exports.configValidationSchema = {
12
12
  properties: {
13
13
  mode: {
14
14
  type: 'string',
15
- enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.off],
15
+ enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.testops_multi, options_1.ModeEnum.off],
16
16
  nullable: true,
17
17
  },
18
18
  fallback: {
19
19
  type: 'string',
20
- enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.off],
20
+ enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.testops_multi, options_1.ModeEnum.off],
21
21
  nullable: true,
22
22
  },
23
23
  debug: {
@@ -187,6 +187,69 @@ exports.configValidationSchema = {
187
187
  },
188
188
  },
189
189
  },
190
+ testops_multi: {
191
+ type: 'object',
192
+ nullable: true,
193
+ properties: {
194
+ default_project: {
195
+ type: 'string',
196
+ nullable: true,
197
+ },
198
+ projects: {
199
+ type: 'array',
200
+ items: {
201
+ type: 'object',
202
+ properties: {
203
+ code: {
204
+ type: 'string',
205
+ nullable: true,
206
+ },
207
+ run: {
208
+ type: 'object',
209
+ nullable: true,
210
+ properties: {
211
+ id: { type: 'number', nullable: true },
212
+ title: { type: 'string', nullable: true },
213
+ description: { type: 'string', nullable: true },
214
+ complete: { type: 'boolean', nullable: true },
215
+ tags: {
216
+ type: 'array',
217
+ items: { type: 'string' },
218
+ nullable: true,
219
+ },
220
+ externalLink: {
221
+ type: 'object',
222
+ nullable: true,
223
+ properties: {
224
+ type: {
225
+ type: 'string',
226
+ enum: [TestOpsOptionsType_1.ExternalLinkType.JIRA_CLOUD, TestOpsOptionsType_1.ExternalLinkType.JIRA_SERVER],
227
+ },
228
+ link: { type: 'string' },
229
+ },
230
+ required: ['type', 'link'],
231
+ },
232
+ },
233
+ },
234
+ plan: {
235
+ type: 'object',
236
+ nullable: true,
237
+ properties: {
238
+ id: { type: 'number', nullable: true },
239
+ },
240
+ },
241
+ environment: {
242
+ type: 'string',
243
+ nullable: true,
244
+ },
245
+ },
246
+ required: ['code'],
247
+ },
248
+ nullable: true,
249
+ },
250
+ },
251
+ required: ['projects'],
252
+ },
190
253
  report: {
191
254
  type: 'object',
192
255
  nullable: true,
@@ -12,12 +12,12 @@ exports.envValidationSchema = {
12
12
  properties: {
13
13
  [env_enum_1.EnvEnum.mode]: {
14
14
  type: 'string',
15
- enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.off],
15
+ enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.testops_multi, options_1.ModeEnum.off],
16
16
  nullable: true,
17
17
  },
18
18
  [env_enum_1.EnvEnum.fallback]: {
19
19
  type: 'string',
20
- enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.off],
20
+ enum: [options_1.ModeEnum.report, options_1.ModeEnum.testops, options_1.ModeEnum.testops_multi, options_1.ModeEnum.off],
21
21
  nullable: true,
22
22
  },
23
23
  [env_enum_1.EnvEnum.debug]: {
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export * from './reporters';
8
8
  export * from './writer';
9
9
  export * from './utils/get-package-version';
10
10
  export * from './utils/mimeTypes';
11
+ export * from './utils/project-mapping-utils';
11
12
  export * from './utils/signature';
12
13
  export * from './utils/test-status-utils';
13
14
  export * from './steps/step';
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ __exportStar(require("./reporters"), exports);
24
24
  __exportStar(require("./writer"), exports);
25
25
  __exportStar(require("./utils/get-package-version"), exports);
26
26
  __exportStar(require("./utils/mimeTypes"), exports);
27
+ __exportStar(require("./utils/project-mapping-utils"), exports);
27
28
  __exportStar(require("./utils/signature"), exports);
28
29
  __exportStar(require("./utils/test-status-utils"), exports);
29
30
  __exportStar(require("./steps/step"), exports);
@@ -1,3 +1,21 @@
1
+ /**
2
+ * Per-project configuration for multi-project (testops_multi) mode.
3
+ */
4
+ export interface TestOpsProjectConfigType {
5
+ code: string;
6
+ run?: TestOpsRunType;
7
+ plan?: TestOpsPlanType;
8
+ environment?: string;
9
+ }
10
+ /**
11
+ * Multi-project TestOps configuration.
12
+ */
13
+ export interface TestOpsMultiConfigType {
14
+ /** Default project for tests without explicit mapping (and for results without any case ID). */
15
+ default_project?: string;
16
+ /** List of project configurations. */
17
+ projects: TestOpsProjectConfigType[];
18
+ }
1
19
  export interface TestOpsOptionsType {
2
20
  project: string;
3
21
  uploadAttachments?: boolean | undefined;
@@ -1,5 +1,5 @@
1
1
  export { TestResultType } from './test-result';
2
- export type { Relation, Suite, SuiteData } from './test-result';
2
+ export type { Relation, Suite, SuiteData, TestopsProjectMapping } from './test-result';
3
3
  export { TestExecution, TestStatusEnum } from './test-execution';
4
4
  export { TestStepType, StepType } from './test-step';
5
5
  export { StepStatusEnum } from './step-execution';
@@ -8,4 +8,4 @@ export type { Report } from './report';
8
8
  export { CompoundError } from './error';
9
9
  export type { ConfigurationGroup, ConfigurationItem, ConfigurationGroupResponse } from './configuration';
10
10
  export { ExternalLinkType } from './config/TestOpsOptionsType';
11
- export type { TestOpsOptionsType, TestOpsApiType, TestOpsRunType, TestOpsPlanType, TestOpsBatchType, TestOpsConfigurationType, TestOpsConfigurationValueType, TestOpsExternalLinkType } from './config/TestOpsOptionsType';
11
+ export type { TestOpsOptionsType, TestOpsApiType, TestOpsRunType, TestOpsPlanType, TestOpsBatchType, TestOpsConfigurationType, TestOpsConfigurationValueType, TestOpsExternalLinkType, TestOpsProjectConfigType, TestOpsMultiConfigType } from './config/TestOpsOptionsType';
@@ -1,12 +1,23 @@
1
1
  import { TestStepType } from './test-step';
2
2
  import { Attachment } from './attachment';
3
3
  import { TestExecution } from './test-execution';
4
+ /**
5
+ * Project code to test case IDs mapping for multi-project support.
6
+ * Key: project code (string), Value: array of test case IDs (numbers).
7
+ */
8
+ export type TestopsProjectMapping = Record<string, number[]>;
4
9
  export declare class TestResultType {
5
10
  id: string;
6
11
  title: string;
7
12
  signature: string;
8
13
  run_id: number | null;
9
14
  testops_id: number | number[] | null;
15
+ /**
16
+ * Multi-project mapping: project code -> array of test case IDs.
17
+ * When set, overrides testops_id for multi-project mode.
18
+ * If empty/null, fall back to testops_id for single project.
19
+ */
20
+ testops_project_mapping: TestopsProjectMapping | null;
10
21
  execution: TestExecution;
11
22
  fields: Record<string, string>;
12
23
  attachments: Attachment[];
@@ -19,6 +30,22 @@ export declare class TestResultType {
19
30
  message: string | null;
20
31
  preparedAttachments?: string[];
21
32
  constructor(title: string);
33
+ /**
34
+ * Set test case IDs for a specific project in multi-project mapping.
35
+ */
36
+ setTestopsProjectMapping(projectCode: string, testopsIds: number[]): void;
37
+ /**
38
+ * Get the entire project-to-IDs mapping.
39
+ */
40
+ getTestopsProjectMapping(): TestopsProjectMapping | null;
41
+ /**
42
+ * Get test case IDs for a specific project.
43
+ */
44
+ getTestopsIdsForProject(projectCode: string): number[] | undefined;
45
+ /**
46
+ * Get list of all project codes in the mapping.
47
+ */
48
+ getProjects(): string[];
22
49
  }
23
50
  export interface Relation {
24
51
  suite?: Suite;
@@ -8,6 +8,12 @@ class TestResultType {
8
8
  signature;
9
9
  run_id;
10
10
  testops_id;
11
+ /**
12
+ * Multi-project mapping: project code -> array of test case IDs.
13
+ * When set, overrides testops_id for multi-project mode.
14
+ * If empty/null, fall back to testops_id for single project.
15
+ */
16
+ testops_project_mapping;
11
17
  execution;
12
18
  fields;
13
19
  attachments;
@@ -25,6 +31,7 @@ class TestResultType {
25
31
  this.signature = '';
26
32
  this.run_id = null;
27
33
  this.testops_id = null;
34
+ this.testops_project_mapping = null;
28
35
  this.execution = new test_execution_1.TestExecution();
29
36
  this.fields = {};
30
37
  this.attachments = [];
@@ -37,5 +44,32 @@ class TestResultType {
37
44
  this.message = null;
38
45
  this.preparedAttachments = [];
39
46
  }
47
+ /**
48
+ * Set test case IDs for a specific project in multi-project mapping.
49
+ */
50
+ setTestopsProjectMapping(projectCode, testopsIds) {
51
+ if (!this.testops_project_mapping) {
52
+ this.testops_project_mapping = {};
53
+ }
54
+ this.testops_project_mapping[projectCode] = testopsIds;
55
+ }
56
+ /**
57
+ * Get the entire project-to-IDs mapping.
58
+ */
59
+ getTestopsProjectMapping() {
60
+ return this.testops_project_mapping;
61
+ }
62
+ /**
63
+ * Get test case IDs for a specific project.
64
+ */
65
+ getTestopsIdsForProject(projectCode) {
66
+ return this.testops_project_mapping?.[projectCode];
67
+ }
68
+ /**
69
+ * Get list of all project codes in the mapping.
70
+ */
71
+ getProjects() {
72
+ return this.testops_project_mapping ? Object.keys(this.testops_project_mapping) : [];
73
+ }
40
74
  }
41
75
  exports.TestResultType = TestResultType;
@@ -4,5 +4,7 @@
4
4
  export declare enum ModeEnum {
5
5
  report = "report",
6
6
  testops = "testops",
7
+ /** Multi-project mode: send results to multiple Qase projects. */
8
+ testops_multi = "testops_multi",
7
9
  off = "off"
8
10
  }