@wdio/browserstack-service 9.7.3 → 9.9.0
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/build/Percy/Percy-Handler.d.ts.map +1 -1
- package/build/Percy/Percy.d.ts.map +1 -1
- package/build/Percy/PercyBinary.d.ts.map +1 -1
- package/build/Percy/PercyHelper.d.ts +1 -1
- package/build/Percy/PercyHelper.d.ts.map +1 -1
- package/build/accessibility-handler.d.ts.map +1 -1
- package/build/cleanup.d.ts.map +1 -1
- package/build/cleanup.js +571 -67
- package/build/config.d.ts +1 -0
- package/build/config.d.ts.map +1 -1
- package/build/constants.d.ts +1 -0
- package/build/constants.d.ts.map +1 -1
- package/build/exitHandler.d.ts.map +1 -1
- package/build/index.js +524 -177
- package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -1
- package/build/instrumentation/performance/constants.d.ts +79 -0
- package/build/instrumentation/performance/constants.d.ts.map +1 -0
- package/build/instrumentation/performance/performance-tester.d.ts +47 -0
- package/build/instrumentation/performance/performance-tester.d.ts.map +1 -0
- package/build/launcher.d.ts.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/types.d.ts +3 -0
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +6 -14
- package/build/util.d.ts.map +1 -1
- package/package.json +6 -6
- package/build/performance-tester.d.ts +0 -16
- package/build/performance-tester.d.ts.map +0 -1
package/build/index.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
2
3
|
var __export = (target, all) => {
|
|
3
4
|
for (var name in all)
|
|
4
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
6
|
};
|
|
7
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
8
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
9
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
10
|
+
if (decorator = decorators[i])
|
|
11
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
12
|
+
if (kind && result) __defProp(target, key, result);
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
6
15
|
|
|
7
16
|
// src/launcher.ts
|
|
8
|
-
import { v4 as uuidv4 } from "uuid";
|
|
9
17
|
import fs11 from "node:fs";
|
|
10
18
|
import { readFile } from "node:fs/promises";
|
|
11
|
-
import
|
|
19
|
+
import path12 from "node:path";
|
|
12
20
|
import { promisify as promisify2, format as format3 } from "node:util";
|
|
13
|
-
import { performance as
|
|
21
|
+
import { performance as performance3, PerformanceObserver as PerformanceObserver2 } from "node:perf_hooks";
|
|
14
22
|
import os5 from "node:os";
|
|
15
23
|
import { SevereServiceError } from "webdriverio";
|
|
16
24
|
import * as BrowserstackLocalLauncher from "browserstack-local";
|
|
@@ -18,7 +26,7 @@ import * as BrowserstackLocalLauncher from "browserstack-local";
|
|
|
18
26
|
// package.json
|
|
19
27
|
var package_default = {
|
|
20
28
|
name: "@wdio/browserstack-service",
|
|
21
|
-
version: "9.
|
|
29
|
+
version: "9.8.0",
|
|
22
30
|
description: "WebdriverIO service for better Browserstack integration",
|
|
23
31
|
author: "Adam Bjerstedt <abjerstedt@gmail.com>",
|
|
24
32
|
homepage: "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
|
|
@@ -143,6 +151,7 @@ var LOG_KIND_USAGE_MAP = {
|
|
|
143
151
|
"HTTP": "http"
|
|
144
152
|
};
|
|
145
153
|
var FUNNEL_INSTRUMENTATION_URL = "https://api.browserstack.com/sdk/v1/event";
|
|
154
|
+
var EDS_URL = "https://eds.browserstack.com";
|
|
146
155
|
var SUPPORTED_BROWSERS_FOR_AI = ["chrome", "microsoftedge", "firefox"];
|
|
147
156
|
var TCG_URL = "https://tcg.browserstack.com";
|
|
148
157
|
var TCG_INFO = {
|
|
@@ -165,21 +174,22 @@ var MAX_GIT_META_DATA_SIZE_IN_BYTES = 64 * 1024;
|
|
|
165
174
|
var GIT_META_DATA_TRUNCATED = "...[TRUNCATED]";
|
|
166
175
|
|
|
167
176
|
// src/bstackLogger.ts
|
|
168
|
-
import
|
|
177
|
+
import path4 from "node:path";
|
|
169
178
|
import fs4 from "node:fs";
|
|
170
179
|
import chalk from "chalk";
|
|
171
180
|
import logger from "@wdio/logger";
|
|
172
181
|
|
|
173
182
|
// src/util.ts
|
|
174
|
-
import { hostname, platform, type, version, arch } from "node:os";
|
|
183
|
+
import { hostname as hostname2, platform as platform2, type as type2, version as version2, arch as arch2 } from "node:os";
|
|
175
184
|
import fs3 from "node:fs";
|
|
176
185
|
import zlib from "node:zlib";
|
|
177
186
|
import { format, promisify } from "node:util";
|
|
178
|
-
import
|
|
179
|
-
import
|
|
187
|
+
import path3 from "node:path";
|
|
188
|
+
import util2 from "node:util";
|
|
180
189
|
import gitRepoInfo from "git-repo-info";
|
|
181
190
|
import gitconfig from "gitconfiglocal";
|
|
182
191
|
import { FormData as FormData2 } from "formdata-node";
|
|
192
|
+
import { performance as performance2 } from "node:perf_hooks";
|
|
183
193
|
|
|
184
194
|
// src/logPatcher.ts
|
|
185
195
|
import Transport from "winston-transport";
|
|
@@ -222,33 +232,81 @@ var logPatcher = class extends Transport {
|
|
|
222
232
|
};
|
|
223
233
|
var logPatcher_default = logPatcher;
|
|
224
234
|
|
|
225
|
-
// src/performance-tester.ts
|
|
235
|
+
// src/instrumentation/performance/performance-tester.ts
|
|
226
236
|
import { createObjectCsvWriter } from "csv-writer";
|
|
227
237
|
import fs from "node:fs";
|
|
238
|
+
import fsPromise from "node:fs/promises";
|
|
228
239
|
import { performance, PerformanceObserver } from "node:perf_hooks";
|
|
229
|
-
|
|
240
|
+
import util from "node:util";
|
|
241
|
+
import worker from "node:worker_threads";
|
|
242
|
+
import path from "node:path";
|
|
243
|
+
import { arch, hostname, platform, type, version } from "node:os";
|
|
244
|
+
|
|
245
|
+
// src/fetchWrapper.ts
|
|
246
|
+
var ResponseError = class extends Error {
|
|
247
|
+
response;
|
|
248
|
+
constructor(message, res) {
|
|
249
|
+
super(message);
|
|
250
|
+
this.response = res;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
async function fetchWrap(input, init) {
|
|
254
|
+
const res = await fetch(input, init);
|
|
255
|
+
if (!res.ok) {
|
|
256
|
+
throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
|
|
257
|
+
}
|
|
258
|
+
return res;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/instrumentation/performance/performance-tester.ts
|
|
262
|
+
var PerformanceTester = class _PerformanceTester {
|
|
230
263
|
static _observer;
|
|
231
264
|
static _csvWriter;
|
|
232
265
|
static _events = [];
|
|
266
|
+
static _measuredEvents = [];
|
|
233
267
|
static started = false;
|
|
268
|
+
static details = {};
|
|
269
|
+
static eventsMap = {};
|
|
270
|
+
static browser;
|
|
271
|
+
static scenarioThatRan;
|
|
272
|
+
static jsonReportDirName = "performance-report";
|
|
273
|
+
static jsonReportDirPath = path.join(process.cwd(), "logs", this.jsonReportDirName);
|
|
274
|
+
static jsonReportFileName = `${this.jsonReportDirPath}/performance-report-${_PerformanceTester.getProcessId()}.json`;
|
|
234
275
|
static startMonitoring(csvName = "performance-report.csv") {
|
|
276
|
+
if (!fs.existsSync(this.jsonReportDirPath)) {
|
|
277
|
+
fs.mkdirSync(this.jsonReportDirPath, { recursive: true });
|
|
278
|
+
}
|
|
235
279
|
this._observer = new PerformanceObserver((list) => {
|
|
236
|
-
list.getEntries().
|
|
237
|
-
|
|
238
|
-
|
|
280
|
+
list.getEntries().filter((entry) => entry.entryType === "measure").forEach(
|
|
281
|
+
(entry) => {
|
|
282
|
+
let finalEntry = entry;
|
|
283
|
+
finalEntry = entry.toJSON();
|
|
284
|
+
if (this.details[entry.name]) {
|
|
285
|
+
finalEntry = Object.assign(finalEntry, this.details[entry.name]);
|
|
286
|
+
}
|
|
287
|
+
delete this.details[entry.name];
|
|
288
|
+
this._measuredEvents.push(finalEntry);
|
|
289
|
+
}
|
|
290
|
+
);
|
|
291
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
292
|
+
list.getEntries().forEach((entry) => this._events.push(entry));
|
|
293
|
+
}
|
|
239
294
|
});
|
|
240
|
-
|
|
295
|
+
const entryTypes = ["measure"];
|
|
296
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
297
|
+
entryTypes.push("function");
|
|
298
|
+
}
|
|
299
|
+
this._observer.observe({ buffered: true, entryTypes });
|
|
241
300
|
this.started = true;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return performance;
|
|
301
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
302
|
+
this._csvWriter = createObjectCsvWriter({
|
|
303
|
+
path: csvName,
|
|
304
|
+
header: [
|
|
305
|
+
{ id: "name", title: "Function Name" },
|
|
306
|
+
{ id: "time", title: "Execution Time (ms)" }
|
|
307
|
+
]
|
|
308
|
+
});
|
|
309
|
+
}
|
|
252
310
|
}
|
|
253
311
|
static calculateTimes(methods) {
|
|
254
312
|
const times = {};
|
|
@@ -261,26 +319,35 @@ var PerformanceTester = class {
|
|
|
261
319
|
const timeTaken = methods.reduce((a, c) => {
|
|
262
320
|
return times[c] + (a || 0);
|
|
263
321
|
}, 0);
|
|
264
|
-
BStackLogger.
|
|
322
|
+
BStackLogger.debug(`Time for ${methods} is ${timeTaken}`);
|
|
265
323
|
return timeTaken;
|
|
266
324
|
}
|
|
267
325
|
static async stopAndGenerate(filename = "performance-own.html") {
|
|
268
326
|
if (!this.started) {
|
|
269
327
|
return;
|
|
270
328
|
}
|
|
271
|
-
|
|
329
|
+
try {
|
|
330
|
+
const eventsJson = JSON.stringify(this._measuredEvents);
|
|
331
|
+
const finalJSONStr = eventsJson.slice(1, -1) + ",";
|
|
332
|
+
await fsPromise.appendFile(this.jsonReportFileName, finalJSONStr);
|
|
333
|
+
} catch (er) {
|
|
334
|
+
BStackLogger.debug(`Failed to write events of the worker to ${this.jsonReportFileName}: ${util.format(er)}`);
|
|
335
|
+
}
|
|
272
336
|
this._observer.disconnect();
|
|
337
|
+
if (!process.env[PERF_MEASUREMENT_ENV]) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
await _PerformanceTester.sleep(2e3);
|
|
273
341
|
this.started = false;
|
|
274
342
|
this.generateCSV(this._events);
|
|
275
343
|
const content = this.generateReport(this._events);
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
});
|
|
344
|
+
const dir = path.join(process.cwd(), filename);
|
|
345
|
+
try {
|
|
346
|
+
await fsPromise.writeFile(dir, content);
|
|
347
|
+
BStackLogger.info(`Performance report is at ${path}`);
|
|
348
|
+
} catch (err) {
|
|
349
|
+
BStackLogger.error(`Error in writing html ${util.format(err)}`);
|
|
350
|
+
}
|
|
284
351
|
}
|
|
285
352
|
static generateReport(entries) {
|
|
286
353
|
let html = "<!DOCTYPE html><html><head><title>Performance Report</title></head><body>";
|
|
@@ -312,6 +379,221 @@ var PerformanceTester = class {
|
|
|
312
379
|
});
|
|
313
380
|
this._csvWriter.writeRecords(dat).then(() => BStackLogger.info("Performance CSV report generated successfully")).catch((error) => console.error(error));
|
|
314
381
|
}
|
|
382
|
+
static Measure(label, details = {}) {
|
|
383
|
+
const self = this;
|
|
384
|
+
return (target, key, descriptor) => {
|
|
385
|
+
const originalMethod = descriptor.value;
|
|
386
|
+
if (descriptor.value) {
|
|
387
|
+
descriptor.value = function(...args) {
|
|
388
|
+
return _PerformanceTester.measure.apply(self, [label, originalMethod, { methodName: key.toString(), ...details }, args, this]);
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
static measureWrapper(name, fn, details = {}) {
|
|
394
|
+
const self = this;
|
|
395
|
+
details.worker = _PerformanceTester.getProcessId();
|
|
396
|
+
details.testName = _PerformanceTester.scenarioThatRan && _PerformanceTester.scenarioThatRan[_PerformanceTester.scenarioThatRan.length - 1];
|
|
397
|
+
details.platform = _PerformanceTester.browser?.sessionId;
|
|
398
|
+
return function(...args) {
|
|
399
|
+
return self.measure(name, fn, details, args);
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
static isEnabled() {
|
|
403
|
+
return !(process.env.BROWSERSTACK_SDK_INSTRUMENTATION === "false");
|
|
404
|
+
}
|
|
405
|
+
static measure(label, fn, details = {}, args, thisArg = null) {
|
|
406
|
+
if (!this.started || !this.isEnabled()) {
|
|
407
|
+
return fn.apply(thisArg, args);
|
|
408
|
+
}
|
|
409
|
+
_PerformanceTester.start(label);
|
|
410
|
+
if (this.details) {
|
|
411
|
+
this.details[label] = details;
|
|
412
|
+
}
|
|
413
|
+
try {
|
|
414
|
+
const returnVal = fn.apply(thisArg, args);
|
|
415
|
+
if (returnVal instanceof Promise) {
|
|
416
|
+
return new Promise((resolve, reject) => {
|
|
417
|
+
returnVal.then((v) => {
|
|
418
|
+
_PerformanceTester.end(label);
|
|
419
|
+
resolve(v);
|
|
420
|
+
}).catch((e) => {
|
|
421
|
+
_PerformanceTester.end(label, false, util.format(e));
|
|
422
|
+
reject(e);
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
_PerformanceTester.end(label);
|
|
427
|
+
return returnVal;
|
|
428
|
+
} catch (er) {
|
|
429
|
+
_PerformanceTester.end(label, false, util.format(er));
|
|
430
|
+
throw er;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
static start(event) {
|
|
434
|
+
const finalEvent = event + "-start";
|
|
435
|
+
if (this.eventsMap[finalEvent]) {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
performance.mark(finalEvent);
|
|
439
|
+
this.eventsMap[finalEvent] = 1;
|
|
440
|
+
}
|
|
441
|
+
static end(event, success = true, failure, details = {}) {
|
|
442
|
+
performance.mark(event + "-end");
|
|
443
|
+
performance.measure(event, event + "-start", event + "-end");
|
|
444
|
+
this.details[event] = Object.assign({ success, failure: util.format(failure) }, Object.assign(Object.assign({
|
|
445
|
+
worker: _PerformanceTester.getProcessId(),
|
|
446
|
+
platform: _PerformanceTester.browser?.sessionId,
|
|
447
|
+
testName: _PerformanceTester.scenarioThatRan && _PerformanceTester.scenarioThatRan[_PerformanceTester.scenarioThatRan.length - 1]
|
|
448
|
+
}, details), this.details[event] || {}));
|
|
449
|
+
}
|
|
450
|
+
static getProcessId() {
|
|
451
|
+
return `${process.pid}-${worker.threadId}`;
|
|
452
|
+
}
|
|
453
|
+
static sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
454
|
+
static async uploadEventsData() {
|
|
455
|
+
try {
|
|
456
|
+
let measures = [];
|
|
457
|
+
if (await fsPromise.access(this.jsonReportDirPath).then(() => true).catch(() => false)) {
|
|
458
|
+
const files = (await fsPromise.readdir(this.jsonReportDirPath)).map((file) => path.resolve(this.jsonReportDirPath, file));
|
|
459
|
+
measures = (await Promise.all(files.map((file) => fsPromise.readFile(file, "utf-8")))).map((el) => `[${el.slice(0, -1)}]`).map((el) => JSON.parse(el)).flat();
|
|
460
|
+
}
|
|
461
|
+
if (this._measuredEvents.length > 0) {
|
|
462
|
+
measures = measures.concat(this._measuredEvents);
|
|
463
|
+
}
|
|
464
|
+
const date = /* @__PURE__ */ new Date();
|
|
465
|
+
const options = {
|
|
466
|
+
timeZone: "UTC",
|
|
467
|
+
year: "numeric",
|
|
468
|
+
month: "2-digit",
|
|
469
|
+
day: "2-digit",
|
|
470
|
+
hour: "2-digit",
|
|
471
|
+
minute: "2-digit",
|
|
472
|
+
second: "2-digit",
|
|
473
|
+
fractionalSecondDigits: 3,
|
|
474
|
+
// To include microseconds
|
|
475
|
+
hour12: false
|
|
476
|
+
};
|
|
477
|
+
const formattedDate = new Intl.DateTimeFormat("en-GB", options).formatToParts(date).map(({ type: type3, value }) => type3 === "timeZoneName" ? "Z" : value).join("").replace(",", "T");
|
|
478
|
+
const payload = {
|
|
479
|
+
event_type: "sdk_events",
|
|
480
|
+
data: {
|
|
481
|
+
testhub_uuid: process.env.PERF_TESTHUB_UUID || process.env.SDK_RUN_ID,
|
|
482
|
+
created_day: formattedDate,
|
|
483
|
+
event_name: "SDKFeaturePerformance",
|
|
484
|
+
user_data: process.env.PERF_USER_NAME,
|
|
485
|
+
host_info: JSON.stringify({
|
|
486
|
+
hostname: hostname(),
|
|
487
|
+
platform: platform(),
|
|
488
|
+
type: type(),
|
|
489
|
+
version: version(),
|
|
490
|
+
arch: arch()
|
|
491
|
+
}),
|
|
492
|
+
event_json: { measures, sdkRunId: process.env.SDK_RUN_ID }
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
const result = await fetchWrap(`${EDS_URL}/send_sdk_events`, {
|
|
496
|
+
method: "POST",
|
|
497
|
+
headers: {
|
|
498
|
+
"content-type": "application/json"
|
|
499
|
+
},
|
|
500
|
+
body: JSON.stringify(payload)
|
|
501
|
+
});
|
|
502
|
+
BStackLogger.debug(`Successfully uploaded performance events ${util.format(await result.text())}`);
|
|
503
|
+
} catch (er) {
|
|
504
|
+
BStackLogger.debug(`Failed to upload performance events ${util.format(er)}`);
|
|
505
|
+
}
|
|
506
|
+
try {
|
|
507
|
+
if (await fsPromise.access(this.jsonReportDirPath).then(() => true, () => false)) {
|
|
508
|
+
const files = await fsPromise.readdir(this.jsonReportDirPath);
|
|
509
|
+
for (const file of files) {
|
|
510
|
+
await fsPromise.unlink(path.join(this.jsonReportDirPath, file));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
} catch (er) {
|
|
514
|
+
BStackLogger.debug(`Failed to delete performance related files ${util.format(er)}`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// src/instrumentation/performance/constants.ts
|
|
520
|
+
var EVENTS = {
|
|
521
|
+
SDK_SETUP: "sdk:setup",
|
|
522
|
+
SDK_CLEANUP: "sdk:cleanup",
|
|
523
|
+
SDK_PRE_TEST: "sdk:pre-test",
|
|
524
|
+
SDK_TEST: "sdk:test",
|
|
525
|
+
SDK_POST_TEST: "sdk:post-test",
|
|
526
|
+
SDK_HOOK: "sdk:hook",
|
|
527
|
+
SDK_DRIVER: "sdk:driver",
|
|
528
|
+
SDK_A11Y: "sdk:a11y",
|
|
529
|
+
SDK_O11Y: "sdk:o11y",
|
|
530
|
+
SDK_AUTO_CAPTURE: "sdk:auto-capture",
|
|
531
|
+
SDK_PROXY_SETUP: "sdk:proxy-setup",
|
|
532
|
+
SDK_TESTHUB: "sdk:testhub",
|
|
533
|
+
SDK_AUTOMATE: "sdk:automate",
|
|
534
|
+
SDK_APP_AUTOMATE: "sdk:app-automate",
|
|
535
|
+
SDK_TURBOSCALE: "sdk:turboscale",
|
|
536
|
+
SDK_PERCY: "sdk:percy",
|
|
537
|
+
SDK_PRE_INITIALIZE: "sdk:driver:pre-initialization",
|
|
538
|
+
SDK_POST_INITIALIZE: "sdk:driver:post-initialization"
|
|
539
|
+
};
|
|
540
|
+
var TESTHUB_EVENTS = {
|
|
541
|
+
START: `${EVENTS.SDK_TESTHUB}:start`,
|
|
542
|
+
STOP: `${EVENTS.SDK_TESTHUB}:stop`
|
|
543
|
+
};
|
|
544
|
+
var AUTOMATE_EVENTS = {
|
|
545
|
+
KEEP_ALIVE: `${EVENTS.SDK_AUTOMATE}:keep-alive`,
|
|
546
|
+
HUB_MANAGEMENT: `${EVENTS.SDK_AUTOMATE}:hub-management`,
|
|
547
|
+
LOCAL_START: `${EVENTS.SDK_AUTOMATE}:local-start`,
|
|
548
|
+
LOCAL_STOP: `${EVENTS.SDK_AUTOMATE}:local-stop`,
|
|
549
|
+
DRIVER_MANAGE: `${EVENTS.SDK_AUTOMATE}:driver-manage`,
|
|
550
|
+
SESSION_NAME: `${EVENTS.SDK_AUTOMATE}:session-name`,
|
|
551
|
+
SESSION_STATUS: `${EVENTS.SDK_AUTOMATE}:session-status`,
|
|
552
|
+
SESSION_ANNOTATION: `${EVENTS.SDK_AUTOMATE}:session-annotation`,
|
|
553
|
+
IDLE_TIMEOUT: `${EVENTS.SDK_AUTOMATE}:idle-timeout`,
|
|
554
|
+
GENERATE_CI_ARTIFACT: `${EVENTS.SDK_AUTOMATE}:ci-artifacts`,
|
|
555
|
+
PRINT_BUILDLINK: `${EVENTS.SDK_AUTOMATE}:print-buildlink`
|
|
556
|
+
};
|
|
557
|
+
var A11Y_EVENTS = {
|
|
558
|
+
PERFORM_SCAN: `${EVENTS.SDK_A11Y}:driver-performscan`,
|
|
559
|
+
SAVE_RESULTS: `${EVENTS.SDK_A11Y}:save-results`,
|
|
560
|
+
GET_RESULTS: `${EVENTS.SDK_A11Y}:get-accessibility-results`,
|
|
561
|
+
GET_RESULTS_SUMMARY: `${EVENTS.SDK_A11Y}:get-accessibility-results-summary`
|
|
562
|
+
};
|
|
563
|
+
var PERCY_EVENTS = {
|
|
564
|
+
DOWNLOAD: `${EVENTS.SDK_PERCY}:download`,
|
|
565
|
+
SCREENSHOT: `${EVENTS.SDK_PERCY}:screenshot`,
|
|
566
|
+
START: `${EVENTS.SDK_PERCY}:start`,
|
|
567
|
+
STOP: `${EVENTS.SDK_PERCY}:stop`,
|
|
568
|
+
AUTO_CAPTURE: `${EVENTS.SDK_PERCY}:auto-capture`,
|
|
569
|
+
SNAPSHOT: `${EVENTS.SDK_PERCY}:snapshot`,
|
|
570
|
+
SCREENSHOT_APP: `${EVENTS.SDK_PERCY}:screenshot-app`
|
|
571
|
+
};
|
|
572
|
+
var O11Y_EVENTS = {
|
|
573
|
+
SYNC: `${EVENTS.SDK_O11Y}:sync`,
|
|
574
|
+
TAKE_SCREENSHOT: `${EVENTS.SDK_O11Y}:driver-takeScreenShot`,
|
|
575
|
+
PRINT_BUILDLINK: `${EVENTS.SDK_O11Y}:print-buildlink`
|
|
576
|
+
};
|
|
577
|
+
var HOOK_EVENTS = {
|
|
578
|
+
BEFORE_EACH: `${EVENTS.SDK_HOOK}:before-each`,
|
|
579
|
+
AFTER_EACH: `${EVENTS.SDK_HOOK}:after-each`,
|
|
580
|
+
AFTER_ALL: `${EVENTS.SDK_HOOK}:after-all`,
|
|
581
|
+
BEFORE_ALL: `${EVENTS.SDK_HOOK}:before-all`,
|
|
582
|
+
BEFORE: `${EVENTS.SDK_HOOK}:before`,
|
|
583
|
+
AFTER: `${EVENTS.SDK_HOOK}:after`
|
|
584
|
+
};
|
|
585
|
+
var TURBOSCALE_EVENTS = {
|
|
586
|
+
HUB_MANAGEMENT: `${EVENTS.SDK_TURBOSCALE}:hub-management`,
|
|
587
|
+
PRINT_BUILDLINK: `${EVENTS.SDK_TURBOSCALE}:print-buildlink`
|
|
588
|
+
};
|
|
589
|
+
var APP_AUTOMATE_EVENTS = {
|
|
590
|
+
APP_UPLOAD: `${EVENTS.SDK_APP_AUTOMATE}:app-upload`
|
|
591
|
+
};
|
|
592
|
+
var DRIVER_EVENT = {
|
|
593
|
+
QUIT: `${EVENTS.SDK_DRIVER}:quit`,
|
|
594
|
+
GET: `${EVENTS.SDK_DRIVER}:get`,
|
|
595
|
+
PRE_EXECUTE: `${EVENTS.SDK_DRIVER}:pre-execute`,
|
|
596
|
+
POST_EXECUTE: `${EVENTS.SDK_DRIVER}:post-execute`
|
|
315
597
|
};
|
|
316
598
|
|
|
317
599
|
// src/crash-reporter.ts
|
|
@@ -740,7 +1022,7 @@ var UsageStats = class _UsageStats {
|
|
|
740
1022
|
var usageStats_default = UsageStats;
|
|
741
1023
|
|
|
742
1024
|
// src/scripts/accessibility-scripts.ts
|
|
743
|
-
import
|
|
1025
|
+
import path2 from "node:path";
|
|
744
1026
|
import fs2 from "node:fs";
|
|
745
1027
|
import os from "node:os";
|
|
746
1028
|
var AccessibilityScripts = class _AccessibilityScripts {
|
|
@@ -755,7 +1037,7 @@ var AccessibilityScripts = class _AccessibilityScripts {
|
|
|
755
1037
|
// don't allow to create instances from it other than through `checkAndGetInstance`
|
|
756
1038
|
constructor() {
|
|
757
1039
|
this.browserstackFolderPath = this.getWritableDir();
|
|
758
|
-
this.commandsPath =
|
|
1040
|
+
this.commandsPath = path2.join(this.browserstackFolderPath, "commands.json");
|
|
759
1041
|
}
|
|
760
1042
|
static checkAndGetInstance() {
|
|
761
1043
|
if (!_AccessibilityScripts.instance) {
|
|
@@ -767,7 +1049,7 @@ var AccessibilityScripts = class _AccessibilityScripts {
|
|
|
767
1049
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
768
1050
|
getWritableDir() {
|
|
769
1051
|
const orderedPaths = [
|
|
770
|
-
|
|
1052
|
+
path2.join(os.homedir(), ".browserstack"),
|
|
771
1053
|
process.cwd(),
|
|
772
1054
|
os.tmpdir()
|
|
773
1055
|
];
|
|
@@ -879,7 +1161,7 @@ function processError(error, fn, args) {
|
|
|
879
1161
|
try {
|
|
880
1162
|
argsString = JSON.stringify(args);
|
|
881
1163
|
} catch {
|
|
882
|
-
argsString =
|
|
1164
|
+
argsString = util2.inspect(args, { depth: 2 });
|
|
883
1165
|
}
|
|
884
1166
|
CrashReporter.uploadCrashReport(`Error in executing ${fn.name} with args ${argsString} : ${error}`, error && error.stack || "unknown error");
|
|
885
1167
|
}
|
|
@@ -888,7 +1170,7 @@ function o11yErrorHandler(fn) {
|
|
|
888
1170
|
try {
|
|
889
1171
|
let functionToHandle = fn;
|
|
890
1172
|
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
891
|
-
functionToHandle =
|
|
1173
|
+
functionToHandle = performance2.timerify(functionToHandle);
|
|
892
1174
|
}
|
|
893
1175
|
const result = functionToHandle(...args);
|
|
894
1176
|
if (result instanceof Promise) {
|
|
@@ -951,7 +1233,7 @@ function o11yClassErrorHandler(errorClass) {
|
|
|
951
1233
|
writable: true,
|
|
952
1234
|
value: function(...args) {
|
|
953
1235
|
try {
|
|
954
|
-
const result = (process.env[PERF_MEASUREMENT_ENV] ?
|
|
1236
|
+
const result = (process.env[PERF_MEASUREMENT_ENV] ? performance2.timerify(method) : method).call(this, ...args);
|
|
955
1237
|
if (result instanceof Promise) {
|
|
956
1238
|
return result.catch((error) => processError(error, method, args));
|
|
957
1239
|
}
|
|
@@ -1026,7 +1308,7 @@ var processLaunchBuildResponse = (response, options) => {
|
|
|
1026
1308
|
processAccessibilityResponse(response);
|
|
1027
1309
|
}
|
|
1028
1310
|
};
|
|
1029
|
-
var launchTestSession = o11yErrorHandler(async function launchTestSession2(options, config, bsConfig, bStackConfig) {
|
|
1311
|
+
var launchTestSession = PerformanceTester.measureWrapper(TESTHUB_EVENTS.START, o11yErrorHandler(async function launchTestSession2(options, config, bsConfig, bStackConfig) {
|
|
1030
1312
|
const launchBuildUsage = usageStats_default.getInstance().launchBuildUsage;
|
|
1031
1313
|
launchBuildUsage.triggered();
|
|
1032
1314
|
const data = {
|
|
@@ -1037,11 +1319,11 @@ var launchTestSession = o11yErrorHandler(async function launchTestSession2(optio
|
|
|
1037
1319
|
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1038
1320
|
tags: getObservabilityBuildTags(options, bsConfig.buildTag),
|
|
1039
1321
|
host_info: {
|
|
1040
|
-
hostname:
|
|
1041
|
-
platform:
|
|
1042
|
-
type:
|
|
1043
|
-
version:
|
|
1044
|
-
arch:
|
|
1322
|
+
hostname: hostname2(),
|
|
1323
|
+
platform: platform2(),
|
|
1324
|
+
type: type2(),
|
|
1325
|
+
version: version2(),
|
|
1326
|
+
arch: arch2()
|
|
1045
1327
|
},
|
|
1046
1328
|
ci_info: getCiInfo(),
|
|
1047
1329
|
build_run_identifier: process.env.BROWSERSTACK_BUILD_RUN_IDENTIFIER,
|
|
@@ -1093,6 +1375,7 @@ var launchTestSession = o11yErrorHandler(async function launchTestSession2(optio
|
|
|
1093
1375
|
if (jsonResponse.build_hashed_id) {
|
|
1094
1376
|
process.env[BROWSERSTACK_TESTHUB_UUID] = jsonResponse.build_hashed_id;
|
|
1095
1377
|
testOpsConfig_default.getInstance().buildHashedId = jsonResponse.build_hashed_id;
|
|
1378
|
+
BStackLogger.info(`Testhub started with id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
|
|
1096
1379
|
}
|
|
1097
1380
|
processLaunchBuildResponse(jsonResponse, options);
|
|
1098
1381
|
launchBuildUsage.success();
|
|
@@ -1104,7 +1387,7 @@ var launchTestSession = o11yErrorHandler(async function launchTestSession2(optio
|
|
|
1104
1387
|
return;
|
|
1105
1388
|
}
|
|
1106
1389
|
}
|
|
1107
|
-
});
|
|
1390
|
+
}));
|
|
1108
1391
|
var validateCapsWithAppA11y = (platformMeta) => {
|
|
1109
1392
|
if (platformMeta?.platform_name && String(platformMeta?.platform_name).toLowerCase() === "android" && (platformMeta?.platform_version && parseInt(platformMeta?.platform_version?.toString()) < 11)) {
|
|
1110
1393
|
BStackLogger.warn("App Accessibility Automation tests are supported on OS version 11 and above for Android devices.");
|
|
@@ -1202,7 +1485,7 @@ var performA11yScan = async (isAppAutomate, browser, isBrowserStackSession, isAc
|
|
|
1202
1485
|
try {
|
|
1203
1486
|
if (isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
|
|
1204
1487
|
const results = await browser.execute(formatString(accessibility_scripts_default.performScan, JSON.stringify(_getParamsForAppAccessibility(commandName))), {});
|
|
1205
|
-
BStackLogger.debug(
|
|
1488
|
+
BStackLogger.debug(util2.format(results));
|
|
1206
1489
|
return results;
|
|
1207
1490
|
}
|
|
1208
1491
|
if (accessibility_scripts_default.performScan) {
|
|
@@ -1216,7 +1499,7 @@ var performA11yScan = async (isAppAutomate, browser, isBrowserStackSession, isAc
|
|
|
1216
1499
|
return;
|
|
1217
1500
|
}
|
|
1218
1501
|
};
|
|
1219
|
-
var getA11yResults = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
|
|
1502
|
+
var getA11yResults = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
|
|
1220
1503
|
if (!isBrowserStackSession) {
|
|
1221
1504
|
BStackLogger.warn("Not a BrowserStack Automate session, cannot retrieve Accessibility results.");
|
|
1222
1505
|
return [];
|
|
@@ -1239,8 +1522,8 @@ var getA11yResults = async (isAppAutomate, browser, isBrowserStackSession, isAcc
|
|
|
1239
1522
|
BStackLogger.debug(`getA11yResults Failed. Error: ${error}`);
|
|
1240
1523
|
return [];
|
|
1241
1524
|
}
|
|
1242
|
-
};
|
|
1243
|
-
var getAppA11yResults = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1525
|
+
});
|
|
1526
|
+
var getAppA11yResults = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1244
1527
|
if (!isBrowserStackSession) {
|
|
1245
1528
|
return [];
|
|
1246
1529
|
}
|
|
@@ -1259,8 +1542,8 @@ var getAppA11yResults = async (isAppAutomate, browser, isBrowserStackSession, is
|
|
|
1259
1542
|
BStackLogger.debug(`getAppA11yResults Failed. Error: ${error}`);
|
|
1260
1543
|
return [];
|
|
1261
1544
|
}
|
|
1262
|
-
};
|
|
1263
|
-
var getAppA11yResultsSummary = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1545
|
+
});
|
|
1546
|
+
var getAppA11yResultsSummary = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS_SUMMARY, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1264
1547
|
if (!isBrowserStackSession) {
|
|
1265
1548
|
return {};
|
|
1266
1549
|
}
|
|
@@ -1278,7 +1561,7 @@ var getAppA11yResultsSummary = async (isAppAutomate, browser, isBrowserStackSess
|
|
|
1278
1561
|
BStackLogger.error("No accessibility summary was found.");
|
|
1279
1562
|
return {};
|
|
1280
1563
|
}
|
|
1281
|
-
};
|
|
1564
|
+
});
|
|
1282
1565
|
var getAppA11yResultResponse = async (apiUrl, isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1283
1566
|
BStackLogger.debug("Performing scan before getting results summary");
|
|
1284
1567
|
await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
|
|
@@ -1289,7 +1572,7 @@ var getAppA11yResultResponse = async (apiUrl, isAppAutomate, browser, isBrowserS
|
|
|
1289
1572
|
BStackLogger.debug(`Polling Result: ${JSON.stringify(apiRespone)}`);
|
|
1290
1573
|
return apiRespone;
|
|
1291
1574
|
};
|
|
1292
|
-
var getA11yResultsSummary = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
|
|
1575
|
+
var getA11yResultsSummary = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS_SUMMARY, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
|
|
1293
1576
|
if (!isBrowserStackSession) {
|
|
1294
1577
|
return {};
|
|
1295
1578
|
}
|
|
@@ -1310,8 +1593,8 @@ var getA11yResultsSummary = async (isAppAutomate, browser, isBrowserStackSession
|
|
|
1310
1593
|
BStackLogger.error("No accessibility summary was found.");
|
|
1311
1594
|
return {};
|
|
1312
1595
|
}
|
|
1313
|
-
};
|
|
1314
|
-
var stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstream2() {
|
|
1596
|
+
});
|
|
1597
|
+
var stopBuildUpstream = PerformanceTester.measureWrapper(TESTHUB_EVENTS.STOP, o11yErrorHandler(async function stopBuildUpstream2() {
|
|
1315
1598
|
const stopBuildUsage = usageStats_default.getInstance().stopBuildUsage;
|
|
1316
1599
|
stopBuildUsage.triggered();
|
|
1317
1600
|
if (!process.env[TESTOPS_BUILD_COMPLETED_ENV]) {
|
|
@@ -1356,7 +1639,7 @@ var stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstream2() {
|
|
|
1356
1639
|
message: error.message
|
|
1357
1640
|
};
|
|
1358
1641
|
}
|
|
1359
|
-
});
|
|
1642
|
+
}));
|
|
1360
1643
|
function getCiInfo() {
|
|
1361
1644
|
const env = process.env;
|
|
1362
1645
|
if (typeof env.JENKINS_URL === "string" && env.JENKINS_URL.length > 0 || typeof env.JENKINS_HOME === "string" && env.JENKINS_HOME.length > 0) {
|
|
@@ -1779,7 +2062,7 @@ function getObservabilityBuild(options, bstackBuildName) {
|
|
|
1779
2062
|
if (options.testObservabilityOptions && options.testObservabilityOptions.buildName) {
|
|
1780
2063
|
return options.testObservabilityOptions.buildName;
|
|
1781
2064
|
}
|
|
1782
|
-
return bstackBuildName ||
|
|
2065
|
+
return bstackBuildName || path3.basename(path3.resolve(process.cwd()));
|
|
1783
2066
|
}
|
|
1784
2067
|
function getObservabilityBuildTags(options, bstackBuildTag) {
|
|
1785
2068
|
if (process.env.TEST_OBSERVABILITY_BUILD_TAG) {
|
|
@@ -2075,8 +2358,8 @@ async function executeAccessibilityScript(browser, fnBody, arg) {
|
|
|
2075
2358
|
// src/bstackLogger.ts
|
|
2076
2359
|
var log = logger("@wdio/browserstack-service");
|
|
2077
2360
|
var BStackLogger = class {
|
|
2078
|
-
static logFilePath =
|
|
2079
|
-
static logFolderPath =
|
|
2361
|
+
static logFilePath = path4.join(process.cwd(), LOGS_FILE);
|
|
2362
|
+
static logFolderPath = path4.join(process.cwd(), "logs");
|
|
2080
2363
|
static logFileStream;
|
|
2081
2364
|
static logToFile(logMessage, logLevel) {
|
|
2082
2365
|
try {
|
|
@@ -2194,14 +2477,14 @@ var logBuildError = (error, product = "") => {
|
|
|
2194
2477
|
};
|
|
2195
2478
|
|
|
2196
2479
|
// src/Percy/PercyLogger.ts
|
|
2197
|
-
import
|
|
2480
|
+
import path5 from "node:path";
|
|
2198
2481
|
import fs5 from "node:fs";
|
|
2199
2482
|
import chalk2 from "chalk";
|
|
2200
2483
|
import logger2 from "@wdio/logger";
|
|
2201
2484
|
var log2 = logger2("@wdio/browserstack-service");
|
|
2202
2485
|
var PercyLogger = class {
|
|
2203
|
-
static logFilePath =
|
|
2204
|
-
static logFolderPath =
|
|
2486
|
+
static logFilePath = path5.join(process.cwd(), PERCY_LOGS_FILE);
|
|
2487
|
+
static logFolderPath = path5.join(process.cwd(), "logs");
|
|
2205
2488
|
static logFileStream;
|
|
2206
2489
|
static logToFile(logMessage, logLevel) {
|
|
2207
2490
|
try {
|
|
@@ -2261,7 +2544,7 @@ var PercyLogger = class {
|
|
|
2261
2544
|
|
|
2262
2545
|
// src/Percy/Percy.ts
|
|
2263
2546
|
import fs7 from "node:fs";
|
|
2264
|
-
import
|
|
2547
|
+
import path7 from "node:path";
|
|
2265
2548
|
import os3 from "node:os";
|
|
2266
2549
|
import { spawn as spawn2 } from "node:child_process";
|
|
2267
2550
|
|
|
@@ -2270,7 +2553,7 @@ import yauzl from "yauzl";
|
|
|
2270
2553
|
import fs6 from "node:fs";
|
|
2271
2554
|
import fsp from "node:fs/promises";
|
|
2272
2555
|
import { pipeline } from "node:stream/promises";
|
|
2273
|
-
import
|
|
2556
|
+
import path6 from "node:path";
|
|
2274
2557
|
import os2 from "node:os";
|
|
2275
2558
|
import { spawn } from "node:child_process";
|
|
2276
2559
|
var PercyBinary = class {
|
|
@@ -2278,7 +2561,7 @@ var PercyBinary = class {
|
|
|
2278
2561
|
#httpPath = null;
|
|
2279
2562
|
#binaryName = "percy";
|
|
2280
2563
|
#orderedPaths = [
|
|
2281
|
-
|
|
2564
|
+
path6.join(os2.homedir(), ".browserstack"),
|
|
2282
2565
|
process.cwd(),
|
|
2283
2566
|
os2.tmpdir()
|
|
2284
2567
|
];
|
|
@@ -2293,15 +2576,15 @@ var PercyBinary = class {
|
|
|
2293
2576
|
this.#httpPath = base + "/percy-linux.zip";
|
|
2294
2577
|
}
|
|
2295
2578
|
}
|
|
2296
|
-
async #makePath(
|
|
2297
|
-
if (await this.#checkPath(
|
|
2579
|
+
async #makePath(path15) {
|
|
2580
|
+
if (await this.#checkPath(path15)) {
|
|
2298
2581
|
return true;
|
|
2299
2582
|
}
|
|
2300
|
-
return fsp.mkdir(
|
|
2583
|
+
return fsp.mkdir(path15).then(() => true).catch(() => false);
|
|
2301
2584
|
}
|
|
2302
|
-
async #checkPath(
|
|
2585
|
+
async #checkPath(path15) {
|
|
2303
2586
|
try {
|
|
2304
|
-
const hasDir = await fsp.access(
|
|
2587
|
+
const hasDir = await fsp.access(path15).then(() => true, () => false);
|
|
2305
2588
|
if (hasDir) {
|
|
2306
2589
|
return true;
|
|
2307
2590
|
}
|
|
@@ -2311,16 +2594,16 @@ var PercyBinary = class {
|
|
|
2311
2594
|
}
|
|
2312
2595
|
async #getAvailableDirs() {
|
|
2313
2596
|
for (let i = 0; i < this.#orderedPaths.length; i++) {
|
|
2314
|
-
const
|
|
2315
|
-
if (await this.#makePath(
|
|
2316
|
-
return
|
|
2597
|
+
const path15 = this.#orderedPaths[i];
|
|
2598
|
+
if (await this.#makePath(path15)) {
|
|
2599
|
+
return path15;
|
|
2317
2600
|
}
|
|
2318
2601
|
}
|
|
2319
2602
|
throw new Error("Error trying to download percy binary");
|
|
2320
2603
|
}
|
|
2321
2604
|
async getBinaryPath() {
|
|
2322
2605
|
const destParentDir = await this.#getAvailableDirs();
|
|
2323
|
-
const binaryPath =
|
|
2606
|
+
const binaryPath = path6.join(destParentDir, this.#binaryName);
|
|
2324
2607
|
if (await this.#checkPath(binaryPath)) {
|
|
2325
2608
|
return binaryPath;
|
|
2326
2609
|
}
|
|
@@ -2351,8 +2634,8 @@ var PercyBinary = class {
|
|
|
2351
2634
|
await fsp.mkdir(destParentDir);
|
|
2352
2635
|
}
|
|
2353
2636
|
const binaryName = this.#binaryName;
|
|
2354
|
-
const zipFilePath =
|
|
2355
|
-
const binaryPath =
|
|
2637
|
+
const zipFilePath = path6.join(destParentDir, binaryName + ".zip");
|
|
2638
|
+
const binaryPath = path6.join(destParentDir, binaryName);
|
|
2356
2639
|
const downloadedFileStream = fs6.createWriteStream(zipFilePath);
|
|
2357
2640
|
const response = await fetch(this.#httpPath);
|
|
2358
2641
|
await pipeline(response.body, downloadedFileStream);
|
|
@@ -2367,7 +2650,7 @@ var PercyBinary = class {
|
|
|
2367
2650
|
zipfile.readEntry();
|
|
2368
2651
|
} else {
|
|
2369
2652
|
const writeStream = fs6.createWriteStream(
|
|
2370
|
-
|
|
2653
|
+
path6.join(destParentDir, entry.fileName)
|
|
2371
2654
|
);
|
|
2372
2655
|
zipfile.openReadStream(entry, function(zipErr, readStream) {
|
|
2373
2656
|
if (zipErr) {
|
|
@@ -2400,12 +2683,15 @@ var PercyBinary = class {
|
|
|
2400
2683
|
});
|
|
2401
2684
|
}
|
|
2402
2685
|
};
|
|
2686
|
+
__decorateClass([
|
|
2687
|
+
PerformanceTester.Measure(PERCY_EVENTS.DOWNLOAD)
|
|
2688
|
+
], PercyBinary.prototype, "download", 1);
|
|
2403
2689
|
var PercyBinary_default = PercyBinary;
|
|
2404
2690
|
|
|
2405
2691
|
// src/Percy/Percy.ts
|
|
2406
2692
|
var logDir = "logs";
|
|
2407
2693
|
var Percy = class {
|
|
2408
|
-
#logfile =
|
|
2694
|
+
#logfile = path7.join(logDir, "percy.log");
|
|
2409
2695
|
#address = process.env.PERCY_SERVER_ADDRESS || "http://127.0.0.1:5338";
|
|
2410
2696
|
#binaryPath = null;
|
|
2411
2697
|
#options;
|
|
@@ -2494,13 +2780,13 @@ var Percy = class {
|
|
|
2494
2780
|
async fetchPercyToken() {
|
|
2495
2781
|
const projectName = this.#projectName;
|
|
2496
2782
|
try {
|
|
2497
|
-
const
|
|
2783
|
+
const type3 = this.#isApp ? "app" : "automate";
|
|
2498
2784
|
const params = new URLSearchParams();
|
|
2499
2785
|
if (projectName) {
|
|
2500
2786
|
params.set("name", projectName);
|
|
2501
2787
|
}
|
|
2502
|
-
if (
|
|
2503
|
-
params.set("type",
|
|
2788
|
+
if (type3) {
|
|
2789
|
+
params.set("type", type3);
|
|
2504
2790
|
}
|
|
2505
2791
|
if (this.#options.percyCaptureMode) {
|
|
2506
2792
|
params.set("percy_capture_mode", this.#options.percyCaptureMode);
|
|
@@ -2533,7 +2819,7 @@ var Percy = class {
|
|
|
2533
2819
|
if (!this.#options.percyOptions) {
|
|
2534
2820
|
return null;
|
|
2535
2821
|
}
|
|
2536
|
-
const configPath =
|
|
2822
|
+
const configPath = path7.join(os3.tmpdir(), "percy.json");
|
|
2537
2823
|
const percyOptions = this.#options.percyOptions;
|
|
2538
2824
|
if (!percyOptions.version) {
|
|
2539
2825
|
percyOptions.version = "2";
|
|
@@ -2556,6 +2842,12 @@ var Percy = class {
|
|
|
2556
2842
|
});
|
|
2557
2843
|
}
|
|
2558
2844
|
};
|
|
2845
|
+
__decorateClass([
|
|
2846
|
+
PerformanceTester.Measure(PERCY_EVENTS.START)
|
|
2847
|
+
], Percy.prototype, "start", 1);
|
|
2848
|
+
__decorateClass([
|
|
2849
|
+
PerformanceTester.Measure(PERCY_EVENTS.STOP)
|
|
2850
|
+
], Percy.prototype, "stop", 1);
|
|
2559
2851
|
var Percy_default = Percy;
|
|
2560
2852
|
|
|
2561
2853
|
// src/Percy/PercyHelper.ts
|
|
@@ -2566,7 +2858,7 @@ var startPercy = async (options, config, bsConfig) => {
|
|
|
2566
2858
|
if (response) {
|
|
2567
2859
|
return percy;
|
|
2568
2860
|
}
|
|
2569
|
-
return
|
|
2861
|
+
return void 0;
|
|
2570
2862
|
};
|
|
2571
2863
|
var stopPercy = async (percy) => {
|
|
2572
2864
|
PercyLogger.debug("Stopping percy");
|
|
@@ -2623,6 +2915,7 @@ var getBestPlatformForPercySnapshot = (capabilities) => {
|
|
|
2623
2915
|
};
|
|
2624
2916
|
|
|
2625
2917
|
// src/config.ts
|
|
2918
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2626
2919
|
var BrowserStackConfig = class _BrowserStackConfig {
|
|
2627
2920
|
static getInstance(options, config) {
|
|
2628
2921
|
if (!this._instance && options && config) {
|
|
@@ -2646,6 +2939,7 @@ var BrowserStackConfig = class _BrowserStackConfig {
|
|
|
2646
2939
|
funnelDataSent = false;
|
|
2647
2940
|
percyBuildId;
|
|
2648
2941
|
isPercyAutoEnabled = false;
|
|
2942
|
+
sdkRunID;
|
|
2649
2943
|
constructor(options, config) {
|
|
2650
2944
|
this.framework = config.framework;
|
|
2651
2945
|
this.userName = config.user;
|
|
@@ -2657,6 +2951,8 @@ var BrowserStackConfig = class _BrowserStackConfig {
|
|
|
2657
2951
|
this.appAutomate = !isUndefined(options.app);
|
|
2658
2952
|
this.automate = !this.appAutomate;
|
|
2659
2953
|
this.buildIdentifier = options.buildIdentifier;
|
|
2954
|
+
this.sdkRunID = uuidv4();
|
|
2955
|
+
BStackLogger.info(`BrowserStack service started with id: ${this.sdkRunID}`);
|
|
2660
2956
|
}
|
|
2661
2957
|
sentFunnelData() {
|
|
2662
2958
|
this.funnelDataSent = true;
|
|
@@ -2666,18 +2962,18 @@ var config_default = BrowserStackConfig;
|
|
|
2666
2962
|
|
|
2667
2963
|
// src/exitHandler.ts
|
|
2668
2964
|
import { spawn as spawn3 } from "node:child_process";
|
|
2669
|
-
import
|
|
2965
|
+
import path10 from "node:path";
|
|
2670
2966
|
|
|
2671
2967
|
// src/instrumentation/funnelInstrumentation.ts
|
|
2672
2968
|
import os4 from "node:os";
|
|
2673
|
-
import
|
|
2674
|
-
import
|
|
2969
|
+
import util3, { format as format2 } from "node:util";
|
|
2970
|
+
import path9 from "node:path";
|
|
2675
2971
|
import fs9 from "node:fs";
|
|
2676
2972
|
|
|
2677
2973
|
// src/data-store.ts
|
|
2678
|
-
import
|
|
2974
|
+
import path8 from "node:path";
|
|
2679
2975
|
import fs8 from "node:fs";
|
|
2680
|
-
var workersDataDirPath =
|
|
2976
|
+
var workersDataDirPath = path8.join(process.cwd(), "logs", "worker_data");
|
|
2681
2977
|
function getDataFromWorkers() {
|
|
2682
2978
|
const workersData = [];
|
|
2683
2979
|
if (!fs8.existsSync(workersDataDirPath)) {
|
|
@@ -2686,7 +2982,7 @@ function getDataFromWorkers() {
|
|
|
2686
2982
|
const files = fs8.readdirSync(workersDataDirPath);
|
|
2687
2983
|
files.forEach((file) => {
|
|
2688
2984
|
BStackLogger.debug("Reading worker file " + file);
|
|
2689
|
-
const filePath =
|
|
2985
|
+
const filePath = path8.join(workersDataDirPath, file);
|
|
2690
2986
|
const fileContent = fs8.readFileSync(filePath, "utf8");
|
|
2691
2987
|
const workerData = JSON.parse(fileContent);
|
|
2692
2988
|
workersData.push(workerData);
|
|
@@ -2695,7 +2991,7 @@ function getDataFromWorkers() {
|
|
|
2695
2991
|
return workersData;
|
|
2696
2992
|
}
|
|
2697
2993
|
function saveWorkerData(data) {
|
|
2698
|
-
const filePath =
|
|
2994
|
+
const filePath = path8.join(workersDataDirPath, "worker-data-" + process.pid + ".json");
|
|
2699
2995
|
try {
|
|
2700
2996
|
createWorkersDataDir();
|
|
2701
2997
|
fs8.writeFileSync(filePath, JSON.stringify(data));
|
|
@@ -2714,22 +3010,6 @@ function createWorkersDataDir() {
|
|
|
2714
3010
|
return true;
|
|
2715
3011
|
}
|
|
2716
3012
|
|
|
2717
|
-
// src/fetchWrapper.ts
|
|
2718
|
-
var ResponseError = class extends Error {
|
|
2719
|
-
response;
|
|
2720
|
-
constructor(message, res) {
|
|
2721
|
-
super(message);
|
|
2722
|
-
this.response = res;
|
|
2723
|
-
}
|
|
2724
|
-
};
|
|
2725
|
-
async function fetchWrap(input, init) {
|
|
2726
|
-
const res = await fetch(input, init);
|
|
2727
|
-
if (!res.ok) {
|
|
2728
|
-
throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
|
|
2729
|
-
}
|
|
2730
|
-
return res;
|
|
2731
|
-
}
|
|
2732
|
-
|
|
2733
3013
|
// src/instrumentation/funnelInstrumentation.ts
|
|
2734
3014
|
async function fireFunnelTestEvent(eventType, config) {
|
|
2735
3015
|
if (!config.userName || !config.accessKey) {
|
|
@@ -2754,7 +3034,7 @@ async function sendFinish(config) {
|
|
|
2754
3034
|
function saveFunnelData(eventType, config) {
|
|
2755
3035
|
const data = buildEventData(eventType, config);
|
|
2756
3036
|
BStackLogger.ensureLogsFolder();
|
|
2757
|
-
const filePath =
|
|
3037
|
+
const filePath = path9.join(BStackLogger.logFolderPath, "funnelData.json");
|
|
2758
3038
|
fs9.writeFileSync(filePath, JSON.stringify(data));
|
|
2759
3039
|
return filePath;
|
|
2760
3040
|
}
|
|
@@ -2772,7 +3052,7 @@ function redactCredentialsFromFunnelData(data) {
|
|
|
2772
3052
|
async function fireFunnelRequest(data) {
|
|
2773
3053
|
const { userName, accessKey } = data;
|
|
2774
3054
|
redactCredentialsFromFunnelData(data);
|
|
2775
|
-
BStackLogger.debug("Sending SDK event with data " +
|
|
3055
|
+
BStackLogger.debug("Sending SDK event with data " + util3.inspect(data, { depth: 6 }));
|
|
2776
3056
|
const encodedAuth = Buffer.from(`${userName}:${accessKey}`, "utf8").toString("base64");
|
|
2777
3057
|
const response = await fetchWrap(FUNNEL_INSTRUMENTATION_URL, {
|
|
2778
3058
|
method: "POST",
|
|
@@ -2806,6 +3086,8 @@ function getProductList(config) {
|
|
|
2806
3086
|
function buildEventData(eventType, config) {
|
|
2807
3087
|
const eventProperties = {
|
|
2808
3088
|
// Framework Details
|
|
3089
|
+
sdkRunId: config?.sdkRunID,
|
|
3090
|
+
testhub_uuid: testOpsConfig_default.getInstance().buildHashedId,
|
|
2809
3091
|
language_framework: getLanguageFramework(config.framework),
|
|
2810
3092
|
referrer: getReferrer(config.framework),
|
|
2811
3093
|
language: "WebdriverIO",
|
|
@@ -2818,7 +3100,9 @@ function buildEventData(eventType, config) {
|
|
|
2818
3100
|
hostname: os4.hostname() || "unknown",
|
|
2819
3101
|
// Product Details
|
|
2820
3102
|
productMap: getProductMap(config),
|
|
2821
|
-
product: getProductList(config)
|
|
3103
|
+
product: getProductList(config),
|
|
3104
|
+
// framework details
|
|
3105
|
+
framework: config.framework
|
|
2822
3106
|
};
|
|
2823
3107
|
if (eventType === "SDKTestSuccessful") {
|
|
2824
3108
|
const workerData = getDataFromWorkers();
|
|
@@ -2930,12 +3214,12 @@ function handleHealingInstrumentation(authResult, config, isSelfHealEnabled) {
|
|
|
2930
3214
|
// src/exitHandler.ts
|
|
2931
3215
|
import { fileURLToPath } from "node:url";
|
|
2932
3216
|
var __filename = fileURLToPath(import.meta.url);
|
|
2933
|
-
var __dirname =
|
|
3217
|
+
var __dirname = path10.dirname(__filename);
|
|
2934
3218
|
function setupExitHandlers() {
|
|
2935
3219
|
process.on("exit", (code) => {
|
|
2936
3220
|
const args = shouldCallCleanup(config_default.getInstance());
|
|
2937
3221
|
if (Array.isArray(args) && args.length) {
|
|
2938
|
-
const childProcess = spawn3("node", [`${
|
|
3222
|
+
const childProcess = spawn3("node", [`${path10.join(__dirname, "cleanup.js")}`, ...args], { detached: true, stdio: "inherit", env: { ...process.env } });
|
|
2939
3223
|
childProcess.unref();
|
|
2940
3224
|
process.exit(code);
|
|
2941
3225
|
}
|
|
@@ -2950,11 +3234,17 @@ function shouldCallCleanup(config) {
|
|
|
2950
3234
|
const savedFilePath = saveFunnelData("SDKTestSuccessful", config);
|
|
2951
3235
|
args.push("--funnelData", savedFilePath);
|
|
2952
3236
|
}
|
|
3237
|
+
if (PerformanceTester.isEnabled()) {
|
|
3238
|
+
process.env.PERF_USER_NAME = config.userName;
|
|
3239
|
+
process.env.PERF_TESTHUB_UUID = testOpsConfig_default.getInstance().buildHashedId;
|
|
3240
|
+
process.env.SDK_RUN_ID = config.sdkRunID;
|
|
3241
|
+
args.push("--performanceData");
|
|
3242
|
+
}
|
|
2953
3243
|
return args;
|
|
2954
3244
|
}
|
|
2955
3245
|
|
|
2956
3246
|
// src/ai-handler.ts
|
|
2957
|
-
import
|
|
3247
|
+
import path11 from "node:path";
|
|
2958
3248
|
import fs10 from "node:fs";
|
|
2959
3249
|
import url from "node:url";
|
|
2960
3250
|
import aiSDK from "@browserstack/ai-sdk-node";
|
|
@@ -2988,7 +3278,7 @@ var AiHandler = class {
|
|
|
2988
3278
|
}
|
|
2989
3279
|
async installFirefoxExtension(browser) {
|
|
2990
3280
|
const __dirname2 = url.fileURLToPath(new URL(".", import.meta.url));
|
|
2991
|
-
const extensionPath =
|
|
3281
|
+
const extensionPath = path11.resolve(__dirname2, aiSDK.BrowserstackHealing.getFirefoxAddonPath());
|
|
2992
3282
|
const extFile = fs10.readFileSync(extensionPath);
|
|
2993
3283
|
await browser.installAddOn(extFile.toString("base64"), true);
|
|
2994
3284
|
}
|
|
@@ -3197,9 +3487,7 @@ var BrowserstackLauncherService = class {
|
|
|
3197
3487
|
}
|
|
3198
3488
|
this.browserStackConfig.buildIdentifier = this._buildIdentifier;
|
|
3199
3489
|
this.browserStackConfig.buildName = this._buildName;
|
|
3200
|
-
|
|
3201
|
-
PerformanceTester.startMonitoring("performance-report-launcher.csv");
|
|
3202
|
-
}
|
|
3490
|
+
PerformanceTester.startMonitoring("performance-report-launcher.csv");
|
|
3203
3491
|
this._accessibilityAutomation ||= isTrue(this._options.accessibility);
|
|
3204
3492
|
this._options.accessibility = this._accessibilityAutomation;
|
|
3205
3493
|
this._options.testObservability = this._options.testObservability !== false;
|
|
@@ -3265,7 +3553,7 @@ var BrowserstackLauncherService = class {
|
|
|
3265
3553
|
} catch (error) {
|
|
3266
3554
|
throw new SevereServiceError(error.message);
|
|
3267
3555
|
}
|
|
3268
|
-
if (VALID_APP_EXTENSION.includes(
|
|
3556
|
+
if (VALID_APP_EXTENSION.includes(path12.extname(app.app))) {
|
|
3269
3557
|
if (fs11.existsSync(app.app)) {
|
|
3270
3558
|
const data = await this._uploadApp(app);
|
|
3271
3559
|
BStackLogger.info(`app upload completed: ${JSON.stringify(data)}`);
|
|
@@ -3340,7 +3628,8 @@ var BrowserstackLauncherService = class {
|
|
|
3340
3628
|
});
|
|
3341
3629
|
obs.observe({ entryTypes: ["measure"] });
|
|
3342
3630
|
let timer;
|
|
3343
|
-
|
|
3631
|
+
performance3.mark("tbTunnelStart");
|
|
3632
|
+
PerformanceTester.start(AUTOMATE_EVENTS.LOCAL_START);
|
|
3344
3633
|
return Promise.race(
|
|
3345
3634
|
[
|
|
3346
3635
|
promisify2(this.browserstackLocal.start.bind(this.browserstackLocal))(opts),
|
|
@@ -3352,10 +3641,12 @@ var BrowserstackLauncherService = class {
|
|
|
3352
3641
|
]
|
|
3353
3642
|
).then(function(result) {
|
|
3354
3643
|
clearTimeout(timer);
|
|
3355
|
-
|
|
3356
|
-
|
|
3644
|
+
performance3.mark("tbTunnelEnd");
|
|
3645
|
+
PerformanceTester.end(AUTOMATE_EVENTS.LOCAL_START);
|
|
3646
|
+
performance3.measure("bootTime", "tbTunnelStart", "tbTunnelEnd");
|
|
3357
3647
|
return Promise.resolve(result);
|
|
3358
3648
|
}, function(err) {
|
|
3649
|
+
PerformanceTester.end(AUTOMATE_EVENTS.LOCAL_START, false, err);
|
|
3359
3650
|
clearTimeout(timer);
|
|
3360
3651
|
return Promise.reject(err);
|
|
3361
3652
|
});
|
|
@@ -3370,8 +3661,8 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3370
3661
|
`);
|
|
3371
3662
|
}
|
|
3372
3663
|
this.browserStackConfig.testObservability.buildStopped = true;
|
|
3664
|
+
await PerformanceTester.stopAndGenerate("performance-launcher.html");
|
|
3373
3665
|
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
3374
|
-
await PerformanceTester.stopAndGenerate("performance-launcher.html");
|
|
3375
3666
|
PerformanceTester.calculateTimes(["launchTestSession", "stopBuildUpstream"]);
|
|
3376
3667
|
if (!process.env.START_TIME) {
|
|
3377
3668
|
return;
|
|
@@ -3379,6 +3670,7 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3379
3670
|
const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(process.env.START_TIME).getTime();
|
|
3380
3671
|
BStackLogger.info(`Total duration is ${duration / 1e3} s`);
|
|
3381
3672
|
}
|
|
3673
|
+
BStackLogger.info(`BrowserStack service run ended for id: ${this.browserStackConfig?.sdkRunID} testhub id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
|
|
3382
3674
|
await sendFinish(this.browserStackConfig);
|
|
3383
3675
|
try {
|
|
3384
3676
|
await this._uploadServiceLogs();
|
|
@@ -3397,6 +3689,7 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3397
3689
|
return process.kill(this.browserstackLocal.pid);
|
|
3398
3690
|
}
|
|
3399
3691
|
let timer;
|
|
3692
|
+
PerformanceTester.start(AUTOMATE_EVENTS.LOCAL_STOP);
|
|
3400
3693
|
return Promise.race(
|
|
3401
3694
|
[
|
|
3402
3695
|
new Promise((resolve, reject) => {
|
|
@@ -3415,9 +3708,11 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3415
3708
|
})
|
|
3416
3709
|
]
|
|
3417
3710
|
).then(function(result) {
|
|
3711
|
+
PerformanceTester.end(AUTOMATE_EVENTS.LOCAL_STOP);
|
|
3418
3712
|
clearTimeout(timer);
|
|
3419
3713
|
return Promise.resolve(result);
|
|
3420
3714
|
}, function(err) {
|
|
3715
|
+
PerformanceTester.end(AUTOMATE_EVENTS.LOCAL_STOP, false, err);
|
|
3421
3716
|
clearTimeout(timer);
|
|
3422
3717
|
return Promise.reject(err);
|
|
3423
3718
|
});
|
|
@@ -3464,7 +3759,7 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3464
3759
|
BStackLogger.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ""} to browserstack`);
|
|
3465
3760
|
const form = new FormData();
|
|
3466
3761
|
if (app.app) {
|
|
3467
|
-
const fileName =
|
|
3762
|
+
const fileName = path12.basename(app.app);
|
|
3468
3763
|
const fileBlob = new Blob([await readFile(app.app)]);
|
|
3469
3764
|
form.append("file", fileBlob, fileName);
|
|
3470
3765
|
}
|
|
@@ -3761,12 +4056,12 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3761
4056
|
* else returns corresponding value in json file (e.g. { "wdio-build": { "identifier" : 2 } } => 2 in this case)
|
|
3762
4057
|
*/
|
|
3763
4058
|
_getLocalBuildNumber() {
|
|
3764
|
-
const browserstackFolderPath =
|
|
4059
|
+
const browserstackFolderPath = path12.join(os5.homedir(), ".browserstack");
|
|
3765
4060
|
try {
|
|
3766
4061
|
if (!fs11.existsSync(browserstackFolderPath)) {
|
|
3767
4062
|
fs11.mkdirSync(browserstackFolderPath);
|
|
3768
4063
|
}
|
|
3769
|
-
const filePath =
|
|
4064
|
+
const filePath = path12.join(browserstackFolderPath, ".build-name-cache.json");
|
|
3770
4065
|
if (!fs11.existsSync(filePath)) {
|
|
3771
4066
|
fs11.appendFileSync(filePath, JSON.stringify({}));
|
|
3772
4067
|
}
|
|
@@ -3797,18 +4092,30 @@ Visit https://observability.browserstack.com/builds/${process.env[BROWSERSTACK_T
|
|
|
3797
4092
|
if (process.env[BROWSERSTACK_TESTHUB_UUID]) {
|
|
3798
4093
|
return process.env[BROWSERSTACK_TESTHUB_UUID];
|
|
3799
4094
|
}
|
|
3800
|
-
const uuid =
|
|
4095
|
+
const uuid = this.browserStackConfig?.sdkRunID;
|
|
3801
4096
|
BStackLogger.logToFile(`If facing any issues, please contact BrowserStack support with the Build Run Id - ${uuid}`, "info");
|
|
3802
4097
|
return uuid;
|
|
3803
4098
|
}
|
|
3804
4099
|
};
|
|
4100
|
+
__decorateClass([
|
|
4101
|
+
PerformanceTester.Measure(EVENTS.SDK_SETUP)
|
|
4102
|
+
], BrowserstackLauncherService.prototype, "onWorkerStart", 1);
|
|
4103
|
+
__decorateClass([
|
|
4104
|
+
PerformanceTester.Measure(EVENTS.SDK_PRE_TEST)
|
|
4105
|
+
], BrowserstackLauncherService.prototype, "onPrepare", 1);
|
|
4106
|
+
__decorateClass([
|
|
4107
|
+
PerformanceTester.Measure(EVENTS.SDK_CLEANUP)
|
|
4108
|
+
], BrowserstackLauncherService.prototype, "onComplete", 1);
|
|
4109
|
+
__decorateClass([
|
|
4110
|
+
PerformanceTester.Measure(APP_AUTOMATE_EVENTS.APP_UPLOAD)
|
|
4111
|
+
], BrowserstackLauncherService.prototype, "_uploadApp", 1);
|
|
3805
4112
|
|
|
3806
4113
|
// src/insights-handler.ts
|
|
3807
|
-
import
|
|
4114
|
+
import path14 from "node:path";
|
|
3808
4115
|
import { v4 as uuidv43 } from "uuid";
|
|
3809
4116
|
|
|
3810
4117
|
// src/reporter.ts
|
|
3811
|
-
import
|
|
4118
|
+
import path13 from "node:path";
|
|
3812
4119
|
import WDIOReporter from "@wdio/reporter";
|
|
3813
4120
|
import * as url2 from "node:url";
|
|
3814
4121
|
import { v4 as uuidv42 } from "uuid";
|
|
@@ -4362,9 +4669,9 @@ var _TestReporter = class __TestReporter extends WDIOReporter {
|
|
|
4362
4669
|
scope,
|
|
4363
4670
|
scopes,
|
|
4364
4671
|
identifier,
|
|
4365
|
-
file_name: suiteFileName ?
|
|
4366
|
-
location: suiteFileName ?
|
|
4367
|
-
vc_filepath: this._gitConfigPath && suiteFileName ?
|
|
4672
|
+
file_name: suiteFileName ? path13.relative(process.cwd(), suiteFileName) : void 0,
|
|
4673
|
+
location: suiteFileName ? path13.relative(process.cwd(), suiteFileName) : void 0,
|
|
4674
|
+
vc_filepath: this._gitConfigPath && suiteFileName ? path13.relative(this._gitConfigPath, suiteFileName) : void 0,
|
|
4368
4675
|
started_at: testStats.start && testStats.start.toISOString(),
|
|
4369
4676
|
finished_at: testStats.end && testStats.end.toISOString(),
|
|
4370
4677
|
framework,
|
|
@@ -4671,9 +4978,9 @@ var _InsightsHandler = class {
|
|
|
4671
4978
|
test_run_id: hookData.testRunId,
|
|
4672
4979
|
scope: feature?.name,
|
|
4673
4980
|
scopes: [feature?.name || ""],
|
|
4674
|
-
file_name: uri ?
|
|
4675
|
-
location: uri ?
|
|
4676
|
-
vc_filepath: this._gitConfigPath && uri ?
|
|
4981
|
+
file_name: uri ? path14.relative(process.cwd(), uri) : void 0,
|
|
4982
|
+
location: uri ? path14.relative(process.cwd(), uri) : void 0,
|
|
4983
|
+
vc_filepath: this._gitConfigPath && uri ? path14.relative(this._gitConfigPath, uri) : void 0,
|
|
4677
4984
|
result: "pending",
|
|
4678
4985
|
framework: this._framework
|
|
4679
4986
|
};
|
|
@@ -4938,9 +5245,9 @@ var _InsightsHandler = class {
|
|
|
4938
5245
|
scope: fullTitle,
|
|
4939
5246
|
scopes: this.getHierarchy(test),
|
|
4940
5247
|
identifier: fullTitle,
|
|
4941
|
-
file_name: filename ?
|
|
4942
|
-
location: filename ?
|
|
4943
|
-
vc_filepath: this._gitConfigPath && filename ?
|
|
5248
|
+
file_name: filename ? path14.relative(process.cwd(), filename) : void 0,
|
|
5249
|
+
location: filename ? path14.relative(process.cwd(), filename) : void 0,
|
|
5250
|
+
vc_filepath: this._gitConfigPath && filename ? path14.relative(this._gitConfigPath, filename) : void 0,
|
|
4944
5251
|
started_at: testMetaData.startedAt,
|
|
4945
5252
|
finished_at: testMetaData.finishedAt,
|
|
4946
5253
|
result: "pending",
|
|
@@ -5042,9 +5349,9 @@ var _InsightsHandler = class {
|
|
|
5042
5349
|
scope: fullNameWithExamples,
|
|
5043
5350
|
scopes: [feature?.name || ""],
|
|
5044
5351
|
identifier: scenario?.name,
|
|
5045
|
-
file_name: feature && feature.path ?
|
|
5046
|
-
location: feature && feature.path ?
|
|
5047
|
-
vc_filepath: this._gitConfigPath && feature?.path ?
|
|
5352
|
+
file_name: feature && feature.path ? path14.relative(process.cwd(), feature.path) : void 0,
|
|
5353
|
+
location: feature && feature.path ? path14.relative(process.cwd(), feature.path) : void 0,
|
|
5354
|
+
vc_filepath: this._gitConfigPath && feature?.path ? path14.relative(this._gitConfigPath, feature?.path) : void 0,
|
|
5048
5355
|
framework: this._framework,
|
|
5049
5356
|
result: "pending",
|
|
5050
5357
|
meta: {
|
|
@@ -5140,7 +5447,7 @@ var InsightsHandler = o11yClassErrorHandler(_InsightsHandler);
|
|
|
5140
5447
|
var insights_handler_default = InsightsHandler;
|
|
5141
5448
|
|
|
5142
5449
|
// src/accessibility-handler.ts
|
|
5143
|
-
import
|
|
5450
|
+
import util4 from "node:util";
|
|
5144
5451
|
var _AccessibilityHandler = class {
|
|
5145
5452
|
constructor(_browser, _capabilities, isAppAutomate, _framework, _accessibilityAutomation, _accessibilityOpts) {
|
|
5146
5453
|
this._browser = _browser;
|
|
@@ -5362,16 +5669,20 @@ var _AccessibilityHandler = class {
|
|
|
5362
5669
|
}
|
|
5363
5670
|
async sendTestStopEvent(browser, dataForExtension) {
|
|
5364
5671
|
BStackLogger.debug("Performing scan before saving results");
|
|
5365
|
-
await
|
|
5672
|
+
await PerformanceTester.measureWrapper(A11Y_EVENTS.PERFORM_SCAN, async () => {
|
|
5673
|
+
await performA11yScan(this.isAppAutomate, browser, true, true);
|
|
5674
|
+
}, { command: "afterTest" })();
|
|
5366
5675
|
if (isAppAccessibilityAutomationSession(this._accessibility, this.isAppAutomate)) {
|
|
5367
5676
|
return;
|
|
5368
5677
|
}
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5678
|
+
await PerformanceTester.measureWrapper(A11Y_EVENTS.SAVE_RESULTS, async () => {
|
|
5679
|
+
if (accessibility_scripts_default.saveTestResults) {
|
|
5680
|
+
const results = await executeAccessibilityScript(browser, accessibility_scripts_default.saveTestResults, dataForExtension);
|
|
5681
|
+
BStackLogger.debug(util4.format(results));
|
|
5682
|
+
} else {
|
|
5683
|
+
BStackLogger.error("saveTestResults script is null or undefined");
|
|
5684
|
+
}
|
|
5685
|
+
})();
|
|
5375
5686
|
}
|
|
5376
5687
|
getIdentifier(test) {
|
|
5377
5688
|
if ("pickle" in test) {
|
|
@@ -5479,7 +5790,7 @@ if (percySnapshot) {
|
|
|
5479
5790
|
};
|
|
5480
5791
|
}
|
|
5481
5792
|
var snapshot = snapshotHandler;
|
|
5482
|
-
var screenshotHelper = (
|
|
5793
|
+
var screenshotHelper = (type3, driverOrName, nameOrOptions, options) => {
|
|
5483
5794
|
let { name, uuid } = insights_handler_default.currentTest;
|
|
5484
5795
|
if (isUndefined(name)) {
|
|
5485
5796
|
({ name, uuid } = reporter_default.currentTest);
|
|
@@ -5499,7 +5810,7 @@ var screenshotHelper = (type2, driverOrName, nameOrOptions, options) => {
|
|
|
5499
5810
|
testCase: name || ""
|
|
5500
5811
|
};
|
|
5501
5812
|
}
|
|
5502
|
-
if (
|
|
5813
|
+
if (type3 === "app") {
|
|
5503
5814
|
return percyAppScreenshot(driverOrName, nameOrOptions, options);
|
|
5504
5815
|
}
|
|
5505
5816
|
return percySnapshot.percyScreenshot(driverOrName, nameOrOptions, options);
|
|
@@ -5554,6 +5865,7 @@ var _PercyHandler = class {
|
|
|
5554
5865
|
});
|
|
5555
5866
|
}
|
|
5556
5867
|
async percyAutoCapture(eventName, sessionName) {
|
|
5868
|
+
PerformanceTester.start(PERCY_EVENTS.AUTO_CAPTURE);
|
|
5557
5869
|
try {
|
|
5558
5870
|
if (eventName) {
|
|
5559
5871
|
if (!sessionName) {
|
|
@@ -5566,8 +5878,10 @@ var _PercyHandler = class {
|
|
|
5566
5878
|
} catch (err) {
|
|
5567
5879
|
this._percyScreenshotCounter -= 1;
|
|
5568
5880
|
this._percyCaptureMap?.decrement(sessionName ? sessionName : this._sessionName, eventName);
|
|
5881
|
+
PerformanceTester.end(PERCY_EVENTS.AUTO_CAPTURE, false, err, { eventName, sessionName });
|
|
5569
5882
|
PercyLogger.error(`Error while trying to auto capture Percy screenshot ${err}`);
|
|
5570
5883
|
}
|
|
5884
|
+
PerformanceTester.end(PERCY_EVENTS.AUTO_CAPTURE, true, null, { eventName, sessionName });
|
|
5571
5885
|
}
|
|
5572
5886
|
async before() {
|
|
5573
5887
|
this._percyCaptureMap = new PercyCaptureMap_default();
|
|
@@ -5665,11 +5979,9 @@ var BrowserstackService = class {
|
|
|
5665
5979
|
this._percy = isTrue(process.env.BROWSERSTACK_PERCY);
|
|
5666
5980
|
this._percyCaptureMode = process.env.BROWSERSTACK_PERCY_CAPTURE_MODE;
|
|
5667
5981
|
this._turboScale = this._options.turboScale;
|
|
5982
|
+
PerformanceTester.startMonitoring("performance-report-service.csv");
|
|
5668
5983
|
if (shouldProcessEventForTesthub("")) {
|
|
5669
5984
|
this._config.reporters?.push(reporter_default);
|
|
5670
|
-
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
5671
|
-
PerformanceTester.startMonitoring("performance-report-service.csv");
|
|
5672
|
-
}
|
|
5673
5985
|
}
|
|
5674
5986
|
if (process.env.BROWSERSTACK_TURBOSCALE) {
|
|
5675
5987
|
this._turboScale = process.env.BROWSERSTACK_TURBOSCALE === "true";
|
|
@@ -5722,6 +6034,7 @@ var BrowserstackService = class {
|
|
|
5722
6034
|
}
|
|
5723
6035
|
async before(caps, specs, browser) {
|
|
5724
6036
|
this._browser = browser ? browser : globalThis.browser;
|
|
6037
|
+
PerformanceTester.browser = this._browser;
|
|
5725
6038
|
if (!isBrowserstackSession(this._browser)) {
|
|
5726
6039
|
try {
|
|
5727
6040
|
await ai_handler_default.selfHeal(this._options, caps, this._browser);
|
|
@@ -5738,6 +6051,7 @@ var BrowserstackService = class {
|
|
|
5738
6051
|
this._sessionBaseUrl = "https://api.browserstack.com/automate-turboscale/v1/sessions";
|
|
5739
6052
|
}
|
|
5740
6053
|
this._scenariosThatRan = [];
|
|
6054
|
+
PerformanceTester.scenarioThatRan = this._scenariosThatRan;
|
|
5741
6055
|
if (this._browser) {
|
|
5742
6056
|
try {
|
|
5743
6057
|
const sessionId = this._browser.sessionId;
|
|
@@ -5810,13 +6124,6 @@ var BrowserstackService = class {
|
|
|
5810
6124
|
}
|
|
5811
6125
|
return await this._printSessionURL();
|
|
5812
6126
|
}
|
|
5813
|
-
/**
|
|
5814
|
-
* Set the default job name at the suite level to make sure we account
|
|
5815
|
-
* for the cases where there is a long running `before` function for a
|
|
5816
|
-
* suite or one that can fail.
|
|
5817
|
-
* Don't do this for Jasmine because `suite.title` is `Jasmine__TopLevel__Suite`
|
|
5818
|
-
* and `suite.fullTitle` is `undefined`, so no alternative to use for the job name.
|
|
5819
|
-
*/
|
|
5820
6127
|
async beforeSuite(suite) {
|
|
5821
6128
|
this._suiteTitle = suite.title;
|
|
5822
6129
|
this._insightsHandler?.setSuiteFile(suite.file);
|
|
@@ -5865,19 +6172,21 @@ var BrowserstackService = class {
|
|
|
5865
6172
|
if (preferScenarioName && this._scenariosThatRan.length === 1) {
|
|
5866
6173
|
this._fullTitle = this._scenariosThatRan.pop();
|
|
5867
6174
|
}
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
6175
|
+
await PerformanceTester.measureWrapper(AUTOMATE_EVENTS.SESSION_STATUS, async () => {
|
|
6176
|
+
if (setSessionStatus) {
|
|
6177
|
+
const hasReasons = this._failReasons.length > 0;
|
|
6178
|
+
await this._updateJob({
|
|
6179
|
+
status: result === 0 && this._specsRan ? "passed" : "failed",
|
|
6180
|
+
...setSessionName ? { name: this._fullTitle } : {},
|
|
6181
|
+
...result === 0 && this._specsRan ? {} : hasReasons ? { reason: this._failReasons.join("\n") } : {}
|
|
6182
|
+
});
|
|
6183
|
+
}
|
|
6184
|
+
})();
|
|
5876
6185
|
await listener_default.getInstance().onWorkerEnd();
|
|
5877
6186
|
await this._percyHandler?.teardown();
|
|
5878
6187
|
this.saveWorkerData();
|
|
6188
|
+
await PerformanceTester.stopAndGenerate("performance-service.html");
|
|
5879
6189
|
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
5880
|
-
await PerformanceTester.stopAndGenerate("performance-service.html");
|
|
5881
6190
|
PerformanceTester.calculateTimes([
|
|
5882
6191
|
"onRunnerStart",
|
|
5883
6192
|
"onSuiteStart",
|
|
@@ -5896,19 +6205,12 @@ var BrowserstackService = class {
|
|
|
5896
6205
|
]);
|
|
5897
6206
|
}
|
|
5898
6207
|
}
|
|
5899
|
-
/**
|
|
5900
|
-
* For CucumberJS
|
|
5901
|
-
*/
|
|
5902
6208
|
async beforeFeature(uri, feature) {
|
|
5903
6209
|
this._suiteTitle = feature.name;
|
|
5904
6210
|
await this._setSessionName(feature.name);
|
|
5905
6211
|
await this._setAnnotation(`Feature: ${feature.name}`);
|
|
5906
6212
|
await this._insightsHandler?.beforeFeature(uri, feature);
|
|
5907
6213
|
}
|
|
5908
|
-
/**
|
|
5909
|
-
* Runs before a Cucumber Scenario.
|
|
5910
|
-
* @param world world object containing information on pickle and test step
|
|
5911
|
-
*/
|
|
5912
6214
|
async beforeScenario(world) {
|
|
5913
6215
|
this._currentTest = world;
|
|
5914
6216
|
await this._accessibilityHandler?.beforeScenario(world);
|
|
@@ -6102,6 +6404,51 @@ var BrowserstackService = class {
|
|
|
6102
6404
|
});
|
|
6103
6405
|
}
|
|
6104
6406
|
};
|
|
6407
|
+
__decorateClass([
|
|
6408
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeSession" })
|
|
6409
|
+
], BrowserstackService.prototype, "beforeSession", 1);
|
|
6410
|
+
__decorateClass([
|
|
6411
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "before" })
|
|
6412
|
+
], BrowserstackService.prototype, "before", 1);
|
|
6413
|
+
__decorateClass([
|
|
6414
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeSuite" })
|
|
6415
|
+
], BrowserstackService.prototype, "beforeSuite", 1);
|
|
6416
|
+
__decorateClass([
|
|
6417
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeHook" })
|
|
6418
|
+
], BrowserstackService.prototype, "beforeHook", 1);
|
|
6419
|
+
__decorateClass([
|
|
6420
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "afterHook" })
|
|
6421
|
+
], BrowserstackService.prototype, "afterHook", 1);
|
|
6422
|
+
__decorateClass([
|
|
6423
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeTest" })
|
|
6424
|
+
], BrowserstackService.prototype, "beforeTest", 1);
|
|
6425
|
+
__decorateClass([
|
|
6426
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "afterTest" })
|
|
6427
|
+
], BrowserstackService.prototype, "afterTest", 1);
|
|
6428
|
+
__decorateClass([
|
|
6429
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "after" })
|
|
6430
|
+
], BrowserstackService.prototype, "after", 1);
|
|
6431
|
+
__decorateClass([
|
|
6432
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeFeature" })
|
|
6433
|
+
], BrowserstackService.prototype, "beforeFeature", 1);
|
|
6434
|
+
__decorateClass([
|
|
6435
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeScenario" })
|
|
6436
|
+
], BrowserstackService.prototype, "beforeScenario", 1);
|
|
6437
|
+
__decorateClass([
|
|
6438
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "afterScenario" })
|
|
6439
|
+
], BrowserstackService.prototype, "afterScenario", 1);
|
|
6440
|
+
__decorateClass([
|
|
6441
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "beforeStep" })
|
|
6442
|
+
], BrowserstackService.prototype, "beforeStep", 1);
|
|
6443
|
+
__decorateClass([
|
|
6444
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "afterStep" })
|
|
6445
|
+
], BrowserstackService.prototype, "afterStep", 1);
|
|
6446
|
+
__decorateClass([
|
|
6447
|
+
PerformanceTester.Measure(EVENTS.SDK_HOOK, { hookType: "onReload" })
|
|
6448
|
+
], BrowserstackService.prototype, "onReload", 1);
|
|
6449
|
+
__decorateClass([
|
|
6450
|
+
PerformanceTester.Measure(AUTOMATE_EVENTS.PRINT_BUILDLINK)
|
|
6451
|
+
], BrowserstackService.prototype, "_printSessionURL", 1);
|
|
6105
6452
|
|
|
6106
6453
|
// src/logReportingAPI.ts
|
|
6107
6454
|
import Transport2 from "winston-transport";
|