@wdio/browserstack-service 9.27.2 → 9.29.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/index.js CHANGED
@@ -1,8 +1,13 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __esm = (fn, res) => function __init() {
5
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
+ var __esm = (fn, res, err) => function __init() {
5
+ if (err) throw err[0];
6
+ try {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ } catch (e) {
9
+ throw err = [e], e;
10
+ }
6
11
  };
7
12
  var __export = (target, all) => {
8
13
  for (var name in all)
@@ -23,7 +28,7 @@ var init_package = __esm({
23
28
  "package.json"() {
24
29
  package_default = {
25
30
  name: "@wdio/browserstack-service",
26
- version: "9.27.1",
31
+ version: "9.28.0",
27
32
  description: "WebdriverIO service for better Browserstack integration",
28
33
  author: "Adam Bjerstedt <abjerstedt@gmail.com>",
29
34
  homepage: "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
@@ -97,7 +102,7 @@ var init_package = __esm({
97
102
  });
98
103
 
99
104
  // src/constants.ts
100
- var bstackServiceVersion, BROWSER_DESCRIPTION, VALID_APP_EXTENSION, DEFAULT_OPTIONS, consoleHolder, APP_ALLY_ISSUES_ENDPOINT, APP_ALLY_ISSUES_SUMMARY_ENDPOINT, DATA_EVENT_ENDPOINT, DATA_BATCH_ENDPOINT, DATA_SCREENSHOT_ENDPOINT, DATA_BATCH_SIZE, DATA_BATCH_INTERVAL, DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS, DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS, BSTACK_SERVICE_VERSION, NOT_ALLOWED_KEYS_IN_CAPS, BROWSERSTACK_TEST_PLAN_ID, LOGS_FILE, CLI_DEBUG_LOGS_FILE, UPLOAD_LOGS_ENDPOINT, PERCY_LOGS_FILE, PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS, CAPTURE_MODES, LOG_KIND_USAGE_MAP, SUPPORTED_BROWSERS_FOR_AI, TCG_URL, TCG_INFO, SMART_SELECTION_MODE_RELEVANT_FIRST, SMART_SELECTION_MODE_RELEVANT_ONLY, BROWSERSTACK_TESTHUB_JWT, BSTACK_TCG_AUTH_RESULT, TESTOPS_SCREENSHOT_ENV, BROWSERSTACK_TESTHUB_UUID, TEST_ANALYTICS_ID, PERF_MEASUREMENT_ENV, RERUN_TESTS_ENV, RERUN_ENV, TESTOPS_BUILD_COMPLETED_ENV, BROWSERSTACK_PERCY, BROWSERSTACK_ACCESSIBILITY, BROWSERSTACK_OBSERVABILITY, BROWSERSTACK_TEST_REPORTING, TEST_REPORTING_PROJECT_NAME, MAX_GIT_META_DATA_SIZE_IN_BYTES, GIT_META_DATA_TRUNCATED, CLI_STOP_TIMEOUT, BINARY_BUSY_ERROR_CODES, MAX_SPAWN_RETRIES, SPAWN_RETRY_DELAY_MS, WDIO_NAMING_PREFIX, UPDATED_CLI_ENDPOINT;
105
+ var bstackServiceVersion, BROWSER_DESCRIPTION, VALID_APP_EXTENSION, DEFAULT_OPTIONS, consoleHolder, APP_ALLY_ISSUES_ENDPOINT, APP_ALLY_ISSUES_SUMMARY_ENDPOINT, DATA_EVENT_ENDPOINT, DATA_BATCH_ENDPOINT, DATA_SCREENSHOT_ENDPOINT, DATA_BATCH_SIZE, DATA_BATCH_INTERVAL, DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS, DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS, BSTACK_SERVICE_VERSION, NOT_ALLOWED_KEYS_IN_CAPS, BROWSERSTACK_TEST_PLAN_ID, LOGS_FILE, CLI_DEBUG_LOGS_FILE, UPLOAD_LOGS_ENDPOINT, PERCY_LOGS_FILE, PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS, CAPTURE_MODES, LOG_KIND_USAGE_MAP, SUPPORTED_BROWSERS_FOR_AI, SUPPORTED_BROWSERS_FOR_ACCESSIBILITY, MIN_BROWSER_VERSIONS_A11Y, MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK, TCG_URL, TCG_INFO, SMART_SELECTION_MODE_RELEVANT_FIRST, SMART_SELECTION_MODE_RELEVANT_ONLY, BROWSERSTACK_TESTHUB_JWT, BSTACK_TCG_AUTH_RESULT, TESTOPS_SCREENSHOT_ENV, BROWSERSTACK_TESTHUB_UUID, TEST_ANALYTICS_ID, PERF_MEASUREMENT_ENV, RERUN_TESTS_ENV, RERUN_ENV, TESTOPS_BUILD_COMPLETED_ENV, BROWSERSTACK_PERCY, BROWSERSTACK_ACCESSIBILITY, BROWSERSTACK_OBSERVABILITY, BROWSERSTACK_TEST_REPORTING, TEST_REPORTING_PROJECT_NAME, MAX_GIT_META_DATA_SIZE_IN_BYTES, GIT_META_DATA_TRUNCATED, CLI_STOP_TIMEOUT, BINARY_BUSY_ERROR_CODES, MAX_SPAWN_RETRIES, SPAWN_RETRY_DELAY_MS, WDIO_NAMING_PREFIX, UPDATED_CLI_ENDPOINT;
101
106
  var init_constants = __esm({
102
107
  "src/constants.ts"() {
103
108
  "use strict";
@@ -157,6 +162,17 @@ var init_constants = __esm({
157
162
  "HTTP": "http"
158
163
  };
159
164
  SUPPORTED_BROWSERS_FOR_AI = ["chrome", "microsoftedge", "firefox"];
165
+ SUPPORTED_BROWSERS_FOR_ACCESSIBILITY = ["chrome", "chromefortesting", "safari"];
166
+ MIN_BROWSER_VERSIONS_A11Y = {
167
+ chrome: 95,
168
+ chromefortesting: 141,
169
+ safari: 18.4
170
+ };
171
+ MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK = {
172
+ chrome: 100,
173
+ chromefortesting: 141,
174
+ safari: 18.4
175
+ };
160
176
  TCG_URL = "https://tcg.browserstack.com";
161
177
  TCG_INFO = {
162
178
  tcgRegion: "use",
@@ -268,34 +284,155 @@ var init_apiUtils = __esm({
268
284
  }
269
285
  });
270
286
 
287
+ // src/caCert.ts
288
+ import { setGlobalDispatcher, Agent } from "undici";
289
+ import tls from "node:tls";
290
+ import fs from "node:fs";
291
+ import os from "node:os";
292
+ import path from "node:path";
293
+ function derToPem(der) {
294
+ const b64 = der.toString("base64").replace(/(.{64})/g, "$1\n");
295
+ return `-----BEGIN CERTIFICATE-----
296
+ ${b64}${b64.endsWith("\n") ? "" : "\n"}-----END CERTIFICATE-----
297
+ `;
298
+ }
299
+ function loadCaCertsAsPem(buf) {
300
+ if (buf.includes("-----BEGIN CERTIFICATE-----")) {
301
+ return buf.toString("utf8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) || [];
302
+ }
303
+ return [derToPem(buf)];
304
+ }
305
+ function resolveCaCertPath(options) {
306
+ let p = process.env.BROWSERSTACK_EXTRA_CA_CERTS;
307
+ if ((!p || !p.trim()) && options?.proxyCaCertificate) {
308
+ p = options.proxyCaCertificate;
309
+ }
310
+ if (!p || !String(p).trim()) {
311
+ return void 0;
312
+ }
313
+ p = String(p).trim();
314
+ try {
315
+ if (fs.existsSync(p) && fs.statSync(p).isFile()) {
316
+ return p;
317
+ }
318
+ BStackLogger.warn(`proxyCaCertificate: path does not exist or is not a file, falling back to system trust store: ${p}`);
319
+ } catch (e) {
320
+ BStackLogger.warn(`proxyCaCertificate: failed to stat cert path ${p}: ${e.message}`);
321
+ }
322
+ return void 0;
323
+ }
324
+ function getMergedCa() {
325
+ return mergedCa;
326
+ }
327
+ function configureCaCertificate(options) {
328
+ if (configured) {
329
+ return;
330
+ }
331
+ try {
332
+ const certPath = resolveCaCertPath(options);
333
+ if (!certPath) {
334
+ return;
335
+ }
336
+ const buf = fs.readFileSync(certPath);
337
+ const isPem = buf.includes("-----BEGIN CERTIFICATE-----");
338
+ const pemCerts = loadCaCertsAsPem(buf);
339
+ if (!pemCerts.length) {
340
+ BStackLogger.warn(`proxyCaCertificate: no certificate found in ${certPath}; falling back to system trust store.`);
341
+ return;
342
+ }
343
+ mergedCa = [...tls.rootCertificates, ...pemCerts];
344
+ setGlobalDispatcher(new Agent({ connect: { ca: mergedCa } }));
345
+ configured = true;
346
+ BStackLogger.info(`proxyCaCertificate: trusting custom CA from ${certPath} (merged with system roots).`);
347
+ try {
348
+ if (!process.env.NODE_EXTRA_CA_CERTS) {
349
+ let nodeExtra = certPath;
350
+ if (!isPem) {
351
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "browserstack_sdk_ca_"));
352
+ nodeExtra = path.join(tmpDir, "ca.pem");
353
+ const fd = fs.openSync(nodeExtra, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | (fs.constants.O_NOFOLLOW || 0), 384);
354
+ try {
355
+ fs.writeFileSync(fd, pemCerts.join(""));
356
+ } finally {
357
+ fs.closeSync(fd);
358
+ }
359
+ }
360
+ process.env.NODE_EXTRA_CA_CERTS = nodeExtra;
361
+ }
362
+ } catch (e) {
363
+ BStackLogger.warn(`proxyCaCertificate: CA is trusted for this process, but exporting NODE_EXTRA_CA_CERTS for detached child processes failed (children may not trust the custom CA): ${e.message}`);
364
+ }
365
+ } catch (e) {
366
+ BStackLogger.warn(`proxyCaCertificate: setup failed, falling back to system trust store: ${e.message}`);
367
+ }
368
+ }
369
+ var mergedCa, configured;
370
+ var init_caCert = __esm({
371
+ "src/caCert.ts"() {
372
+ "use strict";
373
+ init_bstackLogger();
374
+ configured = false;
375
+ }
376
+ });
377
+
271
378
  // src/fetchWrapper.ts
272
- import { fetch as undiciFetch, ProxyAgent } from "undici";
273
- async function fetchWrap(input, init) {
274
- const res = await _fetch(input, init);
379
+ import { fetch as undiciFetch, ProxyAgent, Agent as Agent2 } from "undici";
380
+ function getDispatcher(proxyUrl, connectTimeoutMs) {
381
+ const ca = getMergedCa();
382
+ const key = `${proxyUrl ?? "direct"}:${connectTimeoutMs ?? "default"}:${ca ? "ca" : "noca"}`;
383
+ let dispatcher = dispatcherCache.get(key);
384
+ if (!dispatcher) {
385
+ const connect = {};
386
+ if (connectTimeoutMs) {
387
+ connect.timeout = connectTimeoutMs;
388
+ }
389
+ if (proxyUrl) {
390
+ dispatcher = new ProxyAgent({ uri: proxyUrl, connect, ...ca ? { requestTls: { ca } } : {} });
391
+ } else {
392
+ if (ca) {
393
+ connect.ca = ca;
394
+ }
395
+ dispatcher = new Agent2({ connect });
396
+ }
397
+ dispatcherCache.set(key, dispatcher);
398
+ }
399
+ return dispatcher;
400
+ }
401
+ async function fetchWrap(input, init, options) {
402
+ const res = await _fetch(input, init, options);
275
403
  if (!res.ok) {
276
404
  throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
277
405
  }
278
406
  return res;
279
407
  }
280
- function _fetch(input, init) {
408
+ function _fetch(input, init, options) {
409
+ const connectTimeoutMs = options?.connectTimeoutMs;
281
410
  const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
282
411
  if (proxyUrl) {
283
412
  const noProxy = process.env.NO_PROXY && process.env.NO_PROXY.trim() ? process.env.NO_PROXY.trim().split(/[\s,;]+/) : [];
284
413
  const request = new Request(input);
285
414
  const url3 = new URL(request.url);
286
415
  if (!noProxy.some((str) => url3.hostname.endsWith(str))) {
416
+ const dispatcher = getDispatcher(proxyUrl, connectTimeoutMs);
287
417
  return undiciFetch(
288
418
  request.url,
289
- { ...init, dispatcher: new ProxyAgent(proxyUrl) }
419
+ { ...init, dispatcher }
290
420
  );
291
421
  }
292
422
  }
423
+ if (connectTimeoutMs) {
424
+ return undiciFetch(
425
+ new Request(input).url,
426
+ { ...init, dispatcher: getDispatcher(void 0, connectTimeoutMs) }
427
+ );
428
+ }
293
429
  return fetch(input, init);
294
430
  }
295
- var ResponseError;
431
+ var ResponseError, dispatcherCache;
296
432
  var init_fetchWrapper = __esm({
297
433
  "src/fetchWrapper.ts"() {
298
434
  "use strict";
435
+ init_caCert();
299
436
  ResponseError = class extends Error {
300
437
  response;
301
438
  constructor(message, res) {
@@ -303,6 +440,7 @@ var init_fetchWrapper = __esm({
303
440
  this.response = res;
304
441
  }
305
442
  };
443
+ dispatcherCache = /* @__PURE__ */ new Map();
306
444
  }
307
445
  });
308
446
 
@@ -460,26 +598,26 @@ var init_constants2 = __esm({
460
598
  });
461
599
 
462
600
  // src/cli/cliLogger.ts
463
- import path from "node:path";
464
- import fs from "node:fs";
601
+ import path2 from "node:path";
602
+ import fs2 from "node:fs";
465
603
  import chalk from "chalk";
466
604
  import logger from "@wdio/logger";
467
- var log, BStackLogger;
605
+ var log, BStackLogger2;
468
606
  var init_cliLogger = __esm({
469
607
  "src/cli/cliLogger.ts"() {
470
608
  "use strict";
471
609
  init_constants();
472
610
  init_util();
473
611
  log = logger("@wdio/browserstack-service/cli");
474
- BStackLogger = class {
475
- static logFilePath = path.join(process.cwd(), LOGS_FILE);
476
- static logFolderPath = path.join(process.cwd(), "logs");
612
+ BStackLogger2 = class {
613
+ static logFilePath = path2.join(process.cwd(), LOGS_FILE);
614
+ static logFolderPath = path2.join(process.cwd(), "logs");
477
615
  static logFileStream;
478
616
  static logToFile(logMessage, logLevel) {
479
617
  try {
480
618
  if (!this.logFileStream) {
481
619
  this.ensureLogsFolder();
482
- this.logFileStream = fs.createWriteStream(this.logFilePath, { flags: "a" });
620
+ this.logFileStream = fs2.createWriteStream(this.logFilePath, { flags: "a" });
483
621
  }
484
622
  if (this.logFileStream && this.logFileStream.writable) {
485
623
  this.logFileStream.write(this.formatLog(logMessage, logLevel));
@@ -523,13 +661,13 @@ var init_cliLogger = __esm({
523
661
  this.logFileStream = null;
524
662
  }
525
663
  static clearLogFile() {
526
- if (fs.existsSync(this.logFilePath)) {
527
- fs.truncateSync(this.logFilePath);
664
+ if (fs2.existsSync(this.logFilePath)) {
665
+ fs2.truncateSync(this.logFilePath);
528
666
  }
529
667
  }
530
668
  static ensureLogsFolder() {
531
- if (!fs.existsSync(this.logFolderPath)) {
532
- fs.mkdirSync(this.logFolderPath);
669
+ if (!fs2.existsSync(this.logFolderPath)) {
670
+ fs2.mkdirSync(this.logFolderPath);
533
671
  }
534
672
  }
535
673
  };
@@ -587,16 +725,16 @@ var init_testFrameworkConstants = __esm({
587
725
  });
588
726
 
589
727
  // src/cli/cliUtils.ts
590
- import fs2 from "node:fs";
728
+ import fs3 from "node:fs";
591
729
  import fsp from "node:fs/promises";
592
730
  import { platform, arch, homedir } from "node:os";
593
- import path2 from "node:path";
731
+ import path3 from "node:path";
594
732
  import util, { promisify } from "node:util";
595
733
  import { exec } from "node:child_process";
596
734
  import { Readable } from "node:stream";
597
735
  import yauzl from "yauzl";
598
736
  import { threadId } from "node:worker_threads";
599
- var CLI_LOCK_TIMEOUT_MS, CLI_LOCK_POLL_MS, CLI_DOWNLOAD_TIMEOUT_MS, CLI_DOWNLOAD_TMP_PREFIX, CLI_DOWNLOAD_TMP_SUFFIX, CLIUtils;
737
+ var CLI_LOCK_TIMEOUT_MS, CLI_LOCK_POLL_MS, CLI_DOWNLOAD_TIMEOUT_MS, CLI_DOWNLOAD_TMP_PREFIX, CLI_DOWNLOAD_TMP_SUFFIX, CLI_CONNECT_TIMEOUT_MS, CLI_FETCH_MAX_ATTEMPTS, CLI_FETCH_RETRY_BASE_DELAY_MS, CLIUtils;
600
738
  var init_cliUtils = __esm({
601
739
  "src/cli/cliUtils.ts"() {
602
740
  "use strict";
@@ -613,6 +751,9 @@ var init_cliUtils = __esm({
613
751
  CLI_DOWNLOAD_TIMEOUT_MS = 5 * 60 * 1e3;
614
752
  CLI_DOWNLOAD_TMP_PREFIX = "downloaded_file_";
615
753
  CLI_DOWNLOAD_TMP_SUFFIX = ".zip";
754
+ CLI_CONNECT_TIMEOUT_MS = Number(process.env.BROWSERSTACK_CLI_CONNECT_TIMEOUT_MS) || 60 * 1e3;
755
+ CLI_FETCH_MAX_ATTEMPTS = 3;
756
+ CLI_FETCH_RETRY_BASE_DELAY_MS = 500;
616
757
  CLIUtils = class _CLIUtils {
617
758
  static automationFrameworkDetail = {};
618
759
  static testFrameworkDetail = {};
@@ -699,10 +840,10 @@ var init_cliUtils = __esm({
699
840
  return "ECMAScript";
700
841
  }
701
842
  static async setupCliPath(config) {
702
- BStackLogger.debug("Configuring Cli path.");
843
+ BStackLogger2.debug("Configuring Cli path.");
703
844
  const developmentBinaryPath = process.env.SDK_CLI_BIN_PATH || null;
704
845
  if (!isNullOrEmpty(developmentBinaryPath)) {
705
- BStackLogger.debug(`Development Cli Path: ${developmentBinaryPath}`);
846
+ BStackLogger2.debug(`Development Cli Path: ${developmentBinaryPath}`);
706
847
  return developmentBinaryPath;
707
848
  }
708
849
  try {
@@ -716,10 +857,10 @@ var init_cliUtils = __esm({
716
857
  cliDir,
717
858
  config
718
859
  );
719
- BStackLogger.debug(`Resolved binary path: ${finalBinaryPath}`);
860
+ BStackLogger2.debug(`Resolved binary path: ${finalBinaryPath}`);
720
861
  return finalBinaryPath;
721
862
  } catch (err) {
722
- BStackLogger.debug(
863
+ BStackLogger2.warn(
723
864
  `Error in setting up cli path directory, Exception: ${util.format(err)}`
724
865
  );
725
866
  }
@@ -727,18 +868,18 @@ var init_cliUtils = __esm({
727
868
  }
728
869
  static async checkAndUpdateCli(existingCliPath, cliDir, config) {
729
870
  if (process.env.BROWSERSTACK_TESTHUB_JWT) {
730
- BStackLogger.debug(
871
+ BStackLogger2.debug(
731
872
  `Worker process detected, skipping CLI update. Using existing: ${existingCliPath}`
732
873
  );
733
- if (existingCliPath && fs2.existsSync(existingCliPath)) {
874
+ if (existingCliPath && fs3.existsSync(existingCliPath)) {
734
875
  return existingCliPath;
735
876
  }
736
- BStackLogger.warn(
877
+ BStackLogger2.warn(
737
878
  "Worker process has no existing CLI binary, attempting download as fallback."
738
879
  );
739
880
  }
740
881
  PerformanceTester.start(EVENTS.SDK_CLI_CHECK_UPDATE);
741
- BStackLogger.info(`Current CLI Path Found: ${existingCliPath}`);
882
+ BStackLogger2.info(`Current CLI Path Found: ${existingCliPath}`);
742
883
  const queryParams = {
743
884
  sdk_version: _CLIUtils.getSdkVersion(),
744
885
  os: platform(),
@@ -748,7 +889,7 @@ var init_cliUtils = __esm({
748
889
  };
749
890
  if (!isNullOrEmpty(existingCliPath)) {
750
891
  if (this.isBinaryBusy(existingCliPath)) {
751
- BStackLogger.warn(`Existing binary is currently in use, skipping update: ${existingCliPath}`);
892
+ BStackLogger2.warn(`Existing binary is currently in use, skipping update: ${existingCliPath}`);
752
893
  PerformanceTester.end(EVENTS.SDK_CLI_CHECK_UPDATE);
753
894
  return existingCliPath;
754
895
  }
@@ -756,7 +897,7 @@ var init_cliUtils = __esm({
756
897
  `${existingCliPath} version`
757
898
  );
758
899
  if (version3.toLowerCase().includes("text file busy")) {
759
- BStackLogger.warn(`Binary busy during version check, skipping update: ${existingCliPath}`);
900
+ BStackLogger2.warn(`Binary busy during version check, skipping update: ${existingCliPath}`);
760
901
  PerformanceTester.end(EVENTS.SDK_CLI_CHECK_UPDATE);
761
902
  return existingCliPath;
762
903
  }
@@ -764,12 +905,12 @@ var init_cliUtils = __esm({
764
905
  }
765
906
  const response = await this.requestToUpdateCLI(queryParams, config);
766
907
  if (nestedKeyValue(response, ["updated_cli_version"])) {
767
- BStackLogger.debug(
908
+ BStackLogger2.debug(
768
909
  `Need to update binary, current binary version: ${queryParams.cli_version}`
769
910
  );
770
911
  const browserStackBinaryUrl = process.env.BROWSERSTACK_BINARY_URL || null;
771
912
  if (!isNullOrEmpty(browserStackBinaryUrl)) {
772
- BStackLogger.debug(
913
+ BStackLogger2.debug(
773
914
  `Using BROWSERSTACK_BINARY_URL: ${browserStackBinaryUrl}`
774
915
  );
775
916
  response.url = browserStackBinaryUrl;
@@ -790,13 +931,13 @@ var init_cliUtils = __esm({
790
931
  if (isNullOrEmpty(writableDir)) {
791
932
  throw new Error("No writable directory available for the CLI");
792
933
  }
793
- const cliDirPath = path2.join(writableDir, "cli");
794
- if (!fs2.existsSync(cliDirPath)) {
934
+ const cliDirPath = path3.join(writableDir, "cli");
935
+ if (!fs3.existsSync(cliDirPath)) {
795
936
  createDir(cliDirPath);
796
937
  }
797
938
  return cliDirPath;
798
939
  } catch (err) {
799
- BStackLogger.error(
940
+ BStackLogger2.error(
800
941
  `Error in getting writable directory, writableDir=${util.format(err)}`
801
942
  );
802
943
  return "";
@@ -805,39 +946,39 @@ var init_cliUtils = __esm({
805
946
  static getWritableDir() {
806
947
  const writableDirOptions = [
807
948
  process.env.BROWSERSTACK_FILES_DIR,
808
- path2.join(homedir(), ".browserstack"),
809
- path2.join("tmp", ".browserstack")
949
+ path3.join(homedir(), ".browserstack"),
950
+ path3.join("tmp", ".browserstack")
810
951
  ];
811
- for (const path21 of writableDirOptions) {
812
- if (isNullOrEmpty(path21)) {
952
+ for (const path22 of writableDirOptions) {
953
+ if (isNullOrEmpty(path22)) {
813
954
  continue;
814
955
  }
815
956
  try {
816
- if (fs2.existsSync(path21)) {
817
- BStackLogger.debug(`File ${path21} already exist`);
818
- if (!isWritable(path21)) {
819
- BStackLogger.debug(`Giving write permission to ${path21}`);
820
- const success = setReadWriteAccess(path21);
957
+ if (fs3.existsSync(path22)) {
958
+ BStackLogger2.debug(`File ${path22} already exist`);
959
+ if (!isWritable(path22)) {
960
+ BStackLogger2.debug(`Giving write permission to ${path22}`);
961
+ const success = setReadWriteAccess(path22);
821
962
  if (!isTrue(success)) {
822
- BStackLogger.warn(
823
- `Unable to provide write permission to ${path21}`
963
+ BStackLogger2.warn(
964
+ `Unable to provide write permission to ${path22}`
824
965
  );
825
966
  }
826
967
  }
827
968
  } else {
828
- BStackLogger.debug(`File does not exist: ${path21}`);
829
- createDir(path21);
830
- BStackLogger.debug(`Giving write permission to ${path21}`);
831
- const success = setReadWriteAccess(path21);
969
+ BStackLogger2.debug(`File does not exist: ${path22}`);
970
+ createDir(path22);
971
+ BStackLogger2.debug(`Giving write permission to ${path22}`);
972
+ const success = setReadWriteAccess(path22);
832
973
  if (!isTrue(success)) {
833
- BStackLogger.warn(
834
- `Unable to provide write permission to ${path21}`
974
+ BStackLogger2.warn(
975
+ `Unable to provide write permission to ${path22}`
835
976
  );
836
977
  }
837
978
  }
838
- return path21;
979
+ return path22;
839
980
  } catch (err) {
840
- BStackLogger.error(
981
+ BStackLogger2.error(
841
982
  `Unable to get writable directory, exception ${util.format(err)}`
842
983
  );
843
984
  }
@@ -846,16 +987,16 @@ var init_cliUtils = __esm({
846
987
  }
847
988
  static getExistingCliPath(cliDir) {
848
989
  try {
849
- if (!fs2.existsSync(cliDir) || !fs2.statSync(cliDir).isDirectory()) {
990
+ if (!fs3.existsSync(cliDir) || !fs3.statSync(cliDir).isDirectory()) {
850
991
  return "";
851
992
  }
852
- const allBinaries = fs2.readdirSync(cliDir).map((file) => path2.join(cliDir, file)).filter(
853
- (filePath) => fs2.statSync(filePath).isFile() && path2.basename(filePath).startsWith("binary-")
993
+ const allBinaries = fs3.readdirSync(cliDir).map((file) => path3.join(cliDir, file)).filter(
994
+ (filePath) => fs3.statSync(filePath).isFile() && path3.basename(filePath).startsWith("binary-")
854
995
  );
855
996
  if (allBinaries.length > 0) {
856
997
  const latestBinary = allBinaries.map((filePath) => ({
857
998
  filePath,
858
- mtime: fs2.statSync(filePath).mtime
999
+ mtime: fs3.statSync(filePath).mtime
859
1000
  })).reduce(
860
1001
  (latest, current) => {
861
1002
  if (!latest || !latest.mtime) {
@@ -872,7 +1013,7 @@ var init_cliUtils = __esm({
872
1013
  }
873
1014
  return "";
874
1015
  } catch (err) {
875
- BStackLogger.error(`Error while reading CLI path: ${util.format(err)}`);
1016
+ BStackLogger2.error(`Error while reading CLI path: ${util.format(err)}`);
876
1017
  return "";
877
1018
  }
878
1019
  }
@@ -883,22 +1024,51 @@ var init_cliUtils = __esm({
883
1024
  if (platform() === "darwin") {
884
1025
  return false;
885
1026
  }
886
- if (!fs2.existsSync(binaryPath)) {
1027
+ if (!fs3.existsSync(binaryPath)) {
887
1028
  return false;
888
1029
  }
889
1030
  try {
890
- const fd = fs2.openSync(binaryPath, "r+");
891
- fs2.closeSync(fd);
1031
+ const fd = fs3.openSync(binaryPath, "r+");
1032
+ fs3.closeSync(fd);
892
1033
  return false;
893
1034
  } catch (err) {
894
1035
  if (BINARY_BUSY_ERROR_CODES.includes(err.code)) {
895
- BStackLogger.debug(`Binary is busy: ${binaryPath}`);
1036
+ BStackLogger2.debug(`Binary is busy: ${binaryPath}`);
896
1037
  return true;
897
1038
  }
898
- BStackLogger.debug(`Error checking if binary is busy: ${err.message}`);
1039
+ BStackLogger2.debug(`Error checking if binary is busy: ${err.message}`);
899
1040
  return false;
900
1041
  }
901
1042
  }
1043
+ /**
1044
+ * fetch wrapper for CLI network calls that (a) raises undici's connect timeout
1045
+ * above the non-overridable 10s default of global fetch and (b) retries a few
1046
+ * times with linear backoff on transient connection failures. Both are needed
1047
+ * for reliability in constrained CI/containerised networks (SDK-6152).
1048
+ */
1049
+ static fetchWithRetry = async (input, init, label) => {
1050
+ let lastError;
1051
+ for (let attempt = 1; attempt <= CLI_FETCH_MAX_ATTEMPTS; attempt++) {
1052
+ try {
1053
+ return await _fetch(input, init, { connectTimeoutMs: CLI_CONNECT_TIMEOUT_MS });
1054
+ } catch (err) {
1055
+ lastError = err;
1056
+ const reason = (
1057
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1058
+ err?.cause?.code || err?.code || err?.message
1059
+ );
1060
+ BStackLogger2.warn(
1061
+ `${label} attempt ${attempt}/${CLI_FETCH_MAX_ATTEMPTS} failed: ${reason}`
1062
+ );
1063
+ if (attempt < CLI_FETCH_MAX_ATTEMPTS) {
1064
+ await new Promise(
1065
+ (resolve) => setTimeout(resolve, CLI_FETCH_RETRY_BASE_DELAY_MS * attempt)
1066
+ );
1067
+ }
1068
+ }
1069
+ }
1070
+ throw lastError;
1071
+ };
902
1072
  static requestToUpdateCLI = async (queryParams, config) => {
903
1073
  const params = new URLSearchParams(queryParams);
904
1074
  const requestInit = {
@@ -907,12 +1077,13 @@ var init_cliUtils = __esm({
907
1077
  Authorization: `Basic ${Buffer.from(`${getBrowserStackUser(config)}:${getBrowserStackKey(config)}`).toString("base64")}`
908
1078
  }
909
1079
  };
910
- const response = await _fetch(
1080
+ const response = await this.fetchWithRetry(
911
1081
  `${APIUtils.BROWSERSTACK_AUTOMATE_API_URL}/${UPDATED_CLI_ENDPOINT}?${params.toString()}`,
912
- requestInit
1082
+ requestInit,
1083
+ "update_cli request"
913
1084
  );
914
1085
  const jsonResponse = await response.json();
915
- BStackLogger.debug(`response ${JSON.stringify(jsonResponse)}`);
1086
+ BStackLogger2.debug(`response ${JSON.stringify(jsonResponse)}`);
916
1087
  return jsonResponse;
917
1088
  };
918
1089
  static runShellCommand(cmdCommand, workingDir = "") {
@@ -934,11 +1105,11 @@ var init_cliUtils = __esm({
934
1105
  });
935
1106
  }
936
1107
  static downloadLatestBinary = async (binDownloadUrl, cliDir) => {
937
- const lockPath = path2.join(cliDir, "download.lock");
1108
+ const lockPath = path3.join(cliDir, "download.lock");
938
1109
  const sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
939
1110
  const parseLockFile = () => {
940
1111
  try {
941
- const content = fs2.readFileSync(lockPath, "utf8").trim();
1112
+ const content = fs3.readFileSync(lockPath, "utf8").trim();
942
1113
  const [pidLine, timestampLine] = content.split("\n");
943
1114
  const pid = Number.parseInt(pidLine, 10);
944
1115
  const timestamp = Number.parseInt(timestampLine, 10);
@@ -962,20 +1133,20 @@ var init_cliUtils = __esm({
962
1133
  const start = Date.now();
963
1134
  while (true) {
964
1135
  try {
965
- const fd = fs2.openSync(lockPath, "wx");
1136
+ const fd = fs3.openSync(lockPath, "wx");
966
1137
  try {
967
- fs2.writeFileSync(fd, `${process.pid}
1138
+ fs3.writeFileSync(fd, `${process.pid}
968
1139
  ${Date.now()}
969
1140
  `);
970
1141
  } catch {
971
1142
  }
972
1143
  return () => {
973
1144
  try {
974
- fs2.closeSync(fd);
1145
+ fs3.closeSync(fd);
975
1146
  } catch {
976
1147
  }
977
1148
  try {
978
- fs2.unlinkSync(lockPath);
1149
+ fs3.unlinkSync(lockPath);
979
1150
  } catch {
980
1151
  }
981
1152
  };
@@ -987,19 +1158,19 @@ ${Date.now()}
987
1158
  const lockAge = Date.now() - lockMeta.timestamp;
988
1159
  const running = isProcessRunning(lockMeta.pid);
989
1160
  if (!running || lockAge > timeoutMs) {
990
- BStackLogger.warn(
1161
+ BStackLogger2.warn(
991
1162
  `Stale CLI download lock detected (pid=${lockMeta.pid}, age=${lockAge}ms). Removing lock.`
992
1163
  );
993
1164
  try {
994
- fs2.unlinkSync(lockPath);
1165
+ fs3.unlinkSync(lockPath);
995
1166
  } catch {
996
1167
  }
997
1168
  continue;
998
1169
  }
999
1170
  }
1000
1171
  const existingBinary = _CLIUtils.getExistingCliPath(cliDir);
1001
- if (existingBinary && fs2.existsSync(existingBinary) && fs2.statSync(existingBinary).size > 0) {
1002
- BStackLogger.debug(
1172
+ if (existingBinary && fs3.existsSync(existingBinary) && fs3.statSync(existingBinary).size > 0) {
1173
+ BStackLogger2.debug(
1003
1174
  `Binary appeared while waiting for lock: ${existingBinary}`
1004
1175
  );
1005
1176
  return { alreadyExists: existingBinary };
@@ -1020,16 +1191,16 @@ ${Date.now()}
1020
1191
  try {
1021
1192
  const now2 = Date.now();
1022
1193
  const tmpExtractRe = /\.tmp\.\d+$/;
1023
- for (const entry of fs2.readdirSync(cliDir)) {
1194
+ for (const entry of fs3.readdirSync(cliDir)) {
1024
1195
  const isDownloadZip = entry.startsWith(CLI_DOWNLOAD_TMP_PREFIX) && entry.endsWith(CLI_DOWNLOAD_TMP_SUFFIX);
1025
1196
  const isExtractTmp = tmpExtractRe.test(entry);
1026
1197
  if (!isDownloadZip && !isExtractTmp) {
1027
1198
  continue;
1028
1199
  }
1029
- const filePath = path2.join(cliDir, entry);
1200
+ const filePath = path3.join(cliDir, entry);
1030
1201
  let stats;
1031
1202
  try {
1032
- stats = fs2.statSync(filePath);
1203
+ stats = fs3.statSync(filePath);
1033
1204
  } catch {
1034
1205
  continue;
1035
1206
  }
@@ -1037,21 +1208,21 @@ ${Date.now()}
1037
1208
  continue;
1038
1209
  }
1039
1210
  try {
1040
- fs2.unlinkSync(filePath);
1211
+ fs3.unlinkSync(filePath);
1041
1212
  } catch (err) {
1042
- BStackLogger.debug(
1213
+ BStackLogger2.debug(
1043
1214
  `Failed to delete temp CLI file ${filePath}: ${util.format(err)}`
1044
1215
  );
1045
1216
  }
1046
1217
  }
1047
1218
  } catch (err) {
1048
- BStackLogger.debug(
1219
+ BStackLogger2.debug(
1049
1220
  `Failed to scan temp CLI files in ${cliDir}: ${util.format(err)}`
1050
1221
  );
1051
1222
  }
1052
1223
  };
1053
1224
  PerformanceTester.start(EVENTS.SDK_CLI_DOWNLOAD);
1054
- BStackLogger.debug(`Downloading SDK binary from: ${binDownloadUrl}`);
1225
+ BStackLogger2.debug(`Downloading SDK binary from: ${binDownloadUrl}`);
1055
1226
  let downloadEnded = false;
1056
1227
  const endDownload = (success = true, errMsg) => {
1057
1228
  if (downloadEnded) {
@@ -1077,8 +1248,8 @@ ${Date.now()}
1077
1248
  }
1078
1249
  releaseLock = lockResult;
1079
1250
  const existingBinary = _CLIUtils.getExistingCliPath(cliDir);
1080
- if (existingBinary && fs2.existsSync(existingBinary) && fs2.statSync(existingBinary).size > 0) {
1081
- BStackLogger.debug(
1251
+ if (existingBinary && fs3.existsSync(existingBinary) && fs3.statSync(existingBinary).size > 0) {
1252
+ BStackLogger2.debug(
1082
1253
  `Binary already exists after acquiring lock: ${existingBinary}`
1083
1254
  );
1084
1255
  endDownload();
@@ -1086,11 +1257,11 @@ ${Date.now()}
1086
1257
  return existingBinary;
1087
1258
  }
1088
1259
  cleanupTemporaryDownloads();
1089
- const zipFilePath = path2.join(
1260
+ const zipFilePath = path3.join(
1090
1261
  cliDir,
1091
1262
  `${CLI_DOWNLOAD_TMP_PREFIX}${process.pid}_${Date.now()}${CLI_DOWNLOAD_TMP_SUFFIX}`
1092
1263
  );
1093
- const downloadedFileStream = fs2.createWriteStream(zipFilePath);
1264
+ const downloadedFileStream = fs3.createWriteStream(zipFilePath);
1094
1265
  return new Promise((resolve, reject) => {
1095
1266
  const processDownload = async () => {
1096
1267
  const abortController = new AbortController();
@@ -1100,9 +1271,11 @@ ${Date.now()}
1100
1271
  );
1101
1272
  let response;
1102
1273
  try {
1103
- response = await _fetch(binDownloadUrl, {
1104
- signal: abortController.signal
1105
- });
1274
+ response = await _fetch(
1275
+ binDownloadUrl,
1276
+ { signal: abortController.signal },
1277
+ { connectTimeoutMs: CLI_CONNECT_TIMEOUT_MS }
1278
+ );
1106
1279
  } finally {
1107
1280
  clearTimeout(timeout);
1108
1281
  }
@@ -1110,7 +1283,7 @@ ${Date.now()}
1110
1283
  throw new Error("No response body received");
1111
1284
  }
1112
1285
  downloadedFileStream.on("error", function(err) {
1113
- BStackLogger.error(
1286
+ BStackLogger2.error(
1114
1287
  `Got Error while downloading cli binary file: ${err}`
1115
1288
  );
1116
1289
  endDownload(false, util.format(err));
@@ -1139,7 +1312,7 @@ ${Date.now()}
1139
1312
  }
1140
1313
  );
1141
1314
  } catch (err) {
1142
- BStackLogger.error(
1315
+ BStackLogger2.error(
1143
1316
  `Got Error in cli binary downloading request ${util.format(err)}`
1144
1317
  );
1145
1318
  endDownload(false, util.format(err));
@@ -1152,7 +1325,7 @@ ${Date.now()}
1152
1325
  } catch (err) {
1153
1326
  releaseLock?.();
1154
1327
  endDownload(false, util.format(err));
1155
- BStackLogger.debug(
1328
+ BStackLogger2.debug(
1156
1329
  `Failed to download binary, Exception: ${util.format(err)}`
1157
1330
  );
1158
1331
  return null;
@@ -1172,17 +1345,17 @@ ${Date.now()}
1172
1345
  zipfile.readEntry();
1173
1346
  return;
1174
1347
  }
1175
- const candidatePath = path2.join(cliDir, entry.fileName);
1176
- const resolvedCandidate = path2.resolve(candidatePath);
1177
- const resolvedDir = path2.resolve(cliDir) + path2.sep;
1348
+ const candidatePath = path3.join(cliDir, entry.fileName);
1349
+ const resolvedCandidate = path3.resolve(candidatePath);
1350
+ const resolvedDir = path3.resolve(cliDir) + path3.sep;
1178
1351
  if (!resolvedCandidate.startsWith(resolvedDir)) {
1179
1352
  zipfile.close();
1180
1353
  reject(new Error(`Zip-slip detected: entry "${entry.fileName}" resolves outside ${cliDir}`));
1181
1354
  return;
1182
1355
  }
1183
- const isBinaryEntry = path2.basename(entry.fileName).startsWith("binary-");
1356
+ const isBinaryEntry = path3.basename(entry.fileName).startsWith("binary-");
1184
1357
  if (!isBinaryEntry) {
1185
- const directStream = fs2.createWriteStream(candidatePath);
1358
+ const directStream = fs3.createWriteStream(candidatePath);
1186
1359
  directStream.on("error", (writeErr) => {
1187
1360
  zipfile.close();
1188
1361
  reject(writeErr);
@@ -1204,8 +1377,8 @@ ${Date.now()}
1204
1377
  return;
1205
1378
  }
1206
1379
  const finalPath = candidatePath;
1207
- const tempPath = path2.join(cliDir, `${entry.fileName}.tmp.${process.pid}`);
1208
- const writeStream = fs2.createWriteStream(tempPath);
1380
+ const tempPath = path3.join(cliDir, `${entry.fileName}.tmp.${process.pid}`);
1381
+ const writeStream = fs3.createWriteStream(tempPath);
1209
1382
  let writeStreamErrored = false;
1210
1383
  writeStream.on("error", (writeErr) => {
1211
1384
  writeStreamErrored = true;
@@ -1226,7 +1399,7 @@ ${Date.now()}
1226
1399
  if (renameErr.code !== "EXDEV") {
1227
1400
  throw renameErr;
1228
1401
  }
1229
- BStackLogger.warn(`Atomic rename failed (cross-device), falling back to copy: ${renameErr.message}`);
1402
+ BStackLogger2.warn(`Atomic rename failed (cross-device), falling back to copy: ${renameErr.message}`);
1230
1403
  await fsp.copyFile(tempPath, finalPath);
1231
1404
  await fsp.unlink(tempPath).catch(() => {
1232
1405
  });
@@ -1263,7 +1436,7 @@ ${Date.now()}
1263
1436
  });
1264
1437
  zipfile.once("end", () => {
1265
1438
  fsp.unlink(zipFilePath).catch(() => {
1266
- BStackLogger.warn(`Failed to delete zip file: ${zipFilePath}`);
1439
+ BStackLogger2.warn(`Failed to delete zip file: ${zipFilePath}`);
1267
1440
  });
1268
1441
  if (!resolvedBinaryPath) {
1269
1442
  zipfile.close();
@@ -1294,7 +1467,7 @@ ${Date.now()}
1294
1467
  }
1295
1468
  static setFrameworkDetail(testFramework, automationFramework) {
1296
1469
  if (!testFramework || !automationFramework) {
1297
- BStackLogger.debug(
1470
+ BStackLogger2.debug(
1298
1471
  `Test or Automation framework not provided testFramework=${testFramework}, automationFramework=${automationFramework}`
1299
1472
  );
1300
1473
  }
@@ -1376,12 +1549,12 @@ ${Date.now()}
1376
1549
 
1377
1550
  // src/instrumentation/performance/performance-tester.ts
1378
1551
  import { createObjectCsvWriter } from "csv-writer";
1379
- import fs3 from "node:fs";
1552
+ import fs4 from "node:fs";
1380
1553
  import fsPromise from "node:fs/promises";
1381
1554
  import { performance, PerformanceObserver } from "node:perf_hooks";
1382
1555
  import util2 from "node:util";
1383
1556
  import worker from "node:worker_threads";
1384
- import path3 from "node:path";
1557
+ import path4 from "node:path";
1385
1558
  import { arch as arch2, hostname, platform as platform2, type, version } from "node:os";
1386
1559
  var PerformanceTester;
1387
1560
  var init_performance_tester = __esm({
@@ -1406,11 +1579,11 @@ var init_performance_tester = __esm({
1406
1579
  static browser;
1407
1580
  static scenarioThatRan;
1408
1581
  static jsonReportDirName = "performance-report";
1409
- static jsonReportDirPath = path3.join(process.cwd(), "logs", this.jsonReportDirName);
1582
+ static jsonReportDirPath = path4.join(process.cwd(), "logs", this.jsonReportDirName);
1410
1583
  static jsonReportFileName = `${this.jsonReportDirPath}/performance-report-${_PerformanceTester.getProcessId()}.json`;
1411
1584
  static startMonitoring(csvName = "performance-report.csv") {
1412
- if (!fs3.existsSync(this.jsonReportDirPath)) {
1413
- fs3.mkdirSync(this.jsonReportDirPath, { recursive: true });
1585
+ if (!fs4.existsSync(this.jsonReportDirPath)) {
1586
+ fs4.mkdirSync(this.jsonReportDirPath, { recursive: true });
1414
1587
  }
1415
1588
  this._observer = new PerformanceObserver((list) => {
1416
1589
  list.getEntries().filter((entry) => entry.entryType === "measure").forEach(
@@ -1420,10 +1593,10 @@ var init_performance_tester = __esm({
1420
1593
  if (typeof finalEntry.startTime === "number" && typeof performance.timeOrigin === "number") {
1421
1594
  const originalStartTime = finalEntry.startTime;
1422
1595
  finalEntry.startTime = performance.timeOrigin + finalEntry.startTime;
1423
- BStackLogger2.debug(`Timestamp conversion for ${entry.name}: ${originalStartTime} -> ${finalEntry.startTime} (timeOrigin: ${performance.timeOrigin})`);
1596
+ BStackLogger.debug(`Timestamp conversion for ${entry.name}: ${originalStartTime} -> ${finalEntry.startTime} (timeOrigin: ${performance.timeOrigin})`);
1424
1597
  }
1425
1598
  } catch (e) {
1426
- BStackLogger2.debug(`Error converting startTime to epoch: ${util2.format(e)}`);
1599
+ BStackLogger.debug(`Error converting startTime to epoch: ${util2.format(e)}`);
1427
1600
  }
1428
1601
  if (this.details[entry.name]) {
1429
1602
  finalEntry = Object.assign(finalEntry, this.details[entry.name]);
@@ -1463,7 +1636,7 @@ var init_performance_tester = __esm({
1463
1636
  const timeTaken = methods.reduce((a, c) => {
1464
1637
  return times[c] + (a || 0);
1465
1638
  }, 0);
1466
- BStackLogger2.debug(`Time for ${methods} is ${timeTaken}`);
1639
+ BStackLogger.debug(`Time for ${methods} is ${timeTaken}`);
1467
1640
  return timeTaken;
1468
1641
  }
1469
1642
  static async stopAndGenerate(filename = "performance-own.html") {
@@ -1475,7 +1648,7 @@ var init_performance_tester = __esm({
1475
1648
  const finalJSONStr = eventsJson.slice(1, -1) + ",";
1476
1649
  await fsPromise.appendFile(this.jsonReportFileName, finalJSONStr);
1477
1650
  } catch (er) {
1478
- BStackLogger2.debug(`Failed to write events of the worker to ${this.jsonReportFileName}: ${util2.format(er)}`);
1651
+ BStackLogger.debug(`Failed to write events of the worker to ${this.jsonReportFileName}: ${util2.format(er)}`);
1479
1652
  }
1480
1653
  this._observer.disconnect();
1481
1654
  if (!process.env[PERF_MEASUREMENT_ENV]) {
@@ -1484,12 +1657,12 @@ var init_performance_tester = __esm({
1484
1657
  this.started = false;
1485
1658
  this.generateCSV(this._events);
1486
1659
  const content = this.generateReport(this._events);
1487
- const dir = path3.join(process.cwd(), filename);
1660
+ const dir = path4.join(process.cwd(), filename);
1488
1661
  try {
1489
1662
  await fsPromise.writeFile(dir, content);
1490
- BStackLogger2.info(`Performance report is at ${path3}`);
1663
+ BStackLogger.info(`Performance report is at ${path4}`);
1491
1664
  } catch (err) {
1492
- BStackLogger2.error(`Error in writing html ${util2.format(err)}`);
1665
+ BStackLogger.error(`Error in writing html ${util2.format(err)}`);
1493
1666
  }
1494
1667
  }
1495
1668
  static generateReport(entries) {
@@ -1520,7 +1693,7 @@ var init_performance_tester = __esm({
1520
1693
  time: value
1521
1694
  };
1522
1695
  });
1523
- this._csvWriter.writeRecords(dat).then(() => BStackLogger2.info("Performance CSV report generated successfully")).catch((error) => console.error(error));
1696
+ this._csvWriter.writeRecords(dat).then(() => BStackLogger.info("Performance CSV report generated successfully")).catch((error) => console.error(error));
1524
1697
  }
1525
1698
  static Measure(label, details = {}) {
1526
1699
  const self = this;
@@ -1654,16 +1827,16 @@ var init_performance_tester = __esm({
1654
1827
  this.start(EVENTS.SDK_SEND_KEY_METRICS);
1655
1828
  try {
1656
1829
  const workerId = `${process.pid}`;
1657
- BStackLogger2.debug(`[Performance Upload] Starting upload for worker ${workerId}`);
1830
+ BStackLogger.debug(`[Performance Upload] Starting upload for worker ${workerId}`);
1658
1831
  this.start(EVENTS.SDK_KEY_METRICS_PREPARATION);
1659
1832
  let measures = [];
1660
1833
  if (await fsPromise.access(this.jsonReportDirPath).then(() => true).catch(() => false)) {
1661
- const files = (await fsPromise.readdir(this.jsonReportDirPath)).map((file) => path3.resolve(this.jsonReportDirPath, file));
1834
+ const files = (await fsPromise.readdir(this.jsonReportDirPath)).map((file) => path4.resolve(this.jsonReportDirPath, file));
1662
1835
  measures = (await Promise.all(files.map((file) => fsPromise.readFile(file, "utf-8")))).map((el) => `[${el.slice(0, -1)}]`).map((el) => JSON.parse(el)).flat();
1663
1836
  }
1664
- BStackLogger2.debug(`[Performance Upload] Total events from files: ${measures.length}`);
1837
+ BStackLogger.debug(`[Performance Upload] Total events from files: ${measures.length}`);
1665
1838
  if (this._measuredEvents.length > 0) {
1666
- BStackLogger2.debug(`[Performance Upload] Adding ${this._measuredEvents.length} in-memory events`);
1839
+ BStackLogger.debug(`[Performance Upload] Adding ${this._measuredEvents.length} in-memory events`);
1667
1840
  measures = measures.concat(
1668
1841
  this._measuredEvents.map((e) => {
1669
1842
  if (typeof e.toJSON === "function") {
@@ -1724,10 +1897,10 @@ var init_performance_tester = __esm({
1724
1897
  },
1725
1898
  body: JSON.stringify(payload)
1726
1899
  });
1727
- BStackLogger2.debug(`[Performance Upload] Successfully uploaded to EDS: ${util2.format(await result.text())}`);
1900
+ BStackLogger.debug(`[Performance Upload] Successfully uploaded to EDS: ${util2.format(await result.text())}`);
1728
1901
  this.end(EVENTS.SDK_SEND_KEY_METRICS, true);
1729
1902
  } catch (er) {
1730
- BStackLogger2.debug(`[Performance Upload] Failed to upload events: ${util2.format(er)}`);
1903
+ BStackLogger.debug(`[Performance Upload] Failed to upload events: ${util2.format(er)}`);
1731
1904
  this.end(EVENTS.SDK_KEY_METRICS_PREPARATION, false, er);
1732
1905
  this.end(EVENTS.SDK_SEND_KEY_METRICS, false, er);
1733
1906
  }
@@ -1735,12 +1908,12 @@ var init_performance_tester = __esm({
1735
1908
  if (await fsPromise.access(this.jsonReportDirPath).then(() => true, () => false)) {
1736
1909
  const files = await fsPromise.readdir(this.jsonReportDirPath);
1737
1910
  for (const file of files) {
1738
- await fsPromise.unlink(path3.join(this.jsonReportDirPath, file));
1911
+ await fsPromise.unlink(path4.join(this.jsonReportDirPath, file));
1739
1912
  }
1740
- BStackLogger2.debug(`[Performance Upload] Cleaned up ${files.length} temporary report files`);
1913
+ BStackLogger.debug(`[Performance Upload] Cleaned up ${files.length} temporary report files`);
1741
1914
  }
1742
1915
  } catch (er) {
1743
- BStackLogger2.debug(`[Performance Upload] Failed to delete temporary files: ${util2.format(er)}`);
1916
+ BStackLogger.debug(`[Performance Upload] Failed to delete temporary files: ${util2.format(er)}`);
1744
1917
  }
1745
1918
  }
1746
1919
  };
@@ -1748,7 +1921,7 @@ var init_performance_tester = __esm({
1748
1921
  });
1749
1922
 
1750
1923
  // src/testorchestration/testorcherstrationutils.ts
1751
- import fs4 from "node:fs";
1924
+ import fs5 from "node:fs";
1752
1925
  var RUN_SMART_SELECTION, ALLOWED_ORCHESTRATION_KEYS, isPlainObject, asString, TestOrdering, OrchestrationUtils;
1753
1926
  var init_testorcherstrationutils = __esm({
1754
1927
  "src/testorchestration/testorcherstrationutils.ts"() {
@@ -1816,7 +1989,7 @@ var init_testorcherstrationutils = __esm({
1816
1989
  for (const service of services) {
1817
1990
  if (Array.isArray(service) && service[0] === "browserstack" && isPlainObject(service[1]) && isPlainObject(service[1].testOrchestrationOptions)) {
1818
1991
  testOrchOptions = service[1].testOrchestrationOptions;
1819
- BStackLogger2.debug("[constructor] Found testOrchestrationOptions in browserstack service config");
1992
+ BStackLogger.debug("[constructor] Found testOrchestrationOptions in browserstack service config");
1820
1993
  break;
1821
1994
  }
1822
1995
  }
@@ -1845,9 +2018,9 @@ var init_testorcherstrationutils = __esm({
1845
2018
  }
1846
2019
  });
1847
2020
  }
1848
- BStackLogger2.debug(`[_extractBuildDetails] Extracted - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
2021
+ BStackLogger.debug(`[_extractBuildDetails] Extracted - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
1849
2022
  } catch (error) {
1850
- BStackLogger2.error(`[_extractBuildDetails] ${error}`);
2023
+ BStackLogger.error(`[_extractBuildDetails] ${error}`);
1851
2024
  }
1852
2025
  }
1853
2026
  _parseCapability(capability) {
@@ -1945,7 +2118,7 @@ var init_testorcherstrationutils = __esm({
1945
2118
  this.projectName = projectName;
1946
2119
  this.buildName = buildName;
1947
2120
  this.buildIdentifier = buildIdentifier;
1948
- BStackLogger2.debug(`[setBuildDetails] Set - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
2121
+ BStackLogger.debug(`[setBuildDetails] Set - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
1949
2122
  }
1950
2123
  /**
1951
2124
  * Set run smart selection
@@ -1955,27 +2128,27 @@ var init_testorcherstrationutils = __esm({
1955
2128
  this.runSmartSelection = isValidEnabledValue(enabled);
1956
2129
  this.smartSelectionMode = mode;
1957
2130
  this.smartSelectionSource = [];
1958
- BStackLogger2.debug(`Setting runSmartSelection: enabled=${this.runSmartSelection}, mode=${this.smartSelectionMode}`);
2131
+ BStackLogger.debug(`Setting runSmartSelection: enabled=${this.runSmartSelection}, mode=${this.smartSelectionMode}`);
1959
2132
  if (this.runSmartSelection) {
1960
2133
  const validModes = [SMART_SELECTION_MODE_RELEVANT_FIRST, SMART_SELECTION_MODE_RELEVANT_ONLY];
1961
2134
  if (!validModes.includes(this.smartSelectionMode)) {
1962
- BStackLogger2.warn(`Invalid smart selection mode '${this.smartSelectionMode}' provided. Defaulting to '${SMART_SELECTION_MODE_RELEVANT_FIRST}'.`);
2135
+ BStackLogger.warn(`Invalid smart selection mode '${this.smartSelectionMode}' provided. Defaulting to '${SMART_SELECTION_MODE_RELEVANT_FIRST}'.`);
1963
2136
  this.smartSelectionMode = SMART_SELECTION_MODE_RELEVANT_FIRST;
1964
2137
  }
1965
2138
  if (source === null) {
1966
2139
  this.smartSelectionSource = null;
1967
- BStackLogger2.debug("No source provided for smart selection; defaulting to null.");
2140
+ BStackLogger.debug("No source provided for smart selection; defaulting to null.");
1968
2141
  } else if (Array.isArray(source)) {
1969
2142
  this.smartSelectionSource = source;
1970
- BStackLogger2.debug(`Smart selection source set to array: ${JSON.stringify(source)}`);
2143
+ BStackLogger.debug(`Smart selection source set to array: ${JSON.stringify(source)}`);
1971
2144
  } else if (typeof source === "string" && source.endsWith(".json")) {
1972
2145
  this.smartSelectionSource = this._loadSourceFromFile(source) || [];
1973
- BStackLogger2.debug(`Smart selection source loaded from file: ${source}`);
2146
+ BStackLogger.debug(`Smart selection source loaded from file: ${source}`);
1974
2147
  }
1975
2148
  this._setTestOrdering();
1976
2149
  }
1977
2150
  } catch (e) {
1978
- BStackLogger2.error(`[_setRunSmartSelection] ${e}`);
2151
+ BStackLogger.error(`[_setRunSmartSelection] ${e}`);
1979
2152
  }
1980
2153
  }
1981
2154
  /**
@@ -1985,17 +2158,17 @@ var init_testorcherstrationutils = __esm({
1985
2158
  * @returns Formatted list of repository configurations
1986
2159
  */
1987
2160
  _loadSourceFromFile(filePath) {
1988
- if (!fs4.existsSync(filePath)) {
1989
- BStackLogger2.error(`Source file '${filePath}' does not exist.`);
2161
+ if (!fs5.existsSync(filePath)) {
2162
+ BStackLogger.error(`Source file '${filePath}' does not exist.`);
1990
2163
  return [];
1991
2164
  }
1992
2165
  let data = null;
1993
2166
  try {
1994
- const fileContent = fs4.readFileSync(filePath, "utf8");
2167
+ const fileContent = fs5.readFileSync(filePath, "utf8");
1995
2168
  data = JSON.parse(fileContent);
1996
2169
  } catch (error) {
1997
2170
  const message = error instanceof Error ? error.message : String(error);
1998
- BStackLogger2.error(`Error parsing JSON from source file '${filePath}': ${message}`);
2171
+ BStackLogger.error(`Error parsing JSON from source file '${filePath}': ${message}`);
1999
2172
  return [];
2000
2173
  }
2001
2174
  let featureBranchEnvMap = null;
@@ -2011,9 +2184,9 @@ var init_testorcherstrationutils = __esm({
2011
2184
  return acc;
2012
2185
  }, {});
2013
2186
  } catch (error) {
2014
- BStackLogger2.error(`Error parsing feature branch mappings: ${error}`);
2187
+ BStackLogger.error(`Error parsing feature branch mappings: ${error}`);
2015
2188
  }
2016
- BStackLogger2.debug(`Feature branch mappings from env: ${JSON.stringify(envMap)}`);
2189
+ BStackLogger.debug(`Feature branch mappings from env: ${JSON.stringify(envMap)}`);
2017
2190
  return envMap;
2018
2191
  };
2019
2192
  featureBranchEnvMap = loadFeatureBranchMaps();
@@ -2035,23 +2208,23 @@ var init_testorcherstrationutils = __esm({
2035
2208
  }
2036
2209
  const typedRepoInfo = repoInfo;
2037
2210
  if (!typedRepoInfo.url || typeof typedRepoInfo.url !== "string") {
2038
- BStackLogger2.warn(`Repository URL is missing or invalid for source '${name}': ${JSON.stringify(repoInfo)}`);
2211
+ BStackLogger.warn(`Repository URL is missing or invalid for source '${name}': ${JSON.stringify(repoInfo)}`);
2039
2212
  continue;
2040
2213
  }
2041
2214
  if (typedRepoInfo.baseBranch !== void 0 && typeof typedRepoInfo.baseBranch !== "string") {
2042
- BStackLogger2.warn(`Base branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2215
+ BStackLogger.warn(`Base branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2043
2216
  continue;
2044
2217
  }
2045
2218
  if (typedRepoInfo.featureBranch !== void 0 && typeof typedRepoInfo.featureBranch !== "string") {
2046
- BStackLogger2.warn(`Feature branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2219
+ BStackLogger.warn(`Feature branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2047
2220
  continue;
2048
2221
  }
2049
2222
  if (!namePattern.test(name)) {
2050
- BStackLogger2.warn(`Invalid source identifier format for '${name}': ${JSON.stringify(repoInfo)}`);
2223
+ BStackLogger.warn(`Invalid source identifier format for '${name}': ${JSON.stringify(repoInfo)}`);
2051
2224
  continue;
2052
2225
  }
2053
2226
  if (name.length > 30 || name.length < 1) {
2054
- BStackLogger2.warn(`Source identifier '${name}' must have a length between 1 and 30 characters.`);
2227
+ BStackLogger.warn(`Source identifier '${name}' must have a length between 1 and 30 characters.`);
2055
2228
  continue;
2056
2229
  }
2057
2230
  const featureBranch = getFeatureBranch(name, typedRepoInfo);
@@ -2064,11 +2237,11 @@ var init_testorcherstrationutils = __esm({
2064
2237
  filteredRepoInfo.baseBranch = typedRepoInfo.baseBranch;
2065
2238
  }
2066
2239
  if (!filteredRepoInfo.featureBranch || filteredRepoInfo.featureBranch === "") {
2067
- BStackLogger2.warn(`Feature branch not specified for source '${name}': ${JSON.stringify(repoInfo)}`);
2240
+ BStackLogger.warn(`Feature branch not specified for source '${name}': ${JSON.stringify(repoInfo)}`);
2068
2241
  continue;
2069
2242
  }
2070
2243
  if (filteredRepoInfo.baseBranch && filteredRepoInfo.baseBranch === filteredRepoInfo.featureBranch) {
2071
- BStackLogger2.warn(`Feature branch and base branch cannot be the same for source '${name}': ${JSON.stringify(repoInfo)}`);
2244
+ BStackLogger.warn(`Feature branch and base branch cannot be the same for source '${name}': ${JSON.stringify(repoInfo)}`);
2072
2245
  continue;
2073
2246
  }
2074
2247
  formattedData.push(filteredRepoInfo);
@@ -2178,17 +2351,17 @@ var init_crash_reporter = __esm({
2178
2351
  this.credentialsForCrashReportUpload = process.env.CREDENTIALS_FOR_CRASH_REPORTING !== void 0 ? JSON.parse(process.env.CREDENTIALS_FOR_CRASH_REPORTING) : this.credentialsForCrashReportUpload;
2179
2352
  }
2180
2353
  } catch (error) {
2181
- return BStackLogger2.error(`[Crash_Report_Upload] Failed to parse user credentials while reporting crash due to ${error}`);
2354
+ return BStackLogger.error(`[Crash_Report_Upload] Failed to parse user credentials while reporting crash due to ${error}`);
2182
2355
  }
2183
2356
  if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
2184
- return BStackLogger2.error("[Crash_Report_Upload] Failed to parse user credentials while reporting crash");
2357
+ return BStackLogger.error("[Crash_Report_Upload] Failed to parse user credentials while reporting crash");
2185
2358
  }
2186
2359
  try {
2187
2360
  if (Object.keys(this.userConfigForReporting).length === 0) {
2188
2361
  this.userConfigForReporting = process.env.USER_CONFIG_FOR_REPORTING !== void 0 ? JSON.parse(process.env.USER_CONFIG_FOR_REPORTING) : {};
2189
2362
  }
2190
2363
  } catch (error) {
2191
- BStackLogger2.error(`[Crash_Report_Upload] Failed to parse user config while reporting crash due to ${error}`);
2364
+ BStackLogger.error(`[Crash_Report_Upload] Failed to parse user config while reporting crash due to ${error}`);
2192
2365
  this.userConfigForReporting = {};
2193
2366
  }
2194
2367
  const data = {
@@ -2220,9 +2393,9 @@ var init_crash_reporter = __esm({
2220
2393
  body = JSON.stringify(JSON.parse(body));
2221
2394
  } catch {
2222
2395
  }
2223
- BStackLogger2.debug(`[Crash_Report_Upload] Success response: ${body}`);
2396
+ BStackLogger.debug(`[Crash_Report_Upload] Success response: ${body}`);
2224
2397
  } else {
2225
- BStackLogger2.error(`[Crash_Report_Upload] Failed due to ${response.body}`);
2398
+ BStackLogger.error(`[Crash_Report_Upload] Failed due to ${response.body}`);
2226
2399
  }
2227
2400
  }
2228
2401
  static recursivelyRedactKeysFromObject(obj, keys) {
@@ -2282,7 +2455,7 @@ var init_crash_reporter = __esm({
2282
2455
  }
2283
2456
  }
2284
2457
  } catch (err) {
2285
- BStackLogger2.error(`Error in parsing user config PII with error ${err ? err.stack || err : err}`);
2458
+ BStackLogger.error(`Error in parsing user config PII with error ${err ? err.stack || err : err}`);
2286
2459
  return configWithoutPII;
2287
2460
  }
2288
2461
  configWithoutPII.services = finalServices;
@@ -2317,7 +2490,7 @@ var init_featureStats = __esm({
2317
2490
  this.failed(groupId);
2318
2491
  break;
2319
2492
  default:
2320
- BStackLogger2.debug("Request to mark usage for unknown status - " + status);
2493
+ BStackLogger.debug("Request to mark usage for unknown status - " + status);
2321
2494
  break;
2322
2495
  }
2323
2496
  }
@@ -2482,6 +2655,8 @@ var init_testOpsConfig = __esm({
2482
2655
  this.manuallySet = manuallySet;
2483
2656
  _TestOpsConfig._instance = this;
2484
2657
  }
2658
+ enabled;
2659
+ manuallySet;
2485
2660
  static _instance;
2486
2661
  buildStopped = false;
2487
2662
  buildHashedId;
@@ -2553,7 +2728,7 @@ var init_usageStats = __esm({
2553
2728
  try {
2554
2729
  usage.events = this.getEventsData();
2555
2730
  } catch (e) {
2556
- BStackLogger2.debug("exception in getFormattedData: " + e);
2731
+ BStackLogger.debug("exception in getFormattedData: " + e);
2557
2732
  }
2558
2733
  return usage;
2559
2734
  }
@@ -2563,7 +2738,7 @@ var init_usageStats = __esm({
2563
2738
  const usageStatsForWorker = _UsageStats.fromJSON(workerData.usageStats);
2564
2739
  this.add(usageStatsForWorker);
2565
2740
  } catch (e) {
2566
- BStackLogger2.debug("Exception in adding workerData: " + e);
2741
+ BStackLogger.debug("Exception in adding workerData: " + e);
2567
2742
  }
2568
2743
  });
2569
2744
  }
@@ -2617,9 +2792,9 @@ var init_usageStats = __esm({
2617
2792
  });
2618
2793
 
2619
2794
  // src/scripts/accessibility-scripts.ts
2620
- import path4 from "node:path";
2621
- import fs5 from "node:fs";
2622
- import os from "node:os";
2795
+ import path5 from "node:path";
2796
+ import fs6 from "node:fs";
2797
+ import os2 from "node:os";
2623
2798
  var AccessibilityScripts, accessibility_scripts_default;
2624
2799
  var init_accessibility_scripts = __esm({
2625
2800
  "src/scripts/accessibility-scripts.ts"() {
@@ -2637,7 +2812,7 @@ var init_accessibility_scripts = __esm({
2637
2812
  // don't allow to create instances from it other than through `checkAndGetInstance`
2638
2813
  constructor() {
2639
2814
  this.browserstackFolderPath = this.getWritableDir();
2640
- this.commandsPath = path4.join(this.browserstackFolderPath, "commands.json");
2815
+ this.commandsPath = path5.join(this.browserstackFolderPath, "commands.json");
2641
2816
  }
2642
2817
  static checkAndGetInstance() {
2643
2818
  if (!_AccessibilityScripts.instance) {
@@ -2649,17 +2824,17 @@ var init_accessibility_scripts = __esm({
2649
2824
  /* eslint-disable @typescript-eslint/no-unused-vars */
2650
2825
  getWritableDir() {
2651
2826
  const orderedPaths = [
2652
- path4.join(os.homedir(), ".browserstack"),
2827
+ path5.join(os2.homedir(), ".browserstack"),
2653
2828
  process.cwd(),
2654
- os.tmpdir()
2829
+ os2.tmpdir()
2655
2830
  ];
2656
2831
  for (const orderedPath of orderedPaths) {
2657
2832
  try {
2658
- if (fs5.existsSync(orderedPath)) {
2659
- fs5.accessSync(orderedPath);
2833
+ if (fs6.existsSync(orderedPath)) {
2834
+ fs6.accessSync(orderedPath);
2660
2835
  return orderedPath;
2661
2836
  }
2662
- fs5.mkdirSync(orderedPath, { recursive: true });
2837
+ fs6.mkdirSync(orderedPath, { recursive: true });
2663
2838
  return orderedPath;
2664
2839
  } catch (error) {
2665
2840
  }
@@ -2668,8 +2843,8 @@ var init_accessibility_scripts = __esm({
2668
2843
  }
2669
2844
  readFromExistingFile() {
2670
2845
  try {
2671
- if (fs5.existsSync(this.commandsPath)) {
2672
- const data = fs5.readFileSync(this.commandsPath, "utf8");
2846
+ if (fs6.existsSync(this.commandsPath)) {
2847
+ const data = fs6.readFileSync(this.commandsPath, "utf8");
2673
2848
  if (data) {
2674
2849
  this.update(JSON.parse(data));
2675
2850
  }
@@ -2692,10 +2867,10 @@ var init_accessibility_scripts = __esm({
2692
2867
  }
2693
2868
  }
2694
2869
  store() {
2695
- if (!fs5.existsSync(this.browserstackFolderPath)) {
2696
- fs5.mkdirSync(this.browserstackFolderPath);
2870
+ if (!fs6.existsSync(this.browserstackFolderPath)) {
2871
+ fs6.mkdirSync(this.browserstackFolderPath);
2697
2872
  }
2698
- fs5.writeFileSync(this.commandsPath, JSON.stringify({
2873
+ fs6.writeFileSync(this.commandsPath, JSON.stringify({
2699
2874
  commands: this.commandsToWrap,
2700
2875
  scripts: {
2701
2876
  scan: this.performScan,
@@ -2714,10 +2889,10 @@ var init_accessibility_scripts = __esm({
2714
2889
  // src/util.ts
2715
2890
  import { hostname as hostname2, platform as platform3, type as type2, version as version2, arch as arch3, tmpdir } from "node:os";
2716
2891
  import crypto from "node:crypto";
2717
- import fs6 from "node:fs";
2892
+ import fs7 from "node:fs";
2718
2893
  import zlib from "node:zlib";
2719
2894
  import { format, promisify as promisify2 } from "node:util";
2720
- import path5 from "node:path";
2895
+ import path6 from "node:path";
2721
2896
  import util3 from "node:util";
2722
2897
  import gitRepoInfo from "git-repo-info";
2723
2898
  import gitconfig from "gitconfiglocal";
@@ -2758,7 +2933,7 @@ function getParentSuiteName(fullTitle, testSuiteTitle) {
2758
2933
  return parentSuiteName.trim();
2759
2934
  }
2760
2935
  function processError(error, fn, args) {
2761
- BStackLogger2.error(`Error in executing ${fn.name} with args ${args}: ${error}`);
2936
+ BStackLogger.error(`Error in executing ${fn.name} with args ${args}: ${error}`);
2762
2937
  let argsString;
2763
2938
  try {
2764
2939
  argsString = JSON.stringify(args);
@@ -2796,7 +2971,7 @@ async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout =
2796
2971
  clearTimeout(timeoutId);
2797
2972
  return await response.json();
2798
2973
  } catch (error) {
2799
- BStackLogger2.debug(`Error in firing request ${apiUrl}/${apiEndpoint}: ${format(error)}`);
2974
+ BStackLogger.debug(`Error in firing request ${apiUrl}/${apiEndpoint}: ${format(error)}`);
2800
2975
  const isLogUpload = apiEndpoint === UPLOAD_LOGS_ENDPOINT;
2801
2976
  if (error && error.response) {
2802
2977
  const errorMessageJson = error.response.body ? JSON.parse(error.response.body.toString()) : null;
@@ -2804,9 +2979,9 @@ async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout =
2804
2979
  if (errorMessage) {
2805
2980
  const message = `${errorMessage} - ${error.stack}`;
2806
2981
  if (isLogUpload) {
2807
- BStackLogger2.debug(message);
2982
+ BStackLogger.debug(message);
2808
2983
  } else {
2809
- BStackLogger2.error(message);
2984
+ BStackLogger.error(message);
2810
2985
  }
2811
2986
  }
2812
2987
  if (isLogUpload) {
@@ -2815,10 +2990,10 @@ async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout =
2815
2990
  throw error;
2816
2991
  } else {
2817
2992
  if (isLogUpload) {
2818
- BStackLogger2.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2993
+ BStackLogger.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2819
2994
  return;
2820
2995
  }
2821
- BStackLogger2.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2996
+ BStackLogger.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2822
2997
  throw error;
2823
2998
  }
2824
2999
  }
@@ -3238,9 +3413,9 @@ async function batchAndPostEvents(eventUrl, kind, data) {
3238
3413
  },
3239
3414
  body: JSON.stringify(data)
3240
3415
  });
3241
- BStackLogger2.debug(`[${kind}] Success response: ${JSON.stringify(await response.json())}`);
3416
+ BStackLogger.debug(`[${kind}] Success response: ${JSON.stringify(await response.json())}`);
3242
3417
  } catch (error) {
3243
- BStackLogger2.debug(`[${kind}] EXCEPTION IN ${kind} REQUEST TO TEST REPORTING AND ANALYTICS : ${error}`);
3418
+ BStackLogger.debug(`[${kind}] EXCEPTION IN ${kind} REQUEST TO TEST REPORTING AND ANALYTICS : ${error}`);
3244
3419
  throw new Error("Exception in request " + error);
3245
3420
  }
3246
3421
  }
@@ -3278,7 +3453,7 @@ function getObservabilityBuild(options, bstackBuildName) {
3278
3453
  if (options.testObservabilityOptions && options.testObservabilityOptions.buildName) {
3279
3454
  return options.testObservabilityOptions.buildName;
3280
3455
  }
3281
- return bstackBuildName || path5.basename(path5.resolve(process.cwd()));
3456
+ return bstackBuildName || path6.basename(path6.resolve(process.cwd()));
3282
3457
  }
3283
3458
  function getObservabilityBuildTags(options, bstackBuildTag) {
3284
3459
  if (process.env.TEST_OBSERVABILITY_BUILD_TAG) {
@@ -3364,26 +3539,26 @@ async function uploadLogs(user, key, clientBuildUuid) {
3364
3539
  if (!user || !key) {
3365
3540
  success = false;
3366
3541
  failure = "skipped: missing_credentials";
3367
- BStackLogger2.debug("Uploading logs failed due to no credentials");
3542
+ BStackLogger.debug("Uploading logs failed due to no credentials");
3368
3543
  return;
3369
3544
  }
3370
3545
  const tmpDir = tmpdir();
3371
- const tarPath = path5.join(tmpDir, "logs.tar");
3372
- const tarGzPath = path5.join(tmpDir, "logs.tar.gz");
3546
+ const tarPath = path6.join(tmpDir, "logs.tar");
3547
+ const tarGzPath = path6.join(tmpDir, "logs.tar.gz");
3373
3548
  const filesToArchive = [
3374
- BStackLogger2.logFilePath,
3549
+ BStackLogger.logFilePath,
3375
3550
  CLI_DEBUG_LOGS_FILE
3376
- ].filter((f) => fs6.existsSync(f));
3551
+ ].filter((f) => fs7.existsSync(f));
3377
3552
  const copiedFileNames = [];
3378
3553
  const archiveAddFailures = [];
3379
3554
  for (const f of filesToArchive) {
3380
3555
  try {
3381
- const dest = path5.join(tmpDir, path5.basename(f));
3382
- fs6.copyFileSync(f, dest);
3383
- copiedFileNames.push(path5.basename(f));
3556
+ const dest = path6.join(tmpDir, path6.basename(f));
3557
+ fs7.copyFileSync(f, dest);
3558
+ copiedFileNames.push(path6.basename(f));
3384
3559
  } catch (copyErr) {
3385
3560
  const msg = copyErr?.message || String(copyErr);
3386
- archiveAddFailures.push(`${path5.basename(f)}: ${msg}`);
3561
+ archiveAddFailures.push(`${path6.basename(f)}: ${msg}`);
3387
3562
  }
3388
3563
  }
3389
3564
  if (archiveAddFailures.length > 0 && failure === void 0) {
@@ -3400,15 +3575,15 @@ async function uploadLogs(user, key, clientBuildUuid) {
3400
3575
  copiedFileNames
3401
3576
  );
3402
3577
  await new Promise((resolve, reject) => {
3403
- const source = fs6.createReadStream(tarPath);
3404
- const dest = fs6.createWriteStream(tarGzPath);
3578
+ const source = fs7.createReadStream(tarPath);
3579
+ const dest = fs7.createWriteStream(tarGzPath);
3405
3580
  const gzip = zlib.createGzip({ level: 1 });
3406
3581
  source.pipe(gzip).pipe(dest);
3407
3582
  dest.on("finish", resolve);
3408
3583
  dest.on("error", reject);
3409
3584
  });
3410
3585
  const formData = new FormData();
3411
- const file = await fs6.openAsBlob(tarGzPath, { type: "application/x-gzip" });
3586
+ const file = await fs7.openAsBlob(tarGzPath, { type: "application/x-gzip" });
3412
3587
  formData.append("data", file, "logs.tar.gz");
3413
3588
  formData.append("clientBuildUuid", clientBuildUuid);
3414
3589
  const auth = Buffer.from(`${user}:${key}`).toString("base64");
@@ -3424,16 +3599,16 @@ async function uploadLogs(user, key, clientBuildUuid) {
3424
3599
  requestOptions,
3425
3600
  APIUtils.UPLOAD_LOGS_ADDRESS
3426
3601
  );
3427
- fs6.unlinkSync(tarPath);
3428
- fs6.unlinkSync(tarGzPath);
3602
+ fs7.unlinkSync(tarPath);
3603
+ fs7.unlinkSync(tarGzPath);
3429
3604
  for (const f of copiedFileNames) {
3430
- const filePath = path5.join(tmpDir, f);
3431
- if (fs6.existsSync(filePath)) {
3432
- fs6.unlinkSync(filePath);
3605
+ const filePath = path6.join(tmpDir, f);
3606
+ if (fs7.existsSync(filePath)) {
3607
+ fs7.unlinkSync(filePath);
3433
3608
  }
3434
3609
  }
3435
- if (fs6.existsSync(CLI_DEBUG_LOGS_FILE)) {
3436
- fs6.unlinkSync(CLI_DEBUG_LOGS_FILE);
3610
+ if (fs7.existsSync(CLI_DEBUG_LOGS_FILE)) {
3611
+ fs7.unlinkSync(CLI_DEBUG_LOGS_FILE);
3437
3612
  }
3438
3613
  if (!response) {
3439
3614
  success = false;
@@ -3446,7 +3621,7 @@ async function uploadLogs(user, key, clientBuildUuid) {
3446
3621
  } catch (error) {
3447
3622
  success = false;
3448
3623
  failure = `uploadLogs exception: ${getErrorString(error)}`;
3449
- BStackLogger2.error(`Error while uploading logs: ${getErrorString(error)}`);
3624
+ BStackLogger.error(`Error while uploading logs: ${getErrorString(error)}`);
3450
3625
  return null;
3451
3626
  } finally {
3452
3627
  PerformanceTester.end(eventName, success, failure);
@@ -3463,7 +3638,7 @@ function truncateString(field, truncateSizeInBytes) {
3463
3638
  return truncatedString;
3464
3639
  }
3465
3640
  } catch (error) {
3466
- BStackLogger2.debug(`Error while truncating field, nothing was truncated here: ${error}`);
3641
+ BStackLogger.debug(`Error while truncating field, nothing was truncated here: ${error}`);
3467
3642
  }
3468
3643
  return field;
3469
3644
  }
@@ -3472,7 +3647,7 @@ function getSizeOfJsonObjectInBytes(jsonData) {
3472
3647
  const buffer = Buffer.from(JSON.stringify(jsonData));
3473
3648
  return buffer.length;
3474
3649
  } catch (error) {
3475
- BStackLogger2.debug(`Something went wrong while calculating size of JSON object: ${error}`);
3650
+ BStackLogger.debug(`Something went wrong while calculating size of JSON object: ${error}`);
3476
3651
  }
3477
3652
  return -1;
3478
3653
  }
@@ -3482,7 +3657,7 @@ function checkAndTruncateVCSInfo(gitMetaData) {
3482
3657
  const truncateSize = gitMetaDataSizeInBytes - MAX_GIT_META_DATA_SIZE_IN_BYTES;
3483
3658
  const truncatedCommitMessage = truncateString(gitMetaData.commit_message, truncateSize);
3484
3659
  gitMetaData.commit_message = truncatedCommitMessage;
3485
- BStackLogger2.info(`The commit has been truncated. Size of commit after truncation is ${getSizeOfJsonObjectInBytes(gitMetaData) / 1024} KB`);
3660
+ BStackLogger.info(`The commit has been truncated. Size of commit after truncation is ${getSizeOfJsonObjectInBytes(gitMetaData) / 1024} KB`);
3486
3661
  }
3487
3662
  return gitMetaData;
3488
3663
  }
@@ -3494,7 +3669,7 @@ function getObservabilityProduct(options, isAppAutomate) {
3494
3669
  }
3495
3670
  async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()) {
3496
3671
  params.timestamp = Math.round(Date.now() / 1e3);
3497
- BStackLogger2.debug(`current timestamp ${params.timestamp}`);
3672
+ BStackLogger.debug(`current timestamp ${params.timestamp}`);
3498
3673
  try {
3499
3674
  const response = await makeGetRequest(url3, params, headers);
3500
3675
  const responseData = await response.json();
@@ -3506,9 +3681,9 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3506
3681
  } catch (error) {
3507
3682
  if (error.response && error.response.status === 404) {
3508
3683
  const nextPollTime = parseInt(error.response.headers.get("next_poll_time"), 10) * 1e3;
3509
- BStackLogger2.debug(`timeInMillis ${nextPollTime}`);
3684
+ BStackLogger.debug(`timeInMillis ${nextPollTime}`);
3510
3685
  if (isNaN(nextPollTime)) {
3511
- BStackLogger2.warn("Invalid or missing `nextPollTime` header. Stopping polling.");
3686
+ BStackLogger.warn("Invalid or missing `nextPollTime` header. Stopping polling.");
3512
3687
  return {
3513
3688
  data: {},
3514
3689
  headers: error.response.headers,
@@ -3516,18 +3691,18 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3516
3691
  };
3517
3692
  }
3518
3693
  const elapsedTime = nextPollTime - Date.now();
3519
- BStackLogger2.debug(
3694
+ BStackLogger.debug(
3520
3695
  `elapsedTime ${elapsedTime} timeInMillis ${nextPollTime} upperLimit ${upperLimit}`
3521
3696
  );
3522
3697
  if (nextPollTime > upperLimit) {
3523
- BStackLogger2.warn("Polling stopped due to upper time limit.");
3698
+ BStackLogger.warn("Polling stopped due to upper time limit.");
3524
3699
  return {
3525
3700
  data: {},
3526
3701
  headers: error.response.headers,
3527
3702
  message: "Polling stopped due to upper time limit."
3528
3703
  };
3529
3704
  }
3530
- BStackLogger2.debug(`Polling again in ${elapsedTime}ms with params:`, params);
3705
+ BStackLogger.debug(`Polling again in ${elapsedTime}ms with params:`, params);
3531
3706
  await new Promise((resolve) => setTimeout(resolve, elapsedTime));
3532
3707
  return pollApi(url3, params, headers, upperLimit, startTime);
3533
3708
  } else if (error.response) {
@@ -3536,7 +3711,7 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3536
3711
  const parsedError = JSON.parse(error.response.json());
3537
3712
  errorMessage = parsedError.message;
3538
3713
  } catch {
3539
- BStackLogger2.debug(`Error parsing pollApi request body ${error.response.body}`);
3714
+ BStackLogger.debug(`Error parsing pollApi request body ${error.response.body}`);
3540
3715
  errorMessage = "Unknown error";
3541
3716
  }
3542
3717
  throw {
@@ -3545,7 +3720,7 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3545
3720
  message: errorMessage
3546
3721
  };
3547
3722
  } else {
3548
- BStackLogger2.error(`Unexpected error occurred: ${error}`);
3723
+ BStackLogger.error(`Unexpected error occurred: ${error}`);
3549
3724
  return { data: {}, headers: {}, message: "Unexpected error occurred." };
3550
3725
  }
3551
3726
  }
@@ -3654,28 +3829,28 @@ function nestedKeyValue(hash, keys) {
3654
3829
  return keys.reduce((hash2, key) => isHash(hash2) ? hash2[key] : void 0, hash);
3655
3830
  }
3656
3831
  function removeDir(dir) {
3657
- const list = fs6.readdirSync(dir);
3832
+ const list = fs7.readdirSync(dir);
3658
3833
  for (let i = 0; i < list.length; i++) {
3659
- const filename = path5.join(dir, list[i]);
3660
- const stat = fs6.statSync(filename);
3834
+ const filename = path6.join(dir, list[i]);
3835
+ const stat = fs7.statSync(filename);
3661
3836
  if (filename === "." || filename === "..") {
3662
3837
  } else if (stat.isDirectory()) {
3663
3838
  removeDir(filename);
3664
3839
  } else {
3665
- fs6.unlinkSync(filename);
3840
+ fs7.unlinkSync(filename);
3666
3841
  }
3667
3842
  }
3668
- fs6.rmdirSync(dir);
3843
+ fs7.rmdirSync(dir);
3669
3844
  }
3670
3845
  function createDir(dir) {
3671
- if (fs6.existsSync(dir)) {
3846
+ if (fs7.existsSync(dir)) {
3672
3847
  removeDir(dir);
3673
3848
  }
3674
- fs6.mkdirSync(dir, { recursive: true });
3849
+ fs7.mkdirSync(dir, { recursive: true });
3675
3850
  }
3676
3851
  function isWritable(dirPath) {
3677
3852
  try {
3678
- fs6.accessSync(dirPath, fs6.constants.W_OK);
3853
+ fs7.accessSync(dirPath, fs7.constants.W_OK);
3679
3854
  return true;
3680
3855
  } catch {
3681
3856
  return false;
@@ -3683,10 +3858,10 @@ function isWritable(dirPath) {
3683
3858
  }
3684
3859
  function setReadWriteAccess(dirPath) {
3685
3860
  try {
3686
- fs6.chmodSync(dirPath, 438);
3687
- BStackLogger2.debug(`Directory ${dirPath} is now read/write accessible.`);
3861
+ fs7.chmodSync(dirPath, 438);
3862
+ BStackLogger.debug(`Directory ${dirPath} is now read/write accessible.`);
3688
3863
  } catch (err) {
3689
- BStackLogger2.error(`Failed to set directory access: ${err.stack}`);
3864
+ BStackLogger.error(`Failed to set directory access: ${err.stack}`);
3690
3865
  }
3691
3866
  }
3692
3867
  function getMochaTestHierarchy(test) {
@@ -3714,7 +3889,7 @@ function isMultiRemoteCaps(capabilities) {
3714
3889
  (cap) => Object.values(cap).length > 0 && Object.values(cap).every((c) => c !== null && typeof c === "object" && c.capabilities)
3715
3890
  );
3716
3891
  }
3717
- var pGitconfig, DEFAULT_REQUEST_CONFIG, COLORS, processTestObservabilityResponse, jsonifyAccessibilityArray, processAccessibilityResponse, processLaunchBuildResponse, launchTestSession, validateCapsWithAppA11y, validateCapsWithA11y, validateCapsWithNonBstackA11y, shouldScanTestForAccessibility, isAccessibilityAutomationSession, isAppAccessibilityAutomationSession, formatString, _getParamsForAppAccessibility, performA11yScan, getA11yResults, getAppA11yResults, getAppA11yResultsSummary, getAppA11yResultResponse, getA11yResultsSummary, stopBuildUpstream, patchConsoleLogs, sleep, isObject, ObjectsAreEqual, getPlatformVersion, getBasicAuthHeader, isObjectEmpty, getErrorString, hasBrowserName, isValidCapsForHealing, performO11ySync;
3892
+ var pGitconfig, DEFAULT_REQUEST_CONFIG, COLORS, processTestObservabilityResponse, jsonifyAccessibilityArray, processAccessibilityResponse, processLaunchBuildResponse, launchTestSession, validateCapsWithAppA11y, validateCapsWithA11y, validateCapsWithNonBstackA11y, shouldScanTestForAccessibility, isAccessibilityAutomationSession, isAppAccessibilityAutomationSession, formatString, _getParamsForAppAccessibility, performA11yScan, getA11yResults, getAppA11yResults, getAppA11yResultsSummary, getAppA11yResultResponse, getA11yResultsSummary, stopBuildUpstream, patchConsoleLogs, sleep, isObject, ObjectsAreEqual, getPlatformVersion, getResolvedDeviceName, getBasicAuthHeader, isObjectEmpty, getErrorString, hasBrowserName, isValidCapsForHealing, performO11ySync;
3718
3893
  var init_util = __esm({
3719
3894
  "src/util.ts"() {
3720
3895
  "use strict";
@@ -3788,7 +3963,7 @@ var init_util = __esm({
3788
3963
  };
3789
3964
  if (scannerVersion) {
3790
3965
  process.env.BSTACK_A11Y_SCANNER_VERSION = scannerVersion;
3791
- BStackLogger2.debug(`Accessibility scannerVersion ${scannerVersion}`);
3966
+ BStackLogger.debug(`Accessibility scannerVersion ${scannerVersion}`);
3792
3967
  }
3793
3968
  if (accessibilityToken) {
3794
3969
  process.env.BSTACK_A11Y_JWT = accessibilityToken;
@@ -3860,7 +4035,7 @@ var init_util = __esm({
3860
4035
  CrashReporter.userConfigForReporting = process.env.USER_CONFIG_FOR_REPORTING !== void 0 ? JSON.parse(process.env.USER_CONFIG_FOR_REPORTING) : {};
3861
4036
  }
3862
4037
  } catch (error) {
3863
- return BStackLogger2.error(`[Crash_Report_Upload] Failed to parse user config while sending build start event due to ${error}`);
4038
+ return BStackLogger.error(`[Crash_Report_Upload] Failed to parse user config while sending build start event due to ${error}`);
3864
4039
  }
3865
4040
  data.config = CrashReporter.userConfigForReporting;
3866
4041
  try {
@@ -3877,8 +4052,8 @@ var init_util = __esm({
3877
4052
  });
3878
4053
  const jsonResponse = await response.json();
3879
4054
  delete data?.accessibility?.settings?.includeEncodedExtension;
3880
- BStackLogger2.debug(`[Start_Build] Success response: ${JSON.stringify(jsonResponse)}`);
3881
- BStackLogger2.debug(`Test Plan Id sent in request: ${getTestPlanId(options)}`);
4055
+ BStackLogger.debug(`[Start_Build] Success response: ${JSON.stringify(jsonResponse)}`);
4056
+ BStackLogger.debug(`Test Plan Id sent in request: ${getTestPlanId(options)}`);
3882
4057
  process.env[TESTOPS_BUILD_COMPLETED_ENV] = "true";
3883
4058
  if (jsonResponse.jwt) {
3884
4059
  process.env[BROWSERSTACK_TESTHUB_JWT] = jsonResponse.jwt;
@@ -3886,13 +4061,13 @@ var init_util = __esm({
3886
4061
  if (jsonResponse.build_hashed_id) {
3887
4062
  process.env[BROWSERSTACK_TESTHUB_UUID] = jsonResponse.build_hashed_id;
3888
4063
  testOpsConfig_default.getInstance().buildHashedId = jsonResponse.build_hashed_id;
3889
- BStackLogger2.info(`Testhub started with id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
4064
+ BStackLogger.info(`Testhub started with id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
3890
4065
  }
3891
4066
  processLaunchBuildResponse(jsonResponse, options);
3892
4067
  launchBuildUsage.success();
3893
4068
  return jsonResponse;
3894
4069
  } catch (error) {
3895
- BStackLogger2.debug(`TestHub build start failed: ${format(error)}`);
4070
+ BStackLogger.debug(`TestHub build start failed: ${format(error)}`);
3896
4071
  if (!error.success) {
3897
4072
  launchBuildUsage.failed(error);
3898
4073
  logBuildError(error);
@@ -3902,7 +4077,7 @@ var init_util = __esm({
3902
4077
  }));
3903
4078
  validateCapsWithAppA11y = (platformMeta) => {
3904
4079
  if (platformMeta?.platform_name && String(platformMeta?.platform_name).toLowerCase() === "android" && (platformMeta?.platform_version && parseInt(platformMeta?.platform_version?.toString()) < 11)) {
3905
- BStackLogger2.warn("App Accessibility Automation tests are supported on OS version 11 and above for Android devices.");
4080
+ BStackLogger.warn("App Accessibility Automation tests are supported on OS version 11 and above for Android devices.");
3906
4081
  return false;
3907
4082
  }
3908
4083
  return true;
@@ -3910,38 +4085,79 @@ var init_util = __esm({
3910
4085
  validateCapsWithA11y = (deviceName, platformMeta, chromeOptions) => {
3911
4086
  try {
3912
4087
  if (deviceName) {
3913
- BStackLogger2.warn("Accessibility Automation will run only on Desktop browsers.");
3914
- return false;
3915
- }
3916
- if (platformMeta?.browser_name?.toLowerCase() !== "chrome") {
3917
- BStackLogger2.warn("Accessibility Automation will run only on Chrome browsers.");
4088
+ BStackLogger.warn("Accessibility Automation will run only on Desktop browsers.");
3918
4089
  return false;
3919
4090
  }
4091
+ const browserName = platformMeta?.browser_name?.toLowerCase();
3920
4092
  const browserVersion = platformMeta?.browser_version;
3921
- if (!isUndefined(browserVersion) && !(browserVersion === "latest" || parseFloat(browserVersion + "") > 94)) {
3922
- BStackLogger2.warn("Accessibility Automation will run only on Chrome browser version greater than 94.");
4093
+ const validBrowsers = SUPPORTED_BROWSERS_FOR_ACCESSIBILITY;
4094
+ if (!browserName || !validBrowsers.includes(browserName)) {
4095
+ BStackLogger.warn(`Accessibility Automation supports Chrome 95+, Chrome for Testing 141+, and Safari 18.4+. Current browser: ${browserName}`);
3923
4096
  return false;
3924
4097
  }
3925
- if (chromeOptions?.args?.includes("--headless")) {
3926
- BStackLogger2.warn("Accessibility Automation will not run on legacy headless mode. Switch to new headless mode or avoid using headless mode.");
3927
- return false;
4098
+ if (browserName === "chrome" || browserName === "chromefortesting") {
4099
+ const minVersion = MIN_BROWSER_VERSIONS_A11Y[browserName];
4100
+ if (browserVersion && browserVersion !== "latest") {
4101
+ const version3 = parseInt(browserVersion.toString().split(".")[0] || "0", 10);
4102
+ if (version3 < minVersion) {
4103
+ BStackLogger.warn(`Accessibility Automation requires ${browserName === "chrome" ? "Chrome" : "Chrome for Testing"} version ${minVersion} or higher.`);
4104
+ return false;
4105
+ }
4106
+ }
4107
+ if (chromeOptions?.args?.includes("--headless")) {
4108
+ BStackLogger.warn("Accessibility Automation will not run on legacy headless mode. Switch to new headless mode or avoid using headless mode.");
4109
+ return false;
4110
+ }
4111
+ }
4112
+ if (browserName === "safari") {
4113
+ if (browserVersion && browserVersion !== "latest") {
4114
+ const [currentMajor = 0, currentMinor = 0] = browserVersion.toString().split(".").map(Number);
4115
+ const [requiredMajor = 0, requiredMinor = 0] = MIN_BROWSER_VERSIONS_A11Y.safari.toString().split(".").map(Number);
4116
+ if (currentMajor < requiredMajor || currentMajor === requiredMajor && currentMinor < requiredMinor) {
4117
+ BStackLogger.warn(`Accessibility Automation requires Safari version ${MIN_BROWSER_VERSIONS_A11Y.safari} or higher.`);
4118
+ return false;
4119
+ }
4120
+ }
3928
4121
  }
3929
4122
  return true;
3930
4123
  } catch (error) {
3931
- BStackLogger2.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
4124
+ BStackLogger.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
3932
4125
  }
3933
4126
  return false;
3934
4127
  };
3935
4128
  validateCapsWithNonBstackA11y = (browserName, browserVersion) => {
3936
- if (browserName?.toLowerCase() !== "chrome") {
3937
- BStackLogger2.warn("Accessibility Automation will run only on Chrome browsers.");
3938
- return false;
3939
- }
3940
- if (!isUndefined(browserVersion) && !(browserVersion === "latest" || parseFloat(browserVersion + "") > 100)) {
3941
- BStackLogger2.warn("Accessibility Automation will run only on Chrome browser version greater than 100.");
3942
- return false;
4129
+ try {
4130
+ const browser = browserName?.toLowerCase();
4131
+ const validBrowsers = ["chrome", "chromefortesting", "safari"];
4132
+ if (!browser || !validBrowsers.includes(browser)) {
4133
+ BStackLogger.warn("Accessibility Automation on non-BrowserStack infrastructure supports Chrome 100+, Chrome for Testing 141+, and Safari 18.4+.");
4134
+ return false;
4135
+ }
4136
+ if (browser === "chrome" || browser === "chromefortesting") {
4137
+ const minVersion = MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK[browser];
4138
+ if (browserVersion && browserVersion !== "latest") {
4139
+ const version3 = parseInt(browserVersion.toString().split(".")[0] || "0", 10);
4140
+ if (version3 < minVersion) {
4141
+ BStackLogger.warn(`Accessibility Automation requires ${browser === "chrome" ? "Chrome" : "Chrome for Testing"} version ${minVersion}+ on non-BrowserStack infrastructure.`);
4142
+ return false;
4143
+ }
4144
+ }
4145
+ }
4146
+ if (browser === "safari") {
4147
+ if (browserVersion && browserVersion !== "latest") {
4148
+ const [currentMajor = 0, currentMinor = 0] = browserVersion.toString().split(".").map(Number);
4149
+ const [requiredMajor = 0, requiredMinor = 0] = MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK.safari.toString().split(".").map(Number);
4150
+ if (currentMajor < requiredMajor || currentMajor === requiredMajor && currentMinor < requiredMinor) {
4151
+ BStackLogger.warn(`Accessibility Automation requires Safari version ${MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK.safari}+ on non-BrowserStack infrastructure.`);
4152
+ return false;
4153
+ }
4154
+ }
4155
+ }
4156
+ return true;
4157
+ } catch (error) {
4158
+ BStackLogger.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
3943
4159
  }
3944
- return true;
4160
+ return false;
3945
4161
  };
3946
4162
  shouldScanTestForAccessibility = (suiteTitle, testTitle, accessibilityOptions, world, isCucumber) => {
3947
4163
  try {
@@ -3959,7 +4175,7 @@ var init_util = __esm({
3959
4175
  const included = includeTags?.length === 0 || includeTags?.some((include) => fullTestName.includes(include));
3960
4176
  return !excluded && included;
3961
4177
  } catch (error) {
3962
- BStackLogger2.debug(`Error while validating test case for accessibility before scanning. Error : ${error}`);
4178
+ BStackLogger.debug(`Error while validating test case for accessibility before scanning. Error : ${error}`);
3963
4179
  }
3964
4180
  return false;
3965
4181
  };
@@ -3968,7 +4184,7 @@ var init_util = __esm({
3968
4184
  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";
3969
4185
  return accessibilityFlag && hasA11yJwtToken;
3970
4186
  } catch (error) {
3971
- BStackLogger2.debug(`Exception in verifying the Accessibility session with error : ${error}`);
4187
+ BStackLogger.debug(`Exception in verifying the Accessibility session with error : ${error}`);
3972
4188
  }
3973
4189
  return false;
3974
4190
  };
@@ -3999,43 +4215,43 @@ var init_util = __esm({
3999
4215
  };
4000
4216
  performA11yScan = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, commandName, testName) => {
4001
4217
  if (!isAccessibilityAutomationSession(isAccessibility)) {
4002
- BStackLogger2.warn("Not an Accessibility Automation session, cannot perform Accessibility scan.");
4218
+ BStackLogger.warn("Not an Accessibility Automation session, cannot perform Accessibility scan.");
4003
4219
  return;
4004
4220
  }
4005
4221
  try {
4006
4222
  if (isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
4007
4223
  const results = await browser.execute(formatString(accessibility_scripts_default.performScan, JSON.stringify(_getParamsForAppAccessibility(commandName, testName))), {});
4008
- BStackLogger2.debug(util3.format(results));
4224
+ BStackLogger.debug(util3.format(results));
4009
4225
  return results;
4010
4226
  }
4011
4227
  if (accessibility_scripts_default.performScan) {
4012
4228
  const results = await executeAccessibilityScript(browser, accessibility_scripts_default.performScan, { method: commandName || "" });
4013
4229
  return results;
4014
4230
  }
4015
- BStackLogger2.error("AccessibilityScripts.performScan is null");
4231
+ BStackLogger.error("AccessibilityScripts.performScan is null");
4016
4232
  return;
4017
4233
  } catch (err) {
4018
- BStackLogger2.error("Accessibility Scan could not be performed : " + err);
4234
+ BStackLogger.error("Accessibility Scan could not be performed : " + err);
4019
4235
  return;
4020
4236
  }
4021
4237
  };
4022
4238
  getA11yResults = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
4023
4239
  if (!isAccessibilityAutomationSession(isAccessibility)) {
4024
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results.");
4240
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results.");
4025
4241
  return [];
4026
4242
  }
4027
4243
  try {
4028
- BStackLogger2.debug("Performing scan before getting results");
4244
+ BStackLogger.debug("Performing scan before getting results");
4029
4245
  await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
4030
4246
  if (accessibility_scripts_default.getResults) {
4031
4247
  const results = await executeAccessibilityScript(browser, accessibility_scripts_default.getResults);
4032
4248
  return results;
4033
4249
  }
4034
- BStackLogger2.error("AccessibilityScripts.getResults is null");
4250
+ BStackLogger.error("AccessibilityScripts.getResults is null");
4035
4251
  return [];
4036
4252
  } catch (error) {
4037
- BStackLogger2.error("No accessibility results were found.");
4038
- BStackLogger2.debug(`getA11yResults Failed. Error: ${error}`);
4253
+ BStackLogger.error("No accessibility results were found.");
4254
+ BStackLogger.debug(`getA11yResults Failed. Error: ${error}`);
4039
4255
  return [];
4040
4256
  }
4041
4257
  });
@@ -4044,18 +4260,18 @@ var init_util = __esm({
4044
4260
  return [];
4045
4261
  }
4046
4262
  if (!isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
4047
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4263
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4048
4264
  return [];
4049
4265
  }
4050
4266
  try {
4051
4267
  const apiUrl = `${APIUtils.APP_ALLY_ENDPOINT}/${APP_ALLY_ISSUES_ENDPOINT}`;
4052
4268
  const apiRespone = await getAppA11yResultResponse(apiUrl, isAppAutomate, browser, testName, isBrowserStackSession, isAccessibility, sessionId);
4053
4269
  const result = apiRespone?.data?.data?.issues;
4054
- BStackLogger2.debug(`Polling Result: ${JSON.stringify(result)}`);
4270
+ BStackLogger.debug(`Polling Result: ${JSON.stringify(result)}`);
4055
4271
  return result;
4056
4272
  } catch (error) {
4057
- BStackLogger2.error("No accessibility summary was found.");
4058
- BStackLogger2.debug(`getAppA11yResults Failed. Error: ${error}`);
4273
+ BStackLogger.error("No accessibility summary was found.");
4274
+ BStackLogger.debug(`getAppA11yResults Failed. Error: ${error}`);
4059
4275
  return [];
4060
4276
  }
4061
4277
  });
@@ -4064,46 +4280,46 @@ var init_util = __esm({
4064
4280
  return {};
4065
4281
  }
4066
4282
  if (!isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
4067
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4283
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4068
4284
  return {};
4069
4285
  }
4070
4286
  try {
4071
4287
  const apiUrl = `${APIUtils.APP_ALLY_ENDPOINT}/${APP_ALLY_ISSUES_SUMMARY_ENDPOINT}`;
4072
4288
  const apiRespone = await getAppA11yResultResponse(apiUrl, isAppAutomate, browser, testName, isBrowserStackSession, isAccessibility, sessionId);
4073
4289
  const result = apiRespone?.data?.data?.summary;
4074
- BStackLogger2.debug(`Polling Result: ${JSON.stringify(result)}`);
4290
+ BStackLogger.debug(`Polling Result: ${JSON.stringify(result)}`);
4075
4291
  return result;
4076
4292
  } catch {
4077
- BStackLogger2.error("No accessibility summary was found.");
4293
+ BStackLogger.error("No accessibility summary was found.");
4078
4294
  return {};
4079
4295
  }
4080
4296
  });
4081
4297
  getAppA11yResultResponse = async (apiUrl, isAppAutomate, browser, testName, isBrowserStackSession, isAccessibility, sessionId) => {
4082
- BStackLogger2.debug("Performing scan before getting results summary");
4298
+ BStackLogger.debug("Performing scan before getting results summary");
4083
4299
  await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility, void 0, testName);
4084
4300
  const upperTimeLimit = process.env.BSTACK_A11Y_POLLING_TIMEOUT ? Date.now() + parseInt(process.env.BSTACK_A11Y_POLLING_TIMEOUT) * 1e3 : Date.now() + 3e4;
4085
4301
  const params = { test_run_uuid: process.env.TEST_ANALYTICS_ID, session_id: sessionId, timestamp: Date.now() };
4086
4302
  const header = { Authorization: `Bearer ${process.env.BSTACK_A11Y_JWT}` };
4087
4303
  const apiRespone = await pollApi(apiUrl, params, header, upperTimeLimit);
4088
- BStackLogger2.debug(`Polling Result: ${JSON.stringify(apiRespone)}`);
4304
+ BStackLogger.debug(`Polling Result: ${JSON.stringify(apiRespone)}`);
4089
4305
  return apiRespone;
4090
4306
  };
4091
4307
  getA11yResultsSummary = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS_SUMMARY, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
4092
4308
  if (!isAccessibilityAutomationSession(isAccessibility)) {
4093
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4309
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4094
4310
  return {};
4095
4311
  }
4096
4312
  try {
4097
- BStackLogger2.debug("Performing scan before getting results summary");
4313
+ BStackLogger.debug("Performing scan before getting results summary");
4098
4314
  await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
4099
4315
  if (accessibility_scripts_default.getResultsSummary) {
4100
4316
  const summaryResults = await executeAccessibilityScript(browser, accessibility_scripts_default.getResultsSummary);
4101
4317
  return summaryResults;
4102
4318
  }
4103
- BStackLogger2.error("AccessibilityScripts.getResultsSummary is null");
4319
+ BStackLogger.error("AccessibilityScripts.getResultsSummary is null");
4104
4320
  return {};
4105
4321
  } catch {
4106
- BStackLogger2.error("No accessibility summary was found.");
4322
+ BStackLogger.error("No accessibility summary was found.");
4107
4323
  return {};
4108
4324
  }
4109
4325
  });
@@ -4119,7 +4335,7 @@ var init_util = __esm({
4119
4335
  }
4120
4336
  if (!process.env[BROWSERSTACK_TESTHUB_JWT]) {
4121
4337
  stopBuildUsage.failed("Token/buildID is undefined, build creation might have failed");
4122
- BStackLogger2.debug("[STOP_BUILD] Missing Authentication Token/ Build ID");
4338
+ BStackLogger.debug("[STOP_BUILD] Missing Authentication Token/ Build ID");
4123
4339
  return {
4124
4340
  status: "error",
4125
4341
  message: "Token/buildID is undefined, build creation might have failed"
@@ -4138,7 +4354,7 @@ var init_util = __esm({
4138
4354
  },
4139
4355
  body: JSON.stringify(data)
4140
4356
  });
4141
- BStackLogger2.debug(`[STOP_BUILD] Success response: ${await response.text()}`);
4357
+ BStackLogger.debug(`[STOP_BUILD] Success response: ${await response.text()}`);
4142
4358
  stopBuildUsage.success();
4143
4359
  return {
4144
4360
  status: "success",
@@ -4146,7 +4362,7 @@ var init_util = __esm({
4146
4362
  };
4147
4363
  } catch (error) {
4148
4364
  stopBuildUsage.failed(error);
4149
- BStackLogger2.debug(`[STOP_BUILD] Failed. Error: ${error}`);
4365
+ BStackLogger.debug(`[STOP_BUILD] Failed. Error: ${error}`);
4150
4366
  return {
4151
4367
  status: "error",
4152
4368
  message: error.message
@@ -4157,7 +4373,7 @@ var init_util = __esm({
4157
4373
  const BSTestOpsPatcher = new logPatcher_default({});
4158
4374
  Object.keys(consoleHolder).forEach((method) => {
4159
4375
  if (!(method in console) || method === "Console" || typeof console[method] !== "function") {
4160
- BStackLogger2.debug(`Skipping method: ${method}, exists: ${method in console}, type: ${typeof console[method]}`);
4376
+ BStackLogger.debug(`Skipping method: ${method}, exists: ${method in console}, type: ${typeof console[method]}`);
4161
4377
  return;
4162
4378
  }
4163
4379
  const origMethod = console[method].bind(console);
@@ -4170,7 +4386,7 @@ var init_util = __esm({
4170
4386
  BSTestOpsPatcher[method](...args);
4171
4387
  }
4172
4388
  } catch (error) {
4173
- BStackLogger2.debug(`Error while patching console logs : ${error}`);
4389
+ BStackLogger.debug(`Error while patching console logs : ${error}`);
4174
4390
  origMethod(...args);
4175
4391
  }
4176
4392
  };
@@ -4204,18 +4420,57 @@ var init_util = __esm({
4204
4420
  const keys = ["platformVersion", "platform_version", "osVersion", "os_version"];
4205
4421
  for (const key of keys) {
4206
4422
  if (caps?.[key]) {
4207
- BStackLogger2.debug(`Got ${key} from driver caps`);
4423
+ BStackLogger.debug(`Got ${key} from driver caps`);
4208
4424
  return String(caps?.[key]);
4209
4425
  } else if (bstackOptions && bstackOptions?.[key]) {
4210
- BStackLogger2.debug(`Got ${key} from user bstack options`);
4426
+ BStackLogger.debug(`Got ${key} from user bstack options`);
4211
4427
  return String(bstackOptions?.[key]);
4212
4428
  } else if (userCaps[key]) {
4213
- BStackLogger2.debug(`Got ${key} from user caps`);
4429
+ BStackLogger.debug(`Got ${key} from user caps`);
4214
4430
  return String(userCaps[key]);
4215
4431
  }
4216
4432
  }
4217
4433
  return void 0;
4218
4434
  });
4435
+ getResolvedDeviceName = o11yErrorHandler(function getResolvedDeviceName2(driverCaps, requestedCaps) {
4436
+ const flattenMultiremote = (caps) => {
4437
+ if (!caps) {
4438
+ return [];
4439
+ }
4440
+ const obj = caps;
4441
+ if (obj["deviceModel"] || obj["appium:deviceModel"] || obj["deviceName"] || obj["bstack:options"]) {
4442
+ return [caps];
4443
+ }
4444
+ return Object.values(obj).filter((v) => v !== null && typeof v === "object" && "capabilities" in v).map((v) => v.capabilities).filter(Boolean);
4445
+ };
4446
+ const sources = [
4447
+ ...flattenMultiremote(driverCaps),
4448
+ ...flattenMultiremote(requestedCaps)
4449
+ ];
4450
+ if (!sources.length) {
4451
+ return void 0;
4452
+ }
4453
+ const pickString = (obj, key) => {
4454
+ const v = obj?.[key];
4455
+ return typeof v === "string" && v.length > 0 ? v : void 0;
4456
+ };
4457
+ const paths = [
4458
+ (c) => pickString(c, "deviceModel"),
4459
+ (c) => pickString(c, "appium:deviceModel"),
4460
+ (c) => pickString(c["bstack:options"], "deviceName"),
4461
+ (c) => pickString(c, "appium:deviceName"),
4462
+ (c) => pickString(c, "deviceName")
4463
+ ];
4464
+ for (const path22 of paths) {
4465
+ for (const src of sources) {
4466
+ const v = path22(src);
4467
+ if (v) {
4468
+ return v;
4469
+ }
4470
+ }
4471
+ }
4472
+ return void 0;
4473
+ });
4219
4474
  getBasicAuthHeader = (username, password) => {
4220
4475
  const encodedAuth = Buffer.from(`${username}:${password}`, "utf8").toString("base64");
4221
4476
  return `Basic ${encodedAuth}`;
@@ -4259,20 +4514,20 @@ var init_util = __esm({
4259
4514
  });
4260
4515
 
4261
4516
  // src/bstackLogger.ts
4262
- import path6 from "node:path";
4263
- import fs7 from "node:fs";
4517
+ import path7 from "node:path";
4518
+ import fs8 from "node:fs";
4264
4519
  import chalk2 from "chalk";
4265
4520
  import logger2 from "@wdio/logger";
4266
- var log2, BStackLogger2;
4521
+ var log2, BStackLogger;
4267
4522
  var init_bstackLogger = __esm({
4268
4523
  "src/bstackLogger.ts"() {
4269
4524
  "use strict";
4270
4525
  init_constants();
4271
4526
  init_util();
4272
4527
  log2 = logger2("@wdio/browserstack-service");
4273
- BStackLogger2 = class {
4274
- static logFilePath = path6.join(process.cwd(), LOGS_FILE);
4275
- static logFolderPath = path6.join(process.cwd(), "logs");
4528
+ BStackLogger = class {
4529
+ static logFilePath = path7.join(process.cwd(), LOGS_FILE);
4530
+ static logFolderPath = path7.join(process.cwd(), "logs");
4276
4531
  static logFileStream;
4277
4532
  static redactCredentials(logMessage) {
4278
4533
  return logMessage.replace(/(["']?(?:username|userName|accesskey|accessKey|user|key)["']?\s*[:=]\s*["']?)([^"'\s,}]+)/gi, "$1").replace(/([?&](?:username|userName|access_key|accesskey|accessKey|user|key)=)([^&#\s]+)/gi, "$1");
@@ -4282,7 +4537,7 @@ var init_bstackLogger = __esm({
4282
4537
  const redactedMessage = this.redactCredentials(logMessage);
4283
4538
  if (!this.logFileStream) {
4284
4539
  this.ensureLogsFolder();
4285
- this.logFileStream = fs7.createWriteStream(this.logFilePath, { flags: "a" });
4540
+ this.logFileStream = fs8.createWriteStream(this.logFilePath, { flags: "a" });
4286
4541
  }
4287
4542
  if (this.logFileStream && this.logFileStream.writable) {
4288
4543
  this.logFileStream.write(this.formatLog(redactedMessage, logLevel));
@@ -4331,13 +4586,13 @@ var init_bstackLogger = __esm({
4331
4586
  this.logFileStream = null;
4332
4587
  }
4333
4588
  static clearLogFile() {
4334
- if (fs7.existsSync(this.logFilePath)) {
4335
- fs7.truncateSync(this.logFilePath);
4589
+ if (fs8.existsSync(this.logFilePath)) {
4590
+ fs8.truncateSync(this.logFilePath);
4336
4591
  }
4337
4592
  }
4338
4593
  static ensureLogsFolder() {
4339
- if (!fs7.existsSync(this.logFolderPath)) {
4340
- fs7.mkdirSync(this.logFolderPath);
4594
+ if (!fs8.existsSync(this.logFolderPath)) {
4595
+ fs8.mkdirSync(this.logFolderPath);
4341
4596
  }
4342
4597
  }
4343
4598
  };
@@ -4355,7 +4610,7 @@ var init_utils = __esm({
4355
4610
  getProductMap = (config) => {
4356
4611
  const entries = [
4357
4612
  ["observability", config.testObservability.enabled],
4358
- ["accessibility", config.accessibility],
4613
+ ["accessibility", !!config.accessibility],
4359
4614
  ["percy", config.percy],
4360
4615
  ["automate", config.automate],
4361
4616
  ["app_automate", config.appAutomate]
@@ -4384,7 +4639,7 @@ var init_utils = __esm({
4384
4639
  };
4385
4640
  logBuildError = (error, product = "") => {
4386
4641
  if (!error || !error.errors) {
4387
- BStackLogger2.error(`${product.toUpperCase()} Build creation failed ${error}`);
4642
+ BStackLogger.error(`${product.toUpperCase()} Build creation failed ${error}`);
4388
4643
  return;
4389
4644
  }
4390
4645
  for (const errorJson of error.errors) {
@@ -4393,16 +4648,16 @@ var init_utils = __esm({
4393
4648
  if (errorMessage) {
4394
4649
  switch (errorType) {
4395
4650
  case "ERROR_INVALID_CREDENTIALS":
4396
- BStackLogger2.error(errorMessage);
4651
+ BStackLogger.error(errorMessage);
4397
4652
  break;
4398
4653
  case "ERROR_ACCESS_DENIED":
4399
- BStackLogger2.info(errorMessage);
4654
+ BStackLogger.info(errorMessage);
4400
4655
  break;
4401
4656
  case "ERROR_SDK_DEPRECATED":
4402
- BStackLogger2.error(errorMessage);
4657
+ BStackLogger.error(errorMessage);
4403
4658
  break;
4404
4659
  default:
4405
- BStackLogger2.error(errorMessage);
4660
+ BStackLogger.error(errorMessage);
4406
4661
  }
4407
4662
  }
4408
4663
  }
@@ -4421,8 +4676,8 @@ var init_utils = __esm({
4421
4676
  });
4422
4677
 
4423
4678
  // src/Percy/PercyLogger.ts
4424
- import path7 from "node:path";
4425
- import fs8 from "node:fs";
4679
+ import path8 from "node:path";
4680
+ import fs9 from "node:fs";
4426
4681
  import chalk3 from "chalk";
4427
4682
  import logger3 from "@wdio/logger";
4428
4683
  var log3, PercyLogger;
@@ -4433,16 +4688,16 @@ var init_PercyLogger = __esm({
4433
4688
  init_util();
4434
4689
  log3 = logger3("@wdio/browserstack-service");
4435
4690
  PercyLogger = class {
4436
- static logFilePath = path7.join(process.cwd(), PERCY_LOGS_FILE);
4437
- static logFolderPath = path7.join(process.cwd(), "logs");
4691
+ static logFilePath = path8.join(process.cwd(), PERCY_LOGS_FILE);
4692
+ static logFolderPath = path8.join(process.cwd(), "logs");
4438
4693
  static logFileStream;
4439
4694
  static logToFile(logMessage, logLevel) {
4440
4695
  try {
4441
4696
  if (!this.logFileStream) {
4442
- if (!fs8.existsSync(this.logFolderPath)) {
4443
- fs8.mkdirSync(this.logFolderPath);
4697
+ if (!fs9.existsSync(this.logFolderPath)) {
4698
+ fs9.mkdirSync(this.logFolderPath);
4444
4699
  }
4445
- this.logFileStream = fs8.createWriteStream(this.logFilePath, { flags: "a" });
4700
+ this.logFileStream = fs9.createWriteStream(this.logFilePath, { flags: "a" });
4446
4701
  }
4447
4702
  if (this.logFileStream && this.logFileStream.writable) {
4448
4703
  this.logFileStream.write(this.formatLog(logMessage, logLevel));
@@ -4486,8 +4741,8 @@ var init_PercyLogger = __esm({
4486
4741
  this.logFileStream = null;
4487
4742
  }
4488
4743
  static clearLogFile() {
4489
- if (fs8.existsSync(this.logFilePath)) {
4490
- fs8.truncateSync(this.logFilePath);
4744
+ if (fs9.existsSync(this.logFilePath)) {
4745
+ fs9.truncateSync(this.logFilePath);
4491
4746
  }
4492
4747
  }
4493
4748
  };
@@ -4495,7 +4750,7 @@ var init_PercyLogger = __esm({
4495
4750
  });
4496
4751
 
4497
4752
  // src/cli/grpcClient.ts
4498
- import path12 from "node:path";
4753
+ import path13 from "node:path";
4499
4754
  import util5, { promisify as promisify3 } from "node:util";
4500
4755
  import {
4501
4756
  SDKClient,
@@ -4528,7 +4783,7 @@ var init_grpcClient = __esm({
4528
4783
  listenAddress;
4529
4784
  channel = null;
4530
4785
  client = null;
4531
- logger = BStackLogger;
4786
+ logger = BStackLogger2;
4532
4787
  constructor() {
4533
4788
  }
4534
4789
  /**
@@ -4620,7 +4875,7 @@ var init_grpcClient = __esm({
4620
4875
  sdkLanguage: CLIUtils.getSdkLanguage(),
4621
4876
  sdkVersion: packageVersion,
4622
4877
  pathProject: process.cwd(),
4623
- pathConfig: path12.resolve(process.cwd(), "browserstack.yml"),
4878
+ pathConfig: path13.resolve(process.cwd(), "browserstack.yml"),
4624
4879
  cliArgs: process.argv.slice(2),
4625
4880
  frameworks: [automationFrameworkDetail.name, testFrameworkDetail.name],
4626
4881
  frameworkVersions,
@@ -5066,7 +5321,7 @@ var init_baseModule = __esm({
5066
5321
  this.platformIndex = platformIndex;
5067
5322
  this.client = client;
5068
5323
  this.config = config;
5069
- BStackLogger.debug(`Configured module ${this.getModuleName()} with binSessionId=${binSessionId}, platformIndex=${platformIndex}`);
5324
+ BStackLogger2.debug(`Configured module ${this.getModuleName()} with binSessionId=${binSessionId}, platformIndex=${platformIndex}`);
5070
5325
  }
5071
5326
  };
5072
5327
  }
@@ -5337,7 +5592,7 @@ var init_testFramework = __esm({
5337
5592
  * @returns {void}
5338
5593
  */
5339
5594
  trackEvent(testFrameworkState, hookState, args = {}) {
5340
- BStackLogger.info(`trackEvent: testFrameworkState=${testFrameworkState}; hookState=${hookState}; args=${args}`);
5595
+ BStackLogger2.info(`trackEvent: testFrameworkState=${testFrameworkState}; hookState=${hookState}; args=${args}`);
5341
5596
  }
5342
5597
  /**
5343
5598
  * run test hooks
@@ -5347,7 +5602,7 @@ var init_testFramework = __esm({
5347
5602
  * @param {*} args
5348
5603
  */
5349
5604
  async runHooks(instance, testFrameworkState, hookState, args = {}) {
5350
- BStackLogger.info(`runHooks: instance=${instance} automationFrameworkState=${testFrameworkState} hookState=${hookState}`);
5605
+ BStackLogger2.info(`runHooks: instance=${instance} automationFrameworkState=${testFrameworkState} hookState=${hookState}`);
5351
5606
  const hookRegistryKey = CLIUtils.getHookRegistryKey(testFrameworkState, hookState);
5352
5607
  await eventDispatcher.notifyObserver(hookRegistryKey, args);
5353
5608
  }
@@ -5611,7 +5866,7 @@ var init_automationFramework = __esm({
5611
5866
  * @returns {void}
5612
5867
  */
5613
5868
  async trackEvent(automationFrameworkState, hookState, args = {}) {
5614
- BStackLogger.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState} args=${args}`);
5869
+ BStackLogger2.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState} args=${args}`);
5615
5870
  }
5616
5871
  /**
5617
5872
  *
@@ -5621,7 +5876,7 @@ var init_automationFramework = __esm({
5621
5876
  * @param {*} args
5622
5877
  */
5623
5878
  async runHooks(instance, automationFrameworkState, hookState, args = {}) {
5624
- BStackLogger.info(`runHooks: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
5879
+ BStackLogger2.info(`runHooks: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
5625
5880
  const hookRegistryKey = CLIUtils.getHookRegistryKey(automationFrameworkState, hookState);
5626
5881
  await eventDispatcher.notifyObserver(hookRegistryKey, args);
5627
5882
  }
@@ -5639,7 +5894,7 @@ var init_automationFramework = __esm({
5639
5894
  * @returns {void}
5640
5895
  */
5641
5896
  static setTrackedInstance(context, instance) {
5642
- BStackLogger.debug(`setTrackedInstance: ${context.getId()}`);
5897
+ BStackLogger2.debug(`setTrackedInstance: ${context.getId()}`);
5643
5898
  _AutomationFramework.instances.set(context.getId(), instance);
5644
5899
  }
5645
5900
  /**
@@ -5647,7 +5902,7 @@ var init_automationFramework = __esm({
5647
5902
  * @returns {TrackedInstance} The tracked instance
5648
5903
  */
5649
5904
  static getTrackedInstance() {
5650
- BStackLogger.debug(`getTrackedInstance: ${CLIUtils.getCurrentInstanceName()}`);
5905
+ BStackLogger2.debug(`getTrackedInstance: ${CLIUtils.getCurrentInstanceName()}`);
5651
5906
  const context = TrackedInstance.createContext(CLIUtils.getCurrentInstanceName());
5652
5907
  return _AutomationFramework.instances.get(context.getId());
5653
5908
  }
@@ -5775,7 +6030,7 @@ var init_automateModule = __esm({
5775
6030
  init_automationFrameworkState();
5776
6031
  init_fetchWrapper();
5777
6032
  AutomateModule = class _AutomateModule extends BaseModule {
5778
- logger = BStackLogger;
6033
+ logger = BStackLogger2;
5779
6034
  browserStackConfig;
5780
6035
  sessionMap = /* @__PURE__ */ new Map();
5781
6036
  static MODULE_NAME = "AutomateModule";
@@ -6091,7 +6346,7 @@ var init_testFrameworkInstance = __esm({
6091
6346
 
6092
6347
  // src/cli/frameworks/wdioMochaTestFramework.ts
6093
6348
  import { v4 as uuidv42 } from "uuid";
6094
- import path13 from "node:path";
6349
+ import path14 from "node:path";
6095
6350
  var WdioMochaTestFramework;
6096
6351
  var init_wdioMochaTestFramework = __esm({
6097
6352
  "src/cli/frameworks/wdioMochaTestFramework.ts"() {
@@ -6125,11 +6380,11 @@ var init_wdioMochaTestFramework = __esm({
6125
6380
  * @param {*} args
6126
6381
  */
6127
6382
  async trackEvent(testFrameworkState, hookState, args = {}) {
6128
- BStackLogger.info(`trackEvent: testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6383
+ BStackLogger2.info(`trackEvent: testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6129
6384
  await super.trackEvent(testFrameworkState, hookState, args);
6130
6385
  const instance = this.resolveInstance(testFrameworkState, hookState, args);
6131
6386
  if (instance === null) {
6132
- BStackLogger.error(`trackEvent: instance not found for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6387
+ BStackLogger2.error(`trackEvent: instance not found for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6133
6388
  return;
6134
6389
  }
6135
6390
  try {
@@ -6141,7 +6396,7 @@ var init_wdioMochaTestFramework = __esm({
6141
6396
  if (!TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_ID) && hookState === HookState.PRE && testFrameworkState === TestFrameworkState.TEST) {
6142
6397
  const test = args.test;
6143
6398
  const testData = await this.getTestData(instance, test);
6144
- BStackLogger.info(`trackEvent: instanceData=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6399
+ BStackLogger2.info(`trackEvent: instanceData=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6145
6400
  instance.updateMultipleEntries(testData);
6146
6401
  }
6147
6402
  if (testFrameworkState === TestFrameworkState.TEST) {
@@ -6159,13 +6414,13 @@ var init_wdioMochaTestFramework = __esm({
6159
6414
  logEntry.uuid = TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOK_ID);
6160
6415
  this.loadLogEntries(instance, testFrameworkState, hookState, logEntry);
6161
6416
  } else if (testFrameworkState === TestFrameworkState.LOG_REPORT && hookState === HookState.POST) {
6162
- BStackLogger.info("trackEvent: load test results");
6417
+ BStackLogger2.info("trackEvent: load test results");
6163
6418
  this.loadTestResult(instance, args);
6164
6419
  }
6165
6420
  await this.trackHookEvents(instance, testFrameworkState, hookState, args);
6166
- BStackLogger.debug(`trackEvent: tracked instance data=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6421
+ BStackLogger2.debug(`trackEvent: tracked instance data=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6167
6422
  } catch (error) {
6168
- BStackLogger.error(`trackEvent: Error in tracking events: ${error} hookState=${hookState} testFrameworkState=${testFrameworkState}`);
6423
+ BStackLogger2.error(`trackEvent: Error in tracking events: ${error} hookState=${hookState} testFrameworkState=${testFrameworkState}`);
6169
6424
  }
6170
6425
  args.instance = instance;
6171
6426
  await this.runHooks(instance, testFrameworkState, hookState, args);
@@ -6179,7 +6434,7 @@ var init_wdioMochaTestFramework = __esm({
6179
6434
  */
6180
6435
  resolveInstance(testFrameworkState, hookState, args = {}) {
6181
6436
  let instance = null;
6182
- BStackLogger.info(`resolveInstance: resolving instance for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6437
+ BStackLogger2.info(`resolveInstance: resolving instance for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6183
6438
  if (testFrameworkState === TestFrameworkState.INIT_TEST || testFrameworkState === TestFrameworkState.NONE) {
6184
6439
  this.trackWdioMochaInstance(testFrameworkState, args);
6185
6440
  }
@@ -6196,7 +6451,7 @@ var init_wdioMochaTestFramework = __esm({
6196
6451
  const target = CLIUtils.getCurrentInstanceName();
6197
6452
  const trackedContext = TrackedInstance.createContext(target);
6198
6453
  let instance = null;
6199
- BStackLogger.info(`trackWdioMochaInstance: created instance for target=${target}, state=${testFrameworkState}, args=${args}`);
6454
+ BStackLogger2.info(`trackWdioMochaInstance: created instance for target=${target}, state=${testFrameworkState}, args=${args}`);
6200
6455
  instance = new TestFrameworkInstance(
6201
6456
  trackedContext,
6202
6457
  this.getTestFrameworks(),
@@ -6219,7 +6474,7 @@ var init_wdioMochaTestFramework = __esm({
6219
6474
  process.env[TEST_ANALYTICS_ID] = instanceEntries[TestFrameworkConstants.KEY_TEST_UUID];
6220
6475
  instance.updateMultipleEntries(instanceEntries);
6221
6476
  TestFramework.setTrackedInstance(trackedContext, instance);
6222
- BStackLogger.info(`trackWdioMochaInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
6477
+ BStackLogger2.info(`trackWdioMochaInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
6223
6478
  }
6224
6479
  async getTestData(instance, test) {
6225
6480
  const framework = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_FRAMEWORK_NAME);
@@ -6230,8 +6485,8 @@ var init_wdioMochaTestFramework = __esm({
6230
6485
  [TestFrameworkConstants.KEY_TEST_ID]: getUniqueIdentifier(test, framework),
6231
6486
  [TestFrameworkConstants.KEY_TEST_NAME]: test.title || test.description,
6232
6487
  [TestFrameworkConstants.KEY_TEST_CODE]: test.body || "",
6233
- [TestFrameworkConstants.KEY_TEST_FILE_PATH]: gitConfig?.root && filename ? path13.relative(gitConfig.root, filename) : void 0,
6234
- [TestFrameworkConstants.KEY_TEST_LOCATION]: filename ? path13.relative(process.cwd(), filename) : void 0,
6488
+ [TestFrameworkConstants.KEY_TEST_FILE_PATH]: gitConfig?.root && filename ? path14.relative(gitConfig.root, filename) : void 0,
6489
+ [TestFrameworkConstants.KEY_TEST_LOCATION]: filename ? path14.relative(process.cwd(), filename) : void 0,
6235
6490
  [TestFrameworkConstants.KEY_TEST_SCOPE]: fullTitle,
6236
6491
  [TestFrameworkConstants.KEY_TEST_SCOPES]: getMochaTestHierarchy(test)
6237
6492
  };
@@ -6284,7 +6539,7 @@ var init_wdioMochaTestFramework = __esm({
6284
6539
  if (lastActiveHook) {
6285
6540
  const hookLogs = lastActiveHook[TestFrameworkConstants.KEY_HOOK_LOGS];
6286
6541
  hookLogs.push(logRecord);
6287
- BStackLogger.debug(`hooks after update logs ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_STARTED)} ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_FINISHED)}`);
6542
+ BStackLogger2.debug(`hooks after update logs ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_STARTED)} ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_FINISHED)}`);
6288
6543
  return;
6289
6544
  }
6290
6545
  const entries = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_LOGS);
@@ -6385,15 +6640,15 @@ var init_wdioMochaTestFramework = __esm({
6385
6640
  [TestFrameworkConstants.KEY_EVENT_STARTED_AT]: (/* @__PURE__ */ new Date()).toISOString(),
6386
6641
  [TestFrameworkConstants.KEY_HOOK_LOGS]: [],
6387
6642
  [TestFrameworkConstants.KEY_HOOK_NAME]: test.title || test.description,
6388
- [TestFrameworkConstants.KEY_TEST_FILE_PATH]: gitConfig?.root && filename ? path13.relative(gitConfig.root, filename) : void 0,
6389
- [TestFrameworkConstants.KEY_TEST_LOCATION]: filename ? path13.relative(process.cwd(), filename) : void 0
6643
+ [TestFrameworkConstants.KEY_TEST_FILE_PATH]: gitConfig?.root && filename ? path14.relative(gitConfig.root, filename) : void 0,
6644
+ [TestFrameworkConstants.KEY_TEST_LOCATION]: filename ? path14.relative(process.cwd(), filename) : void 0
6390
6645
  };
6391
6646
  hooksStarted.get(key)?.push(hook);
6392
6647
  updates[_WdioMochaTestFramework.KEY_HOOK_LAST_STARTED] = key;
6393
- BStackLogger.info(`Hook Started in PRE key = ${key} & hook = ${JSON.stringify(hook)}`);
6648
+ BStackLogger2.info(`Hook Started in PRE key = ${key} & hook = ${JSON.stringify(hook)}`);
6394
6649
  } else if (hookState === HookState.POST) {
6395
6650
  const hooksList = hooksStarted.get(key) || [];
6396
- BStackLogger.info(`Hook List in Post ${JSON.stringify(hooksList)}`);
6651
+ BStackLogger2.info(`Hook List in Post ${JSON.stringify(hooksList)}`);
6397
6652
  if (hooksList.length > 0) {
6398
6653
  const hook = hooksList.pop();
6399
6654
  const result = testResult.status;
@@ -6406,7 +6661,7 @@ var init_wdioMochaTestFramework = __esm({
6406
6661
  }
6407
6662
  }
6408
6663
  instance.updateMultipleEntries(updates);
6409
- BStackLogger.info(`trackHookEvents: hook state=${key}.${hookState}, hooks started=${JSON.stringify(hooksStarted)}, hooks finished=${JSON.stringify(hooksFinished)}`);
6664
+ BStackLogger2.info(`trackHookEvents: hook state=${key}.${hookState}, hooks started=${JSON.stringify(hooksStarted)}, hooks finished=${JSON.stringify(hooksFinished)}`);
6410
6665
  }
6411
6666
  };
6412
6667
  }
@@ -6430,7 +6685,7 @@ var init_testHubModule = __esm({
6430
6685
  init_automationFramework();
6431
6686
  init_automationFrameworkConstants();
6432
6687
  TestHubModule = class _TestHubModule extends BaseModule {
6433
- logger = BStackLogger;
6688
+ logger = BStackLogger2;
6434
6689
  testhubConfig;
6435
6690
  name;
6436
6691
  static MODULE_NAME = "TestHubModule";
@@ -6703,11 +6958,11 @@ var init_wdioAutomationFramework = __esm({
6703
6958
  * @param {*} args
6704
6959
  */
6705
6960
  async trackEvent(automationFrameworkState, hookState, args = {}) {
6706
- BStackLogger.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6961
+ BStackLogger2.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6707
6962
  await super.trackEvent(automationFrameworkState, hookState, args);
6708
6963
  const instance = this.resolveInstance(automationFrameworkState, hookState, args);
6709
6964
  if (instance === null) {
6710
- BStackLogger.error(`trackEvent: instance not found for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6965
+ BStackLogger2.error(`trackEvent: instance not found for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6711
6966
  return;
6712
6967
  }
6713
6968
  args.instance = instance;
@@ -6722,7 +6977,7 @@ var init_wdioAutomationFramework = __esm({
6722
6977
  */
6723
6978
  resolveInstance(automationFrameworkState, hookState, args = {}) {
6724
6979
  let instance = null;
6725
- BStackLogger.info(`resolveInstance: resolving instance for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6980
+ BStackLogger2.info(`resolveInstance: resolving instance for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6726
6981
  if (automationFrameworkState === AutomationFrameworkState.CREATE || automationFrameworkState === AutomationFrameworkState.NONE) {
6727
6982
  this.trackWebdriverIOInstance(automationFrameworkState, args);
6728
6983
  }
@@ -6738,13 +6993,13 @@ var init_wdioAutomationFramework = __esm({
6738
6993
  // !args.browser &&
6739
6994
  AutomationFramework.getTrackedInstance()
6740
6995
  ) {
6741
- BStackLogger.info("trackWebdriverIOInstance: instance already exists");
6996
+ BStackLogger2.info("trackWebdriverIOInstance: instance already exists");
6742
6997
  return;
6743
6998
  }
6744
6999
  const target = CLIUtils.getCurrentInstanceName();
6745
7000
  const trackedContext = TrackedInstance.createContext(target);
6746
7001
  let instance = null;
6747
- BStackLogger.info(`trackWebdriverIOInstance: created instance for target=${target}, state=${automationFrameworkState}, args=${args}`);
7002
+ BStackLogger2.info(`trackWebdriverIOInstance: created instance for target=${target}, state=${automationFrameworkState}, args=${args}`);
6748
7003
  instance = new AutomationFrameworkInstance(
6749
7004
  trackedContext,
6750
7005
  this.getAutomationFrameworkName(),
@@ -6752,7 +7007,7 @@ var init_wdioAutomationFramework = __esm({
6752
7007
  automationFrameworkState
6753
7008
  );
6754
7009
  AutomationFramework.setTrackedInstance(trackedContext, instance);
6755
- BStackLogger.info(`trackWebdriverIOInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
7010
+ BStackLogger2.info(`trackWebdriverIOInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
6756
7011
  }
6757
7012
  };
6758
7013
  }
@@ -6778,7 +7033,7 @@ var init_webdriverIOModule = __esm({
6778
7033
  browserVersion;
6779
7034
  platforms;
6780
7035
  testRunId;
6781
- logger = BStackLogger;
7036
+ logger = BStackLogger2;
6782
7037
  static MODULE_NAME = "WebdriverIOModule";
6783
7038
  /**
6784
7039
  * Create a new WebdriverIOModule
@@ -6906,7 +7161,7 @@ var init_accessibilityModule = __esm({
6906
7161
  init_constants2();
6907
7162
  init_grpcClient();
6908
7163
  AccessibilityModule = class extends BaseModule {
6909
- logger = BStackLogger;
7164
+ logger = BStackLogger2;
6910
7165
  name;
6911
7166
  scriptInstance;
6912
7167
  accessibility = false;
@@ -7190,7 +7445,7 @@ var init_accessibilityModule = __esm({
7190
7445
  formatString(this.scriptInstance.performScan, JSON.stringify(_getParamsForAppAccessibility(commandName, testName))),
7191
7446
  {}
7192
7447
  );
7193
- BStackLogger.debug(util9.format(results2));
7448
+ BStackLogger2.debug(util9.format(results2));
7194
7449
  return results2;
7195
7450
  }
7196
7451
  const results = await browser.executeAsync(
@@ -7313,7 +7568,7 @@ var init_observabilityModule = __esm({
7313
7568
  init_cliLogger();
7314
7569
  init_util();
7315
7570
  ObservabilityModule = class _ObservabilityModule extends BaseModule {
7316
- logger = BStackLogger;
7571
+ logger = BStackLogger2;
7317
7572
  observabilityConfig;
7318
7573
  name;
7319
7574
  static MODULE_NAME = "ObservabilityModule";
@@ -7416,22 +7671,22 @@ var init_request_handler = __esm({
7416
7671
  throw new Error("Test Reporting and Analytics build start not completed yet.");
7417
7672
  }
7418
7673
  this.queue.push(event);
7419
- BStackLogger2.debug(`Added data to request queue. Queue length = ${this.queue.length}`);
7674
+ BStackLogger.debug(`Added data to request queue. Queue length = ${this.queue.length}`);
7420
7675
  const shouldProceed = this.shouldProceed();
7421
7676
  if (shouldProceed) {
7422
7677
  this.sendBatch().catch((e) => {
7423
- BStackLogger2.debug("Exception in sending batch: " + e);
7678
+ BStackLogger.debug("Exception in sending batch: " + e);
7424
7679
  });
7425
7680
  }
7426
7681
  }
7427
7682
  async shutdown() {
7428
- BStackLogger2.debug("shutdown started");
7683
+ BStackLogger.debug("shutdown started");
7429
7684
  this.removeEventBatchPolling("Shutting down");
7430
7685
  while (this.queue.length > 0) {
7431
7686
  const data = this.queue.splice(0, DATA_BATCH_SIZE);
7432
7687
  await this.callCallback(data, "SHUTDOWN_QUEUE");
7433
7688
  }
7434
- BStackLogger2.debug("shutdown ended");
7689
+ BStackLogger.debug("shutdown ended");
7435
7690
  }
7436
7691
  startEventBatchPolling() {
7437
7692
  this.pollEventBatchInterval = setInterval(this.sendBatch.bind(this), DATA_BATCH_INTERVAL);
@@ -7441,11 +7696,11 @@ var init_request_handler = __esm({
7441
7696
  if (data.length === 0) {
7442
7697
  return;
7443
7698
  }
7444
- BStackLogger2.debug(`Sending data from request queue. Data length = ${data.length}, Queue length after removal = ${this.queue.length}`);
7699
+ BStackLogger.debug(`Sending data from request queue. Data length = ${data.length}, Queue length after removal = ${this.queue.length}`);
7445
7700
  await this.callCallback(data, "INTERVAL_QUEUE");
7446
7701
  }
7447
7702
  callCallback = async (data, kind) => {
7448
- BStackLogger2.debug("calling callback with kind " + kind);
7703
+ BStackLogger.debug("calling callback with kind " + kind);
7449
7704
  await this.callback?.(data);
7450
7705
  };
7451
7706
  resetEventBatchPolling() {
@@ -7454,13 +7709,13 @@ var init_request_handler = __esm({
7454
7709
  }
7455
7710
  removeEventBatchPolling(tag) {
7456
7711
  if (this.pollEventBatchInterval) {
7457
- BStackLogger2.debug(`${tag} request queue`);
7712
+ BStackLogger.debug(`${tag} request queue`);
7458
7713
  clearInterval(this.pollEventBatchInterval);
7459
7714
  }
7460
7715
  }
7461
7716
  shouldProceed() {
7462
7717
  if (_RequestQueueHandler.tearDownInvoked) {
7463
- BStackLogger2.debug("Force request-queue shutdown, as test run event is received after teardown");
7718
+ BStackLogger.debug("Force request-queue shutdown, as test run event is received after teardown");
7464
7719
  return true;
7465
7720
  }
7466
7721
  return this.queue.length >= DATA_BATCH_SIZE;
@@ -7483,7 +7738,7 @@ async function uploadEventData(eventData, eventUrl = DATA_EVENT_ENDPOINT) {
7483
7738
  throw new Error("Build start not completed yet");
7484
7739
  }
7485
7740
  if (!process.env[BROWSERSTACK_TESTHUB_JWT]) {
7486
- BStackLogger2.debug(`[${logTag}] Missing Authentication Token/ Build ID`);
7741
+ BStackLogger.debug(`[${logTag}] Missing Authentication Token/ Build ID`);
7487
7742
  throw new Error("Token/buildID is undefined, build creation might have failed");
7488
7743
  }
7489
7744
  try {
@@ -7496,9 +7751,9 @@ async function uploadEventData(eventData, eventUrl = DATA_EVENT_ENDPOINT) {
7496
7751
  },
7497
7752
  body: JSON.stringify(eventData)
7498
7753
  });
7499
- BStackLogger2.debug(`[${logTag}] Success response: ${JSON.stringify(await data.json())}`);
7754
+ BStackLogger.debug(`[${logTag}] Success response: ${JSON.stringify(await data.json())}`);
7500
7755
  } catch (error) {
7501
- BStackLogger2.debug(`[${logTag}] Failed. Error: ${format3(error)}`);
7756
+ BStackLogger.debug(`[${logTag}] Failed. Error: ${format3(error)}`);
7502
7757
  throw error;
7503
7758
  }
7504
7759
  }
@@ -7561,7 +7816,7 @@ var init_listener = __esm({
7561
7816
  await this.uploadPending();
7562
7817
  await this.teardown();
7563
7818
  } catch (e) {
7564
- BStackLogger2.debug("Exception in onWorkerEnd: " + e);
7819
+ BStackLogger.debug("Exception in onWorkerEnd: " + e);
7565
7820
  }
7566
7821
  }
7567
7822
  async uploadPending(waitTimeout = DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS, waitInterval = DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS) {
@@ -7572,10 +7827,10 @@ var init_listener = __esm({
7572
7827
  return this.uploadPending(waitTimeout - waitInterval);
7573
7828
  }
7574
7829
  async teardown() {
7575
- BStackLogger2.debug("teardown started");
7830
+ BStackLogger.debug("teardown started");
7576
7831
  RequestQueueHandler.tearDownInvoked = true;
7577
7832
  await this.requestBatcher?.shutdown();
7578
- BStackLogger2.debug("teardown ended");
7833
+ BStackLogger.debug("teardown ended");
7579
7834
  }
7580
7835
  hookStarted(hookData) {
7581
7836
  try {
@@ -7683,7 +7938,7 @@ var init_listener = __esm({
7683
7938
  }
7684
7939
  markLogs(status, data) {
7685
7940
  if (!data) {
7686
- BStackLogger2.debug("No log data");
7941
+ BStackLogger.debug("No log data");
7687
7942
  return;
7688
7943
  }
7689
7944
  try {
@@ -7692,7 +7947,7 @@ var init_listener = __esm({
7692
7947
  this.logEvents.mark(status, LOG_KIND_USAGE_MAP[kind] || kind);
7693
7948
  }
7694
7949
  } catch (e) {
7695
- BStackLogger2.debug("Exception in marking logs status " + e);
7950
+ BStackLogger.debug("Exception in marking logs status " + e);
7696
7951
  throw e;
7697
7952
  }
7698
7953
  }
@@ -7710,14 +7965,14 @@ var init_listener = __esm({
7710
7965
  }
7711
7966
  if (!this.requestBatcher) {
7712
7967
  this.requestBatcher = RequestQueueHandler.getInstance(async (data) => {
7713
- BStackLogger2.debug("callback: called with events " + data.length);
7968
+ BStackLogger.debug("callback: called with events " + data.length);
7714
7969
  try {
7715
7970
  this.pendingUploads += 1;
7716
7971
  await batchAndPostEvents(DATA_BATCH_ENDPOINT, "BATCH_DATA", data);
7717
- BStackLogger2.debug("callback: marking events success " + data.length);
7972
+ BStackLogger.debug("callback: marking events success " + data.length);
7718
7973
  this.eventsSuccess(data);
7719
7974
  } catch {
7720
- BStackLogger2.debug("callback: marking events failed " + data.length);
7975
+ BStackLogger.debug("callback: marking events failed " + data.length);
7721
7976
  this.eventsFailed(data);
7722
7977
  } finally {
7723
7978
  this.pendingUploads -= 1;
@@ -7774,7 +8029,7 @@ var init_listener = __esm({
7774
8029
  });
7775
8030
 
7776
8031
  // src/reporter.ts
7777
- import path14 from "node:path";
8032
+ import path15 from "node:path";
7778
8033
  import WDIOReporter from "@wdio/reporter";
7779
8034
  import * as url from "node:url";
7780
8035
  import { v4 as uuidv43 } from "uuid";
@@ -7867,7 +8122,7 @@ var init_reporter = __esm({
7867
8122
  filename = this._suiteName || suiteStats.file;
7868
8123
  }
7869
8124
  } catch {
7870
- BStackLogger2.debug("Error in decoding file name of suite");
8125
+ BStackLogger.debug("Error in decoding file name of suite");
7871
8126
  }
7872
8127
  }
7873
8128
  this._suiteName = filename;
@@ -7997,9 +8252,9 @@ var init_reporter = __esm({
7997
8252
  scope,
7998
8253
  scopes,
7999
8254
  identifier,
8000
- file_name: suiteFileName ? path14.relative(process.cwd(), suiteFileName) : void 0,
8001
- location: suiteFileName ? path14.relative(process.cwd(), suiteFileName) : void 0,
8002
- vc_filepath: this._gitConfigPath && suiteFileName ? path14.relative(this._gitConfigPath, suiteFileName) : void 0,
8255
+ file_name: suiteFileName ? path15.relative(process.cwd(), suiteFileName) : void 0,
8256
+ location: suiteFileName ? path15.relative(process.cwd(), suiteFileName) : void 0,
8257
+ vc_filepath: this._gitConfigPath && suiteFileName ? path15.relative(this._gitConfigPath, suiteFileName) : void 0,
8003
8258
  started_at: testStats.start && testStats.start.toISOString(),
8004
8259
  finished_at: testStats.end && testStats.end.toISOString(),
8005
8260
  framework,
@@ -8012,13 +8267,15 @@ var init_reporter = __esm({
8012
8267
  if (eventType.startsWith("TestRun") || eventType === "HookRunStarted") {
8013
8268
  const cloudProvider = getCloudProvider({ options: { hostname: this._config?.hostname } });
8014
8269
  testData.integrations = {};
8270
+ const liveBrowserCaps = globalThis?.browser?.capabilities;
8015
8271
  testData.integrations[cloudProvider] = {
8016
8272
  capabilities: this._capabilities,
8017
8273
  session_id: this._sessionId,
8018
8274
  browser: this._capabilities?.browserName,
8019
8275
  browser_version: this._capabilities?.browserVersion,
8020
8276
  platform: this._capabilities?.platformName,
8021
- platform_version: getPlatformVersion(this._capabilities, this._userCaps)
8277
+ platform_version: getPlatformVersion(this._capabilities, this._userCaps),
8278
+ device: getResolvedDeviceName(liveBrowserCaps, this._userCaps)
8022
8279
  };
8023
8280
  }
8024
8281
  if (eventType === "TestRunFinished" || eventType === "HookRunFinished") {
@@ -8048,7 +8305,7 @@ var init_reporter = __esm({
8048
8305
  });
8049
8306
 
8050
8307
  // src/insights-handler.ts
8051
- import path15 from "node:path";
8308
+ import path16 from "node:path";
8052
8309
  import { v4 as uuidv44 } from "uuid";
8053
8310
  var _InsightsHandler, InsightsHandler, insights_handler_default;
8054
8311
  var init_insights_handler = __esm({
@@ -8082,6 +8339,8 @@ var init_insights_handler = __esm({
8082
8339
  };
8083
8340
  this.registerListeners();
8084
8341
  }
8342
+ _browser;
8343
+ _framework;
8085
8344
  _tests = {};
8086
8345
  _hooks = {};
8087
8346
  _platformMeta;
@@ -8328,9 +8587,9 @@ var init_insights_handler = __esm({
8328
8587
  test_run_id: hookData.testRunId,
8329
8588
  scope: feature?.name,
8330
8589
  scopes: [feature?.name || ""],
8331
- file_name: uri ? path15.relative(process.cwd(), uri) : void 0,
8332
- location: uri ? path15.relative(process.cwd(), uri) : void 0,
8333
- vc_filepath: this._gitConfigPath && uri ? path15.relative(this._gitConfigPath, uri) : void 0,
8590
+ file_name: uri ? path16.relative(process.cwd(), uri) : void 0,
8591
+ location: uri ? path16.relative(process.cwd(), uri) : void 0,
8592
+ vc_filepath: this._gitConfigPath && uri ? path16.relative(this._gitConfigPath, uri) : void 0,
8334
8593
  result: "pending",
8335
8594
  framework: this._framework
8336
8595
  };
@@ -8495,7 +8754,7 @@ var init_insights_handler = __esm({
8495
8754
  this.listener.logCreated([stdLog]);
8496
8755
  }
8497
8756
  } catch (error) {
8498
- BStackLogger2.debug(`Exception in uploading log data to Test Reporting and Analytics with error : ${error}`);
8757
+ BStackLogger.debug(`Exception in uploading log data to Test Reporting and Analytics with error : ${error}`);
8499
8758
  }
8500
8759
  };
8501
8760
  async browserCommand(commandType, args, test) {
@@ -8628,9 +8887,9 @@ var init_insights_handler = __esm({
8628
8887
  scope: fullTitle,
8629
8888
  scopes: this.getHierarchy(test),
8630
8889
  identifier: fullTitle,
8631
- file_name: filename ? path15.relative(process.cwd(), filename) : void 0,
8632
- location: filename ? path15.relative(process.cwd(), filename) : void 0,
8633
- vc_filepath: this._gitConfigPath && filename ? path15.relative(this._gitConfigPath, filename) : void 0,
8890
+ file_name: filename ? path16.relative(process.cwd(), filename) : void 0,
8891
+ location: filename ? path16.relative(process.cwd(), filename) : void 0,
8892
+ vc_filepath: this._gitConfigPath && filename ? path16.relative(this._gitConfigPath, filename) : void 0,
8634
8893
  started_at: testMetaData.startedAt,
8635
8894
  finished_at: testMetaData.finishedAt,
8636
8895
  result: "pending",
@@ -8740,9 +8999,9 @@ var init_insights_handler = __esm({
8740
8999
  scope: fullNameWithExamples,
8741
9000
  scopes: [feature?.name || ""],
8742
9001
  identifier: scenario?.name,
8743
- file_name: feature && feature.path ? path15.relative(process.cwd(), feature.path) : void 0,
8744
- location: feature && feature.path ? path15.relative(process.cwd(), feature.path) : void 0,
8745
- vc_filepath: this._gitConfigPath && feature?.path ? path15.relative(this._gitConfigPath, feature?.path) : void 0,
9002
+ file_name: feature && feature.path ? path16.relative(process.cwd(), feature.path) : void 0,
9003
+ location: feature && feature.path ? path16.relative(process.cwd(), feature.path) : void 0,
9004
+ vc_filepath: this._gitConfigPath && feature?.path ? path16.relative(this._gitConfigPath, feature?.path) : void 0,
8746
9005
  framework: this._framework,
8747
9006
  result: "pending",
8748
9007
  meta: {
@@ -8795,7 +9054,7 @@ var init_insights_handler = __esm({
8795
9054
  return testData;
8796
9055
  }
8797
9056
  async flushCBTDataQueue() {
8798
- BStackLogger2.debug(`Flushing CBT Data Queue ${this.currentTestId}`);
9057
+ BStackLogger.debug(`Flushing CBT Data Queue ${this.currentTestId}`);
8799
9058
  if (isUndefined(this.currentTestId)) {
8800
9059
  return;
8801
9060
  }
@@ -8815,7 +9074,7 @@ var init_insights_handler = __esm({
8815
9074
  uuid: "",
8816
9075
  integrations: integrationsData
8817
9076
  };
8818
- BStackLogger2.debug(`Sending CBT Data ${this.currentTestId} ${JSON.stringify(cbtData)}`);
9077
+ BStackLogger.debug(`Sending CBT Data ${this.currentTestId} ${JSON.stringify(cbtData)}`);
8819
9078
  if (this.currentTestId !== void 0) {
8820
9079
  cbtData.uuid = this.currentTestId;
8821
9080
  this.listener.cbtSessionCreated(cbtData);
@@ -8826,8 +9085,8 @@ var init_insights_handler = __esm({
8826
9085
  getIntegrationsObject() {
8827
9086
  const caps = this._browser?.capabilities;
8828
9087
  const sessionId = this._browser?.sessionId;
8829
- BStackLogger2.debug(`Driver capabilities used for integration object: ${JSON.stringify(caps)}`);
8830
- BStackLogger2.debug(`User capabilities used for integration object: ${JSON.stringify(this._userCaps)}`);
9088
+ BStackLogger.debug(`Driver capabilities used for integration object: ${JSON.stringify(caps)}`);
9089
+ BStackLogger.debug(`User capabilities used for integration object: ${JSON.stringify(this._userCaps)}`);
8831
9090
  return {
8832
9091
  capabilities: caps,
8833
9092
  session_id: sessionId,
@@ -8835,7 +9094,8 @@ var init_insights_handler = __esm({
8835
9094
  browser_version: caps?.browserVersion,
8836
9095
  platform: caps?.platformName,
8837
9096
  product: this._platformMeta?.product,
8838
- platform_version: getPlatformVersion(caps, this._userCaps)
9097
+ platform_version: getPlatformVersion(caps, this._userCaps),
9098
+ device: getResolvedDeviceName(caps, this._userCaps)
8839
9099
  };
8840
9100
  }
8841
9101
  getIdentifier(test) {
@@ -8989,6 +9249,11 @@ var init_Percy_Handler = __esm({
8989
9249
  this._percyAutoCaptureMode = "auto";
8990
9250
  }
8991
9251
  }
9252
+ _percyAutoCaptureMode;
9253
+ _browser;
9254
+ _capabilities;
9255
+ _isAppAutomate;
9256
+ _framework;
8992
9257
  _sessionName;
8993
9258
  _isPercyCleanupProcessingUnderway = false;
8994
9259
  _percyScreenshotCounter = 0;
@@ -9128,7 +9393,7 @@ var init_percyModule = __esm({
9128
9393
  init_Percy_Handler();
9129
9394
  init_testFrameworkConstants();
9130
9395
  PercyModule = class _PercyModule extends BaseModule {
9131
- logger = BStackLogger;
9396
+ logger = BStackLogger2;
9132
9397
  browser;
9133
9398
  static MODULE_NAME = "PercyModule";
9134
9399
  percyHandler;
@@ -9249,7 +9514,7 @@ var init_cli = __esm({
9249
9514
  cliParams = null;
9250
9515
  automationFramework = null;
9251
9516
  SDK_CLI_BIN_PATH = null;
9252
- logger = BStackLogger;
9517
+ logger = BStackLogger2;
9253
9518
  options;
9254
9519
  constructor() {
9255
9520
  this.initialized = false;
@@ -9308,7 +9573,7 @@ var init_cli = __esm({
9308
9573
  const response = await GrpcClient.getInstance().startBinSession(this.wdioConfig);
9309
9574
  const redactedStartResponse = JSON.parse(JSON.stringify(response));
9310
9575
  CrashReporter.recursivelyRedactKeysFromObject(redactedStartResponse, ["user", "username", "key", "accesskey", "password"]);
9311
- BStackLogger.debug(`start: startBinSession response=${JSON.stringify(redactedStartResponse)}`);
9576
+ BStackLogger2.debug(`start: startBinSession response=${JSON.stringify(redactedStartResponse)}`);
9312
9577
  this.loadModules(response);
9313
9578
  this.isMainConnected = true;
9314
9579
  }
@@ -9320,6 +9585,7 @@ var init_cli = __esm({
9320
9585
  this.binSessionId = startBinResponse.binSessionId;
9321
9586
  this.logger.info(`loadModules: binSessionId=${this.binSessionId}`);
9322
9587
  this.setConfig(startBinResponse);
9588
+ this.logBuildErrors(startBinResponse);
9323
9589
  APIUtils.updateURLSForGRR(this.config.apis);
9324
9590
  this.setupTestFramework();
9325
9591
  this.setupAutomationFramework();
@@ -9341,17 +9607,6 @@ var init_cli = __esm({
9341
9607
  }
9342
9608
  this.modules[ObservabilityModule.MODULE_NAME] = new ObservabilityModule(startBinResponse.observability);
9343
9609
  }
9344
- if (startBinResponse.testhub.errors && startBinResponse.testhub.errors.length > 0) {
9345
- try {
9346
- const errors = JSON.parse(Buffer.from(startBinResponse.testhub.errors).toString());
9347
- for (const [code, detail] of Object.entries(errors)) {
9348
- const { message } = detail;
9349
- BStackLogger.error(`[Build] ${code}: ${message}`);
9350
- }
9351
- } catch (e) {
9352
- BStackLogger.debug(`Failed to parse testhub errors: ${e}`);
9353
- }
9354
- }
9355
9610
  this.modules[TestHubModule.MODULE_NAME] = new TestHubModule(startBinResponse.testhub);
9356
9611
  if (startBinResponse.accessibility?.success) {
9357
9612
  process.env[BROWSERSTACK_ACCESSIBILITY] = "true";
@@ -9366,6 +9621,28 @@ var init_cli = __esm({
9366
9621
  }
9367
9622
  this.configureModules();
9368
9623
  }
9624
+ /**
9625
+ * Log any build errors the binary reported via testhub.errors. The
9626
+ * field is a JSON-encoded { [errorKey]: { message, type } } map. Called
9627
+ * early in loadModules so the user sees the actionable cause (e.g.
9628
+ * invalid credentials) before any downstream bootstrap step that
9629
+ * depends on a fully populated config.
9630
+ */
9631
+ logBuildErrors(startBinResponse) {
9632
+ const rawErrors = startBinResponse.testhub?.errors;
9633
+ if (!rawErrors || !rawErrors.length) {
9634
+ return;
9635
+ }
9636
+ try {
9637
+ const errors = JSON.parse(Buffer.from(rawErrors).toString());
9638
+ for (const [code, detail] of Object.entries(errors)) {
9639
+ const { message } = detail;
9640
+ BStackLogger2.error(`[Build] ${code}: ${message}`);
9641
+ }
9642
+ } catch (e) {
9643
+ BStackLogger2.debug(`Failed to parse testhub errors: ${e}`);
9644
+ }
9645
+ }
9369
9646
  /**
9370
9647
  * Configure modules
9371
9648
  * @returns {Promise<void>}
@@ -9490,7 +9767,7 @@ var init_cli = __esm({
9490
9767
  try {
9491
9768
  if (this.isMainConnected) {
9492
9769
  const response = await GrpcClient.getInstance().stopBinSession();
9493
- BStackLogger.debug(`stop: stopBinSession response=${JSON.stringify(response)}`);
9770
+ BStackLogger2.debug(`stop: stopBinSession response=${JSON.stringify(response)}`);
9494
9771
  }
9495
9772
  await this.unConfigureModules();
9496
9773
  if (this.process && this.process.pid) {
@@ -9672,8 +9949,8 @@ var init_cli = __esm({
9672
9949
  });
9673
9950
 
9674
9951
  // src/testorchestration/helpers.ts
9675
- import os5 from "node:os";
9676
- import path18 from "node:path";
9952
+ import os6 from "node:os";
9953
+ import path19 from "node:path";
9677
9954
  import { spawnSync } from "node:child_process";
9678
9955
  import logger4 from "@wdio/logger";
9679
9956
  function isValidGitRef(ref) {
@@ -9699,11 +9976,11 @@ function safeGitCommand(args, cwd) {
9699
9976
  }
9700
9977
  function getHostInfo() {
9701
9978
  return {
9702
- hostname: os5.hostname(),
9979
+ hostname: os6.hostname(),
9703
9980
  platform: process.platform,
9704
9981
  architecture: process.arch,
9705
- release: os5.release(),
9706
- username: os5.userInfo().username
9982
+ release: os6.release(),
9983
+ username: os6.userInfo().username
9707
9984
  };
9708
9985
  }
9709
9986
  function isValidGitResult(result) {
@@ -9794,7 +10071,7 @@ function getGitMetadataForAISelection(folders = []) {
9794
10071
  if (folders === null) {
9795
10072
  folders = [process.cwd()];
9796
10073
  }
9797
- const uniqueFolders = [...new Set(folders.map((f) => path18.resolve(f)))];
10074
+ const uniqueFolders = [...new Set(folders.map((f) => path19.resolve(f)))];
9798
10075
  log4.debug(`Processing ${uniqueFolders.length} unique folders out of ${folders.length} total`);
9799
10076
  const results = [];
9800
10077
  for (const folder of uniqueFolders) {
@@ -9951,14 +10228,14 @@ var init_request_utils = __esm({
9951
10228
  * Makes a request to the test orchestration split tests endpoint
9952
10229
  */
9953
10230
  static async testOrchestrationSplitTests(reqEndpoint, data) {
9954
- BStackLogger2.debug("Processing Request for testOrchestrationSplitTests");
10231
+ BStackLogger.debug("Processing Request for testOrchestrationSplitTests");
9955
10232
  return _RequestUtils.makeOrchestrationRequest("POST", reqEndpoint, { data });
9956
10233
  }
9957
10234
  /**
9958
10235
  * Gets ordered tests from the test orchestration
9959
10236
  */
9960
10237
  static async getTestOrchestrationOrderedTests(reqEndpoint) {
9961
- BStackLogger2.debug("Processing Request for getTestOrchestrationOrderedTests");
10238
+ BStackLogger.debug("Processing Request for getTestOrchestrationOrderedTests");
9962
10239
  return _RequestUtils.makeOrchestrationRequest("GET", reqEndpoint, {});
9963
10240
  }
9964
10241
  /**
@@ -9995,13 +10272,13 @@ var init_request_utils = __esm({
9995
10272
  throw new Error(`Unsupported HTTP method: ${method}`);
9996
10273
  }
9997
10274
  const response = await fetchWrap(urlObject.toString(), requestInit);
9998
- BStackLogger2.debug(`Orchestration request made to URL: ${urlObject.toString()} with method: ${method}`);
10275
+ BStackLogger.debug(`Orchestration request made to URL: ${urlObject.toString()} with method: ${method}`);
9999
10276
  const rawBody = await response.text();
10000
10277
  let responseObj = rawBody;
10001
10278
  try {
10002
10279
  responseObj = rawBody ? JSON.parse(rawBody) : {};
10003
10280
  } catch (error) {
10004
- BStackLogger2.debug(`Failed to parse JSON response: ${error} - ${rawBody}`);
10281
+ BStackLogger.debug(`Failed to parse JSON response: ${error} - ${rawBody}`);
10005
10282
  }
10006
10283
  if (responseObj && typeof responseObj === "object" && !Array.isArray(responseObj)) {
10007
10284
  return {
@@ -10012,7 +10289,7 @@ var init_request_utils = __esm({
10012
10289
  }
10013
10290
  return typeof responseObj === "string" ? responseObj : rawBody;
10014
10291
  } catch (error) {
10015
- BStackLogger2.error(`Orchestration request failed: ${error} - ${url3}`);
10292
+ BStackLogger.error(`Orchestration request failed: ${error} - ${url3}`);
10016
10293
  return null;
10017
10294
  }
10018
10295
  }
@@ -10021,7 +10298,7 @@ var init_request_utils = __esm({
10021
10298
  });
10022
10299
 
10023
10300
  // src/testorchestration/test-ordering-server.ts
10024
- import path19 from "node:path";
10301
+ import path20 from "node:path";
10025
10302
  function isSplitTestsResponse(value) {
10026
10303
  return typeof value === "object" && value !== null;
10027
10304
  }
@@ -10055,7 +10332,7 @@ var init_test_ordering_server = __esm({
10055
10332
  * Initiates the split tests request and stores the response data for polling.
10056
10333
  */
10057
10334
  async splitTests(testFiles, orchestrationStrategy, orchestrationMetadata = "{}") {
10058
- BStackLogger2.debug(`[splitTests] Initiating split tests with strategy: ${orchestrationStrategy}`);
10335
+ BStackLogger.debug(`[splitTests] Initiating split tests with strategy: ${orchestrationStrategy}`);
10059
10336
  try {
10060
10337
  let prDetails = [];
10061
10338
  const parsedMetadata = JSON.parse(orchestrationMetadata);
@@ -10065,7 +10342,7 @@ var init_test_ordering_server = __esm({
10065
10342
  const multiRepoSource = parsedMetadata.run_smart_selection?.source;
10066
10343
  prDetails = getGitMetadataForAISelection(multiRepoSource);
10067
10344
  }
10068
- BStackLogger2.debug(`PR Details for AI Selection: ${JSON.stringify(prDetails)}`);
10345
+ BStackLogger.debug(`PR Details for AI Selection: ${JSON.stringify(prDetails)}`);
10069
10346
  const payload = {
10070
10347
  tests: testFiles.map((f) => ({ filePath: f })),
10071
10348
  orchestrationStrategy,
@@ -10073,23 +10350,23 @@ var init_test_ordering_server = __esm({
10073
10350
  nodeIndex: parseInt(process.env.BROWSERSTACK_NODE_INDEX || "0"),
10074
10351
  totalNodes: parseInt(process.env.BROWSERSTACK_TOTAL_NODE_COUNT || "1"),
10075
10352
  projectName: this.config.testObservabilityOptions?.projectName || "",
10076
- buildName: this.config.testObservabilityOptions?.buildName || path19.basename(process.cwd()),
10353
+ buildName: this.config.testObservabilityOptions?.buildName || path20.basename(process.cwd()),
10077
10354
  buildRunIdentifier: process.env.BROWSERSTACK_BUILD_RUN_IDENTIFIER || "",
10078
10355
  hostInfo: getHostInfo(),
10079
10356
  prDetails
10080
10357
  };
10081
- BStackLogger2.info(`[splitTests] Split tests payload: ${JSON.stringify(payload)}`);
10358
+ BStackLogger.info(`[splitTests] Split tests payload: ${JSON.stringify(payload)}`);
10082
10359
  const response = await RequestUtils.testOrchestrationSplitTests(this.ORDERING_ENDPOINT, payload);
10083
10360
  if (isSplitTestsResponse(response)) {
10084
10361
  this.requestData = this._processSplitTestsResponse(response);
10085
- BStackLogger2.debug(`[splitTests] Split tests response: ${JSON.stringify(this.requestData)}`);
10362
+ BStackLogger.debug(`[splitTests] Split tests response: ${JSON.stringify(this.requestData)}`);
10086
10363
  } else if (response) {
10087
- BStackLogger2.error("[splitTests] Received unexpected response format from split tests request.");
10364
+ BStackLogger.error("[splitTests] Received unexpected response format from split tests request.");
10088
10365
  } else {
10089
- BStackLogger2.error("[splitTests] Failed to get split tests response.");
10366
+ BStackLogger.error("[splitTests] Failed to get split tests response.");
10090
10367
  }
10091
10368
  } catch (error) {
10092
- BStackLogger2.error(`[splitTests] Exception in sending test files:: ${error}`);
10369
+ BStackLogger.error(`[splitTests] Exception in sending test files:: ${error}`);
10093
10370
  }
10094
10371
  }
10095
10372
  /**
@@ -10107,7 +10384,7 @@ var init_test_ordering_server = __esm({
10107
10384
  const resultUrl = normalizeUrl(response.resultUrl);
10108
10385
  const timeoutUrl = normalizeUrl(response.timeoutUrl);
10109
10386
  if (response.timeout === void 0 || response.timeoutInterval === void 0 || response.timeoutUrl === void 0 || response.resultUrl === void 0) {
10110
- BStackLogger2.debug("[process_split_tests_response] Received null value(s) for some attributes in split tests API response");
10387
+ BStackLogger.debug("[process_split_tests_response] Received null value(s) for some attributes in split tests API response");
10111
10388
  }
10112
10389
  return {
10113
10390
  timeout,
@@ -10121,7 +10398,7 @@ var init_test_ordering_server = __esm({
10121
10398
  */
10122
10399
  async getOrderedTestFiles() {
10123
10400
  if (!this.requestData) {
10124
- BStackLogger2.error("[getOrderedTestFiles] No request data available to fetch ordered test files.");
10401
+ BStackLogger.error("[getOrderedTestFiles] No request data available to fetch ordered test files.");
10125
10402
  return null;
10126
10403
  }
10127
10404
  let testFilesJsonList = null;
@@ -10145,10 +10422,10 @@ var init_test_ordering_server = __esm({
10145
10422
  break;
10146
10423
  }
10147
10424
  await new Promise((resolve) => setTimeout(resolve, timeoutInterval * 1e3));
10148
- BStackLogger2.debug(`[getOrderedTestFiles] Fetching ordered tests from result URL after waiting for ${timeoutInterval} seconds.`);
10425
+ BStackLogger.debug(`[getOrderedTestFiles] Fetching ordered tests from result URL after waiting for ${timeoutInterval} seconds.`);
10149
10426
  }
10150
10427
  if (timeoutUrl && !testFilesJsonList) {
10151
- BStackLogger2.debug("[getOrderedTestFiles] Fetching ordered tests from timeout URL");
10428
+ BStackLogger.debug("[getOrderedTestFiles] Fetching ordered tests from timeout URL");
10152
10429
  const response = await RequestUtils.getTestOrchestrationOrderedTests(timeoutUrl);
10153
10430
  if (isSplitTestsResponse(response) && Array.isArray(response.tests)) {
10154
10431
  testFilesJsonList = response.tests;
@@ -10165,10 +10442,10 @@ var init_test_ordering_server = __esm({
10165
10442
  if (!testFilesJsonList) {
10166
10443
  return null;
10167
10444
  }
10168
- BStackLogger2.debug(`[getOrderedTestFiles] Ordered test files received: ${JSON.stringify(testFiles)}`);
10445
+ BStackLogger.debug(`[getOrderedTestFiles] Ordered test files received: ${JSON.stringify(testFiles)}`);
10169
10446
  return testFiles;
10170
10447
  } catch (error) {
10171
- BStackLogger2.error(`[getOrderedTestFiles] Exception in fetching ordered test files: ${error}`);
10448
+ BStackLogger.error(`[getOrderedTestFiles] Exception in fetching ordered test files: ${error}`);
10172
10449
  return null;
10173
10450
  }
10174
10451
  }
@@ -10260,10 +10537,10 @@ var init_testorcherstrationhandler = __esm({
10260
10537
  return;
10261
10538
  }
10262
10539
  if (this.config.projectName === void 0 || this.config.buildName === void 0) {
10263
- BStackLogger2.info("Test Reordering can't work as buildName or projectName is null. Please set a non-null value.");
10540
+ BStackLogger.info("Test Reordering can't work as buildName or projectName is null. Please set a non-null value.");
10264
10541
  }
10265
10542
  if (!this._isObservabilityEnabled()) {
10266
- BStackLogger2.info("Test Reordering can't work as testReporting is disabled. Please enable it from browserstack.yml file.");
10543
+ BStackLogger.info("Test Reordering can't work as testReporting is disabled. Please enable it from browserstack.yml file.");
10267
10544
  }
10268
10545
  }
10269
10546
  /**
@@ -10272,7 +10549,7 @@ var init_testorcherstrationhandler = __esm({
10272
10549
  async reorderTestFiles(testFiles) {
10273
10550
  try {
10274
10551
  if (!testFiles || testFiles.length === 0) {
10275
- BStackLogger2.debug("[reorderTestFiles] No test files provided for ordering.");
10552
+ BStackLogger.debug("[reorderTestFiles] No test files provided for ordering.");
10276
10553
  return null;
10277
10554
  }
10278
10555
  let orchestrationStrategy = null;
@@ -10281,16 +10558,16 @@ var init_testorcherstrationhandler = __esm({
10281
10558
  orchestrationStrategy = this.orchestrationUtils.getTestOrderingName();
10282
10559
  }
10283
10560
  if (orchestrationStrategy === null) {
10284
- BStackLogger2.error("Orchestration strategy is None. Cannot proceed with test orchestration session.");
10561
+ BStackLogger.error("Orchestration strategy is None. Cannot proceed with test orchestration session.");
10285
10562
  return null;
10286
10563
  }
10287
- BStackLogger2.info(`Reordering test files with orchestration strategy: ${orchestrationStrategy}`);
10564
+ BStackLogger.info(`Reordering test files with orchestration strategy: ${orchestrationStrategy}`);
10288
10565
  let orderedTestFiles = [];
10289
10566
  if (BrowserstackCLI.getInstance().isRunning()) {
10290
- BStackLogger2.info("Using CLI flow for test files orchestration.");
10567
+ BStackLogger.info("Using CLI flow for test files orchestration.");
10291
10568
  orderedTestFiles = await GrpcClient.getInstance().testOrchestrationSession(testFiles, orchestrationStrategy, JSON.stringify(orchestrationMetadata)) || [];
10292
10569
  } else {
10293
- BStackLogger2.info("Using SDK flow for test files orchestration.");
10570
+ BStackLogger.info("Using SDK flow for test files orchestration.");
10294
10571
  await this.testOrderingServerHandler.splitTests(testFiles, orchestrationStrategy, JSON.stringify(orchestrationMetadata));
10295
10572
  orderedTestFiles = await this.testOrderingServerHandler.getOrderedTestFiles() || [];
10296
10573
  }
@@ -10301,7 +10578,7 @@ var init_testorcherstrationhandler = __esm({
10301
10578
  this.addToOrderingInstrumentationData("splitTestsAPICallCount", this.testOrderingServerHandler.getSplitTestsApiCallCount());
10302
10579
  return orderedTestFiles;
10303
10580
  } catch (error) {
10304
- BStackLogger2.debug(`[reorderTestFiles] Error in ordering test classes: ${error}`);
10581
+ BStackLogger.debug(`[reorderTestFiles] Error in ordering test classes: ${error}`);
10305
10582
  }
10306
10583
  return null;
10307
10584
  }
@@ -10331,22 +10608,22 @@ import { performance as performance3 } from "node:perf_hooks";
10331
10608
  async function applyOrchestrationIfEnabled(specs, config) {
10332
10609
  const orchestrationHandler = TestOrchestrationHandler.getInstance(config);
10333
10610
  if (!orchestrationHandler) {
10334
- BStackLogger2.debug("Orchestration handler is not initialized. Skipping orchestration.");
10611
+ BStackLogger.debug("Orchestration handler is not initialized. Skipping orchestration.");
10335
10612
  return specs;
10336
10613
  }
10337
10614
  const runSmartSelectionEnabled = isValidEnabledValue(config?.testOrchestrationOptions?.runSmartSelection?.enabled);
10338
10615
  if (!runSmartSelectionEnabled) {
10339
- BStackLogger2.info("runSmartSelection is not enabled in config. Skipping orchestration.");
10616
+ BStackLogger.info("runSmartSelection is not enabled in config. Skipping orchestration.");
10340
10617
  return specs;
10341
10618
  }
10342
10619
  orchestrationHandler.addToOrderingInstrumentationData("enabled", orchestrationHandler.testOrderingEnabled());
10343
10620
  const startTime = performance3.now();
10344
- BStackLogger2.info("Test orchestration is enabled. Attempting to reorder test files.");
10621
+ BStackLogger.info("Test orchestration is enabled. Attempting to reorder test files.");
10345
10622
  const testFiles = specs;
10346
- BStackLogger2.info(`Test files to be reordered: ${testFiles.join(", ")}`);
10623
+ BStackLogger.info(`Test files to be reordered: ${testFiles.join(", ")}`);
10347
10624
  const orderedFiles = await orchestrationHandler.reorderTestFiles(testFiles);
10348
10625
  if (orderedFiles && orderedFiles.length > 0) {
10349
- BStackLogger2.info(`Tests reordered using orchestration: ${orderedFiles.join(", ")}`);
10626
+ BStackLogger.info(`Tests reordered using orchestration: ${orderedFiles.join(", ")}`);
10350
10627
  orchestrationHandler.addToOrderingInstrumentationData(
10351
10628
  "timeTakenToApply",
10352
10629
  Math.floor(performance3.now() - startTime)
@@ -10354,7 +10631,7 @@ async function applyOrchestrationIfEnabled(specs, config) {
10354
10631
  );
10355
10632
  return orderedFiles;
10356
10633
  }
10357
- BStackLogger2.info("No test files were reordered by orchestration.");
10634
+ BStackLogger.info("No test files were reordered by orchestration.");
10358
10635
  orchestrationHandler.addToOrderingInstrumentationData(
10359
10636
  "timeTakenToApply",
10360
10637
  Math.floor(performance3.now() - startTime)
@@ -10376,12 +10653,12 @@ var init_apply_orchestration = __esm({
10376
10653
  // src/launcher.ts
10377
10654
  init_utils();
10378
10655
  init_testOpsConfig();
10379
- import fs14 from "node:fs";
10656
+ import fs15 from "node:fs";
10380
10657
  import { readFile } from "node:fs/promises";
10381
- import path20 from "node:path";
10658
+ import path21 from "node:path";
10382
10659
  import { promisify as promisify4, format as format4 } from "node:util";
10383
10660
  import { performance as performance4, PerformanceObserver as PerformanceObserver2 } from "node:perf_hooks";
10384
- import os6 from "node:os";
10661
+ import os7 from "node:os";
10385
10662
  import { SevereServiceError } from "webdriverio";
10386
10663
  import * as BrowserstackLocalLauncher from "browserstack-local";
10387
10664
 
@@ -10391,9 +10668,9 @@ init_PercyLogger();
10391
10668
  // src/Percy/Percy.ts
10392
10669
  init_util();
10393
10670
  init_PercyLogger();
10394
- import fs10 from "node:fs";
10395
- import path9 from "node:path";
10396
- import os3 from "node:os";
10671
+ import fs11 from "node:fs";
10672
+ import path10 from "node:path";
10673
+ import os4 from "node:os";
10397
10674
  import { spawn as spawn2 } from "node:child_process";
10398
10675
 
10399
10676
  // src/Percy/PercyBinary.ts
@@ -10403,20 +10680,20 @@ init_constants2();
10403
10680
  init_bstackLogger();
10404
10681
  init_fetchWrapper();
10405
10682
  import yauzl2 from "yauzl";
10406
- import fs9 from "node:fs";
10683
+ import fs10 from "node:fs";
10407
10684
  import fsp2 from "node:fs/promises";
10408
10685
  import { pipeline } from "node:stream/promises";
10409
- import path8 from "node:path";
10410
- import os2 from "node:os";
10686
+ import path9 from "node:path";
10687
+ import os3 from "node:os";
10411
10688
  import { spawn } from "node:child_process";
10412
10689
  var PercyBinary = class {
10413
10690
  #hostOS = process.platform;
10414
10691
  #httpPath = null;
10415
10692
  #binaryName = "percy";
10416
10693
  #orderedPaths = [
10417
- path8.join(os2.homedir(), ".browserstack"),
10694
+ path9.join(os3.homedir(), ".browserstack"),
10418
10695
  process.cwd(),
10419
- os2.tmpdir()
10696
+ os3.tmpdir()
10420
10697
  ];
10421
10698
  constructor() {
10422
10699
  const base = "https://github.com/percy/cli/releases/latest/download";
@@ -10429,15 +10706,15 @@ var PercyBinary = class {
10429
10706
  this.#httpPath = base + "/percy-linux.zip";
10430
10707
  }
10431
10708
  }
10432
- async #makePath(path21) {
10433
- if (await this.#checkPath(path21)) {
10709
+ async #makePath(path22) {
10710
+ if (await this.#checkPath(path22)) {
10434
10711
  return true;
10435
10712
  }
10436
- return fsp2.mkdir(path21).then(() => true).catch(() => false);
10713
+ return fsp2.mkdir(path22).then(() => true).catch(() => false);
10437
10714
  }
10438
- async #checkPath(path21) {
10715
+ async #checkPath(path22) {
10439
10716
  try {
10440
- const hasDir = await fsp2.access(path21).then(() => true, () => false);
10717
+ const hasDir = await fsp2.access(path22).then(() => true, () => false);
10441
10718
  if (hasDir) {
10442
10719
  return true;
10443
10720
  }
@@ -10447,7 +10724,7 @@ var PercyBinary = class {
10447
10724
  }
10448
10725
  // Get the path for storing the ETag
10449
10726
  #getETagPath(destParentDir) {
10450
- return path8.join(destParentDir, `${this.#binaryName}.etag`);
10727
+ return path9.join(destParentDir, `${this.#binaryName}.etag`);
10451
10728
  }
10452
10729
  // Load the stored ETag if it exists
10453
10730
  async #loadETag(destParentDir) {
@@ -10457,7 +10734,7 @@ var PercyBinary = class {
10457
10734
  const data = await fsp2.readFile(etagPath, "utf8");
10458
10735
  return data.trim();
10459
10736
  } catch (err) {
10460
- BStackLogger2.warn(`Failed to read ETag file ${err}`);
10737
+ BStackLogger.warn(`Failed to read ETag file ${err}`);
10461
10738
  }
10462
10739
  }
10463
10740
  return null;
@@ -10470,23 +10747,23 @@ var PercyBinary = class {
10470
10747
  try {
10471
10748
  const etagPath = this.#getETagPath(destParentDir);
10472
10749
  await fsp2.writeFile(etagPath, etag);
10473
- BStackLogger2.debug("Saved new ETag for percy binary");
10750
+ BStackLogger.debug("Saved new ETag for percy binary");
10474
10751
  } catch (err) {
10475
- BStackLogger2.error(`Failed to save ETag file ${err}`);
10752
+ BStackLogger.error(`Failed to save ETag file ${err}`);
10476
10753
  }
10477
10754
  }
10478
10755
  async #getAvailableDirs() {
10479
10756
  for (let i = 0; i < this.#orderedPaths.length; i++) {
10480
- const path21 = this.#orderedPaths[i];
10481
- if (await this.#makePath(path21)) {
10482
- return path21;
10757
+ const path22 = this.#orderedPaths[i];
10758
+ if (await this.#makePath(path22)) {
10759
+ return path22;
10483
10760
  }
10484
10761
  }
10485
10762
  throw new Error("Error trying to download percy binary");
10486
10763
  }
10487
10764
  async getBinaryPath() {
10488
10765
  const destParentDir = await this.#getAvailableDirs();
10489
- const binaryPath = path8.join(destParentDir, this.#binaryName);
10766
+ const binaryPath = path9.join(destParentDir, this.#binaryName);
10490
10767
  let response;
10491
10768
  if (await this.#checkPath(binaryPath)) {
10492
10769
  const currentETag = await this.#loadETag(destParentDir);
@@ -10494,13 +10771,13 @@ var PercyBinary = class {
10494
10771
  try {
10495
10772
  const result = await this.#checkForUpdate(currentETag);
10496
10773
  if (!result.needsUpdate) {
10497
- BStackLogger2.debug("Percy binary is up to date (ETag unchanged)");
10774
+ BStackLogger.debug("Percy binary is up to date (ETag unchanged)");
10498
10775
  return binaryPath;
10499
10776
  }
10500
10777
  response = result.response;
10501
- BStackLogger2.debug("New Percy binary version available, downloading update");
10778
+ BStackLogger.debug("New Percy binary version available, downloading update");
10502
10779
  } catch (err) {
10503
- BStackLogger2.warn(`Failed to check for binary updates, using existing binary ${err}`);
10780
+ BStackLogger.warn(`Failed to check for binary updates, using existing binary ${err}`);
10504
10781
  return binaryPath;
10505
10782
  }
10506
10783
  }
@@ -10528,11 +10805,11 @@ var PercyBinary = class {
10528
10805
  }
10529
10806
  const newETag = response.headers.get("eTag");
10530
10807
  if (newETag) {
10531
- await this.#saveETag(path8.dirname(this.#getETagPath(await this.#getAvailableDirs())), newETag);
10808
+ await this.#saveETag(path9.dirname(this.#getETagPath(await this.#getAvailableDirs())), newETag);
10532
10809
  }
10533
10810
  return { needsUpdate: true, response };
10534
10811
  } catch (error) {
10535
- BStackLogger2.warn(`Error checking for Percy binary updates: ${error}`);
10812
+ BStackLogger.warn(`Error checking for Percy binary updates: ${error}`);
10536
10813
  throw error;
10537
10814
  }
10538
10815
  }
@@ -10555,9 +10832,9 @@ var PercyBinary = class {
10555
10832
  await fsp2.mkdir(destParentDir);
10556
10833
  }
10557
10834
  const binaryName = this.#binaryName;
10558
- const zipFilePath = path8.join(destParentDir, binaryName + ".zip");
10559
- const binaryPath = path8.join(destParentDir, binaryName);
10560
- const downloadedFileStream = fs9.createWriteStream(zipFilePath);
10835
+ const zipFilePath = path9.join(destParentDir, binaryName + ".zip");
10836
+ const binaryPath = path9.join(destParentDir, binaryName);
10837
+ const downloadedFileStream = fs10.createWriteStream(zipFilePath);
10561
10838
  if (!response) {
10562
10839
  response = await _fetch(this.#httpPath);
10563
10840
  }
@@ -10576,8 +10853,8 @@ var PercyBinary = class {
10576
10853
  if (/\/$/.test(entry.fileName)) {
10577
10854
  zipfile.readEntry();
10578
10855
  } else {
10579
- const writeStream = fs9.createWriteStream(
10580
- path8.join(destParentDir, entry.fileName)
10856
+ const writeStream = fs10.createWriteStream(
10857
+ path9.join(destParentDir, entry.fileName)
10581
10858
  );
10582
10859
  zipfile.openReadStream(entry, function(zipErr, readStream) {
10583
10860
  if (zipErr) {
@@ -10598,7 +10875,7 @@ var PercyBinary = class {
10598
10875
  reject(zipErr);
10599
10876
  });
10600
10877
  zipfile.once("end", () => {
10601
- fs9.chmod(binaryPath, "0755", function(zipErr) {
10878
+ fs10.chmod(binaryPath, "0755", function(zipErr) {
10602
10879
  if (zipErr) {
10603
10880
  reject(zipErr);
10604
10881
  }
@@ -10622,7 +10899,7 @@ init_constants2();
10622
10899
  init_apiUtils();
10623
10900
  var logDir = "logs";
10624
10901
  var Percy = class {
10625
- #logfile = path9.join(logDir, "percy.log");
10902
+ #logfile = path10.join(logDir, "percy.log");
10626
10903
  #address = process.env.PERCY_SERVER_ADDRESS || "http://127.0.0.1:5338";
10627
10904
  #binaryPath = null;
10628
10905
  #options;
@@ -10663,7 +10940,7 @@ var Percy = class {
10663
10940
  }
10664
10941
  async start() {
10665
10942
  const binaryPath = await this.#getBinaryPath();
10666
- const logStream = fs10.createWriteStream(this.#logfile, { flags: "a" });
10943
+ const logStream = fs11.createWriteStream(this.#logfile, { flags: "a" });
10667
10944
  const token = await this.fetchPercyToken();
10668
10945
  const configPath = await this.createPercyConfig();
10669
10946
  if (!token) {
@@ -10750,13 +11027,13 @@ var Percy = class {
10750
11027
  if (!this.#options.percyOptions) {
10751
11028
  return null;
10752
11029
  }
10753
- const configPath = path9.join(os3.tmpdir(), "percy.json");
11030
+ const configPath = path10.join(os4.tmpdir(), "percy.json");
10754
11031
  const percyOptions = this.#options.percyOptions;
10755
11032
  if (!percyOptions.version) {
10756
11033
  percyOptions.version = "2";
10757
11034
  }
10758
11035
  return new Promise((resolve) => {
10759
- fs10.writeFile(
11036
+ fs11.writeFile(
10760
11037
  configPath,
10761
11038
  JSON.stringify(
10762
11039
  percyOptions
@@ -10850,6 +11127,7 @@ init_constants();
10850
11127
  init_util();
10851
11128
  init_crash_reporter();
10852
11129
  init_bstackLogger();
11130
+ init_caCert();
10853
11131
  init_PercyLogger();
10854
11132
 
10855
11133
  // src/config.ts
@@ -10857,10 +11135,62 @@ init_testOpsConfig();
10857
11135
  init_util();
10858
11136
  init_bstackLogger();
10859
11137
  import { v4 as uuidv4 } from "uuid";
11138
+ var APP_AUTOMATE_CAP_KEYS = ["appium:app", "appium:bundleId", "appium:appPackage", "appium:appActivity"];
11139
+ function hasAppCap(cap) {
11140
+ if (!cap || typeof cap !== "object") {
11141
+ return false;
11142
+ }
11143
+ const record = cap;
11144
+ if (APP_AUTOMATE_CAP_KEYS.some((key) => !isUndefined(record[key]))) {
11145
+ return true;
11146
+ }
11147
+ const appiumOptions = record["appium:options"];
11148
+ return !!(appiumOptions && !isUndefined(appiumOptions.app));
11149
+ }
11150
+ function detectAppAutomate(capabilities) {
11151
+ if (!capabilities) {
11152
+ return false;
11153
+ }
11154
+ const flat = [];
11155
+ if (Array.isArray(capabilities)) {
11156
+ for (const entry of capabilities) {
11157
+ if (!entry || typeof entry !== "object") {
11158
+ continue;
11159
+ }
11160
+ if ("alwaysMatch" in entry) {
11161
+ const w3c = entry;
11162
+ flat.push(w3c.alwaysMatch);
11163
+ if (Array.isArray(w3c.firstMatch)) {
11164
+ flat.push(...w3c.firstMatch);
11165
+ }
11166
+ continue;
11167
+ }
11168
+ const values = Object.values(entry);
11169
+ const isParallelMultiremote = values.length > 0 && values.every(
11170
+ (v) => v !== null && typeof v === "object" && v.capabilities
11171
+ );
11172
+ if (isParallelMultiremote) {
11173
+ for (const v of values) {
11174
+ flat.push(v.capabilities);
11175
+ }
11176
+ } else {
11177
+ flat.push(entry);
11178
+ }
11179
+ }
11180
+ } else {
11181
+ for (const v of Object.values(capabilities)) {
11182
+ const inner = v.capabilities;
11183
+ if (inner) {
11184
+ flat.push(inner);
11185
+ }
11186
+ }
11187
+ }
11188
+ return flat.some(hasAppCap);
11189
+ }
10860
11190
  var BrowserStackConfig = class _BrowserStackConfig {
10861
- static getInstance(options, config) {
11191
+ static getInstance(options, config, capabilities, isBrowserStackInfra) {
10862
11192
  if (!this._instance && options && config) {
10863
- this._instance = new _BrowserStackConfig(options, config);
11193
+ this._instance = new _BrowserStackConfig(options, config, capabilities, isBrowserStackInfra);
10864
11194
  }
10865
11195
  return this._instance;
10866
11196
  }
@@ -10881,7 +11211,7 @@ var BrowserStackConfig = class _BrowserStackConfig {
10881
11211
  percyBuildId;
10882
11212
  isPercyAutoEnabled = false;
10883
11213
  sdkRunID;
10884
- constructor(options, config) {
11214
+ constructor(options, config, capabilities, isBrowserStackInfra = true) {
10885
11215
  this.framework = config.framework;
10886
11216
  this.userName = config.user;
10887
11217
  this.accessKey = config.key;
@@ -10889,11 +11219,11 @@ var BrowserStackConfig = class _BrowserStackConfig {
10889
11219
  this.percy = options.percy || false;
10890
11220
  this.accessibility = options.accessibility;
10891
11221
  this.app = options.app;
10892
- this.appAutomate = !isUndefined(options.app);
10893
- this.automate = !this.appAutomate;
11222
+ this.appAutomate = isBrowserStackInfra && (!isUndefined(options.app) || detectAppAutomate(capabilities));
11223
+ this.automate = isBrowserStackInfra && !this.appAutomate;
10894
11224
  this.buildIdentifier = options.buildIdentifier;
10895
11225
  this.sdkRunID = uuidv4();
10896
- BStackLogger2.info(`BrowserStack service started with id: ${this.sdkRunID}`);
11226
+ BStackLogger.info(`BrowserStack service started with id: ${this.sdkRunID}`);
10897
11227
  }
10898
11228
  sentFunnelData() {
10899
11229
  this.funnelDataSent = true;
@@ -10903,32 +11233,32 @@ var config_default = BrowserStackConfig;
10903
11233
 
10904
11234
  // src/exitHandler.ts
10905
11235
  import { spawn as spawn4 } from "node:child_process";
10906
- import path16 from "node:path";
11236
+ import path17 from "node:path";
10907
11237
 
10908
11238
  // src/instrumentation/funnelInstrumentation.ts
10909
11239
  init_usageStats();
10910
11240
  init_bstackLogger();
10911
11241
  init_constants();
10912
- import os4 from "node:os";
11242
+ import os5 from "node:os";
10913
11243
  import util4, { format as format2 } from "node:util";
10914
- import path11 from "node:path";
10915
- import fs12 from "node:fs";
11244
+ import path12 from "node:path";
11245
+ import fs13 from "node:fs";
10916
11246
 
10917
11247
  // src/data-store.ts
10918
11248
  init_bstackLogger();
10919
- import path10 from "node:path";
10920
- import fs11 from "node:fs";
10921
- var workersDataDirPath = path10.join(process.cwd(), "logs", "worker_data");
11249
+ import path11 from "node:path";
11250
+ import fs12 from "node:fs";
11251
+ var workersDataDirPath = path11.join(process.cwd(), "logs", "worker_data");
10922
11252
  function getDataFromWorkers() {
10923
11253
  const workersData = [];
10924
- if (!fs11.existsSync(workersDataDirPath)) {
11254
+ if (!fs12.existsSync(workersDataDirPath)) {
10925
11255
  return workersData;
10926
11256
  }
10927
- const files = fs11.readdirSync(workersDataDirPath);
11257
+ const files = fs12.readdirSync(workersDataDirPath);
10928
11258
  files.forEach((file) => {
10929
- BStackLogger2.debug("Reading worker file " + file);
10930
- const filePath = path10.join(workersDataDirPath, file);
10931
- const fileContent = fs11.readFileSync(filePath, "utf8");
11259
+ BStackLogger.debug("Reading worker file " + file);
11260
+ const filePath = path11.join(workersDataDirPath, file);
11261
+ const fileContent = fs12.readFileSync(filePath, "utf8");
10932
11262
  const workerData = JSON.parse(fileContent);
10933
11263
  workersData.push(workerData);
10934
11264
  });
@@ -10936,21 +11266,21 @@ function getDataFromWorkers() {
10936
11266
  return workersData;
10937
11267
  }
10938
11268
  function saveWorkerData(data) {
10939
- const filePath = path10.join(workersDataDirPath, "worker-data-" + process.pid + ".json");
11269
+ const filePath = path11.join(workersDataDirPath, "worker-data-" + process.pid + ".json");
10940
11270
  try {
10941
11271
  createWorkersDataDir();
10942
- fs11.writeFileSync(filePath, JSON.stringify(data));
11272
+ fs12.writeFileSync(filePath, JSON.stringify(data));
10943
11273
  } catch (e) {
10944
- BStackLogger2.debug("Exception in saving worker data: " + e);
11274
+ BStackLogger.debug("Exception in saving worker data: " + e);
10945
11275
  }
10946
11276
  }
10947
11277
  function removeWorkersDataDir() {
10948
- fs11.rmSync(workersDataDirPath, { recursive: true, force: true });
11278
+ fs12.rmSync(workersDataDirPath, { recursive: true, force: true });
10949
11279
  return true;
10950
11280
  }
10951
11281
  function createWorkersDataDir() {
10952
- if (!fs11.existsSync(workersDataDirPath)) {
10953
- fs11.mkdirSync(workersDataDirPath, { recursive: true });
11282
+ if (!fs12.existsSync(workersDataDirPath)) {
11283
+ fs12.mkdirSync(workersDataDirPath, { recursive: true });
10954
11284
  }
10955
11285
  return true;
10956
11286
  }
@@ -10964,16 +11294,16 @@ init_performance_tester();
10964
11294
  init_constants2();
10965
11295
  async function fireFunnelTestEvent(eventType, config, isCLIEnabled = false) {
10966
11296
  if (!config.userName || !config.accessKey) {
10967
- BStackLogger2.debug("username/accesskey not passed");
11297
+ BStackLogger.debug("username/accesskey not passed");
10968
11298
  return;
10969
11299
  }
10970
11300
  try {
10971
11301
  const data = buildEventData(eventType, config, isCLIEnabled);
10972
11302
  await fireFunnelRequest(data);
10973
- BStackLogger2.debug("Funnel event success");
11303
+ BStackLogger.debug("Funnel event success");
10974
11304
  config.sentFunnelData();
10975
11305
  } catch (error) {
10976
- BStackLogger2.debug(`Exception in sending funnel data: ${format2(error)}`);
11306
+ BStackLogger.debug(`Exception in sending funnel data: ${format2(error)}`);
10977
11307
  }
10978
11308
  }
10979
11309
  async function sendStart(config) {
@@ -10998,9 +11328,9 @@ async function sendFinish(config, isCLIEnabled = false) {
10998
11328
  }
10999
11329
  function saveFunnelData(eventType, config, isCLIEnabled = false) {
11000
11330
  const data = buildEventData(eventType, config, isCLIEnabled);
11001
- BStackLogger2.ensureLogsFolder();
11002
- const filePath = path11.join(BStackLogger2.logFolderPath, "funnelData.json");
11003
- fs12.writeFileSync(filePath, JSON.stringify(data));
11331
+ BStackLogger.ensureLogsFolder();
11332
+ const filePath = path12.join(BStackLogger.logFolderPath, "funnelData.json");
11333
+ fs13.writeFileSync(filePath, JSON.stringify(data));
11004
11334
  return filePath;
11005
11335
  }
11006
11336
  function redactCredentialsFromFunnelData(data) {
@@ -11017,7 +11347,7 @@ function redactCredentialsFromFunnelData(data) {
11017
11347
  async function fireFunnelRequest(data) {
11018
11348
  const { userName, accessKey } = data;
11019
11349
  redactCredentialsFromFunnelData(data);
11020
- BStackLogger2.debug("Sending SDK event with data " + util4.inspect(data, { depth: 6 }));
11350
+ BStackLogger.debug("Sending SDK event with data " + util4.inspect(data, { depth: 6 }));
11021
11351
  const encodedAuth = Buffer.from(`${userName}:${accessKey}`, "utf8").toString("base64");
11022
11352
  const response = await fetchWrap(APIUtils.FUNNEL_INSTRUMENTATION_URL, {
11023
11353
  method: "POST",
@@ -11027,7 +11357,7 @@ async function fireFunnelRequest(data) {
11027
11357
  },
11028
11358
  body: JSON.stringify(data)
11029
11359
  });
11030
- BStackLogger2.debug("Funnel Event Response: " + JSON.stringify(await response.text()));
11360
+ BStackLogger.debug("Funnel Event Response: " + JSON.stringify(await response.text()));
11031
11361
  }
11032
11362
  function getProductList(config) {
11033
11363
  const products = [];
@@ -11061,8 +11391,8 @@ function buildEventData(eventType, config, isCLIEnabled = false) {
11061
11391
  buildName: config.buildName || "undefined",
11062
11392
  buildIdentifier: String(config.buildIdentifier),
11063
11393
  // Host details
11064
- os: os4.type() || "unknown",
11065
- hostname: os4.hostname() || "unknown",
11394
+ os: os5.type() || "unknown",
11395
+ hostname: os5.hostname() || "unknown",
11066
11396
  // Product Details
11067
11397
  productMap: getProductMap(config),
11068
11398
  product: getProductList(config),
@@ -11077,6 +11407,10 @@ function buildEventData(eventType, config, isCLIEnabled = false) {
11077
11407
  if (process.env.BSTACK_A11Y_POLLING_TIMEOUT) {
11078
11408
  eventProperties.pollingTimeout = process.env.BSTACK_A11Y_POLLING_TIMEOUT;
11079
11409
  }
11410
+ const reloadHappened = workerData.some((worker2) => worker2.reloadHappened === true);
11411
+ if (reloadHappened) {
11412
+ eventProperties.finishedMetadata = { reason: "session_reloaded" };
11413
+ }
11080
11414
  }
11081
11415
  return {
11082
11416
  userName: config.userName,
@@ -11112,30 +11446,30 @@ function isProxyError(authResult) {
11112
11446
  function handleProxyError(config, isSelfHealEnabled) {
11113
11447
  sendEvent.tcgProxyFailure(config);
11114
11448
  if (isSelfHealEnabled) {
11115
- BStackLogger2.warn("Proxy Error. Disabling Healing for this session.");
11449
+ BStackLogger.warn("Proxy Error. Disabling Healing for this session.");
11116
11450
  }
11117
11451
  }
11118
11452
  function handleUpgradeRequired(isSelfHealEnabled) {
11119
11453
  if (isSelfHealEnabled) {
11120
- BStackLogger2.warn("Please upgrade Browserstack Service to the latest version to use the self-healing feature.");
11454
+ BStackLogger.warn("Please upgrade Browserstack Service to the latest version to use the self-healing feature.");
11121
11455
  }
11122
11456
  }
11123
11457
  function handleAuthenticationFailure(status, config, isSelfHealEnabled) {
11124
11458
  if (status >= 500) {
11125
11459
  if (isSelfHealEnabled) {
11126
- BStackLogger2.warn("Something went wrong. Disabling healing for this session. Please try again later.");
11460
+ BStackLogger.warn("Something went wrong. Disabling healing for this session. Please try again later.");
11127
11461
  }
11128
11462
  sendEvent.tcgDown(config);
11129
11463
  } else {
11130
11464
  if (isSelfHealEnabled) {
11131
- BStackLogger2.warn("Authentication Failed. Disabling Healing for this session.");
11465
+ BStackLogger.warn("Authentication Failed. Disabling Healing for this session.");
11132
11466
  }
11133
11467
  sendEvent.tcgAuthFailure(config);
11134
11468
  }
11135
11469
  }
11136
11470
  function handleAuthenticationSuccess(isHealingEnabledForUser, userId, config, isSelfHealEnabled) {
11137
11471
  if (!isHealingEnabledForUser && isSelfHealEnabled) {
11138
- BStackLogger2.warn("Healing is not enabled for your group, please contact the admin");
11472
+ BStackLogger.warn("Healing is not enabled for your group, please contact the admin");
11139
11473
  } else if (userId && isHealingEnabledForUser) {
11140
11474
  sendEvent.tcgtInitSuccessful(config);
11141
11475
  }
@@ -11147,7 +11481,7 @@ function handleInitializationFailure(status, config, isSelfHealEnabled) {
11147
11481
  sendEvent.invalidTcgAuth(config);
11148
11482
  }
11149
11483
  if (isSelfHealEnabled) {
11150
- BStackLogger2.warn("Authentication Failed. Healing will be disabled for this session.");
11484
+ BStackLogger.warn("Authentication Failed. Healing will be disabled for this session.");
11151
11485
  }
11152
11486
  }
11153
11487
  function handleHealingInstrumentation(authResult, config, isSelfHealEnabled) {
@@ -11174,7 +11508,7 @@ function handleHealingInstrumentation(authResult, config, isSelfHealEnabled) {
11174
11508
  return;
11175
11509
  }
11176
11510
  } catch (err) {
11177
- BStackLogger2.debug("Error in handling healing instrumentation: " + err);
11511
+ BStackLogger.debug("Error in handling healing instrumentation: " + err);
11178
11512
  }
11179
11513
  }
11180
11514
 
@@ -11186,36 +11520,36 @@ init_bstackLogger();
11186
11520
  init_cli();
11187
11521
  import { fileURLToPath as fileURLToPath2 } from "node:url";
11188
11522
  var __filename = fileURLToPath2(import.meta.url);
11189
- var __dirname = path16.dirname(__filename);
11523
+ var __dirname = path17.dirname(__filename);
11190
11524
  function setupExitHandlers() {
11191
11525
  const handleCLICleanup = () => {
11192
- BStackLogger2.debug("Handling CLI cleanup in exit handler");
11526
+ BStackLogger.debug("Handling CLI cleanup in exit handler");
11193
11527
  try {
11194
11528
  const cliProcess = BrowserstackCLI.getInstance()?.process;
11195
11529
  if (cliProcess && cliProcess.pid && cliProcess.exitCode === null) {
11196
- BStackLogger2.debug(`Found CLI process with PID ${cliProcess.pid}, terminating`);
11530
+ BStackLogger.debug(`Found CLI process with PID ${cliProcess.pid}, terminating`);
11197
11531
  try {
11198
11532
  if (process.platform === "win32") {
11199
11533
  cliProcess.kill("SIGTERM");
11200
- BStackLogger2.debug("CLI process terminated successfully with SIGTERM (Windows)");
11534
+ BStackLogger.debug("CLI process terminated successfully with SIGTERM (Windows)");
11201
11535
  } else {
11202
11536
  cliProcess.kill("SIGINT");
11203
- BStackLogger2.debug("CLI process terminated successfully with SIGINT (Unix)");
11537
+ BStackLogger.debug("CLI process terminated successfully with SIGINT (Unix)");
11204
11538
  }
11205
11539
  } catch (processError2) {
11206
- BStackLogger2.debug(`CLI process termination error: ${processError2}`);
11540
+ BStackLogger.debug(`CLI process termination error: ${processError2}`);
11207
11541
  try {
11208
11542
  cliProcess.kill();
11209
- BStackLogger2.debug("CLI process terminated with default signal (fallback)");
11543
+ BStackLogger.debug("CLI process terminated with default signal (fallback)");
11210
11544
  } catch (fallbackError) {
11211
- BStackLogger2.debug(`CLI process fallback termination error: ${fallbackError}`);
11545
+ BStackLogger.debug(`CLI process fallback termination error: ${fallbackError}`);
11212
11546
  }
11213
11547
  }
11214
11548
  } else {
11215
- BStackLogger2.debug("No CLI process found to terminate");
11549
+ BStackLogger.debug("No CLI process found to terminate");
11216
11550
  }
11217
11551
  } catch (error) {
11218
- BStackLogger2.debug(`Error in CLI cleanup: ${error}`);
11552
+ BStackLogger.debug(`Error in CLI cleanup: ${error}`);
11219
11553
  }
11220
11554
  };
11221
11555
  process.on("exit", () => {
@@ -11223,8 +11557,8 @@ function setupExitHandlers() {
11223
11557
  handleCLICleanup();
11224
11558
  const args = shouldCallCleanup(config_default.getInstance(), isCLIEnabled);
11225
11559
  if (Array.isArray(args) && args.length) {
11226
- BStackLogger2.debug(`Spawning cleanup.js with args: ${args.join(", ")}`);
11227
- const childProcess = spawn4("node", [`${path16.join(__dirname, "cleanup.js")}`, ...args], { detached: true, stdio: "inherit", env: { ...process.env } });
11560
+ BStackLogger.debug(`Spawning cleanup.js with args: ${args.join(", ")}`);
11561
+ const childProcess = spawn4("node", [`${path17.join(__dirname, "cleanup.js")}`, ...args], { detached: true, stdio: "inherit", env: { ...process.env } });
11228
11562
  childProcess.unref();
11229
11563
  }
11230
11564
  });
@@ -11250,8 +11584,8 @@ function shouldCallCleanup(config, isCLIEnabled = false) {
11250
11584
  // src/ai-handler.ts
11251
11585
  init_bstackLogger();
11252
11586
  init_constants();
11253
- import path17 from "node:path";
11254
- import fs13 from "node:fs";
11587
+ import path18 from "node:path";
11588
+ import fs14 from "node:fs";
11255
11589
  import url2 from "node:url";
11256
11590
  import aiSDK from "@browserstack/ai-sdk-node";
11257
11591
  init_util();
@@ -11278,7 +11612,7 @@ var AiHandler = class {
11278
11612
  }
11279
11613
  } else if (options.selfHeal === true) {
11280
11614
  const healingWarnMessage = authResult.message;
11281
- BStackLogger2.warn(`Healing Auth failed. Disabling healing for this session. Reason: ${healingWarnMessage}`);
11615
+ BStackLogger.warn(`Healing Auth failed. Disabling healing for this session. Reason: ${healingWarnMessage}`);
11282
11616
  }
11283
11617
  return caps;
11284
11618
  }
@@ -11287,8 +11621,8 @@ var AiHandler = class {
11287
11621
  }
11288
11622
  async installFirefoxExtension(browser) {
11289
11623
  const __dirname2 = url2.fileURLToPath(new URL(".", import.meta.url));
11290
- const extensionPath = path17.resolve(__dirname2, aiSDK.BrowserstackHealing.getFirefoxAddonPath());
11291
- const extFile = fs13.readFileSync(extensionPath);
11624
+ const extensionPath = path18.resolve(__dirname2, aiSDK.BrowserstackHealing.getFirefoxAddonPath());
11625
+ const extFile = fs14.readFileSync(extensionPath);
11292
11626
  await browser.installAddOn(extFile.toString("base64"), true);
11293
11627
  }
11294
11628
  async handleHealing(orginalFunc, using, value, browser, options) {
@@ -11315,7 +11649,7 @@ var AiHandler = class {
11315
11649
  return result;
11316
11650
  }
11317
11651
  if (options.selfHeal === true && this.authResult.isHealingEnabled) {
11318
- BStackLogger2.info("findElement failed, trying to heal");
11652
+ BStackLogger.info("findElement failed, trying to heal");
11319
11653
  PerformanceTester.start(AI_EVENTS.SELF_HEAL_STEP);
11320
11654
  const script = await aiSDK.BrowserstackHealing.healFailure(locatorType, locatorValue, void 0, void 0, this.authResult.userId, this.authResult.groupId, sessionId, void 0, void 0, this.authResult.isGroupAIEnabled, tcgDetails);
11321
11655
  if (script) {
@@ -11325,7 +11659,7 @@ var AiHandler = class {
11325
11659
  PerformanceTester.end(AI_EVENTS.SELF_HEAL_GET_RESULT);
11326
11660
  if (tcgData && tcgData.selector && tcgData.value) {
11327
11661
  const healedResult = await orginalFunc(tcgData.selector, tcgData.value);
11328
- BStackLogger2.info("Healing worked, element found: " + tcgData.selector + ": " + tcgData.value);
11662
+ BStackLogger.info("Healing worked, element found: " + tcgData.selector + ": " + tcgData.value);
11329
11663
  PerformanceTester.end(AI_EVENTS.SELF_HEAL_STEP);
11330
11664
  return healedResult.error ? result : healedResult;
11331
11665
  }
@@ -11337,9 +11671,9 @@ var AiHandler = class {
11337
11671
  } catch (err) {
11338
11672
  PerformanceTester.end(AI_EVENTS.SELF_HEAL_STEP, false, String(err));
11339
11673
  if (options.selfHeal === true) {
11340
- BStackLogger2.warn("Something went wrong while healing. Disabling healing for this command");
11674
+ BStackLogger.warn("Something went wrong while healing. Disabling healing for this command");
11341
11675
  } else {
11342
- BStackLogger2.warn("Error in findElement: " + err + "using: " + using + "value: " + value);
11676
+ BStackLogger.warn("Error in findElement: " + err + "using: " + using + "value: " + value);
11343
11677
  }
11344
11678
  }
11345
11679
  return await orginalFunc(using, value);
@@ -11375,7 +11709,7 @@ var AiHandler = class {
11375
11709
  }
11376
11710
  } catch (err) {
11377
11711
  if (options.selfHeal === true) {
11378
- BStackLogger2.warn(`Error while initiliazing Browserstack healing Extension ${err}`);
11712
+ BStackLogger.warn(`Error while initiliazing Browserstack healing Extension ${err}`);
11379
11713
  }
11380
11714
  }
11381
11715
  return caps;
@@ -11384,7 +11718,7 @@ var AiHandler = class {
11384
11718
  if (SUPPORTED_BROWSERS_FOR_AI.includes(browser.capabilities?.browserName?.toLowerCase())) {
11385
11719
  const authInfo = this.authResult;
11386
11720
  if (Object.keys(authInfo).length === 0 && options.selfHeal === true) {
11387
- BStackLogger2.debug("TCG Auth result is empty");
11721
+ BStackLogger.debug("TCG Auth result is empty");
11388
11722
  return;
11389
11723
  }
11390
11724
  const { isAuthenticated, sessionToken, defaultLogDataEnabled } = authInfo;
@@ -11412,7 +11746,7 @@ var AiHandler = class {
11412
11746
  }
11413
11747
  } catch (err) {
11414
11748
  if (options.selfHeal === true) {
11415
- BStackLogger2.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
11749
+ BStackLogger.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
11416
11750
  }
11417
11751
  }
11418
11752
  }
@@ -11430,9 +11764,10 @@ var BrowserstackLauncherService = class {
11430
11764
  constructor(_options, capabilities, _config) {
11431
11765
  this._options = _options;
11432
11766
  this._config = _config;
11433
- BStackLogger2.clearLogFile();
11767
+ BStackLogger.clearLogFile();
11434
11768
  PercyLogger.clearLogFile();
11435
11769
  setupExitHandlers();
11770
+ configureCaCertificate(this._options);
11436
11771
  if (!this._config) {
11437
11772
  this._config = _options;
11438
11773
  }
@@ -11454,12 +11789,13 @@ var BrowserstackLauncherService = class {
11454
11789
  if (!isUndefined(process.env.TEST_REPORTING_BUILD_TAG)) {
11455
11790
  process.env.TEST_OBSERVABILITY_BUILD_TAG = process.env.TEST_REPORTING_BUILD_TAG;
11456
11791
  }
11457
- this.browserStackConfig = config_default.getInstance(_options, _config);
11458
- BStackLogger2.debug(`_options data: ${JSON.stringify(_options)}`);
11459
- BStackLogger2.debug(`webdriver capabilities data: ${JSON.stringify(capabilities)}`);
11792
+ const isBrowserStackInfra = isBrowserstackInfra(_config, capabilities);
11793
+ this.browserStackConfig = config_default.getInstance(_options, _config, capabilities, isBrowserStackInfra);
11794
+ BStackLogger.debug(`_options data: ${JSON.stringify(_options)}`);
11795
+ BStackLogger.debug(`webdriver capabilities data: ${JSON.stringify(capabilities)}`);
11460
11796
  const configCopy = JSON.parse(JSON.stringify(_config));
11461
11797
  CrashReporter.recursivelyRedactKeysFromObject(configCopy, ["user", "username", "key", "accesskey", "password"]);
11462
- BStackLogger2.debug(`_config data: ${JSON.stringify(configCopy)}`);
11798
+ BStackLogger.debug(`_config data: ${JSON.stringify(configCopy)}`);
11463
11799
  if (Array.isArray(capabilities)) {
11464
11800
  capabilities.flatMap((c) => {
11465
11801
  if ("alwaysMatch" in c) {
@@ -11546,9 +11882,11 @@ var BrowserstackLauncherService = class {
11546
11882
  try {
11547
11883
  CrashReporter.setConfigDetails(this._config, capabilities, this._options);
11548
11884
  } catch (error) {
11549
- BStackLogger2.error(`[Crash_Report_Upload] Config processing failed due to ${error}`);
11885
+ BStackLogger.error(`[Crash_Report_Upload] Config processing failed due to ${error}`);
11550
11886
  }
11551
11887
  }
11888
+ _options;
11889
+ _config;
11552
11890
  browserstackLocal;
11553
11891
  _buildName;
11554
11892
  _projectName;
@@ -11576,7 +11914,7 @@ var BrowserstackLauncherService = class {
11576
11914
  if (config.specs && Array.isArray(config.specs) && isValidEnabledValue(this._options.testOrchestrationOptions?.runSmartSelection?.enabled)) {
11577
11915
  try {
11578
11916
  const glob = (await import("glob")).sync;
11579
- const path21 = await import("node:path");
11917
+ const path22 = await import("node:path");
11580
11918
  const expandedSpecs = [];
11581
11919
  for (const specPattern of config.specs) {
11582
11920
  if (typeof specPattern === "string") {
@@ -11593,21 +11931,21 @@ var BrowserstackLauncherService = class {
11593
11931
  }) || [];
11594
11932
  filenames.forEach((filename) => {
11595
11933
  let absolutePath = filename;
11596
- if (!path21.isAbsolute(filename)) {
11597
- absolutePath = path21.resolve(rootDir, filename);
11934
+ if (!path22.isAbsolute(filename)) {
11935
+ absolutePath = path22.resolve(rootDir, filename);
11598
11936
  }
11599
- let relativePath = path21.relative(cwd, absolutePath);
11937
+ let relativePath = path22.relative(cwd, absolutePath);
11600
11938
  relativePath = relativePath.replace(/\\/g, "/");
11601
11939
  expandedSpecs.push(relativePath);
11602
11940
  });
11603
11941
  }
11604
11942
  }
11605
11943
  if (expandedSpecs.length > 0) {
11606
- BStackLogger2.info(`Expanded specs from glob patterns to ${expandedSpecs.length} files`);
11944
+ BStackLogger.info(`Expanded specs from glob patterns to ${expandedSpecs.length} files`);
11607
11945
  config.specs = expandedSpecs;
11608
11946
  }
11609
11947
  } catch (error) {
11610
- BStackLogger2.error(`Failed to expand spec patterns: ${error}`);
11948
+ BStackLogger.error(`Failed to expand spec patterns: ${error}`);
11611
11949
  }
11612
11950
  }
11613
11951
  try {
@@ -11618,11 +11956,11 @@ var BrowserstackLauncherService = class {
11618
11956
  CLIUtils.setFrameworkDetail(WDIO_NAMING_PREFIX + config.framework, "WebdriverIO");
11619
11957
  const binconfig = CLIUtils.getBinConfig(config, capabilities, this._options, this._buildTag);
11620
11958
  await BrowserstackCLI.getInstance().bootstrap(this._options, config, binconfig);
11621
- BStackLogger2.debug(`Is CLI running ${BrowserstackCLI.getInstance().isRunning()}`);
11959
+ BStackLogger.debug(`Is CLI running ${BrowserstackCLI.getInstance().isRunning()}`);
11622
11960
  PerformanceTester.end(FRAMEWORK_EVENTS.START);
11623
11961
  }
11624
11962
  } catch (err) {
11625
- BStackLogger2.error(`Error while starting CLI ${err}`);
11963
+ BStackLogger.error(`Error while starting CLI ${err}`);
11626
11964
  PerformanceTester.end(FRAMEWORK_EVENTS.START, false, format4(err));
11627
11965
  }
11628
11966
  PerformanceTester.end(FRAMEWORK_EVENTS.INIT);
@@ -11641,13 +11979,13 @@ var BrowserstackLauncherService = class {
11641
11979
  }
11642
11980
  } catch (err) {
11643
11981
  if (this._options.selfHeal === true) {
11644
- BStackLogger2.warn(`Error while setting up Browserstack healing Extension ${err}. Disabling healing for this session.`);
11982
+ BStackLogger.warn(`Error while setting up Browserstack healing Extension ${err}. Disabling healing for this session.`);
11645
11983
  }
11646
11984
  }
11647
11985
  }
11648
11986
  if (!BrowserstackCLI.getInstance().isRunning()) {
11649
11987
  if (!this._options.app) {
11650
- BStackLogger2.debug("app is not defined in browserstack-service config, skipping ...");
11988
+ BStackLogger.debug("app is not defined in browserstack-service config, skipping ...");
11651
11989
  } else {
11652
11990
  let app = {};
11653
11991
  const appConfig = this._options.app;
@@ -11656,10 +11994,10 @@ var BrowserstackLauncherService = class {
11656
11994
  } catch (error) {
11657
11995
  throw new SevereServiceError(error.message);
11658
11996
  }
11659
- if (VALID_APP_EXTENSION.includes(path20.extname(app.app))) {
11660
- if (fs14.existsSync(app.app)) {
11997
+ if (VALID_APP_EXTENSION.includes(path21.extname(app.app))) {
11998
+ if (fs15.existsSync(app.app)) {
11661
11999
  const data = await this._uploadApp(app);
11662
- BStackLogger2.info(`app upload completed: ${JSON.stringify(data)}`);
12000
+ BStackLogger.info(`app upload completed: ${JSON.stringify(data)}`);
11663
12001
  app.app = data.app_url;
11664
12002
  } else if (app.customId) {
11665
12003
  app.app = app.customId;
@@ -11667,7 +12005,7 @@ var BrowserstackLauncherService = class {
11667
12005
  throw new SevereServiceError(`[Invalid app path] app path ${app.app} is not correct, Provide correct path to app under test`);
11668
12006
  }
11669
12007
  }
11670
- BStackLogger2.info(`Using app: ${app.app}`);
12008
+ BStackLogger.info(`Using app: ${app.app}`);
11671
12009
  this._updateCaps(capabilities, "app", app.app);
11672
12010
  }
11673
12011
  }
@@ -11680,7 +12018,7 @@ var BrowserstackLauncherService = class {
11680
12018
  const shouldSetupPercy = this._options.percy || isUndefined(this._options.percy) && this._options.app;
11681
12019
  let buildStartResponse = null;
11682
12020
  if (!BrowserstackCLI.getInstance().isRunning() && (this._options.testObservability || this._accessibilityAutomation || shouldSetupPercy)) {
11683
- BStackLogger2.debug("Sending launch start event");
12021
+ BStackLogger.debug("Sending launch start event");
11684
12022
  buildStartResponse = await launchTestSession(this._options, this._config, {
11685
12023
  projectName: this._projectName,
11686
12024
  buildName: this._buildName,
@@ -11739,15 +12077,15 @@ var BrowserstackLauncherService = class {
11739
12077
  if (typeof spec !== "string") {
11740
12078
  return spec;
11741
12079
  }
11742
- const absolutePath = path20.isAbsolute(spec) ? spec : path20.resolve(cwd, spec);
11743
- const relativePath = path20.relative(rootDir, absolutePath);
12080
+ const absolutePath = path21.isAbsolute(spec) ? spec : path21.resolve(cwd, spec);
12081
+ const relativePath = path21.relative(rootDir, absolutePath);
11744
12082
  return relativePath.replace(/\\/g, "/");
11745
12083
  });
11746
12084
  };
11747
12085
  try {
11748
12086
  const { applyOrchestrationIfEnabled: applyOrchestrationIfEnabled2 } = await Promise.resolve().then(() => (init_apply_orchestration(), apply_orchestration_exports));
11749
12087
  if (config.specs && config.specs.length > 0 && this._options.testObservability && isValidEnabledValue(this._options.testOrchestrationOptions?.runSmartSelection?.enabled)) {
11750
- BStackLogger2.info("Applying test orchestration");
12088
+ BStackLogger.info("Applying test orchestration");
11751
12089
  const specs = config.specs.filter((spec) => typeof spec === "string");
11752
12090
  console.log(`Specs before orchestration: ${specs}`);
11753
12091
  const orderedSpecs = await applyOrchestrationIfEnabled2(specs, this._options);
@@ -11755,14 +12093,14 @@ var BrowserstackLauncherService = class {
11755
12093
  const specsToConvert = orderedSpecs && orderedSpecs.length > 0 ? orderedSpecs : specs;
11756
12094
  config.specs = convertToRootDirRelative(specsToConvert);
11757
12095
  console.log(`Specs after orchestration: ${config.specs}`);
11758
- BStackLogger2.info("Test specs updated with orchestrated order");
12096
+ BStackLogger.info("Test specs updated with orchestrated order");
11759
12097
  }
11760
12098
  } catch (error) {
11761
- BStackLogger2.error(`Error applying test orchestration: ${error}`);
12099
+ BStackLogger.error(`Error applying test orchestration: ${error}`);
11762
12100
  if (config.specs && config.specs.length > 0) {
11763
12101
  const specs = config.specs.filter((spec) => typeof spec === "string");
11764
12102
  config.specs = convertToRootDirRelative(specs);
11765
- BStackLogger2.debug(`Specs converted back to rootDir-relative after error: ${config.specs}`);
12103
+ BStackLogger.debug(`Specs converted back to rootDir-relative after error: ${config.specs}`);
11766
12104
  }
11767
12105
  }
11768
12106
  }
@@ -11770,7 +12108,7 @@ var BrowserstackLauncherService = class {
11770
12108
  return;
11771
12109
  }
11772
12110
  if (!this._options.browserstackLocal) {
11773
- return BStackLogger2.info("browserstackLocal is not enabled - skipping...");
12111
+ return BStackLogger.info("browserstackLocal is not enabled - skipping...");
11774
12112
  }
11775
12113
  const opts = {
11776
12114
  key: this._config.key,
@@ -11783,7 +12121,7 @@ var BrowserstackLauncherService = class {
11783
12121
  }
11784
12122
  const obs = new PerformanceObserver2((list) => {
11785
12123
  const entry = list.getEntries()[0];
11786
- BStackLogger2.info(`Browserstack Local successfully started after ${entry.duration}ms`);
12124
+ BStackLogger.info(`Browserstack Local successfully started after ${entry.duration}ms`);
11787
12125
  });
11788
12126
  obs.observe({ entryTypes: ["measure"] });
11789
12127
  let timer;
@@ -11816,13 +12154,13 @@ var BrowserstackLauncherService = class {
11816
12154
  PerformanceTester.start(FRAMEWORK_EVENTS.STOP);
11817
12155
  try {
11818
12156
  const isCLIEnabled = BrowserstackCLI.getInstance().isRunning();
11819
- BStackLogger2.debug("Inside OnComplete hook..");
11820
- BStackLogger2.debug("Sending stop launch event");
12157
+ BStackLogger.debug("Inside OnComplete hook..");
12158
+ BStackLogger.debug("Sending stop launch event");
11821
12159
  try {
11822
12160
  await (isCLIEnabled ? BrowserstackCLI.getInstance().stop() : stopBuildUpstream());
11823
12161
  PerformanceTester.end(FRAMEWORK_EVENTS.STOP);
11824
12162
  } catch (err) {
11825
- BStackLogger2.error(`Error while stopping CLI ${err}`);
12163
+ BStackLogger.error(`Error while stopping CLI ${err}`);
11826
12164
  PerformanceTester.end(FRAMEWORK_EVENTS.STOP, false, format4(err));
11827
12165
  }
11828
12166
  if (process.env[BROWSERSTACK_OBSERVABILITY] && process.env[BROWSERSTACK_TESTHUB_UUID]) {
@@ -11838,16 +12176,16 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11838
12176
  return;
11839
12177
  }
11840
12178
  const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(process.env.START_TIME).getTime();
11841
- BStackLogger2.info(`Total duration is ${duration / 1e3} s`);
12179
+ BStackLogger.info(`Total duration is ${duration / 1e3} s`);
11842
12180
  }
11843
- BStackLogger2.info(`BrowserStack service run ended for id: ${this.browserStackConfig?.sdkRunID} testhub id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
12181
+ BStackLogger.info(`BrowserStack service run ended for id: ${this.browserStackConfig?.sdkRunID} testhub id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
11844
12182
  await sendFinish(this.browserStackConfig, isCLIEnabled);
11845
12183
  try {
11846
12184
  PerformanceTester.start(EVENTS.SDK_SEND_LOGS);
11847
12185
  await this._uploadServiceLogs();
11848
12186
  PerformanceTester.end(EVENTS.SDK_SEND_LOGS);
11849
12187
  } catch (error) {
11850
- BStackLogger2.debug(`Failed to upload BrowserStack WDIO Service logs ${error}`);
12188
+ BStackLogger.debug(`Failed to upload BrowserStack WDIO Service logs ${error}`);
11851
12189
  PerformanceTester.end(EVENTS.SDK_SEND_LOGS, false, format4(error));
11852
12190
  }
11853
12191
  PerformanceTester.end(EVENTS.SDK_ON_STOP);
@@ -11857,9 +12195,9 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11857
12195
  PerformanceTester.end(EVENTS.SDK_ON_STOP, false, format4(error));
11858
12196
  PerformanceTester.end(EVENTS.SDK_CLEANUP, false, format4(error));
11859
12197
  await PerformanceTester.stopAndGenerate("performance-launcher.html");
11860
- BStackLogger2.error(`Error in onComplete hook: ${error}`);
12198
+ BStackLogger.error(`Error in onComplete hook: ${error}`);
11861
12199
  }
11862
- BStackLogger2.clearLogger();
12200
+ BStackLogger.clearLogger();
11863
12201
  if (this._options.percy) {
11864
12202
  await this.stopPercy();
11865
12203
  PercyLogger.clearLogger();
@@ -11943,10 +12281,10 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11943
12281
  }
11944
12282
  }
11945
12283
  async _uploadApp(app) {
11946
- BStackLogger2.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ""} to browserstack`);
12284
+ BStackLogger.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ""} to browserstack`);
11947
12285
  const form = new FormData();
11948
12286
  if (app.app) {
11949
- const fileName = path20.basename(app.app);
12287
+ const fileName = path21.basename(app.app);
11950
12288
  const fileBuffer = await readFile(app.app);
11951
12289
  const fileBlob = new Blob([new Uint8Array(fileBuffer)]);
11952
12290
  form.append("file", fileBlob, fileName);
@@ -11995,8 +12333,8 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11995
12333
  const clientBuildUuid = this._getClientBuildUuid();
11996
12334
  const response = await uploadLogs(getBrowserStackUser(this._config), getBrowserStackKey(this._config), clientBuildUuid);
11997
12335
  if (response) {
11998
- BStackLogger2.info(`Upload response: ${JSON.stringify(response, null, 2)}`);
11999
- BStackLogger2.logToFile(`Response - ${format4(response)}`, "debug");
12336
+ BStackLogger.info(`Upload response: ${JSON.stringify(response, null, 2)}`);
12337
+ BStackLogger.logToFile(`Response - ${format4(response)}`, "debug");
12000
12338
  }
12001
12339
  }
12002
12340
  _removeCliOnlyCapabilityOptions(capabilities) {
@@ -12129,7 +12467,7 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12129
12467
  });
12130
12468
  }
12131
12469
  } catch (error) {
12132
- BStackLogger2.debug(`Exception while retrieving capability value. Error - ${error}`);
12470
+ BStackLogger.debug(`Exception while retrieving capability value. Error - ${error}`);
12133
12471
  }
12134
12472
  }
12135
12473
  _updateCaps(capabilities, capType, value) {
@@ -12265,7 +12603,7 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12265
12603
  }
12266
12604
  if ((!this._buildName || process.env.BROWSERSTACK_BUILD_NAME) && this._buildIdentifier) {
12267
12605
  this._updateCaps(capabilities, "buildIdentifier");
12268
- BStackLogger2.warn("Skipping buildIdentifier as buildName is not passed.");
12606
+ BStackLogger.warn("Skipping buildIdentifier as buildName is not passed.");
12269
12607
  return;
12270
12608
  }
12271
12609
  if (this._buildIdentifier && this._buildIdentifier.includes("${DATE_TIME}")) {
@@ -12308,16 +12646,16 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12308
12646
  * else returns corresponding value in json file (e.g. { "wdio-build": { "identifier" : 2 } } => 2 in this case)
12309
12647
  */
12310
12648
  _getLocalBuildNumber() {
12311
- const browserstackFolderPath = path20.join(os6.homedir(), ".browserstack");
12649
+ const browserstackFolderPath = path21.join(os7.homedir(), ".browserstack");
12312
12650
  try {
12313
- if (!fs14.existsSync(browserstackFolderPath)) {
12314
- fs14.mkdirSync(browserstackFolderPath);
12651
+ if (!fs15.existsSync(browserstackFolderPath)) {
12652
+ fs15.mkdirSync(browserstackFolderPath);
12315
12653
  }
12316
- const filePath = path20.join(browserstackFolderPath, ".build-name-cache.json");
12317
- if (!fs14.existsSync(filePath)) {
12318
- fs14.appendFileSync(filePath, JSON.stringify({}));
12654
+ const filePath = path21.join(browserstackFolderPath, ".build-name-cache.json");
12655
+ if (!fs15.existsSync(filePath)) {
12656
+ fs15.appendFileSync(filePath, JSON.stringify({}));
12319
12657
  }
12320
- const buildCacheFileData = fs14.readFileSync(filePath);
12658
+ const buildCacheFileData = fs15.readFileSync(filePath);
12321
12659
  const parsedBuildCacheFileData = JSON.parse(buildCacheFileData.toString());
12322
12660
  if (this._buildName && this._buildName in parsedBuildCacheFileData) {
12323
12661
  const prevIdentifier = parseInt(parsedBuildCacheFileData[this._buildName].identifier);
@@ -12336,16 +12674,16 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12336
12674
  if (!buildName || !filePath) {
12337
12675
  return;
12338
12676
  }
12339
- const jsonContent = JSON.parse(fs14.readFileSync(filePath).toString());
12677
+ const jsonContent = JSON.parse(fs15.readFileSync(filePath).toString());
12340
12678
  jsonContent[buildName] = { "identifier": buildIdentifier };
12341
- fs14.writeFileSync(filePath, JSON.stringify(jsonContent));
12679
+ fs15.writeFileSync(filePath, JSON.stringify(jsonContent));
12342
12680
  }
12343
12681
  _getClientBuildUuid() {
12344
12682
  if (process.env[BROWSERSTACK_TESTHUB_UUID]) {
12345
12683
  return process.env[BROWSERSTACK_TESTHUB_UUID];
12346
12684
  }
12347
12685
  const uuid = this.browserStackConfig?.sdkRunID;
12348
- BStackLogger2.logToFile(`If facing any issues, please contact BrowserStack support with the Build Run Id - ${uuid}`, "info");
12686
+ BStackLogger.logToFile(`If facing any issues, please contact BrowserStack support with the Build Run Id - ${uuid}`, "info");
12349
12687
  return uuid;
12350
12688
  }
12351
12689
  };
@@ -12367,6 +12705,7 @@ init_util();
12367
12705
  init_insights_handler();
12368
12706
  init_reporter();
12369
12707
  init_constants();
12708
+ init_caCert();
12370
12709
  init_crash_reporter();
12371
12710
 
12372
12711
  // src/accessibility-handler.ts
@@ -12400,6 +12739,9 @@ var _AccessibilityHandler = class {
12400
12739
  this._config = _config;
12401
12740
  this._turboscale = isTrue(_turboscale);
12402
12741
  }
12742
+ _browser;
12743
+ isAppAutomate;
12744
+ _framework;
12403
12745
  _platformA11yMeta;
12404
12746
  _caps;
12405
12747
  _suiteFile;
@@ -12490,7 +12832,7 @@ var _AccessibilityHandler = class {
12490
12832
  };
12491
12833
  browserWithA11y.startA11yScanning = async () => {
12492
12834
  if (this._testIdentifier === null) {
12493
- BStackLogger2.warn("Accessibility scanning cannot be started from outside the test");
12835
+ BStackLogger.warn("Accessibility scanning cannot be started from outside the test");
12494
12836
  return;
12495
12837
  }
12496
12838
  AccessibilityHandler._a11yScanSessionMap[sessionId] = true;
@@ -12502,7 +12844,7 @@ var _AccessibilityHandler = class {
12502
12844
  };
12503
12845
  browserWithA11y.stopA11yScanning = async () => {
12504
12846
  if (this._testIdentifier === null) {
12505
- BStackLogger2.warn("Accessibility scanning cannot be stopped from outside the test");
12847
+ BStackLogger.warn("Accessibility scanning cannot be stopped from outside the test");
12506
12848
  return;
12507
12849
  }
12508
12850
  AccessibilityHandler._a11yScanSessionMap[sessionId] = false;
@@ -12521,7 +12863,7 @@ var _AccessibilityHandler = class {
12521
12863
  const prevImpl = orig ? orig.bind(browser) : void 0;
12522
12864
  browser.overwriteCommand(command.name, this.commandWrapper.bind(this, command, prevImpl), command.class === "Element");
12523
12865
  } catch (error) {
12524
- BStackLogger2.debug(`Exception in overwrite command ${command.name} - ${error}`);
12866
+ BStackLogger.debug(`Exception in overwrite command ${command.name} - ${error}`);
12525
12867
  }
12526
12868
  });
12527
12869
  PerformanceTester.end(CONFIG_EVENTS.ACCESSIBILITY);
@@ -12545,14 +12887,14 @@ var _AccessibilityHandler = class {
12545
12887
  };
12546
12888
  this._testMetadata[testIdentifier].accessibilityScanStarted = shouldScanTest;
12547
12889
  if (shouldScanTest) {
12548
- BStackLogger2.info("Automate test case execution has started.");
12890
+ BStackLogger.info("Automate test case execution has started.");
12549
12891
  }
12550
12892
  } catch (error) {
12551
- BStackLogger2.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12893
+ BStackLogger.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12552
12894
  }
12553
12895
  }
12554
12896
  async afterTest(suiteTitle, test) {
12555
- BStackLogger2.debug("Accessibility after test hook. Before sending test stop event");
12897
+ BStackLogger.debug("Accessibility after test hook. Before sending test stop event");
12556
12898
  if (this._framework !== "mocha" || !this.shouldRunTestHooks(this._browser, this._accessibility)) {
12557
12899
  return;
12558
12900
  }
@@ -12564,17 +12906,17 @@ var _AccessibilityHandler = class {
12564
12906
  return;
12565
12907
  }
12566
12908
  if (shouldScanTestForAccessibility2) {
12567
- BStackLogger2.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12909
+ BStackLogger.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12568
12910
  const dataForExtension = {
12569
12911
  "thTestRunUuid": process.env.TEST_ANALYTICS_ID,
12570
12912
  "thBuildUuid": process.env.BROWSERSTACK_TESTHUB_UUID,
12571
12913
  "thJwtToken": process.env.BROWSERSTACK_TESTHUB_JWT
12572
12914
  };
12573
12915
  await this.sendTestStopEvent(this._browser, dataForExtension);
12574
- BStackLogger2.info("Accessibility testing for this test case has ended.");
12916
+ BStackLogger.info("Accessibility testing for this test case has ended.");
12575
12917
  }
12576
12918
  } catch (error) {
12577
- BStackLogger2.error(`Accessibility results could not be processed for the test case ${test.title}. Error : ${error}`);
12919
+ BStackLogger.error(`Accessibility results could not be processed for the test case ${test.title}. Error : ${error}`);
12578
12920
  }
12579
12921
  }
12580
12922
  /**
@@ -12602,14 +12944,14 @@ var _AccessibilityHandler = class {
12602
12944
  }
12603
12945
  listener_default.setTestRunAccessibilityVar(this._accessibility && shouldScanScenario);
12604
12946
  if (shouldScanScenario) {
12605
- BStackLogger2.info("Automate test case execution has started.");
12947
+ BStackLogger.info("Automate test case execution has started.");
12606
12948
  }
12607
12949
  } catch (error) {
12608
- BStackLogger2.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12950
+ BStackLogger.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12609
12951
  }
12610
12952
  }
12611
12953
  async afterScenario(world) {
12612
- BStackLogger2.debug("Accessibility after scenario hook. Before sending test stop event");
12954
+ BStackLogger.debug("Accessibility after scenario hook. Before sending test stop event");
12613
12955
  if (!this.shouldRunTestHooks(this._browser, this._accessibility)) {
12614
12956
  return;
12615
12957
  }
@@ -12622,17 +12964,17 @@ var _AccessibilityHandler = class {
12622
12964
  return;
12623
12965
  }
12624
12966
  if (shouldScanTestForAccessibility2) {
12625
- BStackLogger2.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12967
+ BStackLogger.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12626
12968
  const dataForExtension = {
12627
12969
  "thTestRunUuid": process.env.TEST_ANALYTICS_ID,
12628
12970
  "thBuildUuid": process.env.BROWSERSTACK_TESTHUB_UUID,
12629
12971
  "thJwtToken": process.env.BROWSERSTACK_TESTHUB_JWT
12630
12972
  };
12631
12973
  await this.sendTestStopEvent(this._browser, dataForExtension);
12632
- BStackLogger2.info("Accessibility testing for this test case has ended.");
12974
+ BStackLogger.info("Accessibility testing for this test case has ended.");
12633
12975
  }
12634
12976
  } catch (error) {
12635
- BStackLogger2.error(`Accessibility results could not be processed for the test case ${pickleData.name}. Error : ${error}`);
12977
+ BStackLogger.error(`Accessibility results could not be processed for the test case ${pickleData.name}. Error : ${error}`);
12636
12978
  }
12637
12979
  }
12638
12980
  /*
@@ -12640,14 +12982,14 @@ var _AccessibilityHandler = class {
12640
12982
  */
12641
12983
  async commandWrapper(command, prevImpl, origFunction, ...args) {
12642
12984
  if (this._sessionId && AccessibilityHandler._a11yScanSessionMap[this._sessionId] && (!command.name.includes("execute") || !AccessibilityHandler.shouldPatchExecuteScript(args.length ? args[0] : null))) {
12643
- BStackLogger2.debug(`Performing scan for ${command.class} ${command.name}`);
12985
+ BStackLogger.debug(`Performing scan for ${command.class} ${command.name}`);
12644
12986
  await performA11yScan(this.isAppAutomate, this._browser, true, true, command.name);
12645
12987
  }
12646
12988
  const impl = prevImpl || origFunction;
12647
12989
  return impl(...args);
12648
12990
  }
12649
12991
  async sendTestStopEvent(browser, dataForExtension) {
12650
- BStackLogger2.debug("Performing scan before saving results");
12992
+ BStackLogger.debug("Performing scan before saving results");
12651
12993
  if (AccessibilityHandler._a11yScanSessionMap[this._sessionId]) {
12652
12994
  await PerformanceTester.measureWrapper(A11Y_EVENTS.PERFORM_SCAN, async () => {
12653
12995
  await performA11yScan(this.isAppAutomate, browser, true, true);
@@ -12659,9 +13001,9 @@ var _AccessibilityHandler = class {
12659
13001
  await PerformanceTester.measureWrapper(A11Y_EVENTS.SAVE_RESULTS, async () => {
12660
13002
  if (accessibility_scripts_default.saveTestResults) {
12661
13003
  const results = await executeAccessibilityScript(browser, accessibility_scripts_default.saveTestResults, dataForExtension);
12662
- BStackLogger2.debug(util11.format(results));
13004
+ BStackLogger.debug(util11.format(results));
12663
13005
  } else {
12664
- BStackLogger2.error("saveTestResults script is null or undefined");
13006
+ BStackLogger.error("saveTestResults script is null or undefined");
12665
13007
  }
12666
13008
  })();
12667
13009
  }
@@ -12738,6 +13080,7 @@ var BrowserstackService = class {
12738
13080
  this._caps = _caps;
12739
13081
  this._config = _config;
12740
13082
  this._options = { ...DEFAULT_OPTIONS, ...options };
13083
+ configureCaCertificate(this._options);
12741
13084
  if (!this._config) {
12742
13085
  this._config = this._options;
12743
13086
  }
@@ -12762,6 +13105,8 @@ var BrowserstackService = class {
12762
13105
  process.env.PERCY_SNAPSHOT = "true";
12763
13106
  }
12764
13107
  }
13108
+ _caps;
13109
+ _config;
12765
13110
  _sessionBaseUrl = "https://api.browserstack.com/automate/sessions";
12766
13111
  _failReasons = [];
12767
13112
  _hookFailReasons = [];
@@ -12771,6 +13116,8 @@ var BrowserstackService = class {
12771
13116
  // Track last scenario for preferScenarioName feature
12772
13117
  _scenariosRanCount = 0;
12773
13118
  // Count of non-skipped scenarios
13119
+ _reloadHappened = false;
13120
+ // Set when browser.reloadSession() is called; surfaced as finishedMetadata on SDKTestSuccessful so reload-orphaned builds can be excluded from session-linking
12774
13121
  _failureStatuses = ["failed", "ambiguous", "undefined", "unknown"];
12775
13122
  _browser;
12776
13123
  _suiteTitle;
@@ -12830,20 +13177,20 @@ var BrowserstackService = class {
12830
13177
  NOT_ALLOWED_KEYS_IN_CAPS.forEach((key) => delete capabilities[`browserstack.${key}`]);
12831
13178
  }
12832
13179
  } catch (err) {
12833
- BStackLogger2.error(`Error while tracking automation framework event: ${err}`);
13180
+ BStackLogger.error(`Error while tracking automation framework event: ${err}`);
12834
13181
  }
12835
13182
  } catch (err) {
12836
- BStackLogger2.error(`Error while connecting to Browserstack CLI: ${err}`);
13183
+ BStackLogger.error(`Error while connecting to Browserstack CLI: ${err}`);
12837
13184
  PerformanceTester.end(DRIVER_EVENT.INIT, false, util12.format(err));
12838
13185
  throw err;
12839
13186
  }
12840
13187
  PerformanceTester.end(DRIVER_EVENT.INIT);
12841
13188
  PerformanceTester.start(EVENTS.SDK_DEVICE_ALLOCATION);
12842
- BStackLogger2.debug("Device allocation tracking started - waiting for WebDriverIO to create remote session");
13189
+ BStackLogger.debug("Device allocation tracking started - waiting for WebDriverIO to create remote session");
12843
13190
  }
12844
13191
  async before(caps, specs, browser) {
12845
13192
  PerformanceTester.end(EVENTS.SDK_DEVICE_ALLOCATION, true, "Device allocated and session created");
12846
- BStackLogger2.debug("Device allocation tracking ended - remote session created successfully");
13193
+ BStackLogger.debug("Device allocation tracking ended - remote session created successfully");
12847
13194
  PerformanceTester.start(DRIVER_EVENT.PRE_INITIALIZE);
12848
13195
  this._browser = browser ? browser : globalThis.browser;
12849
13196
  PerformanceTester.browser = this._browser;
@@ -12852,7 +13199,7 @@ var BrowserstackService = class {
12852
13199
  await ai_handler_default.selfHeal(this._options, caps, this._browser);
12853
13200
  } catch (err) {
12854
13201
  if (this._options.selfHeal === true) {
12855
- BStackLogger2.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
13202
+ BStackLogger.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
12856
13203
  }
12857
13204
  }
12858
13205
  }
@@ -12882,13 +13229,13 @@ var BrowserstackService = class {
12882
13229
  this._options.accessibilityOptions
12883
13230
  );
12884
13231
  if (isBrowserstackSession(this._browser) && BrowserstackCLI.getInstance().isRunning()) {
12885
- BStackLogger2.info(`CLI is running, tracking accessibility event for before: ${sessionId}`);
13232
+ BStackLogger.info(`CLI is running, tracking accessibility event for before: ${sessionId}`);
12886
13233
  } else {
12887
13234
  await this._accessibilityHandler.before(sessionId);
12888
13235
  }
12889
13236
  listener_default.setAccessibilityOptions(this._options.accessibilityOptions);
12890
13237
  } catch (err) {
12891
- BStackLogger2.error(`[Accessibility Test Run] Error in service class before function: ${err}`);
13238
+ BStackLogger.error(`[Accessibility Test Run] Error in service class before function: ${err}`);
12892
13239
  }
12893
13240
  if (shouldProcessEventForTesthub("")) {
12894
13241
  patchConsoleLogs();
@@ -12899,7 +13246,7 @@ var BrowserstackService = class {
12899
13246
  this._options
12900
13247
  );
12901
13248
  if (BrowserstackCLI.getInstance().isRunning()) {
12902
- BStackLogger2.info(`CLI is running, tracking insights event for before: ${sessionId}`);
13249
+ BStackLogger.info(`CLI is running, tracking insights event for before: ${sessionId}`);
12903
13250
  await BrowserstackCLI.getInstance().getAutomationFramework().trackEvent(AutomationFrameworkState.CREATE, HookState.POST, { browser: this._browser, hubUrl: this._config.hostname });
12904
13251
  this._insightsHandler.setGitConfigPath();
12905
13252
  PerformanceTester.end(DRIVER_EVENT.PRE_INITIALIZE);
@@ -12934,7 +13281,7 @@ var BrowserstackService = class {
12934
13281
  });
12935
13282
  }
12936
13283
  } catch (err) {
12937
- BStackLogger2.error(`Error in service class before function: ${err}`);
13284
+ BStackLogger.error(`Error in service class before function: ${err}`);
12938
13285
  if (shouldProcessEventForTesthub("")) {
12939
13286
  CrashReporter.uploadCrashReport(`Error in service class before function: ${err}`, err ? err.stack : "unknown error");
12940
13287
  }
@@ -13118,7 +13465,7 @@ var BrowserstackService = class {
13118
13465
  return;
13119
13466
  }
13120
13467
  } catch (error) {
13121
- BStackLogger2.error(`Error in after hook: ${error}`);
13468
+ BStackLogger.error(`Error in after hook: ${error}`);
13122
13469
  PerformanceTester.end(DRIVER_EVENT.QUIT, false, util12.format(error));
13123
13470
  PerformanceTester.end(HOOK_EVENTS.AFTER, false, util12.format(error));
13124
13471
  await PerformanceTester.stopAndGenerate("performance-service.html");
@@ -13175,6 +13522,7 @@ var BrowserstackService = class {
13175
13522
  if (!this._browser) {
13176
13523
  return Promise.resolve();
13177
13524
  }
13525
+ this._reloadHappened = true;
13178
13526
  const { setSessionName, setSessionStatus } = this._options;
13179
13527
  const ignoreHooksStatus = this._options.testObservabilityOptions?.ignoreHooksStatus === true;
13180
13528
  let sessionStatus;
@@ -13189,14 +13537,14 @@ var BrowserstackService = class {
13189
13537
  failureReason = hasReasons ? this._failReasons.join("\n") : void 0;
13190
13538
  }
13191
13539
  if (!this._browser.isMultiremote) {
13192
- BStackLogger2.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${sessionStatus}`);
13540
+ BStackLogger.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${sessionStatus}`);
13193
13541
  } else {
13194
13542
  const browserName = this._browser.instances.filter(
13195
13543
  (browserName2) => this._browser && this._browser.getInstance(browserName2).sessionId === newSessionId
13196
13544
  )[0];
13197
- BStackLogger2.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${sessionStatus}`);
13545
+ BStackLogger.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${sessionStatus}`);
13198
13546
  }
13199
- BStackLogger2.warn(`Session Reloaded: Old Session Id: ${oldSessionId}, New Session Id: ${newSessionId}`);
13547
+ BStackLogger.warn(`Session Reloaded: Old Session Id: ${oldSessionId}, New Session Id: ${newSessionId}`);
13200
13548
  await this._insightsHandler?.sendCBTInfo();
13201
13549
  if (setSessionStatus) {
13202
13550
  await this._update(oldSessionId, {
@@ -13222,7 +13570,7 @@ var BrowserstackService = class {
13222
13570
  }
13223
13571
  _updateJob(requestBody) {
13224
13572
  return this._multiRemoteAction((sessionId, browserName) => {
13225
- BStackLogger2.info(
13573
+ BStackLogger.info(
13226
13574
  browserName ? `Update multiremote job for browser "${browserName}" and sessionId ${sessionId}` : `Update job with sessionId ${sessionId}`
13227
13575
  );
13228
13576
  return this._update(sessionId, requestBody);
@@ -13248,7 +13596,7 @@ var BrowserstackService = class {
13248
13596
  return Promise.resolve();
13249
13597
  }
13250
13598
  const sessionUrl = `${this._sessionBaseUrl}/${sessionId}.json`;
13251
- BStackLogger2.debug(`Updating Browserstack session at ${sessionUrl} with request body: `, requestBody);
13599
+ BStackLogger.debug(`Updating Browserstack session at ${sessionUrl} with request body: `, requestBody);
13252
13600
  const encodedAuth = Buffer.from(`${this._config.user}:${this._config.key}`, "utf8").toString("base64");
13253
13601
  const headers = {
13254
13602
  "Content-Type": "application/json; charset=utf-8",
@@ -13273,7 +13621,7 @@ var BrowserstackService = class {
13273
13621
  }
13274
13622
  await this._multiRemoteAction(async (sessionId, browserName) => {
13275
13623
  const sessionUrl = `${this._sessionBaseUrl}/${sessionId}.json`;
13276
- BStackLogger2.debug(`Requesting Browserstack session URL at ${sessionUrl}`);
13624
+ BStackLogger.debug(`Requesting Browserstack session URL at ${sessionUrl}`);
13277
13625
  let browserUrl;
13278
13626
  const encodedAuth = Buffer.from(`${this._config.user}:${this._config.key}`, "utf8").toString("base64");
13279
13627
  const headers = {
@@ -13300,7 +13648,7 @@ var BrowserstackService = class {
13300
13648
  }
13301
13649
  const capabilities = getBrowserCapabilities(this._browser, this._caps, browserName);
13302
13650
  const browserString = getBrowserDescription(capabilities);
13303
- BStackLogger2.info(`${browserString} session: ${browserUrl}`);
13651
+ BStackLogger.info(`${browserString} session: ${browserUrl}`);
13304
13652
  });
13305
13653
  }
13306
13654
  async _setSessionName(suiteTitle, test) {
@@ -13349,7 +13697,8 @@ var BrowserstackService = class {
13349
13697
  }
13350
13698
  saveWorkerData() {
13351
13699
  saveWorkerData({
13352
- usageStats: usageStats_default.getInstance().getDataToSave()
13700
+ usageStats: usageStats_default.getInstance().getDataToSave(),
13701
+ reloadHappened: this._reloadHappened
13353
13702
  });
13354
13703
  }
13355
13704
  };