@browsermation/test 0.0.67 → 0.0.71

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.
@@ -3,18 +3,23 @@ export default class BrowsermationReporter implements Reporter {
3
3
  browsermationURL: string;
4
4
  apiToken: string;
5
5
  suiteRunId: string | null;
6
+ batchMode: boolean;
7
+ batchEvents: Array<Record<string, any>>;
6
8
  log(message: string): void;
7
9
  logEvent(message: string): void;
8
10
  constructor(options?: {
9
11
  reportingURL?: string;
10
12
  apiToken?: string;
13
+ batchMode?: boolean;
11
14
  });
12
15
  getCurrentBranch(): Promise<string>;
13
16
  getCurrentRepo(): Promise<string>;
14
17
  getLatestCommitId(): Promise<string>;
15
18
  getLatestCommitMessage(): Promise<string>;
16
19
  gitRemoteOriginUrl(): Promise<string>;
20
+ getReportingURL(): string;
17
21
  sendData(data: Record<string, any>): Promise<any>;
22
+ sendBatchData(): Promise<any>;
18
23
  getProjectSuite(parent: Suite): FullProject | undefined;
19
24
  /**
20
25
  * onBegin() is called once with a root suite that contains all other suites and tests. Learn more about suites hierarchy.
@@ -0,0 +1 @@
1
+ export {};
package/dist/reporter.js CHANGED
@@ -36,6 +36,8 @@ var BrowsermationReporter = class {
36
36
  browsermationURL = "";
37
37
  apiToken = "";
38
38
  suiteRunId = null;
39
+ batchMode = false;
40
+ batchEvents = [];
39
41
  log(message) {
40
42
  if (process.env.BM_REPORTER_DEBUG_LOGS) {
41
43
  console.log(message);
@@ -47,9 +49,11 @@ var BrowsermationReporter = class {
47
49
  }
48
50
  }
49
51
  constructor(options = {}) {
52
+ this.batchMode = options.batchMode || process.env.BM_BATCH_MODE === "true" || false;
50
53
  this.browsermationURL = options.reportingURL || process.env.BM_REPORTING_URL || "https://browsermation.com/api/v1/playwright/reporting";
51
54
  this.apiToken = options.apiToken || process.env.BM_API_TOKEN || "";
52
55
  this.log(`Using Browsermation reporting URL: ${this.browsermationURL}`);
56
+ this.log(`Batch mode: ${this.batchMode ? "enabled" : "disabled"}`);
53
57
  this.log(
54
58
  "Using API Token: " + (this.apiToken ? this.apiToken.slice(0, 4) + "****" : "not set")
55
59
  );
@@ -152,6 +156,9 @@ var BrowsermationReporter = class {
152
156
  });
153
157
  });
154
158
  }
159
+ getReportingURL() {
160
+ return this.browsermationURL;
161
+ }
155
162
  async sendData(data) {
156
163
  if (process.env.BM_REPORTER_ONLY_LOG_EVENTS) {
157
164
  this.log(
@@ -160,33 +167,163 @@ var BrowsermationReporter = class {
160
167
  return;
161
168
  }
162
169
  if (process.env.BM_BROWSER_RUN_ID) {
170
+ this.log(
171
+ `BM_BROWSER_RUN_ID is set to ${process.env.BM_BROWSER_RUN_ID}. Adding to event data.`
172
+ );
163
173
  data.browser_run_id = process.env.BM_BROWSER_RUN_ID;
164
174
  }
175
+ if (this.batchMode) {
176
+ this.log(`Batch mode: Adding event to batch: ${data.type}`);
177
+ this.batchEvents.push(data);
178
+ return;
179
+ }
165
180
  if (!this.apiToken) {
166
181
  this.log("API token not set. Skipping sending data to Browsermation.");
167
182
  return;
168
183
  }
169
184
  this.log(`Sending data to Browsermation: ${JSON.stringify(data)}`);
185
+ const url = this.getReportingURL();
170
186
  try {
171
- const response = await fetch(this.browsermationURL, {
187
+ this.log(`Making POST request to: ${url}`);
188
+ const response = await fetch(url, {
172
189
  method: "POST",
173
190
  headers: {
174
191
  Accept: "application/json",
175
192
  "Content-Type": "application/json",
176
- Authorization: `Bearer ${this.apiToken}`
193
+ Authorization: `Bearer ${this.apiToken}`,
194
+ "X-Browsermation-Reporter": "v0.0.67",
195
+ "User-Agent": "Browsermation-Reporter/0.0.67"
177
196
  },
178
- body: JSON.stringify(data)
197
+ body: JSON.stringify(data),
198
+ redirect: "manual"
199
+ // Don't follow redirects that might change method
179
200
  });
201
+ this.log(`Response status: ${response.status} ${response.statusText}`);
202
+ this.log(`Response type: ${response.type}`);
203
+ this.log(`Response URL: ${response.url}`);
204
+ if (response.status === 301 || response.status === 302) {
205
+ const redirectUrl = response.headers.get("location");
206
+ if (redirectUrl) {
207
+ this.log(`Following redirect to: ${redirectUrl}`);
208
+ const redirectResponse = await fetch(redirectUrl, {
209
+ method: "POST",
210
+ headers: {
211
+ Accept: "application/json",
212
+ "Content-Type": "application/json",
213
+ Authorization: `Bearer ${this.apiToken}`,
214
+ "X-Browsermation-Reporter": "v0.0.67",
215
+ "User-Agent": "Browsermation-Reporter/0.0.67"
216
+ },
217
+ body: JSON.stringify(data)
218
+ });
219
+ if (!redirectResponse.ok) {
220
+ const responseText = await redirectResponse.text();
221
+ this.log(
222
+ `Failed to send data to Browsermation after redirect. Status: ${redirectResponse.status} - ${redirectResponse.statusText}`
223
+ );
224
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
225
+ return;
226
+ }
227
+ return await redirectResponse.json();
228
+ }
229
+ }
180
230
  if (!response.ok) {
231
+ const responseText = await response.text();
181
232
  this.log(
182
233
  `Failed to send data to Browsermation. Status: ${response.status} - ${response.statusText}`
183
234
  );
235
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
236
+ return;
184
237
  }
185
238
  return await response.json();
186
239
  } catch (error) {
187
240
  console.error("Error sending data to Browsermation:", error);
188
241
  }
189
242
  }
243
+ async sendBatchData() {
244
+ if (process.env.BM_REPORTER_ONLY_LOG_EVENTS) {
245
+ this.log(
246
+ "BM_REPORTER_ONLY_LOG_EVENTS is set to true. Skipping sending batch data to Browsermation."
247
+ );
248
+ return;
249
+ }
250
+ if (!this.apiToken) {
251
+ this.log(
252
+ "API token not set. Skipping sending batch data to Browsermation."
253
+ );
254
+ return;
255
+ }
256
+ if (this.batchEvents.length === 0) {
257
+ this.log("No batch events to send.");
258
+ return;
259
+ }
260
+ const batchURL = this.getReportingURL().replace(
261
+ "/reporting",
262
+ "/batch-reporting"
263
+ );
264
+ const batchData = {
265
+ events: this.batchEvents,
266
+ suite_run_id: this.suiteRunId
267
+ };
268
+ this.log(
269
+ `Sending ${this.batchEvents.length} events in batch to Browsermation`
270
+ );
271
+ try {
272
+ this.log(`Making POST request to: ${batchURL}`);
273
+ const response = await fetch(batchURL, {
274
+ method: "POST",
275
+ headers: {
276
+ Accept: "application/json",
277
+ "Content-Type": "application/json",
278
+ Authorization: `Bearer ${this.apiToken}`,
279
+ "X-Browsermation-Reporter": "v0.0.67",
280
+ "User-Agent": "Browsermation-Reporter/0.0.67"
281
+ },
282
+ body: JSON.stringify(batchData),
283
+ redirect: "manual"
284
+ });
285
+ this.log(`Response status: ${response.status} ${response.statusText}`);
286
+ this.log(`Response type: ${response.type}`);
287
+ this.log(`Response URL: ${response.url}`);
288
+ if (response.status === 301 || response.status === 302) {
289
+ const redirectUrl = response.headers.get("location");
290
+ if (redirectUrl) {
291
+ this.log(`Following redirect to: ${redirectUrl}`);
292
+ const redirectResponse = await fetch(redirectUrl, {
293
+ method: "POST",
294
+ headers: {
295
+ Accept: "application/json",
296
+ "Content-Type": "application/json",
297
+ Authorization: `Bearer ${this.apiToken}`,
298
+ "X-Browsermation-Reporter": "v0.0.67",
299
+ "User-Agent": "Browsermation-Reporter/0.0.67"
300
+ },
301
+ body: JSON.stringify(batchData)
302
+ });
303
+ if (!redirectResponse.ok) {
304
+ const responseText = await redirectResponse.text();
305
+ this.log(
306
+ `Failed to send batch data to Browsermation after redirect. Status: ${redirectResponse.status} - ${redirectResponse.statusText}`
307
+ );
308
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
309
+ return;
310
+ }
311
+ return await redirectResponse.json();
312
+ }
313
+ }
314
+ if (!response.ok) {
315
+ const responseText = await response.text();
316
+ this.log(
317
+ `Failed to send batch data to Browsermation. Status: ${response.status} - ${response.statusText}`
318
+ );
319
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
320
+ return;
321
+ }
322
+ return await response.json();
323
+ } catch (error) {
324
+ console.error("Error sending batch data to Browsermation:", error);
325
+ }
326
+ }
190
327
  getProjectSuite(parent) {
191
328
  let currentSuite = parent;
192
329
  while (currentSuite.parent) {
@@ -238,12 +375,16 @@ var BrowsermationReporter = class {
238
375
  this.logEvent(`${JSON.stringify(data)}
239
376
  `);
240
377
  await this.sendData(data);
378
+ if (this.batchMode) {
379
+ await this.sendBatchData();
380
+ }
241
381
  }
242
382
  async onTestBegin(test) {
243
383
  const data = {
244
384
  id: test.id,
245
385
  type: "test-start",
246
386
  title: test.title,
387
+ title_path: test.titlePath,
247
388
  file: test.location.file.replace(process.cwd(), ""),
248
389
  hostname: (0, import_node_os.hostname)(),
249
390
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -306,5 +447,8 @@ var BrowsermationReporter = class {
306
447
  this.logEvent(`${JSON.stringify(data)}
307
448
  `);
308
449
  await this.sendData(data);
450
+ if (this.batchMode && this.batchEvents.length > 0) {
451
+ await this.sendBatchData();
452
+ }
309
453
  }
310
454
  };
package/dist/test.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
1
+ export declare const test: import("playwright/test").TestType<import("playwright/test").PlaywrightTestArgs & import("playwright/test").PlaywrightTestOptions, import("playwright/test").PlaywrightWorkerArgs & import("playwright/test").PlaywrightWorkerOptions>;
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@browsermation/test",
3
- "version": "0.0.67",
3
+ "version": "0.0.71",
4
4
  "description": "The testing platform for Playwright by Browsermation.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
+ "types": "./dist/index.d.ts",
9
10
  "import": "./dist/index.js",
10
11
  "require": "./dist/index.js",
11
- "types": "./dist/index.d.ts",
12
12
  "default": "./dist/index.js"
13
13
  },
14
14
  "./reporter": {
15
+ "types": "./dist/reporter.d.ts",
15
16
  "import": "./dist/reporter.js",
16
17
  "require": "./dist/reporter.js",
17
- "types": "./dist/reporter.d.ts",
18
18
  "default": "./dist/reporter.js"
19
19
  },
20
20
  "./package.json": "./package.json"
@@ -32,6 +32,10 @@
32
32
  "build": "rm -rf dist && npm run build:index && npm run build:reporter && npm run build:types",
33
33
  "start": "node dist/bin/cli.js",
34
34
  "build:start": "npm run build && npm start",
35
+ "test": "vitest",
36
+ "test:ui": "vitest --ui",
37
+ "test:run": "vitest run",
38
+ "test:coverage": "vitest run --coverage",
35
39
  "publishPackage": "npm run build && npm publish --access public",
36
40
  "publishBetaPackage": "npm run build && npm publish --access public --tag beta"
37
41
  },
@@ -44,14 +48,18 @@
44
48
  "author": "Browsermation Team",
45
49
  "license": "MIT",
46
50
  "devDependencies": {
47
- "@types/node": "^24.0.13",
48
- "esbuild": "^0.25.6",
49
- "typescript": "^5.9.2"
51
+ "@types/node": "^25.0.3",
52
+ "@vitest/coverage-v8": "^4.0.16",
53
+ "@vitest/ui": "^4.0.16",
54
+ "esbuild": "^0.27.2",
55
+ "happy-dom": "^20.0.11",
56
+ "typescript": "^5.9.3",
57
+ "vitest": "^4.0.16"
50
58
  },
51
59
  "dependencies": {
52
- "@playwright/test": "^1.55.0",
53
- "chalk": "^5.4.1",
54
- "ora": "^8.2.0",
60
+ "@playwright/test": "^1.57.0",
61
+ "chalk": "^5.6.2",
62
+ "ora": "^9.0.0",
55
63
  "ts-node": "^10.9.2"
56
64
  }
57
65
  }