testit-adapter-playwright 2.0.1 → 2.1.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/README.md CHANGED
@@ -96,6 +96,7 @@ Description of methods:
96
96
  - `testit.addLinks` - links in the autotest result
97
97
  - `testit.addAttachments` - uploading files in the autotest result
98
98
  - `testit.addMessage` - information about autotest in the autotest result
99
+ - `testit.step` - information about step in the autotest result
99
100
 
100
101
  ### Examples
101
102
 
@@ -122,6 +123,9 @@ test('All annotations', async () => {
122
123
  ]);
123
124
 
124
125
  testit.addAttachment('file01.txt', 'Content', {contentType: "text/markdown",});
126
+
127
+ await testit.step("step with title", async () => {
128
+ });
125
129
  });
126
130
  ```
127
131
 
@@ -1,6 +1,6 @@
1
- import { TestCase, TestResult } from "@playwright/test/reporter";
1
+ import { TestCase, TestStep, TestResult } from "@playwright/test/reporter";
2
2
  import { TestStatus } from "@playwright/test";
3
- import { AutotestPost, AutotestResult } from "testit-js-commons";
3
+ import { AutotestPost, AutotestResult, ShortStep, Step, Attachment } from "testit-js-commons";
4
4
  import { MetadataMessage } from "./labels";
5
5
  declare enum Status {
6
6
  PASSED = "Passed",
@@ -10,6 +10,10 @@ declare enum Status {
10
10
  export declare class Converter {
11
11
  static convertTestCaseToAutotestPost(autotestData: MetadataMessage): AutotestPost;
12
12
  static convertAutotestPostToAutotestResult(autotestData: MetadataMessage, test: TestCase, result: TestResult): AutotestResult;
13
+ static convertTestStepsToShortSteps(steps: TestStep[]): ShortStep[];
14
+ static convertTestStepToShortStep(step: TestStep): ShortStep;
15
+ static convertTestStepsToSteps(steps: TestStep[], attachmentsMap: Map<Attachment, TestStep>): Step[];
16
+ static convertTestStepToStep(step: TestStep, attachmentsMap: Map<Attachment, TestStep>): Step;
13
17
  static convertStatus(status: TestStatus, expectedStatus: TestStatus): Status;
14
18
  }
15
19
  export type StatusDetails = {
package/dist/converter.js CHANGED
@@ -37,6 +37,26 @@ class Converter {
37
37
  }
38
38
  return autotestResult;
39
39
  }
40
+ static convertTestStepsToShortSteps(steps) {
41
+ return steps.map(step => {
42
+ return this.convertTestStepToShortStep(step);
43
+ });
44
+ }
45
+ static convertTestStepToShortStep(step) {
46
+ return {
47
+ title: step.title,
48
+ };
49
+ }
50
+ static convertTestStepsToSteps(steps, attachmentsMap) {
51
+ return steps.map(step => this.convertTestStepToStep(step, attachmentsMap));
52
+ }
53
+ static convertTestStepToStep(step, attachmentsMap) {
54
+ return {
55
+ title: step.title,
56
+ outcome: step.error ? Status.FAILED : Status.PASSED,
57
+ attachments: [...attachmentsMap.keys()].filter((attachmentId) => attachmentsMap.get(attachmentId) === step),
58
+ };
59
+ }
40
60
  static convertStatus(status, expectedStatus) {
41
61
  if (status === "skipped") {
42
62
  return Status.SKIPPED;
package/dist/labels.d.ts CHANGED
@@ -37,8 +37,8 @@ declare enum ContentType {
37
37
  }
38
38
  type Parameters = Record<string, string>;
39
39
  export declare class testit {
40
- static addAttachment(name: string, content: Buffer | string, options: ContentType | string | Pick<AttachmentOptions, "contentType">): Promise<void>;
41
40
  private static addMetadataAttachment;
41
+ static addAttachment(name: string, content: Buffer | string, options: ContentType | string | Pick<AttachmentOptions, "contentType">): Promise<void>;
42
42
  private static mapParams;
43
43
  static workItemIds(value: string[]): Promise<void>;
44
44
  static displayName(value: string): Promise<void>;
@@ -52,5 +52,6 @@ export declare class testit {
52
52
  static addLinks(value: Link[]): Promise<void>;
53
53
  static addMessage(value: string): Promise<void>;
54
54
  static params(value: any): Promise<void>;
55
+ static step<T>(name: string, body: () => Promise<T>): Promise<T>;
55
56
  }
56
57
  export {};
package/dist/labels.js CHANGED
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.testit = void 0;
7
+ const crypto_1 = require("crypto");
7
8
  const test_1 = __importDefault(require("@playwright/test"));
8
9
  var ContentType;
9
10
  (function (ContentType) {
@@ -23,19 +24,22 @@ var ContentType;
23
24
  ContentType["MP4"] = "video/mp4";
24
25
  })(ContentType || (ContentType = {}));
25
26
  class testit {
26
- static async addAttachment(name, content, options) {
27
- const contentType = typeof options === "string" ? options : options.contentType;
28
- await test_1.default.info().attach(name, {
29
- body: content,
30
- contentType,
31
- });
32
- }
33
27
  static async addMetadataAttachment(metadata) {
34
28
  await test_1.default.info().attach("tms-metadata.json", {
35
29
  contentType: "application/vnd.tms.metadata+json",
36
30
  body: Buffer.from(JSON.stringify(metadata), "utf8"),
37
31
  });
38
32
  }
33
+ static async addAttachment(name, content, options) {
34
+ const stepName = `stepattach_${(0, crypto_1.randomUUID)()}_${name}`;
35
+ const contentType = typeof options === "string" ? options : options.contentType;
36
+ await this.step(stepName, async () => {
37
+ await test_1.default.info().attach(stepName, {
38
+ body: content,
39
+ contentType,
40
+ });
41
+ });
42
+ }
39
43
  static async mapParams(params) {
40
44
  switch (typeof params) {
41
45
  case 'string':
@@ -115,5 +119,8 @@ class testit {
115
119
  params: await this.mapParams(value),
116
120
  });
117
121
  }
122
+ static step(name, body) {
123
+ return test_1.default.step(name, body);
124
+ }
118
125
  }
119
126
  exports.testit = testit;
@@ -1,5 +1,5 @@
1
1
  import { FullConfig } from "@playwright/test";
2
- import { Reporter, Suite, TestCase, TestResult } from "@playwright/test/reporter";
2
+ import { Reporter, Suite, TestCase, TestResult, TestStep } from "@playwright/test/reporter";
3
3
  import { IStrategy } from "testit-js-commons";
4
4
  export type ReporterOptions = {
5
5
  detail?: boolean;
@@ -15,11 +15,14 @@ declare class TmsReporter implements Reporter {
15
15
  strategy: IStrategy;
16
16
  private readonly additions;
17
17
  private testCache;
18
+ private stepCache;
19
+ private attachmentSteps;
18
20
  private globalStartTime;
19
21
  constructor(options: ReporterOptions);
20
22
  onBegin(config: FullConfig, suite: Suite): void;
21
23
  onTestBegin(test: TestCase): void;
22
24
  onTestEnd(test: TestCase, result: TestResult): Promise<void>;
25
+ onStepBegin(test: TestCase, _result: TestResult, step: TestStep): void;
23
26
  onEnd(): void;
24
27
  addSkippedResults(): void;
25
28
  printsToStdio(): boolean;
package/dist/reporter.js CHANGED
@@ -16,9 +16,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  const testit_js_commons_1 = require("testit-js-commons");
18
18
  const converter_1 = require("./converter");
19
+ const stepAttachRegexp = /^stepattach_(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})_/i;
19
20
  class TmsReporter {
20
21
  constructor(options) {
21
22
  this.testCache = new Array();
23
+ this.stepCache = new Map();
24
+ this.attachmentSteps = new Map();
22
25
  this.globalStartTime = new Date();
23
26
  this.options = { suiteTitle: true, detail: true, ...options };
24
27
  const config = new testit_js_commons_1.ConfigComposer().compose();
@@ -35,8 +38,24 @@ class TmsReporter {
35
38
  }
36
39
  async onTestEnd(test, result) {
37
40
  const autotest = converter_1.Converter.convertTestCaseToAutotestPost(await this.getAutotestData(test, result));
41
+ const steps = [...this.stepCache.keys()].filter((step) => this.stepCache.get(step) === test);
42
+ autotest.steps = converter_1.Converter.convertTestStepsToShortSteps(steps);
38
43
  await this.strategy.loadAutotest(autotest, converter_1.Converter.convertStatus(result.status, test.expectedStatus) == "Passed");
39
- await this.strategy.loadTestRun([converter_1.Converter.convertAutotestPostToAutotestResult(await this.getAutotestData(test, result), test, result)]);
44
+ const autotestResult = converter_1.Converter.convertAutotestPostToAutotestResult(await this.getAutotestData(test, result), test, result);
45
+ autotestResult.stepResults = converter_1.Converter.convertTestStepsToSteps(steps, this.attachmentSteps);
46
+ await this.strategy.loadTestRun([autotestResult]);
47
+ }
48
+ onStepBegin(test, _result, step) {
49
+ if (!this.testCache.includes(test)) {
50
+ return;
51
+ }
52
+ if (step.category !== "test.step") {
53
+ return;
54
+ }
55
+ if (this.stepCache.get(step)) {
56
+ return;
57
+ }
58
+ this.stepCache.set(step, test);
40
59
  }
41
60
  onEnd() {
42
61
  this.addSkippedResults();
@@ -71,7 +90,7 @@ class TmsReporter {
71
90
  addAttachments: []
72
91
  };
73
92
  for (const attachment of result.attachments) {
74
- if (!attachment.body || !attachment.path) {
93
+ if (!attachment.body) {
75
94
  continue;
76
95
  }
77
96
  if (attachment.contentType === "application/vnd.tms.metadata+json") {
@@ -111,9 +130,19 @@ class TmsReporter {
111
130
  }
112
131
  continue;
113
132
  }
114
- await this.additions.addAttachments(attachment.body.toString(), attachment.name).then((ids) => {
115
- autotestData.addAttachments?.push(...ids);
116
- });
133
+ if (attachment.name.match(stepAttachRegexp)) {
134
+ const step = [...this.stepCache.keys()].find((step) => step.title === attachment.name);
135
+ if (step) {
136
+ this.stepCache.delete(step);
137
+ }
138
+ await this.additions.addAttachments(attachment.body.toString(), attachment.name.replace(stepAttachRegexp, "")).then((ids) => {
139
+ if (step?.parent) {
140
+ this.attachmentSteps.set(ids[0], step.parent);
141
+ return;
142
+ }
143
+ autotestData.addAttachments?.push(...ids);
144
+ });
145
+ }
117
146
  }
118
147
  return autotestData;
119
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testit-adapter-playwright",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Playwright adapter for Test IT",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -39,7 +39,7 @@
39
39
  "prettier": "^3.0.1"
40
40
  },
41
41
  "dependencies": {
42
- "testit-js-commons": "^2.0.1"
42
+ "testit-js-commons": "^2.1.0"
43
43
  },
44
44
  "files": [
45
45
  "dist"