testcafe-reporter-qase 2.1.2 → 2.2.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/changelog.md CHANGED
@@ -1,3 +1,16 @@
1
+ # qase-testcafe@2.2.0
2
+
3
+ ## What's new
4
+
5
+ - Added support for multi-project support.
6
+
7
+ # qase-testcafe@2.1.3
8
+
9
+ ## What's new
10
+
11
+ - Added support for status filter in the test run.
12
+ - Improved error handling.
13
+
1
14
  # qase-testcafe@2.1.0
2
15
 
3
16
  ## What's new
package/dist/qase.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { StepFunction } from 'qase-javascript-commons';
2
+ import type { TestopsProjectMapping } from 'qase-javascript-commons';
2
3
  export declare class qase {
3
4
  private static _qaseID;
4
5
  private static _qaseTitle;
@@ -6,6 +7,16 @@ export declare class qase {
6
7
  private static _qaseParameters;
7
8
  private static _qaseGroupParameters;
8
9
  private static _qaseIgnore;
10
+ private static _qaseProjects;
11
+ /**
12
+ * Set multi-project mapping (for testops_multi mode). Project code → test case IDs.
13
+ * Don't forget to call `create` after setting parameters.
14
+ * @param {TestopsProjectMapping} mapping — e.g. { PROJ1: [1, 2], PROJ2: [3] }
15
+ * @example
16
+ * const q = qase.projects({ PROJ1: [1], PROJ2: [2] }).create();
17
+ * test.meta(q)('Test reported to two projects', async t => { ... });
18
+ */
19
+ static projects: (mapping: TestopsProjectMapping) => typeof qase;
9
20
  /**
10
21
  * Set a Qase ID for the test case
11
22
  * Don't forget to call `create` method after setting all the necessary parameters
@@ -116,6 +127,7 @@ export declare class qase {
116
127
  QaseParameters: string;
117
128
  QaseGroupParameters: string;
118
129
  QaseIgnore: string;
130
+ QaseProjects: string;
119
131
  };
120
132
  private static toNormalizeRecord;
121
133
  }
package/dist/qase.js CHANGED
@@ -16,6 +16,21 @@ class qase {
16
16
  static _qaseParameters = '';
17
17
  static _qaseGroupParameters = '';
18
18
  static _qaseIgnore = '';
19
+ static _qaseProjects = '';
20
+ /**
21
+ * Set multi-project mapping (for testops_multi mode). Project code → test case IDs.
22
+ * Don't forget to call `create` after setting parameters.
23
+ * @param {TestopsProjectMapping} mapping — e.g. { PROJ1: [1, 2], PROJ2: [3] }
24
+ * @example
25
+ * const q = qase.projects({ PROJ1: [1], PROJ2: [2] }).create();
26
+ * test.meta(q)('Test reported to two projects', async t => { ... });
27
+ */
28
+ static projects = (mapping) => {
29
+ if (mapping && typeof mapping === 'object' && Object.keys(mapping).length > 0) {
30
+ this._qaseProjects = JSON.stringify(mapping);
31
+ }
32
+ return this;
33
+ };
19
34
  /**
20
35
  * Set a Qase ID for the test case
21
36
  * Don't forget to call `create` method after setting all the necessary parameters
@@ -114,7 +129,12 @@ class qase {
114
129
  static step = async (name, body) => {
115
130
  const runningStep = new qase_javascript_commons_1.QaseStep(name);
116
131
  // eslint-disable-next-line @typescript-eslint/require-await
117
- await runningStep.run(body, async (step) => global.Qase.step(step));
132
+ await runningStep.run(body, async (step) => {
133
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
134
+ // @ts-expect-error - global.Qase is dynamically added at runtime
135
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
136
+ return global.Qase.step(step);
137
+ });
118
138
  };
119
139
  /**
120
140
  * Add an attachment to the test case
@@ -131,6 +151,8 @@ class qase {
131
151
  for (const file of attach.paths) {
132
152
  const attachmentName = path_1.default.basename(file);
133
153
  const contentType = (0, qase_javascript_commons_1.getMimeTypes)(file);
154
+ // @ts-expect-error - global.Qase is dynamically added at runtime
155
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
134
156
  global.Qase.attachment({
135
157
  file_path: file,
136
158
  size: 0,
@@ -143,6 +165,8 @@ class qase {
143
165
  return;
144
166
  }
145
167
  if (attach.content) {
168
+ // @ts-expect-error - global.Qase is dynamically added at runtime
169
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
146
170
  global.Qase.attachment({
147
171
  file_path: null,
148
172
  size: attach.content.length,
@@ -170,6 +194,7 @@ class qase {
170
194
  QaseParameters: this._qaseParameters,
171
195
  QaseGroupParameters: this._qaseGroupParameters,
172
196
  QaseIgnore: this._qaseIgnore,
197
+ QaseProjects: this._qaseProjects,
173
198
  };
174
199
  this._qaseID = '';
175
200
  this._qaseTitle = '';
@@ -177,6 +202,7 @@ class qase {
177
202
  this._qaseParameters = '';
178
203
  this._qaseGroupParameters = '';
179
204
  this._qaseIgnore = '';
205
+ this._qaseProjects = '';
180
206
  return meta;
181
207
  };
182
208
  static toNormalizeRecord = (record) => {
package/dist/reporter.js CHANGED
@@ -13,6 +13,7 @@ var metadataEnum;
13
13
  metadataEnum["groupParameters"] = "QaseGroupParameters";
14
14
  metadataEnum["oldID"] = "CID";
15
15
  metadataEnum["ignore"] = "QaseIgnore";
16
+ metadataEnum["projects"] = "QaseProjects";
16
17
  })(metadataEnum || (metadataEnum = {}));
17
18
  /**
18
19
  * @class TestcafeQaseReporter
@@ -28,7 +29,15 @@ class TestcafeQaseReporter {
28
29
  return qase_javascript_commons_1.TestStatusEnum.skipped;
29
30
  }
30
31
  else if (testRunInfo.errs.length > 0) {
31
- return qase_javascript_commons_1.TestStatusEnum.failed;
32
+ // Create error object for status determination
33
+ const firstError = testRunInfo.errs[0];
34
+ const error = new Error(firstError?.errMsg ?? 'Test failed');
35
+ if (firstError?.callsite) {
36
+ const filename = firstError.callsite.filename ?? 'unknown';
37
+ const lineNum = firstError.callsite.lineNum ?? 'unknown';
38
+ error.stack = `Error: ${firstError.errMsg}\n at ${filename}:${lineNum}`;
39
+ }
40
+ return (0, qase_javascript_commons_1.determineTestStatus)(error, 'failed');
32
41
  }
33
42
  return qase_javascript_commons_1.TestStatusEnum.passed;
34
43
  }
@@ -71,6 +80,7 @@ class TestcafeQaseReporter {
71
80
  frameworkName: 'testcafe',
72
81
  reporterName: 'testcafe-reporter-qase',
73
82
  });
83
+ // @ts-expect-error - global.Qase is dynamically added at runtime
74
84
  global.Qase = new global_1.Qase(this);
75
85
  }
76
86
  addStep(step) {
@@ -108,7 +118,8 @@ class TestcafeQaseReporter {
108
118
  .join('\n');
109
119
  const attachments = TestcafeQaseReporter.transformAttachments(testRunInfo.screenshots);
110
120
  attachments.push(...this.attachments);
111
- await this.reporter.addTestResult({
121
+ const projectMapping = metadata[metadataEnum.projects];
122
+ const result = {
112
123
  author: null,
113
124
  execution: {
114
125
  status: TestcafeQaseReporter.getStatus(testRunInfo),
@@ -140,7 +151,9 @@ class TestcafeQaseReporter {
140
151
  testops_id: metadata[metadataEnum.id].length > 0 ? metadata[metadataEnum.id] : null,
141
152
  title: metadata[metadataEnum.title] != undefined ? metadata[metadataEnum.title] : title,
142
153
  attachments: attachments,
143
- });
154
+ testops_project_mapping: (projectMapping && Object.keys(projectMapping).length > 0) ? projectMapping : null,
155
+ };
156
+ await this.reporter.addTestResult(result);
144
157
  };
145
158
  /**
146
159
  * @returns {Promise<void>}
@@ -156,6 +169,7 @@ class TestcafeQaseReporter {
156
169
  QaseParameters: {},
157
170
  QaseGroupParameters: {},
158
171
  QaseIgnore: false,
172
+ QaseProjects: {},
159
173
  };
160
174
  if (meta[metadataEnum.oldID] !== undefined && meta[metadataEnum.oldID] !== '') {
161
175
  const v = meta[metadataEnum.oldID].split(',');
@@ -180,6 +194,17 @@ class TestcafeQaseReporter {
180
194
  if (meta[metadataEnum.ignore] !== undefined && meta[metadataEnum.ignore] !== '') {
181
195
  metadata.QaseIgnore = meta[metadataEnum.ignore] === 'true';
182
196
  }
197
+ if (meta[metadataEnum.projects] !== undefined && meta[metadataEnum.projects] !== '') {
198
+ try {
199
+ const parsed = JSON.parse(meta[metadataEnum.projects]);
200
+ if (parsed && typeof parsed === 'object') {
201
+ metadata.QaseProjects = parsed;
202
+ }
203
+ }
204
+ catch {
205
+ // ignore invalid JSON
206
+ }
207
+ }
183
208
  return metadata;
184
209
  }
185
210
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testcafe-reporter-qase",
3
- "version": "2.1.2",
3
+ "version": "2.2.0",
4
4
  "description": "Qase TMS TestCafe Reporter",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -40,16 +40,16 @@
40
40
  "author": "Qase Team <support@qase.io>",
41
41
  "license": "Apache-2.0",
42
42
  "dependencies": {
43
- "qase-javascript-commons": "~2.4.1",
44
- "uuid": "^9.0.0"
43
+ "qase-javascript-commons": "~2.5.0",
44
+ "uuid": "^9.0.1"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "testcafe": ">=2.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@jest/globals": "^29.5.0",
51
- "@types/jest": "^29.5.2",
52
- "jest": "^29.5.0",
53
- "ts-jest": "^29.1.0"
50
+ "@jest/globals": "^29.7.0",
51
+ "@types/jest": "^29.5.14",
52
+ "jest": "^29.7.0",
53
+ "ts-jest": "^29.4.5"
54
54
  }
55
55
  }
@@ -2,7 +2,9 @@
2
2
  "extends": "./tsconfig.json",
3
3
 
4
4
  "compilerOptions": {
5
- "noEmit": false
5
+ "noEmit": false,
6
+ "skipLibCheck": true,
7
+ "types": []
6
8
  },
7
9
 
8
10
  "include": ["./src/**/*.ts"]