@wdio/browserstack-service 9.8.0 → 9.9.1
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/cleanup.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// src/util.ts
|
|
2
|
-
import { hostname, platform, type, version, arch } from "node:os";
|
|
2
|
+
import { hostname as hostname2, platform as platform2, type as type2, version as version2, arch as arch2 } from "node:os";
|
|
3
3
|
import fs4 from "node:fs";
|
|
4
4
|
import zlib from "node:zlib";
|
|
5
5
|
import { format, promisify } from "node:util";
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import path4 from "node:path";
|
|
7
|
+
import util2 from "node:util";
|
|
8
8
|
import gitRepoInfo from "git-repo-info";
|
|
9
9
|
import gitconfig from "gitconfiglocal";
|
|
10
10
|
import { FormData } from "formdata-node";
|
|
11
|
+
import { performance as performance2 } from "node:perf_hooks";
|
|
11
12
|
|
|
12
13
|
// src/logPatcher.ts
|
|
13
14
|
import Transport from "winston-transport";
|
|
@@ -50,10 +51,15 @@ var logPatcher = class extends Transport {
|
|
|
50
51
|
};
|
|
51
52
|
var logPatcher_default = logPatcher;
|
|
52
53
|
|
|
53
|
-
// src/performance-tester.ts
|
|
54
|
+
// src/instrumentation/performance/performance-tester.ts
|
|
54
55
|
import { createObjectCsvWriter } from "csv-writer";
|
|
55
56
|
import fs2 from "node:fs";
|
|
57
|
+
import fsPromise from "node:fs/promises";
|
|
56
58
|
import { performance, PerformanceObserver } from "node:perf_hooks";
|
|
59
|
+
import util from "node:util";
|
|
60
|
+
import worker from "node:worker_threads";
|
|
61
|
+
import path2 from "node:path";
|
|
62
|
+
import { arch, hostname, platform, type, version } from "node:os";
|
|
57
63
|
|
|
58
64
|
// src/bstackLogger.ts
|
|
59
65
|
import path from "node:path";
|
|
@@ -64,7 +70,7 @@ import logger from "@wdio/logger";
|
|
|
64
70
|
// package.json
|
|
65
71
|
var package_default = {
|
|
66
72
|
name: "@wdio/browserstack-service",
|
|
67
|
-
version: "9.
|
|
73
|
+
version: "9.9.0",
|
|
68
74
|
description: "WebdriverIO service for better Browserstack integration",
|
|
69
75
|
author: "Adam Bjerstedt <abjerstedt@gmail.com>",
|
|
70
76
|
homepage: "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
|
|
@@ -135,9 +141,13 @@ var package_default = {
|
|
|
135
141
|
var bstackServiceVersion = package_default.version;
|
|
136
142
|
var consoleHolder = Object.assign({}, console);
|
|
137
143
|
var DATA_ENDPOINT = "https://collector-observability.browserstack.com";
|
|
144
|
+
var APP_ALLY_ENDPOINT = "https://app-accessibility.browserstack.com/automate";
|
|
145
|
+
var APP_ALLY_ISSUES_ENDPOINT = "api/v1/issues";
|
|
146
|
+
var APP_ALLY_ISSUES_SUMMARY_ENDPOINT = "api/v1/issues-summary";
|
|
138
147
|
var BSTACK_SERVICE_VERSION = bstackServiceVersion;
|
|
139
148
|
var LOGS_FILE = "logs/bstack-wdio-service.log";
|
|
140
149
|
var FUNNEL_INSTRUMENTATION_URL = "https://api.browserstack.com/sdk/v1/event";
|
|
150
|
+
var EDS_URL = "https://eds.browserstack.com";
|
|
141
151
|
var BROWSERSTACK_TESTHUB_JWT = "BROWSERSTACK_TESTHUB_JWT";
|
|
142
152
|
var TESTOPS_SCREENSHOT_ENV = "BS_TESTOPS_ALLOW_SCREENSHOTS";
|
|
143
153
|
var BROWSERSTACK_TESTHUB_UUID = "BROWSERSTACK_TESTHUB_UUID";
|
|
@@ -214,30 +224,71 @@ var BStackLogger = class {
|
|
|
214
224
|
}
|
|
215
225
|
};
|
|
216
226
|
|
|
217
|
-
// src/
|
|
218
|
-
var
|
|
227
|
+
// src/fetchWrapper.ts
|
|
228
|
+
var ResponseError = class extends Error {
|
|
229
|
+
response;
|
|
230
|
+
constructor(message, res) {
|
|
231
|
+
super(message);
|
|
232
|
+
this.response = res;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
async function fetchWrap(input, init) {
|
|
236
|
+
const res = await fetch(input, init);
|
|
237
|
+
if (!res.ok) {
|
|
238
|
+
throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
|
|
239
|
+
}
|
|
240
|
+
return res;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/instrumentation/performance/performance-tester.ts
|
|
244
|
+
var PerformanceTester = class _PerformanceTester {
|
|
219
245
|
static _observer;
|
|
220
246
|
static _csvWriter;
|
|
221
247
|
static _events = [];
|
|
248
|
+
static _measuredEvents = [];
|
|
222
249
|
static started = false;
|
|
250
|
+
static details = {};
|
|
251
|
+
static eventsMap = {};
|
|
252
|
+
static browser;
|
|
253
|
+
static scenarioThatRan;
|
|
254
|
+
static jsonReportDirName = "performance-report";
|
|
255
|
+
static jsonReportDirPath = path2.join(process.cwd(), "logs", this.jsonReportDirName);
|
|
256
|
+
static jsonReportFileName = `${this.jsonReportDirPath}/performance-report-${_PerformanceTester.getProcessId()}.json`;
|
|
223
257
|
static startMonitoring(csvName = "performance-report.csv") {
|
|
258
|
+
if (!fs2.existsSync(this.jsonReportDirPath)) {
|
|
259
|
+
fs2.mkdirSync(this.jsonReportDirPath, { recursive: true });
|
|
260
|
+
}
|
|
224
261
|
this._observer = new PerformanceObserver((list) => {
|
|
225
|
-
list.getEntries().
|
|
226
|
-
|
|
227
|
-
|
|
262
|
+
list.getEntries().filter((entry) => entry.entryType === "measure").forEach(
|
|
263
|
+
(entry) => {
|
|
264
|
+
let finalEntry = entry;
|
|
265
|
+
finalEntry = entry.toJSON();
|
|
266
|
+
if (this.details[entry.name]) {
|
|
267
|
+
finalEntry = Object.assign(finalEntry, this.details[entry.name]);
|
|
268
|
+
}
|
|
269
|
+
delete this.details[entry.name];
|
|
270
|
+
this._measuredEvents.push(finalEntry);
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
274
|
+
list.getEntries().forEach((entry) => this._events.push(entry));
|
|
275
|
+
}
|
|
228
276
|
});
|
|
229
|
-
|
|
277
|
+
const entryTypes = ["measure"];
|
|
278
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
279
|
+
entryTypes.push("function");
|
|
280
|
+
}
|
|
281
|
+
this._observer.observe({ buffered: true, entryTypes });
|
|
230
282
|
this.started = true;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
return performance;
|
|
283
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
284
|
+
this._csvWriter = createObjectCsvWriter({
|
|
285
|
+
path: csvName,
|
|
286
|
+
header: [
|
|
287
|
+
{ id: "name", title: "Function Name" },
|
|
288
|
+
{ id: "time", title: "Execution Time (ms)" }
|
|
289
|
+
]
|
|
290
|
+
});
|
|
291
|
+
}
|
|
241
292
|
}
|
|
242
293
|
static calculateTimes(methods) {
|
|
243
294
|
const times = {};
|
|
@@ -250,26 +301,35 @@ var PerformanceTester = class {
|
|
|
250
301
|
const timeTaken = methods.reduce((a, c) => {
|
|
251
302
|
return times[c] + (a || 0);
|
|
252
303
|
}, 0);
|
|
253
|
-
BStackLogger.
|
|
304
|
+
BStackLogger.debug(`Time for ${methods} is ${timeTaken}`);
|
|
254
305
|
return timeTaken;
|
|
255
306
|
}
|
|
256
307
|
static async stopAndGenerate(filename = "performance-own.html") {
|
|
257
308
|
if (!this.started) {
|
|
258
309
|
return;
|
|
259
310
|
}
|
|
260
|
-
|
|
311
|
+
try {
|
|
312
|
+
const eventsJson = JSON.stringify(this._measuredEvents);
|
|
313
|
+
const finalJSONStr = eventsJson.slice(1, -1) + ",";
|
|
314
|
+
await fsPromise.appendFile(this.jsonReportFileName, finalJSONStr);
|
|
315
|
+
} catch (er) {
|
|
316
|
+
BStackLogger.debug(`Failed to write events of the worker to ${this.jsonReportFileName}: ${util.format(er)}`);
|
|
317
|
+
}
|
|
261
318
|
this._observer.disconnect();
|
|
319
|
+
if (!process.env[PERF_MEASUREMENT_ENV]) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
await _PerformanceTester.sleep(2e3);
|
|
262
323
|
this.started = false;
|
|
263
324
|
this.generateCSV(this._events);
|
|
264
325
|
const content = this.generateReport(this._events);
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
});
|
|
326
|
+
const dir = path2.join(process.cwd(), filename);
|
|
327
|
+
try {
|
|
328
|
+
await fsPromise.writeFile(dir, content);
|
|
329
|
+
BStackLogger.info(`Performance report is at ${path2}`);
|
|
330
|
+
} catch (err) {
|
|
331
|
+
BStackLogger.error(`Error in writing html ${util.format(err)}`);
|
|
332
|
+
}
|
|
273
333
|
}
|
|
274
334
|
static generateReport(entries) {
|
|
275
335
|
let html = "<!DOCTYPE html><html><head><title>Performance Report</title></head><body>";
|
|
@@ -301,6 +361,221 @@ var PerformanceTester = class {
|
|
|
301
361
|
});
|
|
302
362
|
this._csvWriter.writeRecords(dat).then(() => BStackLogger.info("Performance CSV report generated successfully")).catch((error) => console.error(error));
|
|
303
363
|
}
|
|
364
|
+
static Measure(label, details = {}) {
|
|
365
|
+
const self = this;
|
|
366
|
+
return (target, key, descriptor) => {
|
|
367
|
+
const originalMethod = descriptor.value;
|
|
368
|
+
if (descriptor.value) {
|
|
369
|
+
descriptor.value = function(...args) {
|
|
370
|
+
return _PerformanceTester.measure.apply(self, [label, originalMethod, { methodName: key.toString(), ...details }, args, this]);
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
static measureWrapper(name, fn, details = {}) {
|
|
376
|
+
const self = this;
|
|
377
|
+
details.worker = _PerformanceTester.getProcessId();
|
|
378
|
+
details.testName = _PerformanceTester.scenarioThatRan && _PerformanceTester.scenarioThatRan[_PerformanceTester.scenarioThatRan.length - 1];
|
|
379
|
+
details.platform = _PerformanceTester.browser?.sessionId;
|
|
380
|
+
return function(...args) {
|
|
381
|
+
return self.measure(name, fn, details, args);
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
static isEnabled() {
|
|
385
|
+
return !(process.env.BROWSERSTACK_SDK_INSTRUMENTATION === "false");
|
|
386
|
+
}
|
|
387
|
+
static measure(label, fn, details = {}, args, thisArg = null) {
|
|
388
|
+
if (!this.started || !this.isEnabled()) {
|
|
389
|
+
return fn.apply(thisArg, args);
|
|
390
|
+
}
|
|
391
|
+
_PerformanceTester.start(label);
|
|
392
|
+
if (this.details) {
|
|
393
|
+
this.details[label] = details;
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const returnVal = fn.apply(thisArg, args);
|
|
397
|
+
if (returnVal instanceof Promise) {
|
|
398
|
+
return new Promise((resolve, reject) => {
|
|
399
|
+
returnVal.then((v) => {
|
|
400
|
+
_PerformanceTester.end(label);
|
|
401
|
+
resolve(v);
|
|
402
|
+
}).catch((e) => {
|
|
403
|
+
_PerformanceTester.end(label, false, util.format(e));
|
|
404
|
+
reject(e);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
_PerformanceTester.end(label);
|
|
409
|
+
return returnVal;
|
|
410
|
+
} catch (er) {
|
|
411
|
+
_PerformanceTester.end(label, false, util.format(er));
|
|
412
|
+
throw er;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
static start(event) {
|
|
416
|
+
const finalEvent = event + "-start";
|
|
417
|
+
if (this.eventsMap[finalEvent]) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
performance.mark(finalEvent);
|
|
421
|
+
this.eventsMap[finalEvent] = 1;
|
|
422
|
+
}
|
|
423
|
+
static end(event, success = true, failure, details = {}) {
|
|
424
|
+
performance.mark(event + "-end");
|
|
425
|
+
performance.measure(event, event + "-start", event + "-end");
|
|
426
|
+
this.details[event] = Object.assign({ success, failure: util.format(failure) }, Object.assign(Object.assign({
|
|
427
|
+
worker: _PerformanceTester.getProcessId(),
|
|
428
|
+
platform: _PerformanceTester.browser?.sessionId,
|
|
429
|
+
testName: _PerformanceTester.scenarioThatRan && _PerformanceTester.scenarioThatRan[_PerformanceTester.scenarioThatRan.length - 1]
|
|
430
|
+
}, details), this.details[event] || {}));
|
|
431
|
+
}
|
|
432
|
+
static getProcessId() {
|
|
433
|
+
return `${process.pid}-${worker.threadId}`;
|
|
434
|
+
}
|
|
435
|
+
static sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
436
|
+
static async uploadEventsData() {
|
|
437
|
+
try {
|
|
438
|
+
let measures = [];
|
|
439
|
+
if (await fsPromise.access(this.jsonReportDirPath).then(() => true).catch(() => false)) {
|
|
440
|
+
const files = (await fsPromise.readdir(this.jsonReportDirPath)).map((file) => path2.resolve(this.jsonReportDirPath, file));
|
|
441
|
+
measures = (await Promise.all(files.map((file) => fsPromise.readFile(file, "utf-8")))).map((el) => `[${el.slice(0, -1)}]`).map((el) => JSON.parse(el)).flat();
|
|
442
|
+
}
|
|
443
|
+
if (this._measuredEvents.length > 0) {
|
|
444
|
+
measures = measures.concat(this._measuredEvents);
|
|
445
|
+
}
|
|
446
|
+
const date = /* @__PURE__ */ new Date();
|
|
447
|
+
const options = {
|
|
448
|
+
timeZone: "UTC",
|
|
449
|
+
year: "numeric",
|
|
450
|
+
month: "2-digit",
|
|
451
|
+
day: "2-digit",
|
|
452
|
+
hour: "2-digit",
|
|
453
|
+
minute: "2-digit",
|
|
454
|
+
second: "2-digit",
|
|
455
|
+
fractionalSecondDigits: 3,
|
|
456
|
+
// To include microseconds
|
|
457
|
+
hour12: false
|
|
458
|
+
};
|
|
459
|
+
const formattedDate = new Intl.DateTimeFormat("en-GB", options).formatToParts(date).map(({ type: type3, value }) => type3 === "timeZoneName" ? "Z" : value).join("").replace(",", "T");
|
|
460
|
+
const payload = {
|
|
461
|
+
event_type: "sdk_events",
|
|
462
|
+
data: {
|
|
463
|
+
testhub_uuid: process.env.PERF_TESTHUB_UUID || process.env.SDK_RUN_ID,
|
|
464
|
+
created_day: formattedDate,
|
|
465
|
+
event_name: "SDKFeaturePerformance",
|
|
466
|
+
user_data: process.env.PERF_USER_NAME,
|
|
467
|
+
host_info: JSON.stringify({
|
|
468
|
+
hostname: hostname(),
|
|
469
|
+
platform: platform(),
|
|
470
|
+
type: type(),
|
|
471
|
+
version: version(),
|
|
472
|
+
arch: arch()
|
|
473
|
+
}),
|
|
474
|
+
event_json: { measures, sdkRunId: process.env.SDK_RUN_ID }
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
const result = await fetchWrap(`${EDS_URL}/send_sdk_events`, {
|
|
478
|
+
method: "POST",
|
|
479
|
+
headers: {
|
|
480
|
+
"content-type": "application/json"
|
|
481
|
+
},
|
|
482
|
+
body: JSON.stringify(payload)
|
|
483
|
+
});
|
|
484
|
+
BStackLogger.debug(`Successfully uploaded performance events ${util.format(await result.text())}`);
|
|
485
|
+
} catch (er) {
|
|
486
|
+
BStackLogger.debug(`Failed to upload performance events ${util.format(er)}`);
|
|
487
|
+
}
|
|
488
|
+
try {
|
|
489
|
+
if (await fsPromise.access(this.jsonReportDirPath).then(() => true, () => false)) {
|
|
490
|
+
const files = await fsPromise.readdir(this.jsonReportDirPath);
|
|
491
|
+
for (const file of files) {
|
|
492
|
+
await fsPromise.unlink(path2.join(this.jsonReportDirPath, file));
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
} catch (er) {
|
|
496
|
+
BStackLogger.debug(`Failed to delete performance related files ${util.format(er)}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
// src/instrumentation/performance/constants.ts
|
|
502
|
+
var EVENTS = {
|
|
503
|
+
SDK_SETUP: "sdk:setup",
|
|
504
|
+
SDK_CLEANUP: "sdk:cleanup",
|
|
505
|
+
SDK_PRE_TEST: "sdk:pre-test",
|
|
506
|
+
SDK_TEST: "sdk:test",
|
|
507
|
+
SDK_POST_TEST: "sdk:post-test",
|
|
508
|
+
SDK_HOOK: "sdk:hook",
|
|
509
|
+
SDK_DRIVER: "sdk:driver",
|
|
510
|
+
SDK_A11Y: "sdk:a11y",
|
|
511
|
+
SDK_O11Y: "sdk:o11y",
|
|
512
|
+
SDK_AUTO_CAPTURE: "sdk:auto-capture",
|
|
513
|
+
SDK_PROXY_SETUP: "sdk:proxy-setup",
|
|
514
|
+
SDK_TESTHUB: "sdk:testhub",
|
|
515
|
+
SDK_AUTOMATE: "sdk:automate",
|
|
516
|
+
SDK_APP_AUTOMATE: "sdk:app-automate",
|
|
517
|
+
SDK_TURBOSCALE: "sdk:turboscale",
|
|
518
|
+
SDK_PERCY: "sdk:percy",
|
|
519
|
+
SDK_PRE_INITIALIZE: "sdk:driver:pre-initialization",
|
|
520
|
+
SDK_POST_INITIALIZE: "sdk:driver:post-initialization"
|
|
521
|
+
};
|
|
522
|
+
var TESTHUB_EVENTS = {
|
|
523
|
+
START: `${EVENTS.SDK_TESTHUB}:start`,
|
|
524
|
+
STOP: `${EVENTS.SDK_TESTHUB}:stop`
|
|
525
|
+
};
|
|
526
|
+
var AUTOMATE_EVENTS = {
|
|
527
|
+
KEEP_ALIVE: `${EVENTS.SDK_AUTOMATE}:keep-alive`,
|
|
528
|
+
HUB_MANAGEMENT: `${EVENTS.SDK_AUTOMATE}:hub-management`,
|
|
529
|
+
LOCAL_START: `${EVENTS.SDK_AUTOMATE}:local-start`,
|
|
530
|
+
LOCAL_STOP: `${EVENTS.SDK_AUTOMATE}:local-stop`,
|
|
531
|
+
DRIVER_MANAGE: `${EVENTS.SDK_AUTOMATE}:driver-manage`,
|
|
532
|
+
SESSION_NAME: `${EVENTS.SDK_AUTOMATE}:session-name`,
|
|
533
|
+
SESSION_STATUS: `${EVENTS.SDK_AUTOMATE}:session-status`,
|
|
534
|
+
SESSION_ANNOTATION: `${EVENTS.SDK_AUTOMATE}:session-annotation`,
|
|
535
|
+
IDLE_TIMEOUT: `${EVENTS.SDK_AUTOMATE}:idle-timeout`,
|
|
536
|
+
GENERATE_CI_ARTIFACT: `${EVENTS.SDK_AUTOMATE}:ci-artifacts`,
|
|
537
|
+
PRINT_BUILDLINK: `${EVENTS.SDK_AUTOMATE}:print-buildlink`
|
|
538
|
+
};
|
|
539
|
+
var A11Y_EVENTS = {
|
|
540
|
+
PERFORM_SCAN: `${EVENTS.SDK_A11Y}:driver-performscan`,
|
|
541
|
+
SAVE_RESULTS: `${EVENTS.SDK_A11Y}:save-results`,
|
|
542
|
+
GET_RESULTS: `${EVENTS.SDK_A11Y}:get-accessibility-results`,
|
|
543
|
+
GET_RESULTS_SUMMARY: `${EVENTS.SDK_A11Y}:get-accessibility-results-summary`
|
|
544
|
+
};
|
|
545
|
+
var PERCY_EVENTS = {
|
|
546
|
+
DOWNLOAD: `${EVENTS.SDK_PERCY}:download`,
|
|
547
|
+
SCREENSHOT: `${EVENTS.SDK_PERCY}:screenshot`,
|
|
548
|
+
START: `${EVENTS.SDK_PERCY}:start`,
|
|
549
|
+
STOP: `${EVENTS.SDK_PERCY}:stop`,
|
|
550
|
+
AUTO_CAPTURE: `${EVENTS.SDK_PERCY}:auto-capture`,
|
|
551
|
+
SNAPSHOT: `${EVENTS.SDK_PERCY}:snapshot`,
|
|
552
|
+
SCREENSHOT_APP: `${EVENTS.SDK_PERCY}:screenshot-app`
|
|
553
|
+
};
|
|
554
|
+
var O11Y_EVENTS = {
|
|
555
|
+
SYNC: `${EVENTS.SDK_O11Y}:sync`,
|
|
556
|
+
TAKE_SCREENSHOT: `${EVENTS.SDK_O11Y}:driver-takeScreenShot`,
|
|
557
|
+
PRINT_BUILDLINK: `${EVENTS.SDK_O11Y}:print-buildlink`
|
|
558
|
+
};
|
|
559
|
+
var HOOK_EVENTS = {
|
|
560
|
+
BEFORE_EACH: `${EVENTS.SDK_HOOK}:before-each`,
|
|
561
|
+
AFTER_EACH: `${EVENTS.SDK_HOOK}:after-each`,
|
|
562
|
+
AFTER_ALL: `${EVENTS.SDK_HOOK}:after-all`,
|
|
563
|
+
BEFORE_ALL: `${EVENTS.SDK_HOOK}:before-all`,
|
|
564
|
+
BEFORE: `${EVENTS.SDK_HOOK}:before`,
|
|
565
|
+
AFTER: `${EVENTS.SDK_HOOK}:after`
|
|
566
|
+
};
|
|
567
|
+
var TURBOSCALE_EVENTS = {
|
|
568
|
+
HUB_MANAGEMENT: `${EVENTS.SDK_TURBOSCALE}:hub-management`,
|
|
569
|
+
PRINT_BUILDLINK: `${EVENTS.SDK_TURBOSCALE}:print-buildlink`
|
|
570
|
+
};
|
|
571
|
+
var APP_AUTOMATE_EVENTS = {
|
|
572
|
+
APP_UPLOAD: `${EVENTS.SDK_APP_AUTOMATE}:app-upload`
|
|
573
|
+
};
|
|
574
|
+
var DRIVER_EVENT = {
|
|
575
|
+
QUIT: `${EVENTS.SDK_DRIVER}:quit`,
|
|
576
|
+
GET: `${EVENTS.SDK_DRIVER}:get`,
|
|
577
|
+
PRE_EXECUTE: `${EVENTS.SDK_DRIVER}:pre-execute`,
|
|
578
|
+
POST_EXECUTE: `${EVENTS.SDK_DRIVER}:post-execute`
|
|
304
579
|
};
|
|
305
580
|
|
|
306
581
|
// src/testHub/utils.ts
|
|
@@ -773,7 +1048,7 @@ var UsageStats = class _UsageStats {
|
|
|
773
1048
|
var usageStats_default = UsageStats;
|
|
774
1049
|
|
|
775
1050
|
// src/scripts/accessibility-scripts.ts
|
|
776
|
-
import
|
|
1051
|
+
import path3 from "node:path";
|
|
777
1052
|
import fs3 from "node:fs";
|
|
778
1053
|
import os from "node:os";
|
|
779
1054
|
var AccessibilityScripts = class _AccessibilityScripts {
|
|
@@ -788,7 +1063,7 @@ var AccessibilityScripts = class _AccessibilityScripts {
|
|
|
788
1063
|
// don't allow to create instances from it other than through `checkAndGetInstance`
|
|
789
1064
|
constructor() {
|
|
790
1065
|
this.browserstackFolderPath = this.getWritableDir();
|
|
791
|
-
this.commandsPath =
|
|
1066
|
+
this.commandsPath = path3.join(this.browserstackFolderPath, "commands.json");
|
|
792
1067
|
}
|
|
793
1068
|
static checkAndGetInstance() {
|
|
794
1069
|
if (!_AccessibilityScripts.instance) {
|
|
@@ -800,7 +1075,7 @@ var AccessibilityScripts = class _AccessibilityScripts {
|
|
|
800
1075
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
801
1076
|
getWritableDir() {
|
|
802
1077
|
const orderedPaths = [
|
|
803
|
-
|
|
1078
|
+
path3.join(os.homedir(), ".browserstack"),
|
|
804
1079
|
process.cwd(),
|
|
805
1080
|
os.tmpdir()
|
|
806
1081
|
];
|
|
@@ -878,7 +1153,7 @@ function processError(error, fn, args) {
|
|
|
878
1153
|
try {
|
|
879
1154
|
argsString = JSON.stringify(args);
|
|
880
1155
|
} catch {
|
|
881
|
-
argsString =
|
|
1156
|
+
argsString = util2.inspect(args, { depth: 2 });
|
|
882
1157
|
}
|
|
883
1158
|
CrashReporter.uploadCrashReport(`Error in executing ${fn.name} with args ${argsString} : ${error}`, error && error.stack || "unknown error");
|
|
884
1159
|
}
|
|
@@ -887,7 +1162,7 @@ function o11yErrorHandler(fn) {
|
|
|
887
1162
|
try {
|
|
888
1163
|
let functionToHandle = fn;
|
|
889
1164
|
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
890
|
-
functionToHandle =
|
|
1165
|
+
functionToHandle = performance2.timerify(functionToHandle);
|
|
891
1166
|
}
|
|
892
1167
|
const result = functionToHandle(...args);
|
|
893
1168
|
if (result instanceof Promise) {
|
|
@@ -960,7 +1235,7 @@ var processLaunchBuildResponse = (response, options) => {
|
|
|
960
1235
|
processAccessibilityResponse(response);
|
|
961
1236
|
}
|
|
962
1237
|
};
|
|
963
|
-
var launchTestSession = o11yErrorHandler(async function launchTestSession2(options, config, bsConfig, bStackConfig) {
|
|
1238
|
+
var launchTestSession = PerformanceTester.measureWrapper(TESTHUB_EVENTS.START, o11yErrorHandler(async function launchTestSession2(options, config, bsConfig, bStackConfig) {
|
|
964
1239
|
const launchBuildUsage = usageStats_default.getInstance().launchBuildUsage;
|
|
965
1240
|
launchBuildUsage.triggered();
|
|
966
1241
|
const data = {
|
|
@@ -971,11 +1246,11 @@ var launchTestSession = o11yErrorHandler(async function launchTestSession2(optio
|
|
|
971
1246
|
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
972
1247
|
tags: getObservabilityBuildTags(options, bsConfig.buildTag),
|
|
973
1248
|
host_info: {
|
|
974
|
-
hostname:
|
|
975
|
-
platform:
|
|
976
|
-
type:
|
|
977
|
-
version:
|
|
978
|
-
arch:
|
|
1249
|
+
hostname: hostname2(),
|
|
1250
|
+
platform: platform2(),
|
|
1251
|
+
type: type2(),
|
|
1252
|
+
version: version2(),
|
|
1253
|
+
arch: arch2()
|
|
979
1254
|
},
|
|
980
1255
|
ci_info: getCiInfo(),
|
|
981
1256
|
build_run_identifier: process.env.BROWSERSTACK_BUILD_RUN_IDENTIFIER,
|
|
@@ -1027,6 +1302,7 @@ var launchTestSession = o11yErrorHandler(async function launchTestSession2(optio
|
|
|
1027
1302
|
if (jsonResponse.build_hashed_id) {
|
|
1028
1303
|
process.env[BROWSERSTACK_TESTHUB_UUID] = jsonResponse.build_hashed_id;
|
|
1029
1304
|
testOpsConfig_default.getInstance().buildHashedId = jsonResponse.build_hashed_id;
|
|
1305
|
+
BStackLogger.info(`Testhub started with id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
|
|
1030
1306
|
}
|
|
1031
1307
|
processLaunchBuildResponse(jsonResponse, options);
|
|
1032
1308
|
launchBuildUsage.success();
|
|
@@ -1038,8 +1314,162 @@ var launchTestSession = o11yErrorHandler(async function launchTestSession2(optio
|
|
|
1038
1314
|
return;
|
|
1039
1315
|
}
|
|
1040
1316
|
}
|
|
1317
|
+
}));
|
|
1318
|
+
var isAccessibilityAutomationSession = (accessibilityFlag) => {
|
|
1319
|
+
try {
|
|
1320
|
+
const hasA11yJwtToken = typeof process.env.BSTACK_A11Y_JWT === "string" && process.env.BSTACK_A11Y_JWT.length > 0 && process.env.BSTACK_A11Y_JWT !== "null" && process.env.BSTACK_A11Y_JWT !== "undefined";
|
|
1321
|
+
return accessibilityFlag && hasA11yJwtToken;
|
|
1322
|
+
} catch (error) {
|
|
1323
|
+
BStackLogger.debug(`Exception in verifying the Accessibility session with error : ${error}`);
|
|
1324
|
+
}
|
|
1325
|
+
return false;
|
|
1326
|
+
};
|
|
1327
|
+
var isAppAccessibilityAutomationSession = (accessibilityFlag, isAppAutomate) => {
|
|
1328
|
+
const accessibilityAutomation = isAccessibilityAutomationSession(accessibilityFlag);
|
|
1329
|
+
return accessibilityAutomation && isAppAutomate;
|
|
1330
|
+
};
|
|
1331
|
+
var formatString = (template, ...values) => {
|
|
1332
|
+
let i = 0;
|
|
1333
|
+
if (template === null) {
|
|
1334
|
+
return "";
|
|
1335
|
+
}
|
|
1336
|
+
return template.replace(/%s/g, () => {
|
|
1337
|
+
const value = values[i++];
|
|
1338
|
+
return value !== null && value !== void 0 ? value : "";
|
|
1339
|
+
});
|
|
1340
|
+
};
|
|
1341
|
+
var _getParamsForAppAccessibility = (commandName) => {
|
|
1342
|
+
return {
|
|
1343
|
+
"thTestRunUuid": process.env.TEST_ANALYTICS_ID,
|
|
1344
|
+
"thBuildUuid": process.env.BROWSERSTACK_TESTHUB_UUID,
|
|
1345
|
+
"thJwtToken": process.env.BROWSERSTACK_TESTHUB_JWT,
|
|
1346
|
+
"authHeader": process.env.BSTACK_A11Y_JWT,
|
|
1347
|
+
"scanTimestamp": Date.now(),
|
|
1348
|
+
"method": commandName
|
|
1349
|
+
};
|
|
1350
|
+
};
|
|
1351
|
+
var performA11yScan = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, commandName) => {
|
|
1352
|
+
if (!isBrowserStackSession) {
|
|
1353
|
+
BStackLogger.warn("Not a BrowserStack Automate session, cannot perform Accessibility scan.");
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
if (!isAccessibilityAutomationSession(isAccessibility)) {
|
|
1357
|
+
BStackLogger.warn("Not an Accessibility Automation session, cannot perform Accessibility scan.");
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
try {
|
|
1361
|
+
if (isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
|
|
1362
|
+
const results = await browser.execute(formatString(accessibility_scripts_default.performScan, JSON.stringify(_getParamsForAppAccessibility(commandName))), {});
|
|
1363
|
+
BStackLogger.debug(util2.format(results));
|
|
1364
|
+
return results;
|
|
1365
|
+
}
|
|
1366
|
+
if (accessibility_scripts_default.performScan) {
|
|
1367
|
+
const results = await executeAccessibilityScript(browser, accessibility_scripts_default.performScan, { method: commandName || "" });
|
|
1368
|
+
return results;
|
|
1369
|
+
}
|
|
1370
|
+
BStackLogger.error("AccessibilityScripts.performScan is null");
|
|
1371
|
+
return;
|
|
1372
|
+
} catch (err) {
|
|
1373
|
+
BStackLogger.error("Accessibility Scan could not be performed : " + err);
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
var getA11yResults = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
|
|
1378
|
+
if (!isBrowserStackSession) {
|
|
1379
|
+
BStackLogger.warn("Not a BrowserStack Automate session, cannot retrieve Accessibility results.");
|
|
1380
|
+
return [];
|
|
1381
|
+
}
|
|
1382
|
+
if (!isAccessibilityAutomationSession(isAccessibility)) {
|
|
1383
|
+
BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results.");
|
|
1384
|
+
return [];
|
|
1385
|
+
}
|
|
1386
|
+
try {
|
|
1387
|
+
BStackLogger.debug("Performing scan before getting results");
|
|
1388
|
+
await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
|
|
1389
|
+
if (accessibility_scripts_default.getResults) {
|
|
1390
|
+
const results = await executeAccessibilityScript(browser, accessibility_scripts_default.getResults);
|
|
1391
|
+
return results;
|
|
1392
|
+
}
|
|
1393
|
+
BStackLogger.error("AccessibilityScripts.getResults is null");
|
|
1394
|
+
return [];
|
|
1395
|
+
} catch (error) {
|
|
1396
|
+
BStackLogger.error("No accessibility results were found.");
|
|
1397
|
+
BStackLogger.debug(`getA11yResults Failed. Error: ${error}`);
|
|
1398
|
+
return [];
|
|
1399
|
+
}
|
|
1041
1400
|
});
|
|
1042
|
-
var
|
|
1401
|
+
var getAppA11yResults = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1402
|
+
if (!isBrowserStackSession) {
|
|
1403
|
+
return [];
|
|
1404
|
+
}
|
|
1405
|
+
if (!isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
|
|
1406
|
+
BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
|
|
1407
|
+
return [];
|
|
1408
|
+
}
|
|
1409
|
+
try {
|
|
1410
|
+
const apiUrl = `${APP_ALLY_ENDPOINT}/${APP_ALLY_ISSUES_ENDPOINT}`;
|
|
1411
|
+
const apiRespone = await getAppA11yResultResponse(apiUrl, isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId);
|
|
1412
|
+
const result = apiRespone?.data?.data?.issues;
|
|
1413
|
+
BStackLogger.debug(`Polling Result: ${JSON.stringify(result)}`);
|
|
1414
|
+
return result;
|
|
1415
|
+
} catch (error) {
|
|
1416
|
+
BStackLogger.error("No accessibility summary was found.");
|
|
1417
|
+
BStackLogger.debug(`getAppA11yResults Failed. Error: ${error}`);
|
|
1418
|
+
return [];
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
var getAppA11yResultsSummary = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS_SUMMARY, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1422
|
+
if (!isBrowserStackSession) {
|
|
1423
|
+
return {};
|
|
1424
|
+
}
|
|
1425
|
+
if (!isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
|
|
1426
|
+
BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
|
|
1427
|
+
return {};
|
|
1428
|
+
}
|
|
1429
|
+
try {
|
|
1430
|
+
const apiUrl = `${APP_ALLY_ENDPOINT}/${APP_ALLY_ISSUES_SUMMARY_ENDPOINT}`;
|
|
1431
|
+
const apiRespone = await getAppA11yResultResponse(apiUrl, isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId);
|
|
1432
|
+
const result = apiRespone?.data?.data?.summary;
|
|
1433
|
+
BStackLogger.debug(`Polling Result: ${JSON.stringify(result)}`);
|
|
1434
|
+
return result;
|
|
1435
|
+
} catch {
|
|
1436
|
+
BStackLogger.error("No accessibility summary was found.");
|
|
1437
|
+
return {};
|
|
1438
|
+
}
|
|
1439
|
+
});
|
|
1440
|
+
var getAppA11yResultResponse = async (apiUrl, isAppAutomate, browser, isBrowserStackSession, isAccessibility, sessionId) => {
|
|
1441
|
+
BStackLogger.debug("Performing scan before getting results summary");
|
|
1442
|
+
await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
|
|
1443
|
+
const upperTimeLimit = process.env.BSTACK_A11Y_POLLING_TIMEOUT ? Date.now() + parseInt(process.env.BSTACK_A11Y_POLLING_TIMEOUT) * 1e3 : Date.now() + 3e4;
|
|
1444
|
+
const params = { test_run_uuid: process.env.TEST_ANALYTICS_ID, session_id: sessionId, timestamp: Date.now() };
|
|
1445
|
+
const header = { Authorization: `Bearer ${process.env.BSTACK_A11Y_JWT}` };
|
|
1446
|
+
const apiRespone = await pollApi(apiUrl, params, header, upperTimeLimit);
|
|
1447
|
+
BStackLogger.debug(`Polling Result: ${JSON.stringify(apiRespone)}`);
|
|
1448
|
+
return apiRespone;
|
|
1449
|
+
};
|
|
1450
|
+
var getA11yResultsSummary = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS_SUMMARY, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
|
|
1451
|
+
if (!isBrowserStackSession) {
|
|
1452
|
+
return {};
|
|
1453
|
+
}
|
|
1454
|
+
if (!isAccessibilityAutomationSession(isAccessibility)) {
|
|
1455
|
+
BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
|
|
1456
|
+
return {};
|
|
1457
|
+
}
|
|
1458
|
+
try {
|
|
1459
|
+
BStackLogger.debug("Performing scan before getting results summary");
|
|
1460
|
+
await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
|
|
1461
|
+
if (accessibility_scripts_default.getResultsSummary) {
|
|
1462
|
+
const summaryResults = await executeAccessibilityScript(browser, accessibility_scripts_default.getResultsSummary);
|
|
1463
|
+
return summaryResults;
|
|
1464
|
+
}
|
|
1465
|
+
BStackLogger.error("AccessibilityScripts.getResultsSummary is null");
|
|
1466
|
+
return {};
|
|
1467
|
+
} catch {
|
|
1468
|
+
BStackLogger.error("No accessibility summary was found.");
|
|
1469
|
+
return {};
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
var stopBuildUpstream = PerformanceTester.measureWrapper(TESTHUB_EVENTS.STOP, o11yErrorHandler(async function stopBuildUpstream2() {
|
|
1043
1473
|
const stopBuildUsage = usageStats_default.getInstance().stopBuildUsage;
|
|
1044
1474
|
stopBuildUsage.triggered();
|
|
1045
1475
|
if (!process.env[TESTOPS_BUILD_COMPLETED_ENV]) {
|
|
@@ -1084,7 +1514,7 @@ var stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstream2() {
|
|
|
1084
1514
|
message: error.message
|
|
1085
1515
|
};
|
|
1086
1516
|
}
|
|
1087
|
-
});
|
|
1517
|
+
}));
|
|
1088
1518
|
function getCiInfo() {
|
|
1089
1519
|
const env = process.env;
|
|
1090
1520
|
if (typeof env.JENKINS_URL === "string" && env.JENKINS_URL.length > 0 || typeof env.JENKINS_HOME === "string" && env.JENKINS_HOME.length > 0) {
|
|
@@ -1383,7 +1813,7 @@ function getObservabilityBuild(options, bstackBuildName) {
|
|
|
1383
1813
|
if (options.testObservabilityOptions && options.testObservabilityOptions.buildName) {
|
|
1384
1814
|
return options.testObservabilityOptions.buildName;
|
|
1385
1815
|
}
|
|
1386
|
-
return bstackBuildName ||
|
|
1816
|
+
return bstackBuildName || path4.basename(path4.resolve(process.cwd()));
|
|
1387
1817
|
}
|
|
1388
1818
|
function getObservabilityBuildTags(options, bstackBuildTag) {
|
|
1389
1819
|
if (process.env.TEST_OBSERVABILITY_BUILD_TAG) {
|
|
@@ -1412,7 +1842,6 @@ var patchConsoleLogs = o11yErrorHandler(() => {
|
|
|
1412
1842
|
}
|
|
1413
1843
|
});
|
|
1414
1844
|
});
|
|
1415
|
-
var sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1416
1845
|
var getPlatformVersion = o11yErrorHandler(function getPlatformVersion2(caps) {
|
|
1417
1846
|
if (!caps) {
|
|
1418
1847
|
return void 0;
|
|
@@ -1475,36 +1904,104 @@ function checkAndTruncateVCSInfo(gitMetaData) {
|
|
|
1475
1904
|
}
|
|
1476
1905
|
return gitMetaData;
|
|
1477
1906
|
}
|
|
1907
|
+
async function pollApi(url, params, headers, upperLimit, startTime = Date.now()) {
|
|
1908
|
+
params.timestamp = Math.round(Date.now() / 1e3);
|
|
1909
|
+
BStackLogger.debug(`current timestamp ${params.timestamp}`);
|
|
1910
|
+
try {
|
|
1911
|
+
const response = await makeGetRequest(url, params, headers);
|
|
1912
|
+
const responseData = await response.json();
|
|
1913
|
+
return {
|
|
1914
|
+
data: responseData,
|
|
1915
|
+
headers: response.headers,
|
|
1916
|
+
message: "Polling succeeded."
|
|
1917
|
+
};
|
|
1918
|
+
} catch (error) {
|
|
1919
|
+
if (error.response && error.response.status === 404) {
|
|
1920
|
+
const nextPollTime = parseInt(error.response.headers.get("next_poll_time"), 10) * 1e3;
|
|
1921
|
+
BStackLogger.debug(`timeInMillis ${nextPollTime}`);
|
|
1922
|
+
if (isNaN(nextPollTime)) {
|
|
1923
|
+
BStackLogger.warn("Invalid or missing `nextPollTime` header. Stopping polling.");
|
|
1924
|
+
return {
|
|
1925
|
+
data: {},
|
|
1926
|
+
headers: error.response.headers,
|
|
1927
|
+
message: "Invalid nextPollTime header value. Polling stopped."
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
const elapsedTime = nextPollTime - Date.now();
|
|
1931
|
+
BStackLogger.debug(
|
|
1932
|
+
`elapsedTime ${elapsedTime} timeInMillis ${nextPollTime} upperLimit ${upperLimit}`
|
|
1933
|
+
);
|
|
1934
|
+
if (nextPollTime > upperLimit) {
|
|
1935
|
+
BStackLogger.warn("Polling stopped due to upper time limit.");
|
|
1936
|
+
return {
|
|
1937
|
+
data: {},
|
|
1938
|
+
headers: error.response.headers,
|
|
1939
|
+
message: "Polling stopped due to upper time limit."
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
BStackLogger.debug(`Polling again in ${elapsedTime}ms with params:`, params);
|
|
1943
|
+
await new Promise((resolve) => setTimeout(resolve, elapsedTime));
|
|
1944
|
+
return pollApi(url, params, headers, upperLimit, startTime);
|
|
1945
|
+
} else if (error.response) {
|
|
1946
|
+
let errorMessage = error.response.statusText;
|
|
1947
|
+
try {
|
|
1948
|
+
const parsedError = JSON.parse(error.response.json());
|
|
1949
|
+
errorMessage = parsedError.message;
|
|
1950
|
+
} catch {
|
|
1951
|
+
BStackLogger.debug(`Error parsing pollApi request body ${error.response.body}`);
|
|
1952
|
+
errorMessage = "Unknown error";
|
|
1953
|
+
}
|
|
1954
|
+
throw {
|
|
1955
|
+
data: {},
|
|
1956
|
+
headers: {},
|
|
1957
|
+
message: errorMessage
|
|
1958
|
+
};
|
|
1959
|
+
} else {
|
|
1960
|
+
BStackLogger.error(`Unexpected error occurred: ${error}`);
|
|
1961
|
+
return { data: {}, headers: {}, message: "Unexpected error occurred." };
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
async function makeGetRequest(url, params, headers) {
|
|
1966
|
+
const urlObj = new URL(url);
|
|
1967
|
+
Object.keys(params).forEach((key) => urlObj.searchParams.append(key, params[key]));
|
|
1968
|
+
const response = await fetch(urlObj.toString(), {
|
|
1969
|
+
method: "GET",
|
|
1970
|
+
headers
|
|
1971
|
+
});
|
|
1972
|
+
if (!response.ok) {
|
|
1973
|
+
const error = new Error("Request failed");
|
|
1974
|
+
error.response = response;
|
|
1975
|
+
throw error;
|
|
1976
|
+
}
|
|
1977
|
+
return response;
|
|
1978
|
+
}
|
|
1979
|
+
async function executeAccessibilityScript(browser, fnBody, arg) {
|
|
1980
|
+
return browser.execute(
|
|
1981
|
+
`return (function (...bstackSdkArgs) {
|
|
1982
|
+
return new Promise((resolve, reject) => {
|
|
1983
|
+
const data = bstackSdkArgs[0];
|
|
1984
|
+
bstackSdkArgs.push(resolve);
|
|
1985
|
+
${fnBody.replace(/arguments/g, "bstackSdkArgs")}
|
|
1986
|
+
});
|
|
1987
|
+
})(${arg ? JSON.stringify(arg) : ""})`
|
|
1988
|
+
);
|
|
1989
|
+
}
|
|
1478
1990
|
|
|
1479
1991
|
// src/cleanup.ts
|
|
1480
1992
|
import fs7 from "node:fs";
|
|
1993
|
+
import util4 from "node:util";
|
|
1481
1994
|
|
|
1482
1995
|
// src/instrumentation/funnelInstrumentation.ts
|
|
1483
1996
|
import os2 from "node:os";
|
|
1484
|
-
import
|
|
1485
|
-
import
|
|
1997
|
+
import util3, { format as format2 } from "node:util";
|
|
1998
|
+
import path6 from "node:path";
|
|
1486
1999
|
import fs6 from "node:fs";
|
|
1487
2000
|
|
|
1488
2001
|
// src/data-store.ts
|
|
1489
|
-
import
|
|
2002
|
+
import path5 from "node:path";
|
|
1490
2003
|
import fs5 from "node:fs";
|
|
1491
|
-
var workersDataDirPath =
|
|
1492
|
-
|
|
1493
|
-
// src/fetchWrapper.ts
|
|
1494
|
-
var ResponseError = class extends Error {
|
|
1495
|
-
response;
|
|
1496
|
-
constructor(message, res) {
|
|
1497
|
-
super(message);
|
|
1498
|
-
this.response = res;
|
|
1499
|
-
}
|
|
1500
|
-
};
|
|
1501
|
-
async function fetchWrap(input, init) {
|
|
1502
|
-
const res = await fetch(input, init);
|
|
1503
|
-
if (!res.ok) {
|
|
1504
|
-
throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
|
|
1505
|
-
}
|
|
1506
|
-
return res;
|
|
1507
|
-
}
|
|
2004
|
+
var workersDataDirPath = path5.join(process.cwd(), "logs", "worker_data");
|
|
1508
2005
|
|
|
1509
2006
|
// src/instrumentation/funnelInstrumentation.ts
|
|
1510
2007
|
function redactCredentialsFromFunnelData(data) {
|
|
@@ -1521,7 +2018,7 @@ function redactCredentialsFromFunnelData(data) {
|
|
|
1521
2018
|
async function fireFunnelRequest(data) {
|
|
1522
2019
|
const { userName, accessKey } = data;
|
|
1523
2020
|
redactCredentialsFromFunnelData(data);
|
|
1524
|
-
BStackLogger.debug("Sending SDK event with data " +
|
|
2021
|
+
BStackLogger.debug("Sending SDK event with data " + util3.inspect(data, { depth: 6 }));
|
|
1525
2022
|
const encodedAuth = Buffer.from(`${userName}:${accessKey}`, "utf8").toString("base64");
|
|
1526
2023
|
const response = await fetchWrap(FUNNEL_INSTRUMENTATION_URL, {
|
|
1527
2024
|
method: "POST",
|
|
@@ -1555,6 +2052,13 @@ var BStackCleanup = class _BStackCleanup {
|
|
|
1555
2052
|
const error = err;
|
|
1556
2053
|
BStackLogger.error(error);
|
|
1557
2054
|
}
|
|
2055
|
+
try {
|
|
2056
|
+
if (process.argv.includes("--performanceData")) {
|
|
2057
|
+
await PerformanceTester.uploadEventsData();
|
|
2058
|
+
}
|
|
2059
|
+
} catch (er) {
|
|
2060
|
+
BStackLogger.debug(`Error in sending events data ${util4.format(er)}`);
|
|
2061
|
+
}
|
|
1558
2062
|
}
|
|
1559
2063
|
static async executeObservabilityCleanup(funnelData) {
|
|
1560
2064
|
if (!process.env[BROWSERSTACK_TESTHUB_JWT]) {
|