@browsermation/test 0.0.66 → 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.
- package/dist/reporter/reporter.d.ts +5 -0
- package/dist/reporter/reporter.test.d.ts +1 -0
- package/dist/reporter.js +156 -13
- 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,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,37 +174,158 @@ var BrowsermationReporter = class {
|
|
|
159
174
|
);
|
|
160
175
|
return;
|
|
161
176
|
}
|
|
162
|
-
if (
|
|
163
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
189
|
+
this.log(`Making POST request to: ${url}`);
|
|
190
|
+
const response = await fetch(url, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: {
|
|
193
|
+
Accept: "application/json",
|
|
194
|
+
"Content-Type": "application/json",
|
|
195
|
+
Authorization: `Bearer ${this.apiToken}`,
|
|
196
|
+
"X-Browsermation-Reporter": "v0.0.67",
|
|
197
|
+
"User-Agent": "Browsermation-Reporter/0.0.67"
|
|
198
|
+
},
|
|
199
|
+
body: JSON.stringify(data),
|
|
200
|
+
redirect: "manual"
|
|
201
|
+
// Don't follow redirects that might change method
|
|
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();
|
|
181
230
|
}
|
|
182
|
-
|
|
231
|
+
}
|
|
183
232
|
if (!response.ok) {
|
|
233
|
+
const responseText = await response.text();
|
|
184
234
|
this.log(
|
|
185
235
|
`Failed to send data to Browsermation. Status: ${response.status} - ${response.statusText}`
|
|
186
236
|
);
|
|
237
|
+
this.log(`Response body: ${responseText.substring(0, 500)}`);
|
|
238
|
+
return;
|
|
187
239
|
}
|
|
188
240
|
return await response.json();
|
|
189
241
|
} catch (error) {
|
|
190
242
|
console.error("Error sending data to Browsermation:", error);
|
|
191
243
|
}
|
|
192
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
|
+
}
|
|
193
329
|
getProjectSuite(parent) {
|
|
194
330
|
let currentSuite = parent;
|
|
195
331
|
while (currentSuite.parent) {
|
|
@@ -241,12 +377,16 @@ var BrowsermationReporter = class {
|
|
|
241
377
|
this.logEvent(`${JSON.stringify(data)}
|
|
242
378
|
`);
|
|
243
379
|
await this.sendData(data);
|
|
380
|
+
if (this.batchMode) {
|
|
381
|
+
await this.sendBatchData();
|
|
382
|
+
}
|
|
244
383
|
}
|
|
245
384
|
async onTestBegin(test) {
|
|
246
385
|
const data = {
|
|
247
386
|
id: test.id,
|
|
248
387
|
type: "test-start",
|
|
249
388
|
title: test.title,
|
|
389
|
+
title_path: test.titlePath,
|
|
250
390
|
file: test.location.file.replace(process.cwd(), ""),
|
|
251
391
|
hostname: (0, import_node_os.hostname)(),
|
|
252
392
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -309,5 +449,8 @@ var BrowsermationReporter = class {
|
|
|
309
449
|
this.logEvent(`${JSON.stringify(data)}
|
|
310
450
|
`);
|
|
311
451
|
await this.sendData(data);
|
|
452
|
+
if (this.batchMode && this.batchEvents.length > 0) {
|
|
453
|
+
await this.sendBatchData();
|
|
454
|
+
}
|
|
312
455
|
}
|
|
313
456
|
};
|
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.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": "^
|
|
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
|
}
|