@qavajs/format-report-portal 0.0.4 → 0.0.6

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,2 +1,9 @@
1
+ ## 0.0.6
2
+ - :rocket: enable support of cucumber logs
3
+
4
+ ## 0.0.5
5
+ - :rocket: updated step logging as nested steps instead plain logs
6
+ - :beetle: added capability to attach multiple attachment to step
7
+
1
8
  ## 0.0.4
2
9
  - :beetle: fixed issue with sending text plain
package/README.MD CHANGED
@@ -15,6 +15,8 @@ module.exports = {
15
15
  ],
16
16
  formatOptions: {
17
17
  rpConfig: {
18
+ enable: true,
19
+ debug: false,
18
20
  token: 'your token',
19
21
  endpoint: 'https://your-rp-instance/api/v1',
20
22
  description: 'Description',
@@ -27,3 +29,9 @@ module.exports = {
27
29
  }
28
30
  }
29
31
  ```
32
+ Option `enable` is set to `true` even if it is not defined explicitly in rpConfig section.
33
+
34
+ ### run e2e test
35
+ add token.json file with rp token and other config
36
+ run
37
+ `npm run test-e2e`
package/index.js CHANGED
@@ -5,9 +5,12 @@ class RPFormatter extends Formatter {
5
5
 
6
6
  constructor(options) {
7
7
  super(options);
8
+ const rpEnable = options.parsedArgvOptions.rpConfig.enable;
9
+ if (rpEnable !== undefined && !rpEnable) return undefined;
8
10
  options.eventBroadcaster.on('envelope', this.processEnvelope.bind(this));
9
11
  this.rpConfig = options.parsedArgvOptions.rpConfig;
10
12
  this.rpClient = new RPClient(this.rpConfig);
13
+ this.promiseQ = [];
11
14
  }
12
15
 
13
16
  async processEnvelope(envelope) {
@@ -28,15 +31,18 @@ class RPFormatter extends Formatter {
28
31
  startTime: this.rpClient.helpers.now(),
29
32
  description: this.rpConfig.description,
30
33
  attributes: this.rpConfig.tags,
31
- mode: this.rpConfig.mode
34
+ mode: this.rpConfig.mode,
35
+ debug: this.rpConfig.debug
32
36
  });
33
37
 
34
38
  this.launchId = launchObj.tempId;
35
39
  this.features = {};
40
+ this.promiseQ.push(launchObj.promise);
36
41
  await launchObj.promise;
37
42
  }
38
43
 
39
44
  async finishLaunch() {
45
+ await Promise.allSettled(this.promiseQ);
40
46
  for (const featureName in this.features) {
41
47
  await this.rpClient.finishTestItem(this.features[featureName], { status: 'PASSED' }).promise;
42
48
  }
@@ -60,6 +66,7 @@ class RPFormatter extends Formatter {
60
66
  type: 'SUITE'
61
67
  }, this.launchId);
62
68
  this.features[featureName] = featureItem.tempId;
69
+ this.promiseQ.push(featureItem.promise);
63
70
  await featureItem.promise;
64
71
  }
65
72
 
@@ -71,36 +78,52 @@ class RPFormatter extends Formatter {
71
78
  startTime: this.rpClient.helpers.now(),
72
79
  type: 'STEP'
73
80
  }, this.launchId, featureTempId);
81
+ this.promiseQ.push(testItem.promise);
74
82
  await testItem.promise;
75
83
 
76
84
  //send steps
77
85
  const steps = this.getStepResults(testCase)
78
86
  for (const step of steps) {
79
- const attachment = step.attachment && step.attachment[0]
80
- ? {
81
- name: 'attachment',
82
- type: step.attachment[0].mediaType,
83
- content: step.attachment[0].mediaType === 'text/plain'
84
- ? Buffer.from(step.attachment[0].body).toString('base64')
85
- : step.attachment[0].body,
87
+ const nestedTestItem = this.rpClient.startTestItem({
88
+ description: 'test description',
89
+ name: this.getStepText(step, steps),
90
+ startTime: this.rpClient.helpers.now(),
91
+ type: 'STEP',
92
+ hasStats: false
93
+ }, this.launchId, testItem.tempId);
94
+ this.promiseQ.push(nestedTestItem.promise);
95
+ await nestedTestItem.promise;
96
+ if (step.result.message) {
97
+ const log = await this.rpClient.sendLog(nestedTestItem.tempId, {
98
+ level: 'ERROR',
99
+ message: this.getMessage(step),
100
+ time: this.rpClient.helpers.now()
101
+ });
102
+ this.promiseQ.push(log.promise);
103
+ await log.promise;
104
+ }
105
+ if (step.attachment) {
106
+ for (const attachment of step.attachment) {
107
+ await this.sendAttachment(attachment, nestedTestItem);
86
108
  }
87
- : undefined;
88
- await this.rpClient.sendLog(testItem.tempId, {
89
- level: step.result.status === Status.PASSED
90
- ? 'INFO'
91
- : 'ERROR',
92
- message: this.getMessage(step),
93
- time: this.rpClient.helpers.now()
94
- }, attachment).promise
109
+ }
110
+ const nestedItemFinish = this.rpClient.finishTestItem(nestedTestItem.tempId, {
111
+ status: this.getStatus(step),
112
+ endTime: this.rpClient.helpers.now()
113
+ });
114
+ this.promiseQ.push(nestedItemFinish.promise);
115
+ await nestedItemFinish.promise;
95
116
  }
96
117
 
97
118
  //finish test item
98
119
  const status = Object.values(testCase.stepResults).some(step => step.status !== Status.PASSED)
99
120
  ? Status.FAILED.toLowerCase()
100
121
  : Status.PASSED.toLowerCase()
101
- await this.rpClient.finishTestItem(testItem.tempId, {
122
+ const testItemFinish = this.rpClient.finishTestItem(testItem.tempId, {
102
123
  status
103
- }).promise;
124
+ });
125
+ this.promiseQ.push(testItemFinish.promise);
126
+ await testItemFinish.promise;
104
127
  }
105
128
 
106
129
  getStepResults(testCase) {
@@ -111,8 +134,8 @@ class RPFormatter extends Formatter {
111
134
  }))
112
135
  }
113
136
 
114
- getMessage(step) {
115
- if (!step.pickle) return 'Hook';
137
+ getStepText(step, steps) {
138
+ if (!step.pickle) return this.hookKeyword(step, steps);
116
139
  const messageParts = [step.pickle.text];
117
140
  if (step.pickle.argument) {
118
141
  if (step.pickle.argument.dataTable) messageParts.push(
@@ -120,11 +143,26 @@ class RPFormatter extends Formatter {
120
143
  )
121
144
  if (step.pickle.argument.docString) messageParts.push(this.formatDocString(step.pickle.argument.docString))
122
145
  }
123
- if (step.result.status === Status.FAILED) messageParts.push(step.result.message)
124
146
 
125
147
  return messageParts.join('\n')
126
148
  }
127
149
 
150
+ hookKeyword(step, steps) {
151
+ const stepsBefore = steps.slice(0, steps.findIndex((element) => element === step));
152
+ return stepsBefore.every(element => element.pickle === undefined) ? 'Before' : 'After'
153
+ }
154
+ getMessage(step) {
155
+ return step.result.message
156
+ }
157
+
158
+ getStatus(step) {
159
+ switch (step.result.status) {
160
+ case Status.PASSED: return Status.PASSED.toLowerCase();
161
+ case Status.SKIPPED: return Status.SKIPPED.toLowerCase();
162
+ default: return Status.FAILED.toLowerCase()
163
+ }
164
+ }
165
+
128
166
  formatTable(dataTable) {
129
167
  const TR = '<tr>';
130
168
  const TRE = '</tr>';
@@ -141,6 +179,36 @@ class RPFormatter extends Formatter {
141
179
  formatTags(tags) {
142
180
  return tags.map(tag => '<code>' + tag.name + '</code>').join('')
143
181
  }
182
+
183
+ prepareContent(attachment) {
184
+ return ['text/plain', 'application/json'].includes(attachment.mediaType)
185
+ ? Buffer.from(attachment.body).toString('base64')
186
+ : attachment.body
187
+ }
188
+
189
+ async sendAttachment(attachment, testItem) {
190
+ let log;
191
+ if (attachment.mediaType === 'text/x.cucumber.log+plain') {
192
+ log = await this.rpClient.sendLog(testItem.tempId, {
193
+ level: 'INFO',
194
+ message: attachment.body,
195
+ time: this.rpClient.helpers.now()
196
+ });
197
+ } else {
198
+ const attachmentData = {
199
+ name: 'attachment',
200
+ type: attachment.mediaType,
201
+ content: this.prepareContent(attachment),
202
+ };
203
+ log = await this.rpClient.sendLog(testItem.tempId, {
204
+ level: 'INFO',
205
+ message: 'Attachment',
206
+ time: this.rpClient.helpers.now()
207
+ }, attachmentData);
208
+ }
209
+ this.promiseQ.push(log.promise);
210
+ await log.promise;
211
+ }
144
212
  }
145
213
 
146
214
  module.exports = RPFormatter
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@qavajs/format-report-portal",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "cucumber formatter for report portal",
5
5
  "main": "index.js",
6
- "scripts": {},
6
+ "scripts": {
7
+ "test-e2e": "qavajs run --config test-e2e/config.js"
8
+ },
7
9
  "repository": {
8
10
  "type": "git",
9
11
  "url": "git+https://github.com/qavajs/format-report-portal.git"
@@ -18,5 +20,10 @@
18
20
  "homepage": "https://github.com/qavajs/format-report-portal#readme",
19
21
  "dependencies": {
20
22
  "@reportportal/client-javascript": "^5.0.8"
23
+ },
24
+ "devDependencies": {
25
+ "@cucumber/cucumber": "^9.0.0",
26
+ "@qavajs/cli": "^0.0.19",
27
+ "@qavajs/memory": "^1.2.0"
21
28
  }
22
29
  }
@@ -1,32 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v2
15
- - uses: actions/setup-node@v2
16
- with:
17
- node-version: 16
18
- - run: npm ci
19
-
20
- publish-npm:
21
- needs: build
22
- runs-on: ubuntu-latest
23
- steps:
24
- - uses: actions/checkout@v2
25
- - uses: actions/setup-node@v2
26
- with:
27
- node-version: 16
28
- registry-url: https://registry.npmjs.org/
29
- - run: npm ci
30
- - run: npm publish --access public
31
- env:
32
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}