@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.
- package/dist/reporter/reporter.d.ts +5 -0
- package/dist/reporter/reporter.test.d.ts +1 -0
- package/dist/reporter.js +147 -3
- package/dist/test.d.ts +1 -1
- package/package.json +17 -9
|
@@ -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
|
-
|
|
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("
|
|
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.
|
|
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": "^
|
|
48
|
-
"
|
|
49
|
-
"
|
|
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.
|
|
53
|
-
"chalk": "^5.
|
|
54
|
-
"ora": "^
|
|
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
|
}
|