@orangebeard-io/playwright-orangebeard-reporter 1.0.8 → 1.0.10

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.
@@ -383,7 +383,7 @@ class OrangebeardReporter {
383
383
  }
384
384
  const orangebeardAttachment = {
385
385
  file: {
386
- name: path.basename(attachment.path),
386
+ name: (0, utils_1.getAttachmentFileName)(attachment),
387
387
  content: content,
388
388
  contentType: attachment.contentType,
389
389
  },
@@ -47,11 +47,13 @@ exports.getTime = getTime;
47
47
  exports.removeAnsi = removeAnsi;
48
48
  exports.ansiToMarkdown = ansiToMarkdown;
49
49
  exports.getCodeSnippet = getCodeSnippet;
50
+ exports.getAttachmentFileName = getAttachmentFileName;
50
51
  exports.getAttachmentKey = getAttachmentKey;
51
52
  exports.determineTestType = determineTestType;
52
53
  const core_1 = require("@js-joda/core");
53
54
  const FinishTest_1 = require("@orangebeard-io/javascript-client/dist/client/models/FinishTest");
54
55
  const fs = __importStar(require("node:fs"));
56
+ const path = __importStar(require("node:path"));
55
57
  const util_1 = require("util");
56
58
  var Status = FinishTest_1.FinishTest.Status;
57
59
  const StartTest_1 = require("@orangebeard-io/javascript-client/dist/client/models/StartTest");
@@ -64,7 +66,7 @@ function getTime() {
64
66
  exports.testStatusMap = {
65
67
  "passed": Status.PASSED,
66
68
  "failed": Status.FAILED,
67
- "timedOut": Status.TIMED_OUT,
69
+ "timedOut": Status.FAILED,
68
70
  "skipped": Status.SKIPPED,
69
71
  "interrupted": Status.STOPPED
70
72
  };
@@ -179,6 +181,35 @@ const getBytes = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
179
181
  }
180
182
  });
181
183
  exports.getBytes = getBytes;
184
+ const EXTENSION_BY_CONTENT_TYPE = {
185
+ 'image/png': '.png',
186
+ 'image/jpeg': '.jpg',
187
+ 'image/gif': '.gif',
188
+ 'image/webp': '.webp',
189
+ 'application/zip': '.zip',
190
+ 'video/webm': '.webm',
191
+ 'video/mp4': '.mp4',
192
+ 'text/plain': '.txt',
193
+ 'application/json': '.json',
194
+ 'application/pdf': '.pdf',
195
+ };
196
+ /**
197
+ * Derives the file name to upload an attachment as. Path-backed attachments
198
+ * (screenshots/traces/videos written to disk by Playwright) use the basename
199
+ * of that path. Body-only attachments (e.g. from `testInfo.attach(name, { body })`)
200
+ * have no path, so `attachment.name` is used instead, adding an extension
201
+ * inferred from `contentType` if the name doesn't already have one.
202
+ */
203
+ function getAttachmentFileName(attachment) {
204
+ if (attachment.path) {
205
+ return path.basename(attachment.path);
206
+ }
207
+ if (path.extname(attachment.name)) {
208
+ return attachment.name;
209
+ }
210
+ const extension = EXTENSION_BY_CONTENT_TYPE[attachment.contentType];
211
+ return extension ? `${attachment.name}${extension}` : attachment.name;
212
+ }
182
213
  function getAttachmentKey(attachment) {
183
214
  var _a, _b;
184
215
  const size = attachment.body ? attachment.body.byteLength : undefined;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("./utils");
4
+ describe('getAttachmentFileName', () => {
5
+ it('uses the basename of attachment.path when a path is present', () => {
6
+ const name = (0, utils_1.getAttachmentFileName)({
7
+ name: 'trace',
8
+ path: '/tmp/playwright-artifacts/abc123/trace.zip',
9
+ contentType: 'application/zip',
10
+ });
11
+ expect(name).toBe('trace.zip');
12
+ });
13
+ it('does not crash for a body-only attachment with no path', () => {
14
+ expect(() => (0, utils_1.getAttachmentFileName)({
15
+ name: 'homepage-screenshot',
16
+ contentType: 'image/png',
17
+ })).not.toThrow();
18
+ });
19
+ it('appends an extension derived from contentType when the name has none', () => {
20
+ const name = (0, utils_1.getAttachmentFileName)({
21
+ name: 'homepage-screenshot',
22
+ contentType: 'image/png',
23
+ });
24
+ expect(name).toBe('homepage-screenshot.png');
25
+ });
26
+ it('leaves the name untouched when it already has an extension', () => {
27
+ const name = (0, utils_1.getAttachmentFileName)({
28
+ name: 'homepage-screenshot.png',
29
+ contentType: 'image/png',
30
+ });
31
+ expect(name).toBe('homepage-screenshot.png');
32
+ });
33
+ it('falls back to the bare name for an unrecognized content type', () => {
34
+ const name = (0, utils_1.getAttachmentFileName)({
35
+ name: 'custom-data',
36
+ contentType: 'application/x-custom',
37
+ });
38
+ expect(name).toBe('custom-data');
39
+ });
40
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orangebeard-io/playwright-orangebeard-reporter",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "A Playwright reporter to report to Orangebeard.io",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -33,13 +33,16 @@
33
33
  "homepage": "https://github.com/orangebeard-io/playwright-listener#readme",
34
34
  "devDependencies": {
35
35
  "@playwright/test": "^1.57.0",
36
+ "@types/jest": "^30.0.0",
36
37
  "@types/node": "^22.10.9",
37
38
  "@typescript-eslint/parser": "^8.15.0",
38
39
  "eslint": "^9.15.0",
39
40
  "eslint-config-prettier": "^9.1.0",
40
41
  "eslint-plugin-prettier": "^5.2.1",
42
+ "jest": "^30.4.2",
41
43
  "prettier": "^3.3.3",
42
44
  "rimraf": "^6.0.1",
45
+ "ts-jest": "^29.4.12",
43
46
  "typescript": "^5.6.3"
44
47
  },
45
48
  "dependencies": {