@browsermation/test 0.0.67 → 0.0.70

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,17 @@ var BrowsermationReporter = class {
152
156
  });
153
157
  });
154
158
  }
159
+ getReportingURL() {
160
+ const browserRunId = process.env.BM_BROWSER_RUN_ID;
161
+ if (browserRunId) {
162
+ const baseURL = this.browsermationURL.replace(
163
+ /\/api\/v1\/playwright\/reporting$/,
164
+ ""
165
+ );
166
+ return `${baseURL}/api/v1/browser-runs/${browserRunId}/reporting`;
167
+ }
168
+ return this.browsermationURL;
169
+ }
155
170
  async sendData(data) {
156
171
  if (process.env.BM_REPORTER_ONLY_LOG_EVENTS) {
157
172
  this.log(
@@ -159,34 +174,158 @@ var BrowsermationReporter = class {
159
174
  );
160
175
  return;
161
176
  }
162
- if (process.env.BM_BROWSER_RUN_ID) {
163
- data.browser_run_id = process.env.BM_BROWSER_RUN_ID;
177
+ if (this.batchMode) {
178
+ this.log(`Batch mode: Adding event to batch: ${data.type}`);
179
+ this.batchEvents.push(data);
180
+ return;
164
181
  }
165
182
  if (!this.apiToken) {
166
183
  this.log("API token not set. Skipping sending data to Browsermation.");
167
184
  return;
168
185
  }
169
186
  this.log(`Sending data to Browsermation: ${JSON.stringify(data)}`);
187
+ const url = this.getReportingURL();
170
188
  try {
171
- const response = await fetch(this.browsermationURL, {
189
+ this.log(`Making POST request to: ${url}`);
190
+ const response = await fetch(url, {
172
191
  method: "POST",
173
192
  headers: {
174
193
  Accept: "application/json",
175
194
  "Content-Type": "application/json",
176
- Authorization: `Bearer ${this.apiToken}`
195
+ Authorization: `Bearer ${this.apiToken}`,
196
+ "X-Browsermation-Reporter": "v0.0.67",
197
+ "User-Agent": "Browsermation-Reporter/0.0.67"
177
198
  },
178
- body: JSON.stringify(data)
199
+ body: JSON.stringify(data),
200
+ redirect: "manual"
201
+ // Don't follow redirects that might change method
179
202
  });
203
+ this.log(`Response status: ${response.status} ${response.statusText}`);
204
+ this.log(`Response type: ${response.type}`);
205
+ this.log(`Response URL: ${response.url}`);
206
+ if (response.status === 301 || response.status === 302) {
207
+ const redirectUrl = response.headers.get("location");
208
+ if (redirectUrl) {
209
+ this.log(`Following redirect to: ${redirectUrl}`);
210
+ const redirectResponse = await fetch(redirectUrl, {
211
+ method: "POST",
212
+ headers: {
213
+ Accept: "application/json",
214
+ "Content-Type": "application/json",
215
+ Authorization: `Bearer ${this.apiToken}`,
216
+ "X-Browsermation-Reporter": "v0.0.67",
217
+ "User-Agent": "Browsermation-Reporter/0.0.67"
218
+ },
219
+ body: JSON.stringify(data)
220
+ });
221
+ if (!redirectResponse.ok) {
222
+ const responseText = await redirectResponse.text();
223
+ this.log(
224
+ `Failed to send data to Browsermation after redirect. Status: ${redirectResponse.status} - ${redirectResponse.statusText}`
225
+ );
226
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
227
+ return;
228
+ }
229
+ return await redirectResponse.json();
230
+ }
231
+ }
180
232
  if (!response.ok) {
233
+ const responseText = await response.text();
181
234
  this.log(
182
235
  `Failed to send data to Browsermation. Status: ${response.status} - ${response.statusText}`
183
236
  );
237
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
238
+ return;
184
239
  }
185
240
  return await response.json();
186
241
  } catch (error) {
187
242
  console.error("Error sending data to Browsermation:", error);
188
243
  }
189
244
  }
245
+ async sendBatchData() {
246
+ if (process.env.BM_REPORTER_ONLY_LOG_EVENTS) {
247
+ this.log(
248
+ "BM_REPORTER_ONLY_LOG_EVENTS is set to true. Skipping sending batch data to Browsermation."
249
+ );
250
+ return;
251
+ }
252
+ if (!this.apiToken) {
253
+ this.log(
254
+ "API token not set. Skipping sending batch data to Browsermation."
255
+ );
256
+ return;
257
+ }
258
+ if (this.batchEvents.length === 0) {
259
+ this.log("No batch events to send.");
260
+ return;
261
+ }
262
+ const batchURL = this.getReportingURL().replace(
263
+ "/reporting",
264
+ "/batch-reporting"
265
+ );
266
+ const batchData = {
267
+ events: this.batchEvents,
268
+ suite_run_id: this.suiteRunId
269
+ };
270
+ this.log(
271
+ `Sending ${this.batchEvents.length} events in batch to Browsermation`
272
+ );
273
+ try {
274
+ this.log(`Making POST request to: ${batchURL}`);
275
+ const response = await fetch(batchURL, {
276
+ method: "POST",
277
+ headers: {
278
+ Accept: "application/json",
279
+ "Content-Type": "application/json",
280
+ Authorization: `Bearer ${this.apiToken}`,
281
+ "X-Browsermation-Reporter": "v0.0.67",
282
+ "User-Agent": "Browsermation-Reporter/0.0.67"
283
+ },
284
+ body: JSON.stringify(batchData),
285
+ redirect: "manual"
286
+ });
287
+ this.log(`Response status: ${response.status} ${response.statusText}`);
288
+ this.log(`Response type: ${response.type}`);
289
+ this.log(`Response URL: ${response.url}`);
290
+ if (response.status === 301 || response.status === 302) {
291
+ const redirectUrl = response.headers.get("location");
292
+ if (redirectUrl) {
293
+ this.log(`Following redirect to: ${redirectUrl}`);
294
+ const redirectResponse = await fetch(redirectUrl, {
295
+ method: "POST",
296
+ headers: {
297
+ Accept: "application/json",
298
+ "Content-Type": "application/json",
299
+ Authorization: `Bearer ${this.apiToken}`,
300
+ "X-Browsermation-Reporter": "v0.0.67",
301
+ "User-Agent": "Browsermation-Reporter/0.0.67"
302
+ },
303
+ body: JSON.stringify(batchData)
304
+ });
305
+ if (!redirectResponse.ok) {
306
+ const responseText = await redirectResponse.text();
307
+ this.log(
308
+ `Failed to send batch data to Browsermation after redirect. Status: ${redirectResponse.status} - ${redirectResponse.statusText}`
309
+ );
310
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
311
+ return;
312
+ }
313
+ return await redirectResponse.json();
314
+ }
315
+ }
316
+ if (!response.ok) {
317
+ const responseText = await response.text();
318
+ this.log(
319
+ `Failed to send batch data to Browsermation. Status: ${response.status} - ${response.statusText}`
320
+ );
321
+ this.log(`Response body: ${responseText.substring(0, 500)}`);
322
+ return;
323
+ }
324
+ return await response.json();
325
+ } catch (error) {
326
+ console.error("Error sending batch data to Browsermation:", error);
327
+ }
328
+ }
190
329
  getProjectSuite(parent) {
191
330
  let currentSuite = parent;
192
331
  while (currentSuite.parent) {
@@ -238,12 +377,16 @@ var BrowsermationReporter = class {
238
377
  this.logEvent(`${JSON.stringify(data)}
239
378
  `);
240
379
  await this.sendData(data);
380
+ if (this.batchMode) {
381
+ await this.sendBatchData();
382
+ }
241
383
  }
242
384
  async onTestBegin(test) {
243
385
  const data = {
244
386
  id: test.id,
245
387
  type: "test-start",
246
388
  title: test.title,
389
+ title_path: test.titlePath,
247
390
  file: test.location.file.replace(process.cwd(), ""),
248
391
  hostname: (0, import_node_os.hostname)(),
249
392
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -306,5 +449,8 @@ var BrowsermationReporter = class {
306
449
  this.logEvent(`${JSON.stringify(data)}
307
450
  `);
308
451
  await this.sendData(data);
452
+ if (this.batchMode && this.batchEvents.length > 0) {
453
+ await this.sendBatchData();
454
+ }
309
455
  }
310
456
  };
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.70",
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
  }