testcafe-reporter-qase 2.0.3 → 2.0.4

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,15 +20,28 @@ To update a test project using testcafe-reporter-qaser@v1 to version 2:
20
20
  The TestCafe reporter has the ability to auto-generate test cases
21
21
  and suites from your test data.
22
22
 
23
- But if necessary, you can independently register the ID of already
24
- existing test cases from TMS before the executing tests. Meta key should be `CID`.
25
- You should assign list of case IDs to it, e.g.:
23
+ You can also annotate the tests with the IDs of existing test cases
24
+ from Qase.io before executing tests. It's a more reliable way to bind
25
+ autotests to test cases, that persists when you rename, move, or
26
+ parameterize your tests.
26
27
 
27
- ```js
28
- test.meta('CID', [1])('Text typing basics', async (t) => {
29
- await t;
30
- });
28
+ ### Metadata
29
+
30
+ - `qase.title` - set the title of the test case
31
+ - `qase.fields` - set the fields of the test case
32
+ - `qase.suite` - set the suite of the test case
33
+ - `qase.comment` - set the comment of the test case
34
+ - `qase.parameters` - set the parameters of the test case
35
+ - `qase.groupParameters` - set the group parameters of the test case
36
+ - `qase.ignore` - ignore the test case in Qase. The test will be executed, but the results will not be sent to Qase.
37
+ - `qase.step` - create a step in the test case
38
+ - `qase.attach` - attach a file or content to the test case
39
+
40
+ For detailed instructions on using annotations and methods, refer to [Usage](docs/usage.md).
31
41
 
42
+ For example:
43
+
44
+ ```js
32
45
  const q = qase.id(1)
33
46
  .title('Text typing basics')
34
47
  .field({ 'severity': 'high' })
@@ -98,16 +111,8 @@ Example `qase.config.json` file:
98
111
  }
99
112
  ```
100
113
 
101
- Supported ENV variables:
102
-
103
- - `QASE_MODE` - Same as `mode`
104
- - `QASE_DEBUG` - Same as `debug`
105
- - `QASE_ENVIRONMENT` - Same as `environment`
106
- - `QASE_TESTOPS_API_TOKEN` - Same as `testops.api.token`
107
- - `QASE_TESTOPS_PROJECT` - Same as `testops.project`
108
- - `QASE_TESTOPS_RUN_ID` - Pass Run ID from ENV and override reporter option `testops.run.id`
109
- - `QASE_TESTOPS_RUN_TITLE` - Same as `testops.run.title`
110
- - `QASE_TESTOPS_RUN_DESCRIPTION` - Same as `testops.run.description`
114
+ Check out the example of configuration for multiple reporters in the
115
+ [demo project](../examples/testcafe/qase.config.json).
111
116
 
112
117
  ## Requirements
113
118
 
package/changelog.md CHANGED
@@ -1,3 +1,28 @@
1
+ # qase-testcafe@2.0.4
2
+
3
+ ## What's new
4
+
5
+ Support `step` and `attach` methods for test cases.
6
+
7
+ ```javascript
8
+ import { qase } from 'testcafe-qase-reporter/qase';
9
+
10
+ test('test', async (t) => {
11
+ qase.attach({ name: 'attachment.txt', content: 'Hello, world!', contentType: 'text/plain' });
12
+
13
+ await qase.step('Step 1', async (s1) => {
14
+ await s1.step('Step 1.1', async (s11) => {
15
+ await s11.step('Step 1.1.1', async (s111) => {
16
+ s11.attach({ name: 'attachment.txt', content: 'Hello, world!', contentType: 'text/plain' });
17
+ await s111.expect(true).ok();
18
+ });
19
+ });
20
+ await t.expect(true).ok();
21
+ });
22
+ await t.expect(true).ok();
23
+ });
24
+ ```
25
+
1
26
  # qase-testcafe@2.0.3
2
27
 
3
28
  ## What's new
package/dist/factory.d.ts CHANGED
@@ -7,6 +7,7 @@ export declare const factory: (options: TestcafeQaseOptionsType) => {
7
7
  noColors: boolean;
8
8
  reportTaskStart: () => void;
9
9
  reportFixtureStart: () => void;
10
+ reportTestStart: () => void;
10
11
  reportTestDone(name: string, testRunInfo: TestRunInfoType, meta: Record<string, string>): Promise<void>;
11
12
  reportTaskDone: () => Promise<void>;
12
13
  };
package/dist/factory.js CHANGED
@@ -16,6 +16,9 @@ const factory = (options) => {
16
16
  reportFixtureStart: () => {
17
17
  /* empty */
18
18
  },
19
+ reportTestStart: () => {
20
+ reporter.reportTestStart();
21
+ },
19
22
  async reportTestDone(name, testRunInfo, meta) {
20
23
  return reporter.reportTestDone(name, testRunInfo, meta,
21
24
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -0,0 +1,16 @@
1
+ import { TestcafeQaseReporter } from './reporter';
2
+ import { Attachment, TestStepType } from 'qase-javascript-commons';
3
+ declare global {
4
+ namespace NodeJS {
5
+ interface Global {
6
+ Qase: Qase;
7
+ }
8
+ }
9
+ }
10
+ export declare class Qase {
11
+ private reporter;
12
+ constructor(reporter: TestcafeQaseReporter);
13
+ step(step: TestStepType): void;
14
+ attachment(attachment: Attachment): void;
15
+ }
16
+ export {};
package/dist/global.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Qase = void 0;
4
+ class Qase {
5
+ constructor(reporter) {
6
+ this.reporter = reporter;
7
+ }
8
+ step(step) {
9
+ this.reporter.addStep(step);
10
+ }
11
+ attachment(attachment) {
12
+ this.reporter.addAttachment(attachment);
13
+ }
14
+ }
15
+ exports.Qase = Qase;
package/dist/qase.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { StepFunction } from 'qase-javascript-commons';
1
2
  export declare class qase {
2
3
  private static _qaseID;
3
4
  private static _qaseTitle;
@@ -70,6 +71,35 @@ export declare class qase {
70
71
  * test.meta({userField: 123, ...q})('Test case title', async t => { ... });
71
72
  */
72
73
  static ignore: () => typeof qase;
74
+ /**
75
+ * Add a step to the test case
76
+ * @param name
77
+ * @param body
78
+ * @example
79
+ * test.meta({userField: 123, ...q})('Test case title', async t => {
80
+ * await qase.step("Step", () => {
81
+ * expect(true).toBe(true);
82
+ * });
83
+ * expect(true).toBe(true);
84
+ * });
85
+ */
86
+ static step: (name: string, body: StepFunction) => Promise<void>;
87
+ /**
88
+ * Add an attachment to the test case
89
+ * @param attach
90
+ * @example
91
+ * test.meta({userField: 123, ...q})('Test case title', async t => {
92
+ * qase.attach({ name: 'attachment.txt', content: 'Hello, world!', type: 'text/plain' });
93
+ * qase.attach({ paths: ['/path/to/file', '/path/to/another/file']});
94
+ * expect(true).toBe(true);
95
+ * });
96
+ */
97
+ static attach: (attach: {
98
+ name?: string;
99
+ type?: string;
100
+ content?: string;
101
+ paths?: string[];
102
+ }) => void;
73
103
  /**
74
104
  * Create a Qase metadata
75
105
  * Call this method after setting all the necessary parameters
package/dist/qase.js CHANGED
@@ -1,8 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  var _a;
3
6
  Object.defineProperty(exports, "__esModule", { value: true });
4
7
  exports.qase = void 0;
5
8
  // eslint-disable-next-line @typescript-eslint/no-extraneous-class
9
+ const path_1 = __importDefault(require("path"));
10
+ const qase_javascript_commons_1 = require("qase-javascript-commons");
11
+ const uuid_1 = require("uuid");
6
12
  class qase {
7
13
  }
8
14
  exports.qase = qase;
@@ -96,6 +102,60 @@ qase.ignore = () => {
96
102
  _a._qaseIgnore = 'true';
97
103
  return _a;
98
104
  };
105
+ /**
106
+ * Add a step to the test case
107
+ * @param name
108
+ * @param body
109
+ * @example
110
+ * test.meta({userField: 123, ...q})('Test case title', async t => {
111
+ * await qase.step("Step", () => {
112
+ * expect(true).toBe(true);
113
+ * });
114
+ * expect(true).toBe(true);
115
+ * });
116
+ */
117
+ qase.step = async (name, body) => {
118
+ const runningStep = new qase_javascript_commons_1.QaseStep(name);
119
+ // eslint-disable-next-line @typescript-eslint/require-await
120
+ await runningStep.run(body, async (step) => global.Qase.step(step));
121
+ };
122
+ /**
123
+ * Add an attachment to the test case
124
+ * @param attach
125
+ * @example
126
+ * test.meta({userField: 123, ...q})('Test case title', async t => {
127
+ * qase.attach({ name: 'attachment.txt', content: 'Hello, world!', type: 'text/plain' });
128
+ * qase.attach({ paths: ['/path/to/file', '/path/to/another/file']});
129
+ * expect(true).toBe(true);
130
+ * });
131
+ */
132
+ qase.attach = (attach) => {
133
+ if (attach.paths) {
134
+ for (const file of attach.paths) {
135
+ const attachmentName = path_1.default.basename(file);
136
+ const contentType = (0, qase_javascript_commons_1.getMimeTypes)(file);
137
+ global.Qase.attachment({
138
+ file_path: file,
139
+ size: 0,
140
+ id: (0, uuid_1.v4)(),
141
+ file_name: attachmentName,
142
+ mime_type: contentType,
143
+ content: '',
144
+ });
145
+ }
146
+ return;
147
+ }
148
+ if (attach.content) {
149
+ global.Qase.attachment({
150
+ file_path: null,
151
+ size: attach.content.length,
152
+ id: (0, uuid_1.v4)(),
153
+ file_name: attach.name ?? 'attachment',
154
+ mime_type: attach.type ?? 'application/octet-stream',
155
+ content: attach.content,
156
+ });
157
+ }
158
+ };
99
159
  /**
100
160
  * Create a Qase metadata
101
161
  * Call this method after setting all the necessary parameters
@@ -1,4 +1,4 @@
1
- import { ConfigLoader, ConfigType } from 'qase-javascript-commons';
1
+ import { ConfigLoader, ConfigType, Attachment, TestStepType } from 'qase-javascript-commons';
2
2
  interface CallsiteRecordType {
3
3
  filename?: string;
4
4
  lineNum?: number;
@@ -65,15 +65,20 @@ export declare class TestcafeQaseReporter {
65
65
  * @private
66
66
  */
67
67
  private reporter;
68
+ private steps;
69
+ private attachments;
68
70
  /**
69
71
  * @param {TestcafeQaseOptionsType} options
70
72
  * @param {ConfigLoaderInterface} configLoader
71
73
  */
72
74
  constructor(options: TestcafeQaseOptionsType, configLoader?: ConfigLoader<Partial<ConfigType> & Record<string, unknown>>);
75
+ addStep(step: TestStepType): void;
76
+ addAttachment(attachment: Attachment): void;
73
77
  /**
74
78
  * @returns {Promise<void>}
75
79
  */
76
80
  startTestRun: () => void;
81
+ reportTestStart: () => void;
77
82
  /**
78
83
  * @param {string} title
79
84
  * @param {TestRunInfoType} testRunInfo
package/dist/reporter.js CHANGED
@@ -3,6 +3,7 @@ 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
+ const global_1 = require("./global");
6
7
  var metadataEnum;
7
8
  (function (metadataEnum) {
8
9
  metadataEnum["id"] = "QaseID";
@@ -55,12 +56,18 @@ class TestcafeQaseReporter {
55
56
  * @param {ConfigLoaderInterface} configLoader
56
57
  */
57
58
  constructor(options, configLoader = new qase_javascript_commons_1.ConfigLoader()) {
59
+ this.steps = [];
60
+ this.attachments = [];
58
61
  /**
59
62
  * @returns {Promise<void>}
60
63
  */
61
64
  this.startTestRun = () => {
62
65
  this.reporter.startTestRun();
63
66
  };
67
+ this.reportTestStart = () => {
68
+ this.steps = [];
69
+ this.attachments = [];
70
+ };
64
71
  /**
65
72
  * @param {string} title
66
73
  * @param {TestRunInfoType} testRunInfo
@@ -77,6 +84,8 @@ class TestcafeQaseReporter {
77
84
  // eslint-disable-next-line no-control-regex
78
85
  /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ''))
79
86
  .join('\n');
87
+ const attachments = TestcafeQaseReporter.transformAttachments(testRunInfo.screenshots);
88
+ attachments.push(...this.attachments);
80
89
  await this.reporter.addTestResult({
81
90
  author: null,
82
91
  execution: {
@@ -104,11 +113,11 @@ class TestcafeQaseReporter {
104
113
  },
105
114
  run_id: null,
106
115
  signature: this.getSignature(testRunInfo.fixture, title, metadata[metadataEnum.id], metadata[metadataEnum.parameters]),
107
- steps: [],
116
+ steps: this.steps,
108
117
  id: (0, uuid_1.v4)(),
109
118
  testops_id: metadata[metadataEnum.id].length > 0 ? metadata[metadataEnum.id] : null,
110
119
  title: metadata[metadataEnum.title] != undefined ? metadata[metadataEnum.title] : title,
111
- attachments: TestcafeQaseReporter.transformAttachments(testRunInfo.screenshots),
120
+ attachments: attachments,
112
121
  });
113
122
  };
114
123
  /**
@@ -124,6 +133,13 @@ class TestcafeQaseReporter {
124
133
  frameworkName: 'testcafe',
125
134
  reporterName: 'testcafe-reporter-qase',
126
135
  });
136
+ global.Qase = new global_1.Qase(this);
137
+ }
138
+ addStep(step) {
139
+ this.steps.push(step);
140
+ }
141
+ addAttachment(attachment) {
142
+ this.attachments.push(attachment);
127
143
  }
128
144
  getMeta(meta) {
129
145
  const metadata = {
package/docs/usage.md ADDED
@@ -0,0 +1,163 @@
1
+ # Qase Integration in TestCafe
2
+
3
+ This guide demonstrates how to integrate Qase with TestCafe, 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 TestCafe, 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 'testcafe-qase-reporter/qase';
17
+
18
+ const q = qase.id(1).create();
19
+ test.meta(q)('simple test', async (t) => {
20
+ await t.expect(true).ok();
21
+ });
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Adding a Title to a Test
27
+
28
+ You can provide a title for your test using the `qase.title` function. The function accepts a string, which will be
29
+ used as the test's title in Qase. If no title is provided, the test method name will be used by default.
30
+
31
+ ### Example:
32
+
33
+ ```javascript
34
+ import { qase } from 'testcafe-qase-reporter/qase';
35
+
36
+ const q = qase.title('Some title').create();
37
+ test.meta(q)('simple test', async (t) => {
38
+ await t.expect(true).ok();
39
+ });
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Adding Fields to a Test
45
+
46
+ The `qase.fields` function allows you to add additional metadata to a test case. You can specify multiple fields to
47
+ enhance test case information in Qase.
48
+
49
+ ### System Fields:
50
+
51
+ - `description` — Description of the test case.
52
+ - `preconditions` — Preconditions for the test case.
53
+ - `postconditions` — Postconditions for the test case.
54
+ - `severity` — Severity of the test case (e.g., `critical`, `major`).
55
+ - `priority` — Priority of the test case (e.g., `high`, `low`).
56
+ - `layer` — Test layer (e.g., `UI`, `API`).
57
+
58
+ ### Example:
59
+
60
+ ```javascript
61
+ import { qase } from 'testcafe-qase-reporter/qase';
62
+
63
+ const q = qase.fields({ 'severity': 'high', 'priority': 'medium' }).create();
64
+ test.meta(q)('simple test', async (t) => {
65
+ await t.expect(true).ok();
66
+ });
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Ignoring a Test in Qase
72
+
73
+ To exclude a test from being reported to Qase (while still executing the test in TestCafe), use the `qase.ignore`
74
+ function. The test will run, but its result will not be sent to Qase.
75
+
76
+ ### Example:
77
+
78
+ ```javascript
79
+ import { qase } from 'testcafe-qase-reporter/qase';
80
+
81
+ const q = qase.ignore().create();
82
+ test.meta(q)('simple test', async (t) => {
83
+ await t.expect(true).ok();
84
+ });
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Attaching Files to a Test
90
+
91
+ To attach files to a test result, use the `qase.attach` function. This method supports attaching one or multiple files,
92
+ along with optional file names, comments, and file types.
93
+
94
+ ### Example:
95
+
96
+ ```javascript
97
+ import { qase } from 'testcafe-qase-reporter/qase';
98
+
99
+ test('test', async (t) => {
100
+ qase.attach({ name: 'attachment.txt', content: 'Hello, world!', contentType: 'text/plain' });
101
+ qase.attach({ paths: '/path/to/file' });
102
+ qase.attach({ paths: ['/path/to/file', '/path/to/another/file'] });
103
+ await t.expect(true).ok();
104
+ });
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Adding Parameters to a Test
110
+
111
+ You can add parameters to a test case using the `qase.parameters` function. This function accepts an object with
112
+ parameter names and values.
113
+
114
+ ### Example:
115
+
116
+ ```javascript
117
+ import { qase } from 'testcafe-qase-reporter/qase';
118
+
119
+ const q = qase.parameters({ param1: 'value1', param2: 'value2' }).create();
120
+ test.meta(q)('simple test', async (t) => {
121
+ await t.expect(true).ok();
122
+ });
123
+ ```
124
+
125
+ ## Adding Group Parameters to a Test
126
+
127
+ To add group parameters to a test case, use the `qase.groupParameters` function. This function accepts an list with
128
+ group parameter names.
129
+
130
+ ### Example:
131
+
132
+ ```javascript
133
+ import { qase } from 'testcafe-qase-reporter/qase';
134
+
135
+ const q = qase.parameters({ param1: 'value1', param2: 'value2' }).groupParameters(['param1']).create();
136
+ test.meta(q)('simple test', async (t) => {
137
+ await t.expect(true).ok();
138
+ });
139
+ ```
140
+
141
+ ## Adding Steps to a Test
142
+
143
+ You can add steps to a test case using the `qase.step` function. This function accepts a string, which will be used as
144
+ the step description in Qase.
145
+
146
+ ### Example:
147
+
148
+ ```javascript
149
+ import { qase } from 'testcafe-qase-reporter/qase';
150
+
151
+ test('test', async (t) => {
152
+ await qase.step('Step 1', async (s1) => {
153
+ await s1.step('Step 1.1', async (s11) => {
154
+ await s11.step('Step 1.1.1', async (s111) => {
155
+ s11.attach({ name: 'attachment.txt', content: 'Hello, world!', contentType: 'text/plain' });
156
+ await s111.expect(true).ok();
157
+ });
158
+ });
159
+ await t.expect(true).ok();
160
+ });
161
+ await t.expect(true).ok();
162
+ });
163
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testcafe-reporter-qase",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "Qase TMS TestCafe Reporter",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  "author": "Qase Team <support@qase.io>",
41
41
  "license": "Apache-2.0",
42
42
  "dependencies": {
43
- "qase-javascript-commons": "~2.2.0",
43
+ "qase-javascript-commons": "~2.2.4",
44
44
  "uuid": "^9.0.0"
45
45
  },
46
46
  "peerDependencies": {