@wdio/browserstack-service 9.27.2 → 9.28.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
@@ -23,7 +23,7 @@ var init_package = __esm({
23
23
  "package.json"() {
24
24
  package_default = {
25
25
  name: "@wdio/browserstack-service",
26
- version: "9.27.1",
26
+ version: "9.27.2",
27
27
  description: "WebdriverIO service for better Browserstack integration",
28
28
  author: "Adam Bjerstedt <abjerstedt@gmail.com>",
29
29
  homepage: "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
@@ -97,7 +97,7 @@ var init_package = __esm({
97
97
  });
98
98
 
99
99
  // 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;
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, 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
101
  var init_constants = __esm({
102
102
  "src/constants.ts"() {
103
103
  "use strict";
@@ -157,6 +157,17 @@ var init_constants = __esm({
157
157
  "HTTP": "http"
158
158
  };
159
159
  SUPPORTED_BROWSERS_FOR_AI = ["chrome", "microsoftedge", "firefox"];
160
+ SUPPORTED_BROWSERS_FOR_ACCESSIBILITY = ["chrome", "chromefortesting", "safari"];
161
+ MIN_BROWSER_VERSIONS_A11Y = {
162
+ chrome: 95,
163
+ chromefortesting: 141,
164
+ safari: 18.4
165
+ };
166
+ MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK = {
167
+ chrome: 100,
168
+ chromefortesting: 141,
169
+ safari: 18.4
170
+ };
160
171
  TCG_URL = "https://tcg.browserstack.com";
161
172
  TCG_INFO = {
162
173
  tcgRegion: "use",
@@ -268,34 +279,155 @@ var init_apiUtils = __esm({
268
279
  }
269
280
  });
270
281
 
282
+ // src/caCert.ts
283
+ import { setGlobalDispatcher, Agent } from "undici";
284
+ import tls from "node:tls";
285
+ import fs from "node:fs";
286
+ import os from "node:os";
287
+ import path from "node:path";
288
+ function derToPem(der) {
289
+ const b64 = der.toString("base64").replace(/(.{64})/g, "$1\n");
290
+ return `-----BEGIN CERTIFICATE-----
291
+ ${b64}${b64.endsWith("\n") ? "" : "\n"}-----END CERTIFICATE-----
292
+ `;
293
+ }
294
+ function loadCaCertsAsPem(buf) {
295
+ if (buf.includes("-----BEGIN CERTIFICATE-----")) {
296
+ return buf.toString("utf8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) || [];
297
+ }
298
+ return [derToPem(buf)];
299
+ }
300
+ function resolveCaCertPath(options) {
301
+ let p = process.env.BROWSERSTACK_EXTRA_CA_CERTS;
302
+ if ((!p || !p.trim()) && options?.proxyCaCertificate) {
303
+ p = options.proxyCaCertificate;
304
+ }
305
+ if (!p || !String(p).trim()) {
306
+ return void 0;
307
+ }
308
+ p = String(p).trim();
309
+ try {
310
+ if (fs.existsSync(p) && fs.statSync(p).isFile()) {
311
+ return p;
312
+ }
313
+ BStackLogger.warn(`proxyCaCertificate: path does not exist or is not a file, falling back to system trust store: ${p}`);
314
+ } catch (e) {
315
+ BStackLogger.warn(`proxyCaCertificate: failed to stat cert path ${p}: ${e.message}`);
316
+ }
317
+ return void 0;
318
+ }
319
+ function getMergedCa() {
320
+ return mergedCa;
321
+ }
322
+ function configureCaCertificate(options) {
323
+ if (configured) {
324
+ return;
325
+ }
326
+ try {
327
+ const certPath = resolveCaCertPath(options);
328
+ if (!certPath) {
329
+ return;
330
+ }
331
+ const buf = fs.readFileSync(certPath);
332
+ const isPem = buf.includes("-----BEGIN CERTIFICATE-----");
333
+ const pemCerts = loadCaCertsAsPem(buf);
334
+ if (!pemCerts.length) {
335
+ BStackLogger.warn(`proxyCaCertificate: no certificate found in ${certPath}; falling back to system trust store.`);
336
+ return;
337
+ }
338
+ mergedCa = [...tls.rootCertificates, ...pemCerts];
339
+ setGlobalDispatcher(new Agent({ connect: { ca: mergedCa } }));
340
+ configured = true;
341
+ BStackLogger.info(`proxyCaCertificate: trusting custom CA from ${certPath} (merged with system roots).`);
342
+ try {
343
+ if (!process.env.NODE_EXTRA_CA_CERTS) {
344
+ let nodeExtra = certPath;
345
+ if (!isPem) {
346
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "browserstack_sdk_ca_"));
347
+ nodeExtra = path.join(tmpDir, "ca.pem");
348
+ const fd = fs.openSync(nodeExtra, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | (fs.constants.O_NOFOLLOW || 0), 384);
349
+ try {
350
+ fs.writeFileSync(fd, pemCerts.join(""));
351
+ } finally {
352
+ fs.closeSync(fd);
353
+ }
354
+ }
355
+ process.env.NODE_EXTRA_CA_CERTS = nodeExtra;
356
+ }
357
+ } catch (e) {
358
+ 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}`);
359
+ }
360
+ } catch (e) {
361
+ BStackLogger.warn(`proxyCaCertificate: setup failed, falling back to system trust store: ${e.message}`);
362
+ }
363
+ }
364
+ var mergedCa, configured;
365
+ var init_caCert = __esm({
366
+ "src/caCert.ts"() {
367
+ "use strict";
368
+ init_bstackLogger();
369
+ configured = false;
370
+ }
371
+ });
372
+
271
373
  // src/fetchWrapper.ts
272
- import { fetch as undiciFetch, ProxyAgent } from "undici";
273
- async function fetchWrap(input, init) {
274
- const res = await _fetch(input, init);
374
+ import { fetch as undiciFetch, ProxyAgent, Agent as Agent2 } from "undici";
375
+ function getDispatcher(proxyUrl, connectTimeoutMs) {
376
+ const ca = getMergedCa();
377
+ const key = `${proxyUrl ?? "direct"}:${connectTimeoutMs ?? "default"}:${ca ? "ca" : "noca"}`;
378
+ let dispatcher = dispatcherCache.get(key);
379
+ if (!dispatcher) {
380
+ const connect = {};
381
+ if (connectTimeoutMs) {
382
+ connect.timeout = connectTimeoutMs;
383
+ }
384
+ if (proxyUrl) {
385
+ dispatcher = new ProxyAgent({ uri: proxyUrl, connect, ...ca ? { requestTls: { ca } } : {} });
386
+ } else {
387
+ if (ca) {
388
+ connect.ca = ca;
389
+ }
390
+ dispatcher = new Agent2({ connect });
391
+ }
392
+ dispatcherCache.set(key, dispatcher);
393
+ }
394
+ return dispatcher;
395
+ }
396
+ async function fetchWrap(input, init, options) {
397
+ const res = await _fetch(input, init, options);
275
398
  if (!res.ok) {
276
399
  throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
277
400
  }
278
401
  return res;
279
402
  }
280
- function _fetch(input, init) {
403
+ function _fetch(input, init, options) {
404
+ const connectTimeoutMs = options?.connectTimeoutMs;
281
405
  const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
282
406
  if (proxyUrl) {
283
407
  const noProxy = process.env.NO_PROXY && process.env.NO_PROXY.trim() ? process.env.NO_PROXY.trim().split(/[\s,;]+/) : [];
284
408
  const request = new Request(input);
285
409
  const url3 = new URL(request.url);
286
410
  if (!noProxy.some((str) => url3.hostname.endsWith(str))) {
411
+ const dispatcher = getDispatcher(proxyUrl, connectTimeoutMs);
287
412
  return undiciFetch(
288
413
  request.url,
289
- { ...init, dispatcher: new ProxyAgent(proxyUrl) }
414
+ { ...init, dispatcher }
290
415
  );
291
416
  }
292
417
  }
418
+ if (connectTimeoutMs) {
419
+ return undiciFetch(
420
+ new Request(input).url,
421
+ { ...init, dispatcher: getDispatcher(void 0, connectTimeoutMs) }
422
+ );
423
+ }
293
424
  return fetch(input, init);
294
425
  }
295
- var ResponseError;
426
+ var ResponseError, dispatcherCache;
296
427
  var init_fetchWrapper = __esm({
297
428
  "src/fetchWrapper.ts"() {
298
429
  "use strict";
430
+ init_caCert();
299
431
  ResponseError = class extends Error {
300
432
  response;
301
433
  constructor(message, res) {
@@ -303,6 +435,7 @@ var init_fetchWrapper = __esm({
303
435
  this.response = res;
304
436
  }
305
437
  };
438
+ dispatcherCache = /* @__PURE__ */ new Map();
306
439
  }
307
440
  });
308
441
 
@@ -460,26 +593,26 @@ var init_constants2 = __esm({
460
593
  });
461
594
 
462
595
  // src/cli/cliLogger.ts
463
- import path from "node:path";
464
- import fs from "node:fs";
596
+ import path2 from "node:path";
597
+ import fs2 from "node:fs";
465
598
  import chalk from "chalk";
466
599
  import logger from "@wdio/logger";
467
- var log, BStackLogger;
600
+ var log, BStackLogger2;
468
601
  var init_cliLogger = __esm({
469
602
  "src/cli/cliLogger.ts"() {
470
603
  "use strict";
471
604
  init_constants();
472
605
  init_util();
473
606
  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");
607
+ BStackLogger2 = class {
608
+ static logFilePath = path2.join(process.cwd(), LOGS_FILE);
609
+ static logFolderPath = path2.join(process.cwd(), "logs");
477
610
  static logFileStream;
478
611
  static logToFile(logMessage, logLevel) {
479
612
  try {
480
613
  if (!this.logFileStream) {
481
614
  this.ensureLogsFolder();
482
- this.logFileStream = fs.createWriteStream(this.logFilePath, { flags: "a" });
615
+ this.logFileStream = fs2.createWriteStream(this.logFilePath, { flags: "a" });
483
616
  }
484
617
  if (this.logFileStream && this.logFileStream.writable) {
485
618
  this.logFileStream.write(this.formatLog(logMessage, logLevel));
@@ -523,13 +656,13 @@ var init_cliLogger = __esm({
523
656
  this.logFileStream = null;
524
657
  }
525
658
  static clearLogFile() {
526
- if (fs.existsSync(this.logFilePath)) {
527
- fs.truncateSync(this.logFilePath);
659
+ if (fs2.existsSync(this.logFilePath)) {
660
+ fs2.truncateSync(this.logFilePath);
528
661
  }
529
662
  }
530
663
  static ensureLogsFolder() {
531
- if (!fs.existsSync(this.logFolderPath)) {
532
- fs.mkdirSync(this.logFolderPath);
664
+ if (!fs2.existsSync(this.logFolderPath)) {
665
+ fs2.mkdirSync(this.logFolderPath);
533
666
  }
534
667
  }
535
668
  };
@@ -587,16 +720,16 @@ var init_testFrameworkConstants = __esm({
587
720
  });
588
721
 
589
722
  // src/cli/cliUtils.ts
590
- import fs2 from "node:fs";
723
+ import fs3 from "node:fs";
591
724
  import fsp from "node:fs/promises";
592
725
  import { platform, arch, homedir } from "node:os";
593
- import path2 from "node:path";
726
+ import path3 from "node:path";
594
727
  import util, { promisify } from "node:util";
595
728
  import { exec } from "node:child_process";
596
729
  import { Readable } from "node:stream";
597
730
  import yauzl from "yauzl";
598
731
  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;
732
+ 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
733
  var init_cliUtils = __esm({
601
734
  "src/cli/cliUtils.ts"() {
602
735
  "use strict";
@@ -613,6 +746,9 @@ var init_cliUtils = __esm({
613
746
  CLI_DOWNLOAD_TIMEOUT_MS = 5 * 60 * 1e3;
614
747
  CLI_DOWNLOAD_TMP_PREFIX = "downloaded_file_";
615
748
  CLI_DOWNLOAD_TMP_SUFFIX = ".zip";
749
+ CLI_CONNECT_TIMEOUT_MS = Number(process.env.BROWSERSTACK_CLI_CONNECT_TIMEOUT_MS) || 60 * 1e3;
750
+ CLI_FETCH_MAX_ATTEMPTS = 3;
751
+ CLI_FETCH_RETRY_BASE_DELAY_MS = 500;
616
752
  CLIUtils = class _CLIUtils {
617
753
  static automationFrameworkDetail = {};
618
754
  static testFrameworkDetail = {};
@@ -699,10 +835,10 @@ var init_cliUtils = __esm({
699
835
  return "ECMAScript";
700
836
  }
701
837
  static async setupCliPath(config) {
702
- BStackLogger.debug("Configuring Cli path.");
838
+ BStackLogger2.debug("Configuring Cli path.");
703
839
  const developmentBinaryPath = process.env.SDK_CLI_BIN_PATH || null;
704
840
  if (!isNullOrEmpty(developmentBinaryPath)) {
705
- BStackLogger.debug(`Development Cli Path: ${developmentBinaryPath}`);
841
+ BStackLogger2.debug(`Development Cli Path: ${developmentBinaryPath}`);
706
842
  return developmentBinaryPath;
707
843
  }
708
844
  try {
@@ -716,10 +852,10 @@ var init_cliUtils = __esm({
716
852
  cliDir,
717
853
  config
718
854
  );
719
- BStackLogger.debug(`Resolved binary path: ${finalBinaryPath}`);
855
+ BStackLogger2.debug(`Resolved binary path: ${finalBinaryPath}`);
720
856
  return finalBinaryPath;
721
857
  } catch (err) {
722
- BStackLogger.debug(
858
+ BStackLogger2.warn(
723
859
  `Error in setting up cli path directory, Exception: ${util.format(err)}`
724
860
  );
725
861
  }
@@ -727,18 +863,18 @@ var init_cliUtils = __esm({
727
863
  }
728
864
  static async checkAndUpdateCli(existingCliPath, cliDir, config) {
729
865
  if (process.env.BROWSERSTACK_TESTHUB_JWT) {
730
- BStackLogger.debug(
866
+ BStackLogger2.debug(
731
867
  `Worker process detected, skipping CLI update. Using existing: ${existingCliPath}`
732
868
  );
733
- if (existingCliPath && fs2.existsSync(existingCliPath)) {
869
+ if (existingCliPath && fs3.existsSync(existingCliPath)) {
734
870
  return existingCliPath;
735
871
  }
736
- BStackLogger.warn(
872
+ BStackLogger2.warn(
737
873
  "Worker process has no existing CLI binary, attempting download as fallback."
738
874
  );
739
875
  }
740
876
  PerformanceTester.start(EVENTS.SDK_CLI_CHECK_UPDATE);
741
- BStackLogger.info(`Current CLI Path Found: ${existingCliPath}`);
877
+ BStackLogger2.info(`Current CLI Path Found: ${existingCliPath}`);
742
878
  const queryParams = {
743
879
  sdk_version: _CLIUtils.getSdkVersion(),
744
880
  os: platform(),
@@ -748,7 +884,7 @@ var init_cliUtils = __esm({
748
884
  };
749
885
  if (!isNullOrEmpty(existingCliPath)) {
750
886
  if (this.isBinaryBusy(existingCliPath)) {
751
- BStackLogger.warn(`Existing binary is currently in use, skipping update: ${existingCliPath}`);
887
+ BStackLogger2.warn(`Existing binary is currently in use, skipping update: ${existingCliPath}`);
752
888
  PerformanceTester.end(EVENTS.SDK_CLI_CHECK_UPDATE);
753
889
  return existingCliPath;
754
890
  }
@@ -756,7 +892,7 @@ var init_cliUtils = __esm({
756
892
  `${existingCliPath} version`
757
893
  );
758
894
  if (version3.toLowerCase().includes("text file busy")) {
759
- BStackLogger.warn(`Binary busy during version check, skipping update: ${existingCliPath}`);
895
+ BStackLogger2.warn(`Binary busy during version check, skipping update: ${existingCliPath}`);
760
896
  PerformanceTester.end(EVENTS.SDK_CLI_CHECK_UPDATE);
761
897
  return existingCliPath;
762
898
  }
@@ -764,12 +900,12 @@ var init_cliUtils = __esm({
764
900
  }
765
901
  const response = await this.requestToUpdateCLI(queryParams, config);
766
902
  if (nestedKeyValue(response, ["updated_cli_version"])) {
767
- BStackLogger.debug(
903
+ BStackLogger2.debug(
768
904
  `Need to update binary, current binary version: ${queryParams.cli_version}`
769
905
  );
770
906
  const browserStackBinaryUrl = process.env.BROWSERSTACK_BINARY_URL || null;
771
907
  if (!isNullOrEmpty(browserStackBinaryUrl)) {
772
- BStackLogger.debug(
908
+ BStackLogger2.debug(
773
909
  `Using BROWSERSTACK_BINARY_URL: ${browserStackBinaryUrl}`
774
910
  );
775
911
  response.url = browserStackBinaryUrl;
@@ -790,13 +926,13 @@ var init_cliUtils = __esm({
790
926
  if (isNullOrEmpty(writableDir)) {
791
927
  throw new Error("No writable directory available for the CLI");
792
928
  }
793
- const cliDirPath = path2.join(writableDir, "cli");
794
- if (!fs2.existsSync(cliDirPath)) {
929
+ const cliDirPath = path3.join(writableDir, "cli");
930
+ if (!fs3.existsSync(cliDirPath)) {
795
931
  createDir(cliDirPath);
796
932
  }
797
933
  return cliDirPath;
798
934
  } catch (err) {
799
- BStackLogger.error(
935
+ BStackLogger2.error(
800
936
  `Error in getting writable directory, writableDir=${util.format(err)}`
801
937
  );
802
938
  return "";
@@ -805,39 +941,39 @@ var init_cliUtils = __esm({
805
941
  static getWritableDir() {
806
942
  const writableDirOptions = [
807
943
  process.env.BROWSERSTACK_FILES_DIR,
808
- path2.join(homedir(), ".browserstack"),
809
- path2.join("tmp", ".browserstack")
944
+ path3.join(homedir(), ".browserstack"),
945
+ path3.join("tmp", ".browserstack")
810
946
  ];
811
- for (const path21 of writableDirOptions) {
812
- if (isNullOrEmpty(path21)) {
947
+ for (const path22 of writableDirOptions) {
948
+ if (isNullOrEmpty(path22)) {
813
949
  continue;
814
950
  }
815
951
  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);
952
+ if (fs3.existsSync(path22)) {
953
+ BStackLogger2.debug(`File ${path22} already exist`);
954
+ if (!isWritable(path22)) {
955
+ BStackLogger2.debug(`Giving write permission to ${path22}`);
956
+ const success = setReadWriteAccess(path22);
821
957
  if (!isTrue(success)) {
822
- BStackLogger.warn(
823
- `Unable to provide write permission to ${path21}`
958
+ BStackLogger2.warn(
959
+ `Unable to provide write permission to ${path22}`
824
960
  );
825
961
  }
826
962
  }
827
963
  } 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);
964
+ BStackLogger2.debug(`File does not exist: ${path22}`);
965
+ createDir(path22);
966
+ BStackLogger2.debug(`Giving write permission to ${path22}`);
967
+ const success = setReadWriteAccess(path22);
832
968
  if (!isTrue(success)) {
833
- BStackLogger.warn(
834
- `Unable to provide write permission to ${path21}`
969
+ BStackLogger2.warn(
970
+ `Unable to provide write permission to ${path22}`
835
971
  );
836
972
  }
837
973
  }
838
- return path21;
974
+ return path22;
839
975
  } catch (err) {
840
- BStackLogger.error(
976
+ BStackLogger2.error(
841
977
  `Unable to get writable directory, exception ${util.format(err)}`
842
978
  );
843
979
  }
@@ -846,16 +982,16 @@ var init_cliUtils = __esm({
846
982
  }
847
983
  static getExistingCliPath(cliDir) {
848
984
  try {
849
- if (!fs2.existsSync(cliDir) || !fs2.statSync(cliDir).isDirectory()) {
985
+ if (!fs3.existsSync(cliDir) || !fs3.statSync(cliDir).isDirectory()) {
850
986
  return "";
851
987
  }
852
- const allBinaries = fs2.readdirSync(cliDir).map((file) => path2.join(cliDir, file)).filter(
853
- (filePath) => fs2.statSync(filePath).isFile() && path2.basename(filePath).startsWith("binary-")
988
+ const allBinaries = fs3.readdirSync(cliDir).map((file) => path3.join(cliDir, file)).filter(
989
+ (filePath) => fs3.statSync(filePath).isFile() && path3.basename(filePath).startsWith("binary-")
854
990
  );
855
991
  if (allBinaries.length > 0) {
856
992
  const latestBinary = allBinaries.map((filePath) => ({
857
993
  filePath,
858
- mtime: fs2.statSync(filePath).mtime
994
+ mtime: fs3.statSync(filePath).mtime
859
995
  })).reduce(
860
996
  (latest, current) => {
861
997
  if (!latest || !latest.mtime) {
@@ -872,7 +1008,7 @@ var init_cliUtils = __esm({
872
1008
  }
873
1009
  return "";
874
1010
  } catch (err) {
875
- BStackLogger.error(`Error while reading CLI path: ${util.format(err)}`);
1011
+ BStackLogger2.error(`Error while reading CLI path: ${util.format(err)}`);
876
1012
  return "";
877
1013
  }
878
1014
  }
@@ -883,22 +1019,51 @@ var init_cliUtils = __esm({
883
1019
  if (platform() === "darwin") {
884
1020
  return false;
885
1021
  }
886
- if (!fs2.existsSync(binaryPath)) {
1022
+ if (!fs3.existsSync(binaryPath)) {
887
1023
  return false;
888
1024
  }
889
1025
  try {
890
- const fd = fs2.openSync(binaryPath, "r+");
891
- fs2.closeSync(fd);
1026
+ const fd = fs3.openSync(binaryPath, "r+");
1027
+ fs3.closeSync(fd);
892
1028
  return false;
893
1029
  } catch (err) {
894
1030
  if (BINARY_BUSY_ERROR_CODES.includes(err.code)) {
895
- BStackLogger.debug(`Binary is busy: ${binaryPath}`);
1031
+ BStackLogger2.debug(`Binary is busy: ${binaryPath}`);
896
1032
  return true;
897
1033
  }
898
- BStackLogger.debug(`Error checking if binary is busy: ${err.message}`);
1034
+ BStackLogger2.debug(`Error checking if binary is busy: ${err.message}`);
899
1035
  return false;
900
1036
  }
901
1037
  }
1038
+ /**
1039
+ * fetch wrapper for CLI network calls that (a) raises undici's connect timeout
1040
+ * above the non-overridable 10s default of global fetch and (b) retries a few
1041
+ * times with linear backoff on transient connection failures. Both are needed
1042
+ * for reliability in constrained CI/containerised networks (SDK-6152).
1043
+ */
1044
+ static fetchWithRetry = async (input, init, label) => {
1045
+ let lastError;
1046
+ for (let attempt = 1; attempt <= CLI_FETCH_MAX_ATTEMPTS; attempt++) {
1047
+ try {
1048
+ return await _fetch(input, init, { connectTimeoutMs: CLI_CONNECT_TIMEOUT_MS });
1049
+ } catch (err) {
1050
+ lastError = err;
1051
+ const reason = (
1052
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1053
+ err?.cause?.code || err?.code || err?.message
1054
+ );
1055
+ BStackLogger2.warn(
1056
+ `${label} attempt ${attempt}/${CLI_FETCH_MAX_ATTEMPTS} failed: ${reason}`
1057
+ );
1058
+ if (attempt < CLI_FETCH_MAX_ATTEMPTS) {
1059
+ await new Promise(
1060
+ (resolve) => setTimeout(resolve, CLI_FETCH_RETRY_BASE_DELAY_MS * attempt)
1061
+ );
1062
+ }
1063
+ }
1064
+ }
1065
+ throw lastError;
1066
+ };
902
1067
  static requestToUpdateCLI = async (queryParams, config) => {
903
1068
  const params = new URLSearchParams(queryParams);
904
1069
  const requestInit = {
@@ -907,12 +1072,13 @@ var init_cliUtils = __esm({
907
1072
  Authorization: `Basic ${Buffer.from(`${getBrowserStackUser(config)}:${getBrowserStackKey(config)}`).toString("base64")}`
908
1073
  }
909
1074
  };
910
- const response = await _fetch(
1075
+ const response = await this.fetchWithRetry(
911
1076
  `${APIUtils.BROWSERSTACK_AUTOMATE_API_URL}/${UPDATED_CLI_ENDPOINT}?${params.toString()}`,
912
- requestInit
1077
+ requestInit,
1078
+ "update_cli request"
913
1079
  );
914
1080
  const jsonResponse = await response.json();
915
- BStackLogger.debug(`response ${JSON.stringify(jsonResponse)}`);
1081
+ BStackLogger2.debug(`response ${JSON.stringify(jsonResponse)}`);
916
1082
  return jsonResponse;
917
1083
  };
918
1084
  static runShellCommand(cmdCommand, workingDir = "") {
@@ -934,11 +1100,11 @@ var init_cliUtils = __esm({
934
1100
  });
935
1101
  }
936
1102
  static downloadLatestBinary = async (binDownloadUrl, cliDir) => {
937
- const lockPath = path2.join(cliDir, "download.lock");
1103
+ const lockPath = path3.join(cliDir, "download.lock");
938
1104
  const sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
939
1105
  const parseLockFile = () => {
940
1106
  try {
941
- const content = fs2.readFileSync(lockPath, "utf8").trim();
1107
+ const content = fs3.readFileSync(lockPath, "utf8").trim();
942
1108
  const [pidLine, timestampLine] = content.split("\n");
943
1109
  const pid = Number.parseInt(pidLine, 10);
944
1110
  const timestamp = Number.parseInt(timestampLine, 10);
@@ -962,20 +1128,20 @@ var init_cliUtils = __esm({
962
1128
  const start = Date.now();
963
1129
  while (true) {
964
1130
  try {
965
- const fd = fs2.openSync(lockPath, "wx");
1131
+ const fd = fs3.openSync(lockPath, "wx");
966
1132
  try {
967
- fs2.writeFileSync(fd, `${process.pid}
1133
+ fs3.writeFileSync(fd, `${process.pid}
968
1134
  ${Date.now()}
969
1135
  `);
970
1136
  } catch {
971
1137
  }
972
1138
  return () => {
973
1139
  try {
974
- fs2.closeSync(fd);
1140
+ fs3.closeSync(fd);
975
1141
  } catch {
976
1142
  }
977
1143
  try {
978
- fs2.unlinkSync(lockPath);
1144
+ fs3.unlinkSync(lockPath);
979
1145
  } catch {
980
1146
  }
981
1147
  };
@@ -987,19 +1153,19 @@ ${Date.now()}
987
1153
  const lockAge = Date.now() - lockMeta.timestamp;
988
1154
  const running = isProcessRunning(lockMeta.pid);
989
1155
  if (!running || lockAge > timeoutMs) {
990
- BStackLogger.warn(
1156
+ BStackLogger2.warn(
991
1157
  `Stale CLI download lock detected (pid=${lockMeta.pid}, age=${lockAge}ms). Removing lock.`
992
1158
  );
993
1159
  try {
994
- fs2.unlinkSync(lockPath);
1160
+ fs3.unlinkSync(lockPath);
995
1161
  } catch {
996
1162
  }
997
1163
  continue;
998
1164
  }
999
1165
  }
1000
1166
  const existingBinary = _CLIUtils.getExistingCliPath(cliDir);
1001
- if (existingBinary && fs2.existsSync(existingBinary) && fs2.statSync(existingBinary).size > 0) {
1002
- BStackLogger.debug(
1167
+ if (existingBinary && fs3.existsSync(existingBinary) && fs3.statSync(existingBinary).size > 0) {
1168
+ BStackLogger2.debug(
1003
1169
  `Binary appeared while waiting for lock: ${existingBinary}`
1004
1170
  );
1005
1171
  return { alreadyExists: existingBinary };
@@ -1020,16 +1186,16 @@ ${Date.now()}
1020
1186
  try {
1021
1187
  const now2 = Date.now();
1022
1188
  const tmpExtractRe = /\.tmp\.\d+$/;
1023
- for (const entry of fs2.readdirSync(cliDir)) {
1189
+ for (const entry of fs3.readdirSync(cliDir)) {
1024
1190
  const isDownloadZip = entry.startsWith(CLI_DOWNLOAD_TMP_PREFIX) && entry.endsWith(CLI_DOWNLOAD_TMP_SUFFIX);
1025
1191
  const isExtractTmp = tmpExtractRe.test(entry);
1026
1192
  if (!isDownloadZip && !isExtractTmp) {
1027
1193
  continue;
1028
1194
  }
1029
- const filePath = path2.join(cliDir, entry);
1195
+ const filePath = path3.join(cliDir, entry);
1030
1196
  let stats;
1031
1197
  try {
1032
- stats = fs2.statSync(filePath);
1198
+ stats = fs3.statSync(filePath);
1033
1199
  } catch {
1034
1200
  continue;
1035
1201
  }
@@ -1037,21 +1203,21 @@ ${Date.now()}
1037
1203
  continue;
1038
1204
  }
1039
1205
  try {
1040
- fs2.unlinkSync(filePath);
1206
+ fs3.unlinkSync(filePath);
1041
1207
  } catch (err) {
1042
- BStackLogger.debug(
1208
+ BStackLogger2.debug(
1043
1209
  `Failed to delete temp CLI file ${filePath}: ${util.format(err)}`
1044
1210
  );
1045
1211
  }
1046
1212
  }
1047
1213
  } catch (err) {
1048
- BStackLogger.debug(
1214
+ BStackLogger2.debug(
1049
1215
  `Failed to scan temp CLI files in ${cliDir}: ${util.format(err)}`
1050
1216
  );
1051
1217
  }
1052
1218
  };
1053
1219
  PerformanceTester.start(EVENTS.SDK_CLI_DOWNLOAD);
1054
- BStackLogger.debug(`Downloading SDK binary from: ${binDownloadUrl}`);
1220
+ BStackLogger2.debug(`Downloading SDK binary from: ${binDownloadUrl}`);
1055
1221
  let downloadEnded = false;
1056
1222
  const endDownload = (success = true, errMsg) => {
1057
1223
  if (downloadEnded) {
@@ -1077,8 +1243,8 @@ ${Date.now()}
1077
1243
  }
1078
1244
  releaseLock = lockResult;
1079
1245
  const existingBinary = _CLIUtils.getExistingCliPath(cliDir);
1080
- if (existingBinary && fs2.existsSync(existingBinary) && fs2.statSync(existingBinary).size > 0) {
1081
- BStackLogger.debug(
1246
+ if (existingBinary && fs3.existsSync(existingBinary) && fs3.statSync(existingBinary).size > 0) {
1247
+ BStackLogger2.debug(
1082
1248
  `Binary already exists after acquiring lock: ${existingBinary}`
1083
1249
  );
1084
1250
  endDownload();
@@ -1086,11 +1252,11 @@ ${Date.now()}
1086
1252
  return existingBinary;
1087
1253
  }
1088
1254
  cleanupTemporaryDownloads();
1089
- const zipFilePath = path2.join(
1255
+ const zipFilePath = path3.join(
1090
1256
  cliDir,
1091
1257
  `${CLI_DOWNLOAD_TMP_PREFIX}${process.pid}_${Date.now()}${CLI_DOWNLOAD_TMP_SUFFIX}`
1092
1258
  );
1093
- const downloadedFileStream = fs2.createWriteStream(zipFilePath);
1259
+ const downloadedFileStream = fs3.createWriteStream(zipFilePath);
1094
1260
  return new Promise((resolve, reject) => {
1095
1261
  const processDownload = async () => {
1096
1262
  const abortController = new AbortController();
@@ -1100,9 +1266,11 @@ ${Date.now()}
1100
1266
  );
1101
1267
  let response;
1102
1268
  try {
1103
- response = await _fetch(binDownloadUrl, {
1104
- signal: abortController.signal
1105
- });
1269
+ response = await _fetch(
1270
+ binDownloadUrl,
1271
+ { signal: abortController.signal },
1272
+ { connectTimeoutMs: CLI_CONNECT_TIMEOUT_MS }
1273
+ );
1106
1274
  } finally {
1107
1275
  clearTimeout(timeout);
1108
1276
  }
@@ -1110,7 +1278,7 @@ ${Date.now()}
1110
1278
  throw new Error("No response body received");
1111
1279
  }
1112
1280
  downloadedFileStream.on("error", function(err) {
1113
- BStackLogger.error(
1281
+ BStackLogger2.error(
1114
1282
  `Got Error while downloading cli binary file: ${err}`
1115
1283
  );
1116
1284
  endDownload(false, util.format(err));
@@ -1139,7 +1307,7 @@ ${Date.now()}
1139
1307
  }
1140
1308
  );
1141
1309
  } catch (err) {
1142
- BStackLogger.error(
1310
+ BStackLogger2.error(
1143
1311
  `Got Error in cli binary downloading request ${util.format(err)}`
1144
1312
  );
1145
1313
  endDownload(false, util.format(err));
@@ -1152,7 +1320,7 @@ ${Date.now()}
1152
1320
  } catch (err) {
1153
1321
  releaseLock?.();
1154
1322
  endDownload(false, util.format(err));
1155
- BStackLogger.debug(
1323
+ BStackLogger2.debug(
1156
1324
  `Failed to download binary, Exception: ${util.format(err)}`
1157
1325
  );
1158
1326
  return null;
@@ -1172,17 +1340,17 @@ ${Date.now()}
1172
1340
  zipfile.readEntry();
1173
1341
  return;
1174
1342
  }
1175
- const candidatePath = path2.join(cliDir, entry.fileName);
1176
- const resolvedCandidate = path2.resolve(candidatePath);
1177
- const resolvedDir = path2.resolve(cliDir) + path2.sep;
1343
+ const candidatePath = path3.join(cliDir, entry.fileName);
1344
+ const resolvedCandidate = path3.resolve(candidatePath);
1345
+ const resolvedDir = path3.resolve(cliDir) + path3.sep;
1178
1346
  if (!resolvedCandidate.startsWith(resolvedDir)) {
1179
1347
  zipfile.close();
1180
1348
  reject(new Error(`Zip-slip detected: entry "${entry.fileName}" resolves outside ${cliDir}`));
1181
1349
  return;
1182
1350
  }
1183
- const isBinaryEntry = path2.basename(entry.fileName).startsWith("binary-");
1351
+ const isBinaryEntry = path3.basename(entry.fileName).startsWith("binary-");
1184
1352
  if (!isBinaryEntry) {
1185
- const directStream = fs2.createWriteStream(candidatePath);
1353
+ const directStream = fs3.createWriteStream(candidatePath);
1186
1354
  directStream.on("error", (writeErr) => {
1187
1355
  zipfile.close();
1188
1356
  reject(writeErr);
@@ -1204,8 +1372,8 @@ ${Date.now()}
1204
1372
  return;
1205
1373
  }
1206
1374
  const finalPath = candidatePath;
1207
- const tempPath = path2.join(cliDir, `${entry.fileName}.tmp.${process.pid}`);
1208
- const writeStream = fs2.createWriteStream(tempPath);
1375
+ const tempPath = path3.join(cliDir, `${entry.fileName}.tmp.${process.pid}`);
1376
+ const writeStream = fs3.createWriteStream(tempPath);
1209
1377
  let writeStreamErrored = false;
1210
1378
  writeStream.on("error", (writeErr) => {
1211
1379
  writeStreamErrored = true;
@@ -1226,7 +1394,7 @@ ${Date.now()}
1226
1394
  if (renameErr.code !== "EXDEV") {
1227
1395
  throw renameErr;
1228
1396
  }
1229
- BStackLogger.warn(`Atomic rename failed (cross-device), falling back to copy: ${renameErr.message}`);
1397
+ BStackLogger2.warn(`Atomic rename failed (cross-device), falling back to copy: ${renameErr.message}`);
1230
1398
  await fsp.copyFile(tempPath, finalPath);
1231
1399
  await fsp.unlink(tempPath).catch(() => {
1232
1400
  });
@@ -1263,7 +1431,7 @@ ${Date.now()}
1263
1431
  });
1264
1432
  zipfile.once("end", () => {
1265
1433
  fsp.unlink(zipFilePath).catch(() => {
1266
- BStackLogger.warn(`Failed to delete zip file: ${zipFilePath}`);
1434
+ BStackLogger2.warn(`Failed to delete zip file: ${zipFilePath}`);
1267
1435
  });
1268
1436
  if (!resolvedBinaryPath) {
1269
1437
  zipfile.close();
@@ -1294,7 +1462,7 @@ ${Date.now()}
1294
1462
  }
1295
1463
  static setFrameworkDetail(testFramework, automationFramework) {
1296
1464
  if (!testFramework || !automationFramework) {
1297
- BStackLogger.debug(
1465
+ BStackLogger2.debug(
1298
1466
  `Test or Automation framework not provided testFramework=${testFramework}, automationFramework=${automationFramework}`
1299
1467
  );
1300
1468
  }
@@ -1376,12 +1544,12 @@ ${Date.now()}
1376
1544
 
1377
1545
  // src/instrumentation/performance/performance-tester.ts
1378
1546
  import { createObjectCsvWriter } from "csv-writer";
1379
- import fs3 from "node:fs";
1547
+ import fs4 from "node:fs";
1380
1548
  import fsPromise from "node:fs/promises";
1381
1549
  import { performance, PerformanceObserver } from "node:perf_hooks";
1382
1550
  import util2 from "node:util";
1383
1551
  import worker from "node:worker_threads";
1384
- import path3 from "node:path";
1552
+ import path4 from "node:path";
1385
1553
  import { arch as arch2, hostname, platform as platform2, type, version } from "node:os";
1386
1554
  var PerformanceTester;
1387
1555
  var init_performance_tester = __esm({
@@ -1406,11 +1574,11 @@ var init_performance_tester = __esm({
1406
1574
  static browser;
1407
1575
  static scenarioThatRan;
1408
1576
  static jsonReportDirName = "performance-report";
1409
- static jsonReportDirPath = path3.join(process.cwd(), "logs", this.jsonReportDirName);
1577
+ static jsonReportDirPath = path4.join(process.cwd(), "logs", this.jsonReportDirName);
1410
1578
  static jsonReportFileName = `${this.jsonReportDirPath}/performance-report-${_PerformanceTester.getProcessId()}.json`;
1411
1579
  static startMonitoring(csvName = "performance-report.csv") {
1412
- if (!fs3.existsSync(this.jsonReportDirPath)) {
1413
- fs3.mkdirSync(this.jsonReportDirPath, { recursive: true });
1580
+ if (!fs4.existsSync(this.jsonReportDirPath)) {
1581
+ fs4.mkdirSync(this.jsonReportDirPath, { recursive: true });
1414
1582
  }
1415
1583
  this._observer = new PerformanceObserver((list) => {
1416
1584
  list.getEntries().filter((entry) => entry.entryType === "measure").forEach(
@@ -1420,10 +1588,10 @@ var init_performance_tester = __esm({
1420
1588
  if (typeof finalEntry.startTime === "number" && typeof performance.timeOrigin === "number") {
1421
1589
  const originalStartTime = finalEntry.startTime;
1422
1590
  finalEntry.startTime = performance.timeOrigin + finalEntry.startTime;
1423
- BStackLogger2.debug(`Timestamp conversion for ${entry.name}: ${originalStartTime} -> ${finalEntry.startTime} (timeOrigin: ${performance.timeOrigin})`);
1591
+ BStackLogger.debug(`Timestamp conversion for ${entry.name}: ${originalStartTime} -> ${finalEntry.startTime} (timeOrigin: ${performance.timeOrigin})`);
1424
1592
  }
1425
1593
  } catch (e) {
1426
- BStackLogger2.debug(`Error converting startTime to epoch: ${util2.format(e)}`);
1594
+ BStackLogger.debug(`Error converting startTime to epoch: ${util2.format(e)}`);
1427
1595
  }
1428
1596
  if (this.details[entry.name]) {
1429
1597
  finalEntry = Object.assign(finalEntry, this.details[entry.name]);
@@ -1463,7 +1631,7 @@ var init_performance_tester = __esm({
1463
1631
  const timeTaken = methods.reduce((a, c) => {
1464
1632
  return times[c] + (a || 0);
1465
1633
  }, 0);
1466
- BStackLogger2.debug(`Time for ${methods} is ${timeTaken}`);
1634
+ BStackLogger.debug(`Time for ${methods} is ${timeTaken}`);
1467
1635
  return timeTaken;
1468
1636
  }
1469
1637
  static async stopAndGenerate(filename = "performance-own.html") {
@@ -1475,7 +1643,7 @@ var init_performance_tester = __esm({
1475
1643
  const finalJSONStr = eventsJson.slice(1, -1) + ",";
1476
1644
  await fsPromise.appendFile(this.jsonReportFileName, finalJSONStr);
1477
1645
  } catch (er) {
1478
- BStackLogger2.debug(`Failed to write events of the worker to ${this.jsonReportFileName}: ${util2.format(er)}`);
1646
+ BStackLogger.debug(`Failed to write events of the worker to ${this.jsonReportFileName}: ${util2.format(er)}`);
1479
1647
  }
1480
1648
  this._observer.disconnect();
1481
1649
  if (!process.env[PERF_MEASUREMENT_ENV]) {
@@ -1484,12 +1652,12 @@ var init_performance_tester = __esm({
1484
1652
  this.started = false;
1485
1653
  this.generateCSV(this._events);
1486
1654
  const content = this.generateReport(this._events);
1487
- const dir = path3.join(process.cwd(), filename);
1655
+ const dir = path4.join(process.cwd(), filename);
1488
1656
  try {
1489
1657
  await fsPromise.writeFile(dir, content);
1490
- BStackLogger2.info(`Performance report is at ${path3}`);
1658
+ BStackLogger.info(`Performance report is at ${path4}`);
1491
1659
  } catch (err) {
1492
- BStackLogger2.error(`Error in writing html ${util2.format(err)}`);
1660
+ BStackLogger.error(`Error in writing html ${util2.format(err)}`);
1493
1661
  }
1494
1662
  }
1495
1663
  static generateReport(entries) {
@@ -1520,7 +1688,7 @@ var init_performance_tester = __esm({
1520
1688
  time: value
1521
1689
  };
1522
1690
  });
1523
- this._csvWriter.writeRecords(dat).then(() => BStackLogger2.info("Performance CSV report generated successfully")).catch((error) => console.error(error));
1691
+ this._csvWriter.writeRecords(dat).then(() => BStackLogger.info("Performance CSV report generated successfully")).catch((error) => console.error(error));
1524
1692
  }
1525
1693
  static Measure(label, details = {}) {
1526
1694
  const self = this;
@@ -1654,16 +1822,16 @@ var init_performance_tester = __esm({
1654
1822
  this.start(EVENTS.SDK_SEND_KEY_METRICS);
1655
1823
  try {
1656
1824
  const workerId = `${process.pid}`;
1657
- BStackLogger2.debug(`[Performance Upload] Starting upload for worker ${workerId}`);
1825
+ BStackLogger.debug(`[Performance Upload] Starting upload for worker ${workerId}`);
1658
1826
  this.start(EVENTS.SDK_KEY_METRICS_PREPARATION);
1659
1827
  let measures = [];
1660
1828
  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));
1829
+ const files = (await fsPromise.readdir(this.jsonReportDirPath)).map((file) => path4.resolve(this.jsonReportDirPath, file));
1662
1830
  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
1831
  }
1664
- BStackLogger2.debug(`[Performance Upload] Total events from files: ${measures.length}`);
1832
+ BStackLogger.debug(`[Performance Upload] Total events from files: ${measures.length}`);
1665
1833
  if (this._measuredEvents.length > 0) {
1666
- BStackLogger2.debug(`[Performance Upload] Adding ${this._measuredEvents.length} in-memory events`);
1834
+ BStackLogger.debug(`[Performance Upload] Adding ${this._measuredEvents.length} in-memory events`);
1667
1835
  measures = measures.concat(
1668
1836
  this._measuredEvents.map((e) => {
1669
1837
  if (typeof e.toJSON === "function") {
@@ -1724,10 +1892,10 @@ var init_performance_tester = __esm({
1724
1892
  },
1725
1893
  body: JSON.stringify(payload)
1726
1894
  });
1727
- BStackLogger2.debug(`[Performance Upload] Successfully uploaded to EDS: ${util2.format(await result.text())}`);
1895
+ BStackLogger.debug(`[Performance Upload] Successfully uploaded to EDS: ${util2.format(await result.text())}`);
1728
1896
  this.end(EVENTS.SDK_SEND_KEY_METRICS, true);
1729
1897
  } catch (er) {
1730
- BStackLogger2.debug(`[Performance Upload] Failed to upload events: ${util2.format(er)}`);
1898
+ BStackLogger.debug(`[Performance Upload] Failed to upload events: ${util2.format(er)}`);
1731
1899
  this.end(EVENTS.SDK_KEY_METRICS_PREPARATION, false, er);
1732
1900
  this.end(EVENTS.SDK_SEND_KEY_METRICS, false, er);
1733
1901
  }
@@ -1735,12 +1903,12 @@ var init_performance_tester = __esm({
1735
1903
  if (await fsPromise.access(this.jsonReportDirPath).then(() => true, () => false)) {
1736
1904
  const files = await fsPromise.readdir(this.jsonReportDirPath);
1737
1905
  for (const file of files) {
1738
- await fsPromise.unlink(path3.join(this.jsonReportDirPath, file));
1906
+ await fsPromise.unlink(path4.join(this.jsonReportDirPath, file));
1739
1907
  }
1740
- BStackLogger2.debug(`[Performance Upload] Cleaned up ${files.length} temporary report files`);
1908
+ BStackLogger.debug(`[Performance Upload] Cleaned up ${files.length} temporary report files`);
1741
1909
  }
1742
1910
  } catch (er) {
1743
- BStackLogger2.debug(`[Performance Upload] Failed to delete temporary files: ${util2.format(er)}`);
1911
+ BStackLogger.debug(`[Performance Upload] Failed to delete temporary files: ${util2.format(er)}`);
1744
1912
  }
1745
1913
  }
1746
1914
  };
@@ -1748,7 +1916,7 @@ var init_performance_tester = __esm({
1748
1916
  });
1749
1917
 
1750
1918
  // src/testorchestration/testorcherstrationutils.ts
1751
- import fs4 from "node:fs";
1919
+ import fs5 from "node:fs";
1752
1920
  var RUN_SMART_SELECTION, ALLOWED_ORCHESTRATION_KEYS, isPlainObject, asString, TestOrdering, OrchestrationUtils;
1753
1921
  var init_testorcherstrationutils = __esm({
1754
1922
  "src/testorchestration/testorcherstrationutils.ts"() {
@@ -1816,7 +1984,7 @@ var init_testorcherstrationutils = __esm({
1816
1984
  for (const service of services) {
1817
1985
  if (Array.isArray(service) && service[0] === "browserstack" && isPlainObject(service[1]) && isPlainObject(service[1].testOrchestrationOptions)) {
1818
1986
  testOrchOptions = service[1].testOrchestrationOptions;
1819
- BStackLogger2.debug("[constructor] Found testOrchestrationOptions in browserstack service config");
1987
+ BStackLogger.debug("[constructor] Found testOrchestrationOptions in browserstack service config");
1820
1988
  break;
1821
1989
  }
1822
1990
  }
@@ -1845,9 +2013,9 @@ var init_testorcherstrationutils = __esm({
1845
2013
  }
1846
2014
  });
1847
2015
  }
1848
- BStackLogger2.debug(`[_extractBuildDetails] Extracted - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
2016
+ BStackLogger.debug(`[_extractBuildDetails] Extracted - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
1849
2017
  } catch (error) {
1850
- BStackLogger2.error(`[_extractBuildDetails] ${error}`);
2018
+ BStackLogger.error(`[_extractBuildDetails] ${error}`);
1851
2019
  }
1852
2020
  }
1853
2021
  _parseCapability(capability) {
@@ -1945,7 +2113,7 @@ var init_testorcherstrationutils = __esm({
1945
2113
  this.projectName = projectName;
1946
2114
  this.buildName = buildName;
1947
2115
  this.buildIdentifier = buildIdentifier;
1948
- BStackLogger2.debug(`[setBuildDetails] Set - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
2116
+ BStackLogger.debug(`[setBuildDetails] Set - projectName: ${this.projectName}, buildName: ${this.buildName}, buildIdentifier: ${this.buildIdentifier}`);
1949
2117
  }
1950
2118
  /**
1951
2119
  * Set run smart selection
@@ -1955,27 +2123,27 @@ var init_testorcherstrationutils = __esm({
1955
2123
  this.runSmartSelection = isValidEnabledValue(enabled);
1956
2124
  this.smartSelectionMode = mode;
1957
2125
  this.smartSelectionSource = [];
1958
- BStackLogger2.debug(`Setting runSmartSelection: enabled=${this.runSmartSelection}, mode=${this.smartSelectionMode}`);
2126
+ BStackLogger.debug(`Setting runSmartSelection: enabled=${this.runSmartSelection}, mode=${this.smartSelectionMode}`);
1959
2127
  if (this.runSmartSelection) {
1960
2128
  const validModes = [SMART_SELECTION_MODE_RELEVANT_FIRST, SMART_SELECTION_MODE_RELEVANT_ONLY];
1961
2129
  if (!validModes.includes(this.smartSelectionMode)) {
1962
- BStackLogger2.warn(`Invalid smart selection mode '${this.smartSelectionMode}' provided. Defaulting to '${SMART_SELECTION_MODE_RELEVANT_FIRST}'.`);
2130
+ BStackLogger.warn(`Invalid smart selection mode '${this.smartSelectionMode}' provided. Defaulting to '${SMART_SELECTION_MODE_RELEVANT_FIRST}'.`);
1963
2131
  this.smartSelectionMode = SMART_SELECTION_MODE_RELEVANT_FIRST;
1964
2132
  }
1965
2133
  if (source === null) {
1966
2134
  this.smartSelectionSource = null;
1967
- BStackLogger2.debug("No source provided for smart selection; defaulting to null.");
2135
+ BStackLogger.debug("No source provided for smart selection; defaulting to null.");
1968
2136
  } else if (Array.isArray(source)) {
1969
2137
  this.smartSelectionSource = source;
1970
- BStackLogger2.debug(`Smart selection source set to array: ${JSON.stringify(source)}`);
2138
+ BStackLogger.debug(`Smart selection source set to array: ${JSON.stringify(source)}`);
1971
2139
  } else if (typeof source === "string" && source.endsWith(".json")) {
1972
2140
  this.smartSelectionSource = this._loadSourceFromFile(source) || [];
1973
- BStackLogger2.debug(`Smart selection source loaded from file: ${source}`);
2141
+ BStackLogger.debug(`Smart selection source loaded from file: ${source}`);
1974
2142
  }
1975
2143
  this._setTestOrdering();
1976
2144
  }
1977
2145
  } catch (e) {
1978
- BStackLogger2.error(`[_setRunSmartSelection] ${e}`);
2146
+ BStackLogger.error(`[_setRunSmartSelection] ${e}`);
1979
2147
  }
1980
2148
  }
1981
2149
  /**
@@ -1985,17 +2153,17 @@ var init_testorcherstrationutils = __esm({
1985
2153
  * @returns Formatted list of repository configurations
1986
2154
  */
1987
2155
  _loadSourceFromFile(filePath) {
1988
- if (!fs4.existsSync(filePath)) {
1989
- BStackLogger2.error(`Source file '${filePath}' does not exist.`);
2156
+ if (!fs5.existsSync(filePath)) {
2157
+ BStackLogger.error(`Source file '${filePath}' does not exist.`);
1990
2158
  return [];
1991
2159
  }
1992
2160
  let data = null;
1993
2161
  try {
1994
- const fileContent = fs4.readFileSync(filePath, "utf8");
2162
+ const fileContent = fs5.readFileSync(filePath, "utf8");
1995
2163
  data = JSON.parse(fileContent);
1996
2164
  } catch (error) {
1997
2165
  const message = error instanceof Error ? error.message : String(error);
1998
- BStackLogger2.error(`Error parsing JSON from source file '${filePath}': ${message}`);
2166
+ BStackLogger.error(`Error parsing JSON from source file '${filePath}': ${message}`);
1999
2167
  return [];
2000
2168
  }
2001
2169
  let featureBranchEnvMap = null;
@@ -2011,9 +2179,9 @@ var init_testorcherstrationutils = __esm({
2011
2179
  return acc;
2012
2180
  }, {});
2013
2181
  } catch (error) {
2014
- BStackLogger2.error(`Error parsing feature branch mappings: ${error}`);
2182
+ BStackLogger.error(`Error parsing feature branch mappings: ${error}`);
2015
2183
  }
2016
- BStackLogger2.debug(`Feature branch mappings from env: ${JSON.stringify(envMap)}`);
2184
+ BStackLogger.debug(`Feature branch mappings from env: ${JSON.stringify(envMap)}`);
2017
2185
  return envMap;
2018
2186
  };
2019
2187
  featureBranchEnvMap = loadFeatureBranchMaps();
@@ -2035,23 +2203,23 @@ var init_testorcherstrationutils = __esm({
2035
2203
  }
2036
2204
  const typedRepoInfo = repoInfo;
2037
2205
  if (!typedRepoInfo.url || typeof typedRepoInfo.url !== "string") {
2038
- BStackLogger2.warn(`Repository URL is missing or invalid for source '${name}': ${JSON.stringify(repoInfo)}`);
2206
+ BStackLogger.warn(`Repository URL is missing or invalid for source '${name}': ${JSON.stringify(repoInfo)}`);
2039
2207
  continue;
2040
2208
  }
2041
2209
  if (typedRepoInfo.baseBranch !== void 0 && typeof typedRepoInfo.baseBranch !== "string") {
2042
- BStackLogger2.warn(`Base branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2210
+ BStackLogger.warn(`Base branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2043
2211
  continue;
2044
2212
  }
2045
2213
  if (typedRepoInfo.featureBranch !== void 0 && typeof typedRepoInfo.featureBranch !== "string") {
2046
- BStackLogger2.warn(`Feature branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2214
+ BStackLogger.warn(`Feature branch must be a string for source '${name}': ${JSON.stringify(repoInfo)}`);
2047
2215
  continue;
2048
2216
  }
2049
2217
  if (!namePattern.test(name)) {
2050
- BStackLogger2.warn(`Invalid source identifier format for '${name}': ${JSON.stringify(repoInfo)}`);
2218
+ BStackLogger.warn(`Invalid source identifier format for '${name}': ${JSON.stringify(repoInfo)}`);
2051
2219
  continue;
2052
2220
  }
2053
2221
  if (name.length > 30 || name.length < 1) {
2054
- BStackLogger2.warn(`Source identifier '${name}' must have a length between 1 and 30 characters.`);
2222
+ BStackLogger.warn(`Source identifier '${name}' must have a length between 1 and 30 characters.`);
2055
2223
  continue;
2056
2224
  }
2057
2225
  const featureBranch = getFeatureBranch(name, typedRepoInfo);
@@ -2064,11 +2232,11 @@ var init_testorcherstrationutils = __esm({
2064
2232
  filteredRepoInfo.baseBranch = typedRepoInfo.baseBranch;
2065
2233
  }
2066
2234
  if (!filteredRepoInfo.featureBranch || filteredRepoInfo.featureBranch === "") {
2067
- BStackLogger2.warn(`Feature branch not specified for source '${name}': ${JSON.stringify(repoInfo)}`);
2235
+ BStackLogger.warn(`Feature branch not specified for source '${name}': ${JSON.stringify(repoInfo)}`);
2068
2236
  continue;
2069
2237
  }
2070
2238
  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)}`);
2239
+ BStackLogger.warn(`Feature branch and base branch cannot be the same for source '${name}': ${JSON.stringify(repoInfo)}`);
2072
2240
  continue;
2073
2241
  }
2074
2242
  formattedData.push(filteredRepoInfo);
@@ -2178,17 +2346,17 @@ var init_crash_reporter = __esm({
2178
2346
  this.credentialsForCrashReportUpload = process.env.CREDENTIALS_FOR_CRASH_REPORTING !== void 0 ? JSON.parse(process.env.CREDENTIALS_FOR_CRASH_REPORTING) : this.credentialsForCrashReportUpload;
2179
2347
  }
2180
2348
  } catch (error) {
2181
- return BStackLogger2.error(`[Crash_Report_Upload] Failed to parse user credentials while reporting crash due to ${error}`);
2349
+ return BStackLogger.error(`[Crash_Report_Upload] Failed to parse user credentials while reporting crash due to ${error}`);
2182
2350
  }
2183
2351
  if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
2184
- return BStackLogger2.error("[Crash_Report_Upload] Failed to parse user credentials while reporting crash");
2352
+ return BStackLogger.error("[Crash_Report_Upload] Failed to parse user credentials while reporting crash");
2185
2353
  }
2186
2354
  try {
2187
2355
  if (Object.keys(this.userConfigForReporting).length === 0) {
2188
2356
  this.userConfigForReporting = process.env.USER_CONFIG_FOR_REPORTING !== void 0 ? JSON.parse(process.env.USER_CONFIG_FOR_REPORTING) : {};
2189
2357
  }
2190
2358
  } catch (error) {
2191
- BStackLogger2.error(`[Crash_Report_Upload] Failed to parse user config while reporting crash due to ${error}`);
2359
+ BStackLogger.error(`[Crash_Report_Upload] Failed to parse user config while reporting crash due to ${error}`);
2192
2360
  this.userConfigForReporting = {};
2193
2361
  }
2194
2362
  const data = {
@@ -2220,9 +2388,9 @@ var init_crash_reporter = __esm({
2220
2388
  body = JSON.stringify(JSON.parse(body));
2221
2389
  } catch {
2222
2390
  }
2223
- BStackLogger2.debug(`[Crash_Report_Upload] Success response: ${body}`);
2391
+ BStackLogger.debug(`[Crash_Report_Upload] Success response: ${body}`);
2224
2392
  } else {
2225
- BStackLogger2.error(`[Crash_Report_Upload] Failed due to ${response.body}`);
2393
+ BStackLogger.error(`[Crash_Report_Upload] Failed due to ${response.body}`);
2226
2394
  }
2227
2395
  }
2228
2396
  static recursivelyRedactKeysFromObject(obj, keys) {
@@ -2282,7 +2450,7 @@ var init_crash_reporter = __esm({
2282
2450
  }
2283
2451
  }
2284
2452
  } catch (err) {
2285
- BStackLogger2.error(`Error in parsing user config PII with error ${err ? err.stack || err : err}`);
2453
+ BStackLogger.error(`Error in parsing user config PII with error ${err ? err.stack || err : err}`);
2286
2454
  return configWithoutPII;
2287
2455
  }
2288
2456
  configWithoutPII.services = finalServices;
@@ -2317,7 +2485,7 @@ var init_featureStats = __esm({
2317
2485
  this.failed(groupId);
2318
2486
  break;
2319
2487
  default:
2320
- BStackLogger2.debug("Request to mark usage for unknown status - " + status);
2488
+ BStackLogger.debug("Request to mark usage for unknown status - " + status);
2321
2489
  break;
2322
2490
  }
2323
2491
  }
@@ -2553,7 +2721,7 @@ var init_usageStats = __esm({
2553
2721
  try {
2554
2722
  usage.events = this.getEventsData();
2555
2723
  } catch (e) {
2556
- BStackLogger2.debug("exception in getFormattedData: " + e);
2724
+ BStackLogger.debug("exception in getFormattedData: " + e);
2557
2725
  }
2558
2726
  return usage;
2559
2727
  }
@@ -2563,7 +2731,7 @@ var init_usageStats = __esm({
2563
2731
  const usageStatsForWorker = _UsageStats.fromJSON(workerData.usageStats);
2564
2732
  this.add(usageStatsForWorker);
2565
2733
  } catch (e) {
2566
- BStackLogger2.debug("Exception in adding workerData: " + e);
2734
+ BStackLogger.debug("Exception in adding workerData: " + e);
2567
2735
  }
2568
2736
  });
2569
2737
  }
@@ -2617,9 +2785,9 @@ var init_usageStats = __esm({
2617
2785
  });
2618
2786
 
2619
2787
  // src/scripts/accessibility-scripts.ts
2620
- import path4 from "node:path";
2621
- import fs5 from "node:fs";
2622
- import os from "node:os";
2788
+ import path5 from "node:path";
2789
+ import fs6 from "node:fs";
2790
+ import os2 from "node:os";
2623
2791
  var AccessibilityScripts, accessibility_scripts_default;
2624
2792
  var init_accessibility_scripts = __esm({
2625
2793
  "src/scripts/accessibility-scripts.ts"() {
@@ -2637,7 +2805,7 @@ var init_accessibility_scripts = __esm({
2637
2805
  // don't allow to create instances from it other than through `checkAndGetInstance`
2638
2806
  constructor() {
2639
2807
  this.browserstackFolderPath = this.getWritableDir();
2640
- this.commandsPath = path4.join(this.browserstackFolderPath, "commands.json");
2808
+ this.commandsPath = path5.join(this.browserstackFolderPath, "commands.json");
2641
2809
  }
2642
2810
  static checkAndGetInstance() {
2643
2811
  if (!_AccessibilityScripts.instance) {
@@ -2649,17 +2817,17 @@ var init_accessibility_scripts = __esm({
2649
2817
  /* eslint-disable @typescript-eslint/no-unused-vars */
2650
2818
  getWritableDir() {
2651
2819
  const orderedPaths = [
2652
- path4.join(os.homedir(), ".browserstack"),
2820
+ path5.join(os2.homedir(), ".browserstack"),
2653
2821
  process.cwd(),
2654
- os.tmpdir()
2822
+ os2.tmpdir()
2655
2823
  ];
2656
2824
  for (const orderedPath of orderedPaths) {
2657
2825
  try {
2658
- if (fs5.existsSync(orderedPath)) {
2659
- fs5.accessSync(orderedPath);
2826
+ if (fs6.existsSync(orderedPath)) {
2827
+ fs6.accessSync(orderedPath);
2660
2828
  return orderedPath;
2661
2829
  }
2662
- fs5.mkdirSync(orderedPath, { recursive: true });
2830
+ fs6.mkdirSync(orderedPath, { recursive: true });
2663
2831
  return orderedPath;
2664
2832
  } catch (error) {
2665
2833
  }
@@ -2668,8 +2836,8 @@ var init_accessibility_scripts = __esm({
2668
2836
  }
2669
2837
  readFromExistingFile() {
2670
2838
  try {
2671
- if (fs5.existsSync(this.commandsPath)) {
2672
- const data = fs5.readFileSync(this.commandsPath, "utf8");
2839
+ if (fs6.existsSync(this.commandsPath)) {
2840
+ const data = fs6.readFileSync(this.commandsPath, "utf8");
2673
2841
  if (data) {
2674
2842
  this.update(JSON.parse(data));
2675
2843
  }
@@ -2692,10 +2860,10 @@ var init_accessibility_scripts = __esm({
2692
2860
  }
2693
2861
  }
2694
2862
  store() {
2695
- if (!fs5.existsSync(this.browserstackFolderPath)) {
2696
- fs5.mkdirSync(this.browserstackFolderPath);
2863
+ if (!fs6.existsSync(this.browserstackFolderPath)) {
2864
+ fs6.mkdirSync(this.browserstackFolderPath);
2697
2865
  }
2698
- fs5.writeFileSync(this.commandsPath, JSON.stringify({
2866
+ fs6.writeFileSync(this.commandsPath, JSON.stringify({
2699
2867
  commands: this.commandsToWrap,
2700
2868
  scripts: {
2701
2869
  scan: this.performScan,
@@ -2714,10 +2882,10 @@ var init_accessibility_scripts = __esm({
2714
2882
  // src/util.ts
2715
2883
  import { hostname as hostname2, platform as platform3, type as type2, version as version2, arch as arch3, tmpdir } from "node:os";
2716
2884
  import crypto from "node:crypto";
2717
- import fs6 from "node:fs";
2885
+ import fs7 from "node:fs";
2718
2886
  import zlib from "node:zlib";
2719
2887
  import { format, promisify as promisify2 } from "node:util";
2720
- import path5 from "node:path";
2888
+ import path6 from "node:path";
2721
2889
  import util3 from "node:util";
2722
2890
  import gitRepoInfo from "git-repo-info";
2723
2891
  import gitconfig from "gitconfiglocal";
@@ -2758,7 +2926,7 @@ function getParentSuiteName(fullTitle, testSuiteTitle) {
2758
2926
  return parentSuiteName.trim();
2759
2927
  }
2760
2928
  function processError(error, fn, args) {
2761
- BStackLogger2.error(`Error in executing ${fn.name} with args ${args}: ${error}`);
2929
+ BStackLogger.error(`Error in executing ${fn.name} with args ${args}: ${error}`);
2762
2930
  let argsString;
2763
2931
  try {
2764
2932
  argsString = JSON.stringify(args);
@@ -2796,7 +2964,7 @@ async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout =
2796
2964
  clearTimeout(timeoutId);
2797
2965
  return await response.json();
2798
2966
  } catch (error) {
2799
- BStackLogger2.debug(`Error in firing request ${apiUrl}/${apiEndpoint}: ${format(error)}`);
2967
+ BStackLogger.debug(`Error in firing request ${apiUrl}/${apiEndpoint}: ${format(error)}`);
2800
2968
  const isLogUpload = apiEndpoint === UPLOAD_LOGS_ENDPOINT;
2801
2969
  if (error && error.response) {
2802
2970
  const errorMessageJson = error.response.body ? JSON.parse(error.response.body.toString()) : null;
@@ -2804,9 +2972,9 @@ async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout =
2804
2972
  if (errorMessage) {
2805
2973
  const message = `${errorMessage} - ${error.stack}`;
2806
2974
  if (isLogUpload) {
2807
- BStackLogger2.debug(message);
2975
+ BStackLogger.debug(message);
2808
2976
  } else {
2809
- BStackLogger2.error(message);
2977
+ BStackLogger.error(message);
2810
2978
  }
2811
2979
  }
2812
2980
  if (isLogUpload) {
@@ -2815,10 +2983,10 @@ async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout =
2815
2983
  throw error;
2816
2984
  } else {
2817
2985
  if (isLogUpload) {
2818
- BStackLogger2.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2986
+ BStackLogger.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2819
2987
  return;
2820
2988
  }
2821
- BStackLogger2.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2989
+ BStackLogger.debug(`Failed to fire api request due to ${error} - ${error.stack}`);
2822
2990
  throw error;
2823
2991
  }
2824
2992
  }
@@ -3238,9 +3406,9 @@ async function batchAndPostEvents(eventUrl, kind, data) {
3238
3406
  },
3239
3407
  body: JSON.stringify(data)
3240
3408
  });
3241
- BStackLogger2.debug(`[${kind}] Success response: ${JSON.stringify(await response.json())}`);
3409
+ BStackLogger.debug(`[${kind}] Success response: ${JSON.stringify(await response.json())}`);
3242
3410
  } catch (error) {
3243
- BStackLogger2.debug(`[${kind}] EXCEPTION IN ${kind} REQUEST TO TEST REPORTING AND ANALYTICS : ${error}`);
3411
+ BStackLogger.debug(`[${kind}] EXCEPTION IN ${kind} REQUEST TO TEST REPORTING AND ANALYTICS : ${error}`);
3244
3412
  throw new Error("Exception in request " + error);
3245
3413
  }
3246
3414
  }
@@ -3278,7 +3446,7 @@ function getObservabilityBuild(options, bstackBuildName) {
3278
3446
  if (options.testObservabilityOptions && options.testObservabilityOptions.buildName) {
3279
3447
  return options.testObservabilityOptions.buildName;
3280
3448
  }
3281
- return bstackBuildName || path5.basename(path5.resolve(process.cwd()));
3449
+ return bstackBuildName || path6.basename(path6.resolve(process.cwd()));
3282
3450
  }
3283
3451
  function getObservabilityBuildTags(options, bstackBuildTag) {
3284
3452
  if (process.env.TEST_OBSERVABILITY_BUILD_TAG) {
@@ -3364,26 +3532,26 @@ async function uploadLogs(user, key, clientBuildUuid) {
3364
3532
  if (!user || !key) {
3365
3533
  success = false;
3366
3534
  failure = "skipped: missing_credentials";
3367
- BStackLogger2.debug("Uploading logs failed due to no credentials");
3535
+ BStackLogger.debug("Uploading logs failed due to no credentials");
3368
3536
  return;
3369
3537
  }
3370
3538
  const tmpDir = tmpdir();
3371
- const tarPath = path5.join(tmpDir, "logs.tar");
3372
- const tarGzPath = path5.join(tmpDir, "logs.tar.gz");
3539
+ const tarPath = path6.join(tmpDir, "logs.tar");
3540
+ const tarGzPath = path6.join(tmpDir, "logs.tar.gz");
3373
3541
  const filesToArchive = [
3374
- BStackLogger2.logFilePath,
3542
+ BStackLogger.logFilePath,
3375
3543
  CLI_DEBUG_LOGS_FILE
3376
- ].filter((f) => fs6.existsSync(f));
3544
+ ].filter((f) => fs7.existsSync(f));
3377
3545
  const copiedFileNames = [];
3378
3546
  const archiveAddFailures = [];
3379
3547
  for (const f of filesToArchive) {
3380
3548
  try {
3381
- const dest = path5.join(tmpDir, path5.basename(f));
3382
- fs6.copyFileSync(f, dest);
3383
- copiedFileNames.push(path5.basename(f));
3549
+ const dest = path6.join(tmpDir, path6.basename(f));
3550
+ fs7.copyFileSync(f, dest);
3551
+ copiedFileNames.push(path6.basename(f));
3384
3552
  } catch (copyErr) {
3385
3553
  const msg = copyErr?.message || String(copyErr);
3386
- archiveAddFailures.push(`${path5.basename(f)}: ${msg}`);
3554
+ archiveAddFailures.push(`${path6.basename(f)}: ${msg}`);
3387
3555
  }
3388
3556
  }
3389
3557
  if (archiveAddFailures.length > 0 && failure === void 0) {
@@ -3400,15 +3568,15 @@ async function uploadLogs(user, key, clientBuildUuid) {
3400
3568
  copiedFileNames
3401
3569
  );
3402
3570
  await new Promise((resolve, reject) => {
3403
- const source = fs6.createReadStream(tarPath);
3404
- const dest = fs6.createWriteStream(tarGzPath);
3571
+ const source = fs7.createReadStream(tarPath);
3572
+ const dest = fs7.createWriteStream(tarGzPath);
3405
3573
  const gzip = zlib.createGzip({ level: 1 });
3406
3574
  source.pipe(gzip).pipe(dest);
3407
3575
  dest.on("finish", resolve);
3408
3576
  dest.on("error", reject);
3409
3577
  });
3410
3578
  const formData = new FormData();
3411
- const file = await fs6.openAsBlob(tarGzPath, { type: "application/x-gzip" });
3579
+ const file = await fs7.openAsBlob(tarGzPath, { type: "application/x-gzip" });
3412
3580
  formData.append("data", file, "logs.tar.gz");
3413
3581
  formData.append("clientBuildUuid", clientBuildUuid);
3414
3582
  const auth = Buffer.from(`${user}:${key}`).toString("base64");
@@ -3424,16 +3592,16 @@ async function uploadLogs(user, key, clientBuildUuid) {
3424
3592
  requestOptions,
3425
3593
  APIUtils.UPLOAD_LOGS_ADDRESS
3426
3594
  );
3427
- fs6.unlinkSync(tarPath);
3428
- fs6.unlinkSync(tarGzPath);
3595
+ fs7.unlinkSync(tarPath);
3596
+ fs7.unlinkSync(tarGzPath);
3429
3597
  for (const f of copiedFileNames) {
3430
- const filePath = path5.join(tmpDir, f);
3431
- if (fs6.existsSync(filePath)) {
3432
- fs6.unlinkSync(filePath);
3598
+ const filePath = path6.join(tmpDir, f);
3599
+ if (fs7.existsSync(filePath)) {
3600
+ fs7.unlinkSync(filePath);
3433
3601
  }
3434
3602
  }
3435
- if (fs6.existsSync(CLI_DEBUG_LOGS_FILE)) {
3436
- fs6.unlinkSync(CLI_DEBUG_LOGS_FILE);
3603
+ if (fs7.existsSync(CLI_DEBUG_LOGS_FILE)) {
3604
+ fs7.unlinkSync(CLI_DEBUG_LOGS_FILE);
3437
3605
  }
3438
3606
  if (!response) {
3439
3607
  success = false;
@@ -3446,7 +3614,7 @@ async function uploadLogs(user, key, clientBuildUuid) {
3446
3614
  } catch (error) {
3447
3615
  success = false;
3448
3616
  failure = `uploadLogs exception: ${getErrorString(error)}`;
3449
- BStackLogger2.error(`Error while uploading logs: ${getErrorString(error)}`);
3617
+ BStackLogger.error(`Error while uploading logs: ${getErrorString(error)}`);
3450
3618
  return null;
3451
3619
  } finally {
3452
3620
  PerformanceTester.end(eventName, success, failure);
@@ -3463,7 +3631,7 @@ function truncateString(field, truncateSizeInBytes) {
3463
3631
  return truncatedString;
3464
3632
  }
3465
3633
  } catch (error) {
3466
- BStackLogger2.debug(`Error while truncating field, nothing was truncated here: ${error}`);
3634
+ BStackLogger.debug(`Error while truncating field, nothing was truncated here: ${error}`);
3467
3635
  }
3468
3636
  return field;
3469
3637
  }
@@ -3472,7 +3640,7 @@ function getSizeOfJsonObjectInBytes(jsonData) {
3472
3640
  const buffer = Buffer.from(JSON.stringify(jsonData));
3473
3641
  return buffer.length;
3474
3642
  } catch (error) {
3475
- BStackLogger2.debug(`Something went wrong while calculating size of JSON object: ${error}`);
3643
+ BStackLogger.debug(`Something went wrong while calculating size of JSON object: ${error}`);
3476
3644
  }
3477
3645
  return -1;
3478
3646
  }
@@ -3482,7 +3650,7 @@ function checkAndTruncateVCSInfo(gitMetaData) {
3482
3650
  const truncateSize = gitMetaDataSizeInBytes - MAX_GIT_META_DATA_SIZE_IN_BYTES;
3483
3651
  const truncatedCommitMessage = truncateString(gitMetaData.commit_message, truncateSize);
3484
3652
  gitMetaData.commit_message = truncatedCommitMessage;
3485
- BStackLogger2.info(`The commit has been truncated. Size of commit after truncation is ${getSizeOfJsonObjectInBytes(gitMetaData) / 1024} KB`);
3653
+ BStackLogger.info(`The commit has been truncated. Size of commit after truncation is ${getSizeOfJsonObjectInBytes(gitMetaData) / 1024} KB`);
3486
3654
  }
3487
3655
  return gitMetaData;
3488
3656
  }
@@ -3494,7 +3662,7 @@ function getObservabilityProduct(options, isAppAutomate) {
3494
3662
  }
3495
3663
  async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()) {
3496
3664
  params.timestamp = Math.round(Date.now() / 1e3);
3497
- BStackLogger2.debug(`current timestamp ${params.timestamp}`);
3665
+ BStackLogger.debug(`current timestamp ${params.timestamp}`);
3498
3666
  try {
3499
3667
  const response = await makeGetRequest(url3, params, headers);
3500
3668
  const responseData = await response.json();
@@ -3506,9 +3674,9 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3506
3674
  } catch (error) {
3507
3675
  if (error.response && error.response.status === 404) {
3508
3676
  const nextPollTime = parseInt(error.response.headers.get("next_poll_time"), 10) * 1e3;
3509
- BStackLogger2.debug(`timeInMillis ${nextPollTime}`);
3677
+ BStackLogger.debug(`timeInMillis ${nextPollTime}`);
3510
3678
  if (isNaN(nextPollTime)) {
3511
- BStackLogger2.warn("Invalid or missing `nextPollTime` header. Stopping polling.");
3679
+ BStackLogger.warn("Invalid or missing `nextPollTime` header. Stopping polling.");
3512
3680
  return {
3513
3681
  data: {},
3514
3682
  headers: error.response.headers,
@@ -3516,18 +3684,18 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3516
3684
  };
3517
3685
  }
3518
3686
  const elapsedTime = nextPollTime - Date.now();
3519
- BStackLogger2.debug(
3687
+ BStackLogger.debug(
3520
3688
  `elapsedTime ${elapsedTime} timeInMillis ${nextPollTime} upperLimit ${upperLimit}`
3521
3689
  );
3522
3690
  if (nextPollTime > upperLimit) {
3523
- BStackLogger2.warn("Polling stopped due to upper time limit.");
3691
+ BStackLogger.warn("Polling stopped due to upper time limit.");
3524
3692
  return {
3525
3693
  data: {},
3526
3694
  headers: error.response.headers,
3527
3695
  message: "Polling stopped due to upper time limit."
3528
3696
  };
3529
3697
  }
3530
- BStackLogger2.debug(`Polling again in ${elapsedTime}ms with params:`, params);
3698
+ BStackLogger.debug(`Polling again in ${elapsedTime}ms with params:`, params);
3531
3699
  await new Promise((resolve) => setTimeout(resolve, elapsedTime));
3532
3700
  return pollApi(url3, params, headers, upperLimit, startTime);
3533
3701
  } else if (error.response) {
@@ -3536,7 +3704,7 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3536
3704
  const parsedError = JSON.parse(error.response.json());
3537
3705
  errorMessage = parsedError.message;
3538
3706
  } catch {
3539
- BStackLogger2.debug(`Error parsing pollApi request body ${error.response.body}`);
3707
+ BStackLogger.debug(`Error parsing pollApi request body ${error.response.body}`);
3540
3708
  errorMessage = "Unknown error";
3541
3709
  }
3542
3710
  throw {
@@ -3545,7 +3713,7 @@ async function pollApi(url3, params, headers, upperLimit, startTime = Date.now()
3545
3713
  message: errorMessage
3546
3714
  };
3547
3715
  } else {
3548
- BStackLogger2.error(`Unexpected error occurred: ${error}`);
3716
+ BStackLogger.error(`Unexpected error occurred: ${error}`);
3549
3717
  return { data: {}, headers: {}, message: "Unexpected error occurred." };
3550
3718
  }
3551
3719
  }
@@ -3654,28 +3822,28 @@ function nestedKeyValue(hash, keys) {
3654
3822
  return keys.reduce((hash2, key) => isHash(hash2) ? hash2[key] : void 0, hash);
3655
3823
  }
3656
3824
  function removeDir(dir) {
3657
- const list = fs6.readdirSync(dir);
3825
+ const list = fs7.readdirSync(dir);
3658
3826
  for (let i = 0; i < list.length; i++) {
3659
- const filename = path5.join(dir, list[i]);
3660
- const stat = fs6.statSync(filename);
3827
+ const filename = path6.join(dir, list[i]);
3828
+ const stat = fs7.statSync(filename);
3661
3829
  if (filename === "." || filename === "..") {
3662
3830
  } else if (stat.isDirectory()) {
3663
3831
  removeDir(filename);
3664
3832
  } else {
3665
- fs6.unlinkSync(filename);
3833
+ fs7.unlinkSync(filename);
3666
3834
  }
3667
3835
  }
3668
- fs6.rmdirSync(dir);
3836
+ fs7.rmdirSync(dir);
3669
3837
  }
3670
3838
  function createDir(dir) {
3671
- if (fs6.existsSync(dir)) {
3839
+ if (fs7.existsSync(dir)) {
3672
3840
  removeDir(dir);
3673
3841
  }
3674
- fs6.mkdirSync(dir, { recursive: true });
3842
+ fs7.mkdirSync(dir, { recursive: true });
3675
3843
  }
3676
3844
  function isWritable(dirPath) {
3677
3845
  try {
3678
- fs6.accessSync(dirPath, fs6.constants.W_OK);
3846
+ fs7.accessSync(dirPath, fs7.constants.W_OK);
3679
3847
  return true;
3680
3848
  } catch {
3681
3849
  return false;
@@ -3683,10 +3851,10 @@ function isWritable(dirPath) {
3683
3851
  }
3684
3852
  function setReadWriteAccess(dirPath) {
3685
3853
  try {
3686
- fs6.chmodSync(dirPath, 438);
3687
- BStackLogger2.debug(`Directory ${dirPath} is now read/write accessible.`);
3854
+ fs7.chmodSync(dirPath, 438);
3855
+ BStackLogger.debug(`Directory ${dirPath} is now read/write accessible.`);
3688
3856
  } catch (err) {
3689
- BStackLogger2.error(`Failed to set directory access: ${err.stack}`);
3857
+ BStackLogger.error(`Failed to set directory access: ${err.stack}`);
3690
3858
  }
3691
3859
  }
3692
3860
  function getMochaTestHierarchy(test) {
@@ -3714,7 +3882,7 @@ function isMultiRemoteCaps(capabilities) {
3714
3882
  (cap) => Object.values(cap).length > 0 && Object.values(cap).every((c) => c !== null && typeof c === "object" && c.capabilities)
3715
3883
  );
3716
3884
  }
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;
3885
+ 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
3886
  var init_util = __esm({
3719
3887
  "src/util.ts"() {
3720
3888
  "use strict";
@@ -3788,7 +3956,7 @@ var init_util = __esm({
3788
3956
  };
3789
3957
  if (scannerVersion) {
3790
3958
  process.env.BSTACK_A11Y_SCANNER_VERSION = scannerVersion;
3791
- BStackLogger2.debug(`Accessibility scannerVersion ${scannerVersion}`);
3959
+ BStackLogger.debug(`Accessibility scannerVersion ${scannerVersion}`);
3792
3960
  }
3793
3961
  if (accessibilityToken) {
3794
3962
  process.env.BSTACK_A11Y_JWT = accessibilityToken;
@@ -3860,7 +4028,7 @@ var init_util = __esm({
3860
4028
  CrashReporter.userConfigForReporting = process.env.USER_CONFIG_FOR_REPORTING !== void 0 ? JSON.parse(process.env.USER_CONFIG_FOR_REPORTING) : {};
3861
4029
  }
3862
4030
  } catch (error) {
3863
- return BStackLogger2.error(`[Crash_Report_Upload] Failed to parse user config while sending build start event due to ${error}`);
4031
+ return BStackLogger.error(`[Crash_Report_Upload] Failed to parse user config while sending build start event due to ${error}`);
3864
4032
  }
3865
4033
  data.config = CrashReporter.userConfigForReporting;
3866
4034
  try {
@@ -3877,8 +4045,8 @@ var init_util = __esm({
3877
4045
  });
3878
4046
  const jsonResponse = await response.json();
3879
4047
  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)}`);
4048
+ BStackLogger.debug(`[Start_Build] Success response: ${JSON.stringify(jsonResponse)}`);
4049
+ BStackLogger.debug(`Test Plan Id sent in request: ${getTestPlanId(options)}`);
3882
4050
  process.env[TESTOPS_BUILD_COMPLETED_ENV] = "true";
3883
4051
  if (jsonResponse.jwt) {
3884
4052
  process.env[BROWSERSTACK_TESTHUB_JWT] = jsonResponse.jwt;
@@ -3886,13 +4054,13 @@ var init_util = __esm({
3886
4054
  if (jsonResponse.build_hashed_id) {
3887
4055
  process.env[BROWSERSTACK_TESTHUB_UUID] = jsonResponse.build_hashed_id;
3888
4056
  testOpsConfig_default.getInstance().buildHashedId = jsonResponse.build_hashed_id;
3889
- BStackLogger2.info(`Testhub started with id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
4057
+ BStackLogger.info(`Testhub started with id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
3890
4058
  }
3891
4059
  processLaunchBuildResponse(jsonResponse, options);
3892
4060
  launchBuildUsage.success();
3893
4061
  return jsonResponse;
3894
4062
  } catch (error) {
3895
- BStackLogger2.debug(`TestHub build start failed: ${format(error)}`);
4063
+ BStackLogger.debug(`TestHub build start failed: ${format(error)}`);
3896
4064
  if (!error.success) {
3897
4065
  launchBuildUsage.failed(error);
3898
4066
  logBuildError(error);
@@ -3902,7 +4070,7 @@ var init_util = __esm({
3902
4070
  }));
3903
4071
  validateCapsWithAppA11y = (platformMeta) => {
3904
4072
  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.");
4073
+ BStackLogger.warn("App Accessibility Automation tests are supported on OS version 11 and above for Android devices.");
3906
4074
  return false;
3907
4075
  }
3908
4076
  return true;
@@ -3910,38 +4078,79 @@ var init_util = __esm({
3910
4078
  validateCapsWithA11y = (deviceName, platformMeta, chromeOptions) => {
3911
4079
  try {
3912
4080
  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.");
4081
+ BStackLogger.warn("Accessibility Automation will run only on Desktop browsers.");
3918
4082
  return false;
3919
4083
  }
4084
+ const browserName = platformMeta?.browser_name?.toLowerCase();
3920
4085
  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.");
4086
+ const validBrowsers = SUPPORTED_BROWSERS_FOR_ACCESSIBILITY;
4087
+ if (!browserName || !validBrowsers.includes(browserName)) {
4088
+ BStackLogger.warn(`Accessibility Automation supports Chrome 95+, Chrome for Testing 141+, and Safari 18.4+. Current browser: ${browserName}`);
3923
4089
  return false;
3924
4090
  }
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;
4091
+ if (browserName === "chrome" || browserName === "chromefortesting") {
4092
+ const minVersion = MIN_BROWSER_VERSIONS_A11Y[browserName];
4093
+ if (browserVersion && browserVersion !== "latest") {
4094
+ const version3 = parseInt(browserVersion.toString().split(".")[0] || "0", 10);
4095
+ if (version3 < minVersion) {
4096
+ BStackLogger.warn(`Accessibility Automation requires ${browserName === "chrome" ? "Chrome" : "Chrome for Testing"} version ${minVersion} or higher.`);
4097
+ return false;
4098
+ }
4099
+ }
4100
+ if (chromeOptions?.args?.includes("--headless")) {
4101
+ BStackLogger.warn("Accessibility Automation will not run on legacy headless mode. Switch to new headless mode or avoid using headless mode.");
4102
+ return false;
4103
+ }
4104
+ }
4105
+ if (browserName === "safari") {
4106
+ if (browserVersion && browserVersion !== "latest") {
4107
+ const [currentMajor = 0, currentMinor = 0] = browserVersion.toString().split(".").map(Number);
4108
+ const [requiredMajor = 0, requiredMinor = 0] = MIN_BROWSER_VERSIONS_A11Y.safari.toString().split(".").map(Number);
4109
+ if (currentMajor < requiredMajor || currentMajor === requiredMajor && currentMinor < requiredMinor) {
4110
+ BStackLogger.warn(`Accessibility Automation requires Safari version ${MIN_BROWSER_VERSIONS_A11Y.safari} or higher.`);
4111
+ return false;
4112
+ }
4113
+ }
3928
4114
  }
3929
4115
  return true;
3930
4116
  } catch (error) {
3931
- BStackLogger2.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
4117
+ BStackLogger.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
3932
4118
  }
3933
4119
  return false;
3934
4120
  };
3935
4121
  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;
4122
+ try {
4123
+ const browser = browserName?.toLowerCase();
4124
+ const validBrowsers = ["chrome", "chromefortesting", "safari"];
4125
+ if (!browser || !validBrowsers.includes(browser)) {
4126
+ BStackLogger.warn("Accessibility Automation on non-BrowserStack infrastructure supports Chrome 100+, Chrome for Testing 141+, and Safari 18.4+.");
4127
+ return false;
4128
+ }
4129
+ if (browser === "chrome" || browser === "chromefortesting") {
4130
+ const minVersion = MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK[browser];
4131
+ if (browserVersion && browserVersion !== "latest") {
4132
+ const version3 = parseInt(browserVersion.toString().split(".")[0] || "0", 10);
4133
+ if (version3 < minVersion) {
4134
+ BStackLogger.warn(`Accessibility Automation requires ${browser === "chrome" ? "Chrome" : "Chrome for Testing"} version ${minVersion}+ on non-BrowserStack infrastructure.`);
4135
+ return false;
4136
+ }
4137
+ }
4138
+ }
4139
+ if (browser === "safari") {
4140
+ if (browserVersion && browserVersion !== "latest") {
4141
+ const [currentMajor = 0, currentMinor = 0] = browserVersion.toString().split(".").map(Number);
4142
+ const [requiredMajor = 0, requiredMinor = 0] = MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK.safari.toString().split(".").map(Number);
4143
+ if (currentMajor < requiredMajor || currentMajor === requiredMajor && currentMinor < requiredMinor) {
4144
+ BStackLogger.warn(`Accessibility Automation requires Safari version ${MIN_BROWSER_VERSIONS_A11Y_NON_BSTACK.safari}+ on non-BrowserStack infrastructure.`);
4145
+ return false;
4146
+ }
4147
+ }
4148
+ }
4149
+ return true;
4150
+ } catch (error) {
4151
+ BStackLogger.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
3943
4152
  }
3944
- return true;
4153
+ return false;
3945
4154
  };
3946
4155
  shouldScanTestForAccessibility = (suiteTitle, testTitle, accessibilityOptions, world, isCucumber) => {
3947
4156
  try {
@@ -3959,7 +4168,7 @@ var init_util = __esm({
3959
4168
  const included = includeTags?.length === 0 || includeTags?.some((include) => fullTestName.includes(include));
3960
4169
  return !excluded && included;
3961
4170
  } catch (error) {
3962
- BStackLogger2.debug(`Error while validating test case for accessibility before scanning. Error : ${error}`);
4171
+ BStackLogger.debug(`Error while validating test case for accessibility before scanning. Error : ${error}`);
3963
4172
  }
3964
4173
  return false;
3965
4174
  };
@@ -3968,7 +4177,7 @@ var init_util = __esm({
3968
4177
  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
4178
  return accessibilityFlag && hasA11yJwtToken;
3970
4179
  } catch (error) {
3971
- BStackLogger2.debug(`Exception in verifying the Accessibility session with error : ${error}`);
4180
+ BStackLogger.debug(`Exception in verifying the Accessibility session with error : ${error}`);
3972
4181
  }
3973
4182
  return false;
3974
4183
  };
@@ -3999,43 +4208,43 @@ var init_util = __esm({
3999
4208
  };
4000
4209
  performA11yScan = async (isAppAutomate, browser, isBrowserStackSession, isAccessibility, commandName, testName) => {
4001
4210
  if (!isAccessibilityAutomationSession(isAccessibility)) {
4002
- BStackLogger2.warn("Not an Accessibility Automation session, cannot perform Accessibility scan.");
4211
+ BStackLogger.warn("Not an Accessibility Automation session, cannot perform Accessibility scan.");
4003
4212
  return;
4004
4213
  }
4005
4214
  try {
4006
4215
  if (isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
4007
4216
  const results = await browser.execute(formatString(accessibility_scripts_default.performScan, JSON.stringify(_getParamsForAppAccessibility(commandName, testName))), {});
4008
- BStackLogger2.debug(util3.format(results));
4217
+ BStackLogger.debug(util3.format(results));
4009
4218
  return results;
4010
4219
  }
4011
4220
  if (accessibility_scripts_default.performScan) {
4012
4221
  const results = await executeAccessibilityScript(browser, accessibility_scripts_default.performScan, { method: commandName || "" });
4013
4222
  return results;
4014
4223
  }
4015
- BStackLogger2.error("AccessibilityScripts.performScan is null");
4224
+ BStackLogger.error("AccessibilityScripts.performScan is null");
4016
4225
  return;
4017
4226
  } catch (err) {
4018
- BStackLogger2.error("Accessibility Scan could not be performed : " + err);
4227
+ BStackLogger.error("Accessibility Scan could not be performed : " + err);
4019
4228
  return;
4020
4229
  }
4021
4230
  };
4022
4231
  getA11yResults = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
4023
4232
  if (!isAccessibilityAutomationSession(isAccessibility)) {
4024
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results.");
4233
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results.");
4025
4234
  return [];
4026
4235
  }
4027
4236
  try {
4028
- BStackLogger2.debug("Performing scan before getting results");
4237
+ BStackLogger.debug("Performing scan before getting results");
4029
4238
  await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
4030
4239
  if (accessibility_scripts_default.getResults) {
4031
4240
  const results = await executeAccessibilityScript(browser, accessibility_scripts_default.getResults);
4032
4241
  return results;
4033
4242
  }
4034
- BStackLogger2.error("AccessibilityScripts.getResults is null");
4243
+ BStackLogger.error("AccessibilityScripts.getResults is null");
4035
4244
  return [];
4036
4245
  } catch (error) {
4037
- BStackLogger2.error("No accessibility results were found.");
4038
- BStackLogger2.debug(`getA11yResults Failed. Error: ${error}`);
4246
+ BStackLogger.error("No accessibility results were found.");
4247
+ BStackLogger.debug(`getA11yResults Failed. Error: ${error}`);
4039
4248
  return [];
4040
4249
  }
4041
4250
  });
@@ -4044,18 +4253,18 @@ var init_util = __esm({
4044
4253
  return [];
4045
4254
  }
4046
4255
  if (!isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
4047
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4256
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4048
4257
  return [];
4049
4258
  }
4050
4259
  try {
4051
4260
  const apiUrl = `${APIUtils.APP_ALLY_ENDPOINT}/${APP_ALLY_ISSUES_ENDPOINT}`;
4052
4261
  const apiRespone = await getAppA11yResultResponse(apiUrl, isAppAutomate, browser, testName, isBrowserStackSession, isAccessibility, sessionId);
4053
4262
  const result = apiRespone?.data?.data?.issues;
4054
- BStackLogger2.debug(`Polling Result: ${JSON.stringify(result)}`);
4263
+ BStackLogger.debug(`Polling Result: ${JSON.stringify(result)}`);
4055
4264
  return result;
4056
4265
  } catch (error) {
4057
- BStackLogger2.error("No accessibility summary was found.");
4058
- BStackLogger2.debug(`getAppA11yResults Failed. Error: ${error}`);
4266
+ BStackLogger.error("No accessibility summary was found.");
4267
+ BStackLogger.debug(`getAppA11yResults Failed. Error: ${error}`);
4059
4268
  return [];
4060
4269
  }
4061
4270
  });
@@ -4064,46 +4273,46 @@ var init_util = __esm({
4064
4273
  return {};
4065
4274
  }
4066
4275
  if (!isAppAccessibilityAutomationSession(isAccessibility, isAppAutomate)) {
4067
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4276
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4068
4277
  return {};
4069
4278
  }
4070
4279
  try {
4071
4280
  const apiUrl = `${APIUtils.APP_ALLY_ENDPOINT}/${APP_ALLY_ISSUES_SUMMARY_ENDPOINT}`;
4072
4281
  const apiRespone = await getAppA11yResultResponse(apiUrl, isAppAutomate, browser, testName, isBrowserStackSession, isAccessibility, sessionId);
4073
4282
  const result = apiRespone?.data?.data?.summary;
4074
- BStackLogger2.debug(`Polling Result: ${JSON.stringify(result)}`);
4283
+ BStackLogger.debug(`Polling Result: ${JSON.stringify(result)}`);
4075
4284
  return result;
4076
4285
  } catch {
4077
- BStackLogger2.error("No accessibility summary was found.");
4286
+ BStackLogger.error("No accessibility summary was found.");
4078
4287
  return {};
4079
4288
  }
4080
4289
  });
4081
4290
  getAppA11yResultResponse = async (apiUrl, isAppAutomate, browser, testName, isBrowserStackSession, isAccessibility, sessionId) => {
4082
- BStackLogger2.debug("Performing scan before getting results summary");
4291
+ BStackLogger.debug("Performing scan before getting results summary");
4083
4292
  await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility, void 0, testName);
4084
4293
  const upperTimeLimit = process.env.BSTACK_A11Y_POLLING_TIMEOUT ? Date.now() + parseInt(process.env.BSTACK_A11Y_POLLING_TIMEOUT) * 1e3 : Date.now() + 3e4;
4085
4294
  const params = { test_run_uuid: process.env.TEST_ANALYTICS_ID, session_id: sessionId, timestamp: Date.now() };
4086
4295
  const header = { Authorization: `Bearer ${process.env.BSTACK_A11Y_JWT}` };
4087
4296
  const apiRespone = await pollApi(apiUrl, params, header, upperTimeLimit);
4088
- BStackLogger2.debug(`Polling Result: ${JSON.stringify(apiRespone)}`);
4297
+ BStackLogger.debug(`Polling Result: ${JSON.stringify(apiRespone)}`);
4089
4298
  return apiRespone;
4090
4299
  };
4091
4300
  getA11yResultsSummary = PerformanceTester.measureWrapper(A11Y_EVENTS.GET_RESULTS_SUMMARY, async (isAppAutomate, browser, isBrowserStackSession, isAccessibility) => {
4092
4301
  if (!isAccessibilityAutomationSession(isAccessibility)) {
4093
- BStackLogger2.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4302
+ BStackLogger.warn("Not an Accessibility Automation session, cannot retrieve Accessibility results summary.");
4094
4303
  return {};
4095
4304
  }
4096
4305
  try {
4097
- BStackLogger2.debug("Performing scan before getting results summary");
4306
+ BStackLogger.debug("Performing scan before getting results summary");
4098
4307
  await performA11yScan(isAppAutomate, browser, isBrowserStackSession, isAccessibility);
4099
4308
  if (accessibility_scripts_default.getResultsSummary) {
4100
4309
  const summaryResults = await executeAccessibilityScript(browser, accessibility_scripts_default.getResultsSummary);
4101
4310
  return summaryResults;
4102
4311
  }
4103
- BStackLogger2.error("AccessibilityScripts.getResultsSummary is null");
4312
+ BStackLogger.error("AccessibilityScripts.getResultsSummary is null");
4104
4313
  return {};
4105
4314
  } catch {
4106
- BStackLogger2.error("No accessibility summary was found.");
4315
+ BStackLogger.error("No accessibility summary was found.");
4107
4316
  return {};
4108
4317
  }
4109
4318
  });
@@ -4119,7 +4328,7 @@ var init_util = __esm({
4119
4328
  }
4120
4329
  if (!process.env[BROWSERSTACK_TESTHUB_JWT]) {
4121
4330
  stopBuildUsage.failed("Token/buildID is undefined, build creation might have failed");
4122
- BStackLogger2.debug("[STOP_BUILD] Missing Authentication Token/ Build ID");
4331
+ BStackLogger.debug("[STOP_BUILD] Missing Authentication Token/ Build ID");
4123
4332
  return {
4124
4333
  status: "error",
4125
4334
  message: "Token/buildID is undefined, build creation might have failed"
@@ -4138,7 +4347,7 @@ var init_util = __esm({
4138
4347
  },
4139
4348
  body: JSON.stringify(data)
4140
4349
  });
4141
- BStackLogger2.debug(`[STOP_BUILD] Success response: ${await response.text()}`);
4350
+ BStackLogger.debug(`[STOP_BUILD] Success response: ${await response.text()}`);
4142
4351
  stopBuildUsage.success();
4143
4352
  return {
4144
4353
  status: "success",
@@ -4146,7 +4355,7 @@ var init_util = __esm({
4146
4355
  };
4147
4356
  } catch (error) {
4148
4357
  stopBuildUsage.failed(error);
4149
- BStackLogger2.debug(`[STOP_BUILD] Failed. Error: ${error}`);
4358
+ BStackLogger.debug(`[STOP_BUILD] Failed. Error: ${error}`);
4150
4359
  return {
4151
4360
  status: "error",
4152
4361
  message: error.message
@@ -4157,7 +4366,7 @@ var init_util = __esm({
4157
4366
  const BSTestOpsPatcher = new logPatcher_default({});
4158
4367
  Object.keys(consoleHolder).forEach((method) => {
4159
4368
  if (!(method in console) || method === "Console" || typeof console[method] !== "function") {
4160
- BStackLogger2.debug(`Skipping method: ${method}, exists: ${method in console}, type: ${typeof console[method]}`);
4369
+ BStackLogger.debug(`Skipping method: ${method}, exists: ${method in console}, type: ${typeof console[method]}`);
4161
4370
  return;
4162
4371
  }
4163
4372
  const origMethod = console[method].bind(console);
@@ -4170,7 +4379,7 @@ var init_util = __esm({
4170
4379
  BSTestOpsPatcher[method](...args);
4171
4380
  }
4172
4381
  } catch (error) {
4173
- BStackLogger2.debug(`Error while patching console logs : ${error}`);
4382
+ BStackLogger.debug(`Error while patching console logs : ${error}`);
4174
4383
  origMethod(...args);
4175
4384
  }
4176
4385
  };
@@ -4204,18 +4413,57 @@ var init_util = __esm({
4204
4413
  const keys = ["platformVersion", "platform_version", "osVersion", "os_version"];
4205
4414
  for (const key of keys) {
4206
4415
  if (caps?.[key]) {
4207
- BStackLogger2.debug(`Got ${key} from driver caps`);
4416
+ BStackLogger.debug(`Got ${key} from driver caps`);
4208
4417
  return String(caps?.[key]);
4209
4418
  } else if (bstackOptions && bstackOptions?.[key]) {
4210
- BStackLogger2.debug(`Got ${key} from user bstack options`);
4419
+ BStackLogger.debug(`Got ${key} from user bstack options`);
4211
4420
  return String(bstackOptions?.[key]);
4212
4421
  } else if (userCaps[key]) {
4213
- BStackLogger2.debug(`Got ${key} from user caps`);
4422
+ BStackLogger.debug(`Got ${key} from user caps`);
4214
4423
  return String(userCaps[key]);
4215
4424
  }
4216
4425
  }
4217
4426
  return void 0;
4218
4427
  });
4428
+ getResolvedDeviceName = o11yErrorHandler(function getResolvedDeviceName2(driverCaps, requestedCaps) {
4429
+ const flattenMultiremote = (caps) => {
4430
+ if (!caps) {
4431
+ return [];
4432
+ }
4433
+ const obj = caps;
4434
+ if (obj["deviceModel"] || obj["appium:deviceModel"] || obj["deviceName"] || obj["bstack:options"]) {
4435
+ return [caps];
4436
+ }
4437
+ return Object.values(obj).filter((v) => v !== null && typeof v === "object" && "capabilities" in v).map((v) => v.capabilities).filter(Boolean);
4438
+ };
4439
+ const sources = [
4440
+ ...flattenMultiremote(driverCaps),
4441
+ ...flattenMultiremote(requestedCaps)
4442
+ ];
4443
+ if (!sources.length) {
4444
+ return void 0;
4445
+ }
4446
+ const pickString = (obj, key) => {
4447
+ const v = obj?.[key];
4448
+ return typeof v === "string" && v.length > 0 ? v : void 0;
4449
+ };
4450
+ const paths = [
4451
+ (c) => pickString(c, "deviceModel"),
4452
+ (c) => pickString(c, "appium:deviceModel"),
4453
+ (c) => pickString(c["bstack:options"], "deviceName"),
4454
+ (c) => pickString(c, "appium:deviceName"),
4455
+ (c) => pickString(c, "deviceName")
4456
+ ];
4457
+ for (const path22 of paths) {
4458
+ for (const src of sources) {
4459
+ const v = path22(src);
4460
+ if (v) {
4461
+ return v;
4462
+ }
4463
+ }
4464
+ }
4465
+ return void 0;
4466
+ });
4219
4467
  getBasicAuthHeader = (username, password) => {
4220
4468
  const encodedAuth = Buffer.from(`${username}:${password}`, "utf8").toString("base64");
4221
4469
  return `Basic ${encodedAuth}`;
@@ -4259,20 +4507,20 @@ var init_util = __esm({
4259
4507
  });
4260
4508
 
4261
4509
  // src/bstackLogger.ts
4262
- import path6 from "node:path";
4263
- import fs7 from "node:fs";
4510
+ import path7 from "node:path";
4511
+ import fs8 from "node:fs";
4264
4512
  import chalk2 from "chalk";
4265
4513
  import logger2 from "@wdio/logger";
4266
- var log2, BStackLogger2;
4514
+ var log2, BStackLogger;
4267
4515
  var init_bstackLogger = __esm({
4268
4516
  "src/bstackLogger.ts"() {
4269
4517
  "use strict";
4270
4518
  init_constants();
4271
4519
  init_util();
4272
4520
  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");
4521
+ BStackLogger = class {
4522
+ static logFilePath = path7.join(process.cwd(), LOGS_FILE);
4523
+ static logFolderPath = path7.join(process.cwd(), "logs");
4276
4524
  static logFileStream;
4277
4525
  static redactCredentials(logMessage) {
4278
4526
  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 +4530,7 @@ var init_bstackLogger = __esm({
4282
4530
  const redactedMessage = this.redactCredentials(logMessage);
4283
4531
  if (!this.logFileStream) {
4284
4532
  this.ensureLogsFolder();
4285
- this.logFileStream = fs7.createWriteStream(this.logFilePath, { flags: "a" });
4533
+ this.logFileStream = fs8.createWriteStream(this.logFilePath, { flags: "a" });
4286
4534
  }
4287
4535
  if (this.logFileStream && this.logFileStream.writable) {
4288
4536
  this.logFileStream.write(this.formatLog(redactedMessage, logLevel));
@@ -4331,13 +4579,13 @@ var init_bstackLogger = __esm({
4331
4579
  this.logFileStream = null;
4332
4580
  }
4333
4581
  static clearLogFile() {
4334
- if (fs7.existsSync(this.logFilePath)) {
4335
- fs7.truncateSync(this.logFilePath);
4582
+ if (fs8.existsSync(this.logFilePath)) {
4583
+ fs8.truncateSync(this.logFilePath);
4336
4584
  }
4337
4585
  }
4338
4586
  static ensureLogsFolder() {
4339
- if (!fs7.existsSync(this.logFolderPath)) {
4340
- fs7.mkdirSync(this.logFolderPath);
4587
+ if (!fs8.existsSync(this.logFolderPath)) {
4588
+ fs8.mkdirSync(this.logFolderPath);
4341
4589
  }
4342
4590
  }
4343
4591
  };
@@ -4355,7 +4603,7 @@ var init_utils = __esm({
4355
4603
  getProductMap = (config) => {
4356
4604
  const entries = [
4357
4605
  ["observability", config.testObservability.enabled],
4358
- ["accessibility", config.accessibility],
4606
+ ["accessibility", !!config.accessibility],
4359
4607
  ["percy", config.percy],
4360
4608
  ["automate", config.automate],
4361
4609
  ["app_automate", config.appAutomate]
@@ -4384,7 +4632,7 @@ var init_utils = __esm({
4384
4632
  };
4385
4633
  logBuildError = (error, product = "") => {
4386
4634
  if (!error || !error.errors) {
4387
- BStackLogger2.error(`${product.toUpperCase()} Build creation failed ${error}`);
4635
+ BStackLogger.error(`${product.toUpperCase()} Build creation failed ${error}`);
4388
4636
  return;
4389
4637
  }
4390
4638
  for (const errorJson of error.errors) {
@@ -4393,16 +4641,16 @@ var init_utils = __esm({
4393
4641
  if (errorMessage) {
4394
4642
  switch (errorType) {
4395
4643
  case "ERROR_INVALID_CREDENTIALS":
4396
- BStackLogger2.error(errorMessage);
4644
+ BStackLogger.error(errorMessage);
4397
4645
  break;
4398
4646
  case "ERROR_ACCESS_DENIED":
4399
- BStackLogger2.info(errorMessage);
4647
+ BStackLogger.info(errorMessage);
4400
4648
  break;
4401
4649
  case "ERROR_SDK_DEPRECATED":
4402
- BStackLogger2.error(errorMessage);
4650
+ BStackLogger.error(errorMessage);
4403
4651
  break;
4404
4652
  default:
4405
- BStackLogger2.error(errorMessage);
4653
+ BStackLogger.error(errorMessage);
4406
4654
  }
4407
4655
  }
4408
4656
  }
@@ -4421,8 +4669,8 @@ var init_utils = __esm({
4421
4669
  });
4422
4670
 
4423
4671
  // src/Percy/PercyLogger.ts
4424
- import path7 from "node:path";
4425
- import fs8 from "node:fs";
4672
+ import path8 from "node:path";
4673
+ import fs9 from "node:fs";
4426
4674
  import chalk3 from "chalk";
4427
4675
  import logger3 from "@wdio/logger";
4428
4676
  var log3, PercyLogger;
@@ -4433,16 +4681,16 @@ var init_PercyLogger = __esm({
4433
4681
  init_util();
4434
4682
  log3 = logger3("@wdio/browserstack-service");
4435
4683
  PercyLogger = class {
4436
- static logFilePath = path7.join(process.cwd(), PERCY_LOGS_FILE);
4437
- static logFolderPath = path7.join(process.cwd(), "logs");
4684
+ static logFilePath = path8.join(process.cwd(), PERCY_LOGS_FILE);
4685
+ static logFolderPath = path8.join(process.cwd(), "logs");
4438
4686
  static logFileStream;
4439
4687
  static logToFile(logMessage, logLevel) {
4440
4688
  try {
4441
4689
  if (!this.logFileStream) {
4442
- if (!fs8.existsSync(this.logFolderPath)) {
4443
- fs8.mkdirSync(this.logFolderPath);
4690
+ if (!fs9.existsSync(this.logFolderPath)) {
4691
+ fs9.mkdirSync(this.logFolderPath);
4444
4692
  }
4445
- this.logFileStream = fs8.createWriteStream(this.logFilePath, { flags: "a" });
4693
+ this.logFileStream = fs9.createWriteStream(this.logFilePath, { flags: "a" });
4446
4694
  }
4447
4695
  if (this.logFileStream && this.logFileStream.writable) {
4448
4696
  this.logFileStream.write(this.formatLog(logMessage, logLevel));
@@ -4486,8 +4734,8 @@ var init_PercyLogger = __esm({
4486
4734
  this.logFileStream = null;
4487
4735
  }
4488
4736
  static clearLogFile() {
4489
- if (fs8.existsSync(this.logFilePath)) {
4490
- fs8.truncateSync(this.logFilePath);
4737
+ if (fs9.existsSync(this.logFilePath)) {
4738
+ fs9.truncateSync(this.logFilePath);
4491
4739
  }
4492
4740
  }
4493
4741
  };
@@ -4495,7 +4743,7 @@ var init_PercyLogger = __esm({
4495
4743
  });
4496
4744
 
4497
4745
  // src/cli/grpcClient.ts
4498
- import path12 from "node:path";
4746
+ import path13 from "node:path";
4499
4747
  import util5, { promisify as promisify3 } from "node:util";
4500
4748
  import {
4501
4749
  SDKClient,
@@ -4528,7 +4776,7 @@ var init_grpcClient = __esm({
4528
4776
  listenAddress;
4529
4777
  channel = null;
4530
4778
  client = null;
4531
- logger = BStackLogger;
4779
+ logger = BStackLogger2;
4532
4780
  constructor() {
4533
4781
  }
4534
4782
  /**
@@ -4620,7 +4868,7 @@ var init_grpcClient = __esm({
4620
4868
  sdkLanguage: CLIUtils.getSdkLanguage(),
4621
4869
  sdkVersion: packageVersion,
4622
4870
  pathProject: process.cwd(),
4623
- pathConfig: path12.resolve(process.cwd(), "browserstack.yml"),
4871
+ pathConfig: path13.resolve(process.cwd(), "browserstack.yml"),
4624
4872
  cliArgs: process.argv.slice(2),
4625
4873
  frameworks: [automationFrameworkDetail.name, testFrameworkDetail.name],
4626
4874
  frameworkVersions,
@@ -5066,7 +5314,7 @@ var init_baseModule = __esm({
5066
5314
  this.platformIndex = platformIndex;
5067
5315
  this.client = client;
5068
5316
  this.config = config;
5069
- BStackLogger.debug(`Configured module ${this.getModuleName()} with binSessionId=${binSessionId}, platformIndex=${platformIndex}`);
5317
+ BStackLogger2.debug(`Configured module ${this.getModuleName()} with binSessionId=${binSessionId}, platformIndex=${platformIndex}`);
5070
5318
  }
5071
5319
  };
5072
5320
  }
@@ -5337,7 +5585,7 @@ var init_testFramework = __esm({
5337
5585
  * @returns {void}
5338
5586
  */
5339
5587
  trackEvent(testFrameworkState, hookState, args = {}) {
5340
- BStackLogger.info(`trackEvent: testFrameworkState=${testFrameworkState}; hookState=${hookState}; args=${args}`);
5588
+ BStackLogger2.info(`trackEvent: testFrameworkState=${testFrameworkState}; hookState=${hookState}; args=${args}`);
5341
5589
  }
5342
5590
  /**
5343
5591
  * run test hooks
@@ -5347,7 +5595,7 @@ var init_testFramework = __esm({
5347
5595
  * @param {*} args
5348
5596
  */
5349
5597
  async runHooks(instance, testFrameworkState, hookState, args = {}) {
5350
- BStackLogger.info(`runHooks: instance=${instance} automationFrameworkState=${testFrameworkState} hookState=${hookState}`);
5598
+ BStackLogger2.info(`runHooks: instance=${instance} automationFrameworkState=${testFrameworkState} hookState=${hookState}`);
5351
5599
  const hookRegistryKey = CLIUtils.getHookRegistryKey(testFrameworkState, hookState);
5352
5600
  await eventDispatcher.notifyObserver(hookRegistryKey, args);
5353
5601
  }
@@ -5611,7 +5859,7 @@ var init_automationFramework = __esm({
5611
5859
  * @returns {void}
5612
5860
  */
5613
5861
  async trackEvent(automationFrameworkState, hookState, args = {}) {
5614
- BStackLogger.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState} args=${args}`);
5862
+ BStackLogger2.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState} args=${args}`);
5615
5863
  }
5616
5864
  /**
5617
5865
  *
@@ -5621,7 +5869,7 @@ var init_automationFramework = __esm({
5621
5869
  * @param {*} args
5622
5870
  */
5623
5871
  async runHooks(instance, automationFrameworkState, hookState, args = {}) {
5624
- BStackLogger.info(`runHooks: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
5872
+ BStackLogger2.info(`runHooks: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
5625
5873
  const hookRegistryKey = CLIUtils.getHookRegistryKey(automationFrameworkState, hookState);
5626
5874
  await eventDispatcher.notifyObserver(hookRegistryKey, args);
5627
5875
  }
@@ -5639,7 +5887,7 @@ var init_automationFramework = __esm({
5639
5887
  * @returns {void}
5640
5888
  */
5641
5889
  static setTrackedInstance(context, instance) {
5642
- BStackLogger.debug(`setTrackedInstance: ${context.getId()}`);
5890
+ BStackLogger2.debug(`setTrackedInstance: ${context.getId()}`);
5643
5891
  _AutomationFramework.instances.set(context.getId(), instance);
5644
5892
  }
5645
5893
  /**
@@ -5647,7 +5895,7 @@ var init_automationFramework = __esm({
5647
5895
  * @returns {TrackedInstance} The tracked instance
5648
5896
  */
5649
5897
  static getTrackedInstance() {
5650
- BStackLogger.debug(`getTrackedInstance: ${CLIUtils.getCurrentInstanceName()}`);
5898
+ BStackLogger2.debug(`getTrackedInstance: ${CLIUtils.getCurrentInstanceName()}`);
5651
5899
  const context = TrackedInstance.createContext(CLIUtils.getCurrentInstanceName());
5652
5900
  return _AutomationFramework.instances.get(context.getId());
5653
5901
  }
@@ -5775,7 +6023,7 @@ var init_automateModule = __esm({
5775
6023
  init_automationFrameworkState();
5776
6024
  init_fetchWrapper();
5777
6025
  AutomateModule = class _AutomateModule extends BaseModule {
5778
- logger = BStackLogger;
6026
+ logger = BStackLogger2;
5779
6027
  browserStackConfig;
5780
6028
  sessionMap = /* @__PURE__ */ new Map();
5781
6029
  static MODULE_NAME = "AutomateModule";
@@ -6091,7 +6339,7 @@ var init_testFrameworkInstance = __esm({
6091
6339
 
6092
6340
  // src/cli/frameworks/wdioMochaTestFramework.ts
6093
6341
  import { v4 as uuidv42 } from "uuid";
6094
- import path13 from "node:path";
6342
+ import path14 from "node:path";
6095
6343
  var WdioMochaTestFramework;
6096
6344
  var init_wdioMochaTestFramework = __esm({
6097
6345
  "src/cli/frameworks/wdioMochaTestFramework.ts"() {
@@ -6125,11 +6373,11 @@ var init_wdioMochaTestFramework = __esm({
6125
6373
  * @param {*} args
6126
6374
  */
6127
6375
  async trackEvent(testFrameworkState, hookState, args = {}) {
6128
- BStackLogger.info(`trackEvent: testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6376
+ BStackLogger2.info(`trackEvent: testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6129
6377
  await super.trackEvent(testFrameworkState, hookState, args);
6130
6378
  const instance = this.resolveInstance(testFrameworkState, hookState, args);
6131
6379
  if (instance === null) {
6132
- BStackLogger.error(`trackEvent: instance not found for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6380
+ BStackLogger2.error(`trackEvent: instance not found for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6133
6381
  return;
6134
6382
  }
6135
6383
  try {
@@ -6141,7 +6389,7 @@ var init_wdioMochaTestFramework = __esm({
6141
6389
  if (!TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_ID) && hookState === HookState.PRE && testFrameworkState === TestFrameworkState.TEST) {
6142
6390
  const test = args.test;
6143
6391
  const testData = await this.getTestData(instance, test);
6144
- BStackLogger.info(`trackEvent: instanceData=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6392
+ BStackLogger2.info(`trackEvent: instanceData=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6145
6393
  instance.updateMultipleEntries(testData);
6146
6394
  }
6147
6395
  if (testFrameworkState === TestFrameworkState.TEST) {
@@ -6159,13 +6407,13 @@ var init_wdioMochaTestFramework = __esm({
6159
6407
  logEntry.uuid = TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOK_ID);
6160
6408
  this.loadLogEntries(instance, testFrameworkState, hookState, logEntry);
6161
6409
  } else if (testFrameworkState === TestFrameworkState.LOG_REPORT && hookState === HookState.POST) {
6162
- BStackLogger.info("trackEvent: load test results");
6410
+ BStackLogger2.info("trackEvent: load test results");
6163
6411
  this.loadTestResult(instance, args);
6164
6412
  }
6165
6413
  await this.trackHookEvents(instance, testFrameworkState, hookState, args);
6166
- BStackLogger.debug(`trackEvent: tracked instance data=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6414
+ BStackLogger2.debug(`trackEvent: tracked instance data=${JSON.stringify(Object.fromEntries(instance.getAllData()))}`);
6167
6415
  } catch (error) {
6168
- BStackLogger.error(`trackEvent: Error in tracking events: ${error} hookState=${hookState} testFrameworkState=${testFrameworkState}`);
6416
+ BStackLogger2.error(`trackEvent: Error in tracking events: ${error} hookState=${hookState} testFrameworkState=${testFrameworkState}`);
6169
6417
  }
6170
6418
  args.instance = instance;
6171
6419
  await this.runHooks(instance, testFrameworkState, hookState, args);
@@ -6179,7 +6427,7 @@ var init_wdioMochaTestFramework = __esm({
6179
6427
  */
6180
6428
  resolveInstance(testFrameworkState, hookState, args = {}) {
6181
6429
  let instance = null;
6182
- BStackLogger.info(`resolveInstance: resolving instance for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6430
+ BStackLogger2.info(`resolveInstance: resolving instance for testFrameworkState=${testFrameworkState} hookState=${hookState}`);
6183
6431
  if (testFrameworkState === TestFrameworkState.INIT_TEST || testFrameworkState === TestFrameworkState.NONE) {
6184
6432
  this.trackWdioMochaInstance(testFrameworkState, args);
6185
6433
  }
@@ -6196,7 +6444,7 @@ var init_wdioMochaTestFramework = __esm({
6196
6444
  const target = CLIUtils.getCurrentInstanceName();
6197
6445
  const trackedContext = TrackedInstance.createContext(target);
6198
6446
  let instance = null;
6199
- BStackLogger.info(`trackWdioMochaInstance: created instance for target=${target}, state=${testFrameworkState}, args=${args}`);
6447
+ BStackLogger2.info(`trackWdioMochaInstance: created instance for target=${target}, state=${testFrameworkState}, args=${args}`);
6200
6448
  instance = new TestFrameworkInstance(
6201
6449
  trackedContext,
6202
6450
  this.getTestFrameworks(),
@@ -6219,7 +6467,7 @@ var init_wdioMochaTestFramework = __esm({
6219
6467
  process.env[TEST_ANALYTICS_ID] = instanceEntries[TestFrameworkConstants.KEY_TEST_UUID];
6220
6468
  instance.updateMultipleEntries(instanceEntries);
6221
6469
  TestFramework.setTrackedInstance(trackedContext, instance);
6222
- BStackLogger.info(`trackWdioMochaInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
6470
+ BStackLogger2.info(`trackWdioMochaInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
6223
6471
  }
6224
6472
  async getTestData(instance, test) {
6225
6473
  const framework = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_FRAMEWORK_NAME);
@@ -6230,8 +6478,8 @@ var init_wdioMochaTestFramework = __esm({
6230
6478
  [TestFrameworkConstants.KEY_TEST_ID]: getUniqueIdentifier(test, framework),
6231
6479
  [TestFrameworkConstants.KEY_TEST_NAME]: test.title || test.description,
6232
6480
  [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,
6481
+ [TestFrameworkConstants.KEY_TEST_FILE_PATH]: gitConfig?.root && filename ? path14.relative(gitConfig.root, filename) : void 0,
6482
+ [TestFrameworkConstants.KEY_TEST_LOCATION]: filename ? path14.relative(process.cwd(), filename) : void 0,
6235
6483
  [TestFrameworkConstants.KEY_TEST_SCOPE]: fullTitle,
6236
6484
  [TestFrameworkConstants.KEY_TEST_SCOPES]: getMochaTestHierarchy(test)
6237
6485
  };
@@ -6284,7 +6532,7 @@ var init_wdioMochaTestFramework = __esm({
6284
6532
  if (lastActiveHook) {
6285
6533
  const hookLogs = lastActiveHook[TestFrameworkConstants.KEY_HOOK_LOGS];
6286
6534
  hookLogs.push(logRecord);
6287
- BStackLogger.debug(`hooks after update logs ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_STARTED)} ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_FINISHED)}`);
6535
+ BStackLogger2.debug(`hooks after update logs ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_STARTED)} ${TestFramework.getState(instance, TestFrameworkConstants.KEY_HOOKS_FINISHED)}`);
6288
6536
  return;
6289
6537
  }
6290
6538
  const entries = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_LOGS);
@@ -6385,15 +6633,15 @@ var init_wdioMochaTestFramework = __esm({
6385
6633
  [TestFrameworkConstants.KEY_EVENT_STARTED_AT]: (/* @__PURE__ */ new Date()).toISOString(),
6386
6634
  [TestFrameworkConstants.KEY_HOOK_LOGS]: [],
6387
6635
  [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
6636
+ [TestFrameworkConstants.KEY_TEST_FILE_PATH]: gitConfig?.root && filename ? path14.relative(gitConfig.root, filename) : void 0,
6637
+ [TestFrameworkConstants.KEY_TEST_LOCATION]: filename ? path14.relative(process.cwd(), filename) : void 0
6390
6638
  };
6391
6639
  hooksStarted.get(key)?.push(hook);
6392
6640
  updates[_WdioMochaTestFramework.KEY_HOOK_LAST_STARTED] = key;
6393
- BStackLogger.info(`Hook Started in PRE key = ${key} & hook = ${JSON.stringify(hook)}`);
6641
+ BStackLogger2.info(`Hook Started in PRE key = ${key} & hook = ${JSON.stringify(hook)}`);
6394
6642
  } else if (hookState === HookState.POST) {
6395
6643
  const hooksList = hooksStarted.get(key) || [];
6396
- BStackLogger.info(`Hook List in Post ${JSON.stringify(hooksList)}`);
6644
+ BStackLogger2.info(`Hook List in Post ${JSON.stringify(hooksList)}`);
6397
6645
  if (hooksList.length > 0) {
6398
6646
  const hook = hooksList.pop();
6399
6647
  const result = testResult.status;
@@ -6406,7 +6654,7 @@ var init_wdioMochaTestFramework = __esm({
6406
6654
  }
6407
6655
  }
6408
6656
  instance.updateMultipleEntries(updates);
6409
- BStackLogger.info(`trackHookEvents: hook state=${key}.${hookState}, hooks started=${JSON.stringify(hooksStarted)}, hooks finished=${JSON.stringify(hooksFinished)}`);
6657
+ BStackLogger2.info(`trackHookEvents: hook state=${key}.${hookState}, hooks started=${JSON.stringify(hooksStarted)}, hooks finished=${JSON.stringify(hooksFinished)}`);
6410
6658
  }
6411
6659
  };
6412
6660
  }
@@ -6430,7 +6678,7 @@ var init_testHubModule = __esm({
6430
6678
  init_automationFramework();
6431
6679
  init_automationFrameworkConstants();
6432
6680
  TestHubModule = class _TestHubModule extends BaseModule {
6433
- logger = BStackLogger;
6681
+ logger = BStackLogger2;
6434
6682
  testhubConfig;
6435
6683
  name;
6436
6684
  static MODULE_NAME = "TestHubModule";
@@ -6703,11 +6951,11 @@ var init_wdioAutomationFramework = __esm({
6703
6951
  * @param {*} args
6704
6952
  */
6705
6953
  async trackEvent(automationFrameworkState, hookState, args = {}) {
6706
- BStackLogger.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6954
+ BStackLogger2.info(`trackEvent: automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6707
6955
  await super.trackEvent(automationFrameworkState, hookState, args);
6708
6956
  const instance = this.resolveInstance(automationFrameworkState, hookState, args);
6709
6957
  if (instance === null) {
6710
- BStackLogger.error(`trackEvent: instance not found for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6958
+ BStackLogger2.error(`trackEvent: instance not found for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6711
6959
  return;
6712
6960
  }
6713
6961
  args.instance = instance;
@@ -6722,7 +6970,7 @@ var init_wdioAutomationFramework = __esm({
6722
6970
  */
6723
6971
  resolveInstance(automationFrameworkState, hookState, args = {}) {
6724
6972
  let instance = null;
6725
- BStackLogger.info(`resolveInstance: resolving instance for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6973
+ BStackLogger2.info(`resolveInstance: resolving instance for automationFrameworkState=${automationFrameworkState} hookState=${hookState}`);
6726
6974
  if (automationFrameworkState === AutomationFrameworkState.CREATE || automationFrameworkState === AutomationFrameworkState.NONE) {
6727
6975
  this.trackWebdriverIOInstance(automationFrameworkState, args);
6728
6976
  }
@@ -6738,13 +6986,13 @@ var init_wdioAutomationFramework = __esm({
6738
6986
  // !args.browser &&
6739
6987
  AutomationFramework.getTrackedInstance()
6740
6988
  ) {
6741
- BStackLogger.info("trackWebdriverIOInstance: instance already exists");
6989
+ BStackLogger2.info("trackWebdriverIOInstance: instance already exists");
6742
6990
  return;
6743
6991
  }
6744
6992
  const target = CLIUtils.getCurrentInstanceName();
6745
6993
  const trackedContext = TrackedInstance.createContext(target);
6746
6994
  let instance = null;
6747
- BStackLogger.info(`trackWebdriverIOInstance: created instance for target=${target}, state=${automationFrameworkState}, args=${args}`);
6995
+ BStackLogger2.info(`trackWebdriverIOInstance: created instance for target=${target}, state=${automationFrameworkState}, args=${args}`);
6748
6996
  instance = new AutomationFrameworkInstance(
6749
6997
  trackedContext,
6750
6998
  this.getAutomationFrameworkName(),
@@ -6752,7 +7000,7 @@ var init_wdioAutomationFramework = __esm({
6752
7000
  automationFrameworkState
6753
7001
  );
6754
7002
  AutomationFramework.setTrackedInstance(trackedContext, instance);
6755
- BStackLogger.info(`trackWebdriverIOInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
7003
+ BStackLogger2.info(`trackWebdriverIOInstance: saved instance contextId=${trackedContext.getId()} target=${target}`);
6756
7004
  }
6757
7005
  };
6758
7006
  }
@@ -6778,7 +7026,7 @@ var init_webdriverIOModule = __esm({
6778
7026
  browserVersion;
6779
7027
  platforms;
6780
7028
  testRunId;
6781
- logger = BStackLogger;
7029
+ logger = BStackLogger2;
6782
7030
  static MODULE_NAME = "WebdriverIOModule";
6783
7031
  /**
6784
7032
  * Create a new WebdriverIOModule
@@ -6906,7 +7154,7 @@ var init_accessibilityModule = __esm({
6906
7154
  init_constants2();
6907
7155
  init_grpcClient();
6908
7156
  AccessibilityModule = class extends BaseModule {
6909
- logger = BStackLogger;
7157
+ logger = BStackLogger2;
6910
7158
  name;
6911
7159
  scriptInstance;
6912
7160
  accessibility = false;
@@ -7190,7 +7438,7 @@ var init_accessibilityModule = __esm({
7190
7438
  formatString(this.scriptInstance.performScan, JSON.stringify(_getParamsForAppAccessibility(commandName, testName))),
7191
7439
  {}
7192
7440
  );
7193
- BStackLogger.debug(util9.format(results2));
7441
+ BStackLogger2.debug(util9.format(results2));
7194
7442
  return results2;
7195
7443
  }
7196
7444
  const results = await browser.executeAsync(
@@ -7313,7 +7561,7 @@ var init_observabilityModule = __esm({
7313
7561
  init_cliLogger();
7314
7562
  init_util();
7315
7563
  ObservabilityModule = class _ObservabilityModule extends BaseModule {
7316
- logger = BStackLogger;
7564
+ logger = BStackLogger2;
7317
7565
  observabilityConfig;
7318
7566
  name;
7319
7567
  static MODULE_NAME = "ObservabilityModule";
@@ -7416,22 +7664,22 @@ var init_request_handler = __esm({
7416
7664
  throw new Error("Test Reporting and Analytics build start not completed yet.");
7417
7665
  }
7418
7666
  this.queue.push(event);
7419
- BStackLogger2.debug(`Added data to request queue. Queue length = ${this.queue.length}`);
7667
+ BStackLogger.debug(`Added data to request queue. Queue length = ${this.queue.length}`);
7420
7668
  const shouldProceed = this.shouldProceed();
7421
7669
  if (shouldProceed) {
7422
7670
  this.sendBatch().catch((e) => {
7423
- BStackLogger2.debug("Exception in sending batch: " + e);
7671
+ BStackLogger.debug("Exception in sending batch: " + e);
7424
7672
  });
7425
7673
  }
7426
7674
  }
7427
7675
  async shutdown() {
7428
- BStackLogger2.debug("shutdown started");
7676
+ BStackLogger.debug("shutdown started");
7429
7677
  this.removeEventBatchPolling("Shutting down");
7430
7678
  while (this.queue.length > 0) {
7431
7679
  const data = this.queue.splice(0, DATA_BATCH_SIZE);
7432
7680
  await this.callCallback(data, "SHUTDOWN_QUEUE");
7433
7681
  }
7434
- BStackLogger2.debug("shutdown ended");
7682
+ BStackLogger.debug("shutdown ended");
7435
7683
  }
7436
7684
  startEventBatchPolling() {
7437
7685
  this.pollEventBatchInterval = setInterval(this.sendBatch.bind(this), DATA_BATCH_INTERVAL);
@@ -7441,11 +7689,11 @@ var init_request_handler = __esm({
7441
7689
  if (data.length === 0) {
7442
7690
  return;
7443
7691
  }
7444
- BStackLogger2.debug(`Sending data from request queue. Data length = ${data.length}, Queue length after removal = ${this.queue.length}`);
7692
+ BStackLogger.debug(`Sending data from request queue. Data length = ${data.length}, Queue length after removal = ${this.queue.length}`);
7445
7693
  await this.callCallback(data, "INTERVAL_QUEUE");
7446
7694
  }
7447
7695
  callCallback = async (data, kind) => {
7448
- BStackLogger2.debug("calling callback with kind " + kind);
7696
+ BStackLogger.debug("calling callback with kind " + kind);
7449
7697
  await this.callback?.(data);
7450
7698
  };
7451
7699
  resetEventBatchPolling() {
@@ -7454,13 +7702,13 @@ var init_request_handler = __esm({
7454
7702
  }
7455
7703
  removeEventBatchPolling(tag) {
7456
7704
  if (this.pollEventBatchInterval) {
7457
- BStackLogger2.debug(`${tag} request queue`);
7705
+ BStackLogger.debug(`${tag} request queue`);
7458
7706
  clearInterval(this.pollEventBatchInterval);
7459
7707
  }
7460
7708
  }
7461
7709
  shouldProceed() {
7462
7710
  if (_RequestQueueHandler.tearDownInvoked) {
7463
- BStackLogger2.debug("Force request-queue shutdown, as test run event is received after teardown");
7711
+ BStackLogger.debug("Force request-queue shutdown, as test run event is received after teardown");
7464
7712
  return true;
7465
7713
  }
7466
7714
  return this.queue.length >= DATA_BATCH_SIZE;
@@ -7483,7 +7731,7 @@ async function uploadEventData(eventData, eventUrl = DATA_EVENT_ENDPOINT) {
7483
7731
  throw new Error("Build start not completed yet");
7484
7732
  }
7485
7733
  if (!process.env[BROWSERSTACK_TESTHUB_JWT]) {
7486
- BStackLogger2.debug(`[${logTag}] Missing Authentication Token/ Build ID`);
7734
+ BStackLogger.debug(`[${logTag}] Missing Authentication Token/ Build ID`);
7487
7735
  throw new Error("Token/buildID is undefined, build creation might have failed");
7488
7736
  }
7489
7737
  try {
@@ -7496,9 +7744,9 @@ async function uploadEventData(eventData, eventUrl = DATA_EVENT_ENDPOINT) {
7496
7744
  },
7497
7745
  body: JSON.stringify(eventData)
7498
7746
  });
7499
- BStackLogger2.debug(`[${logTag}] Success response: ${JSON.stringify(await data.json())}`);
7747
+ BStackLogger.debug(`[${logTag}] Success response: ${JSON.stringify(await data.json())}`);
7500
7748
  } catch (error) {
7501
- BStackLogger2.debug(`[${logTag}] Failed. Error: ${format3(error)}`);
7749
+ BStackLogger.debug(`[${logTag}] Failed. Error: ${format3(error)}`);
7502
7750
  throw error;
7503
7751
  }
7504
7752
  }
@@ -7561,7 +7809,7 @@ var init_listener = __esm({
7561
7809
  await this.uploadPending();
7562
7810
  await this.teardown();
7563
7811
  } catch (e) {
7564
- BStackLogger2.debug("Exception in onWorkerEnd: " + e);
7812
+ BStackLogger.debug("Exception in onWorkerEnd: " + e);
7565
7813
  }
7566
7814
  }
7567
7815
  async uploadPending(waitTimeout = DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS, waitInterval = DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS) {
@@ -7572,10 +7820,10 @@ var init_listener = __esm({
7572
7820
  return this.uploadPending(waitTimeout - waitInterval);
7573
7821
  }
7574
7822
  async teardown() {
7575
- BStackLogger2.debug("teardown started");
7823
+ BStackLogger.debug("teardown started");
7576
7824
  RequestQueueHandler.tearDownInvoked = true;
7577
7825
  await this.requestBatcher?.shutdown();
7578
- BStackLogger2.debug("teardown ended");
7826
+ BStackLogger.debug("teardown ended");
7579
7827
  }
7580
7828
  hookStarted(hookData) {
7581
7829
  try {
@@ -7683,7 +7931,7 @@ var init_listener = __esm({
7683
7931
  }
7684
7932
  markLogs(status, data) {
7685
7933
  if (!data) {
7686
- BStackLogger2.debug("No log data");
7934
+ BStackLogger.debug("No log data");
7687
7935
  return;
7688
7936
  }
7689
7937
  try {
@@ -7692,7 +7940,7 @@ var init_listener = __esm({
7692
7940
  this.logEvents.mark(status, LOG_KIND_USAGE_MAP[kind] || kind);
7693
7941
  }
7694
7942
  } catch (e) {
7695
- BStackLogger2.debug("Exception in marking logs status " + e);
7943
+ BStackLogger.debug("Exception in marking logs status " + e);
7696
7944
  throw e;
7697
7945
  }
7698
7946
  }
@@ -7710,14 +7958,14 @@ var init_listener = __esm({
7710
7958
  }
7711
7959
  if (!this.requestBatcher) {
7712
7960
  this.requestBatcher = RequestQueueHandler.getInstance(async (data) => {
7713
- BStackLogger2.debug("callback: called with events " + data.length);
7961
+ BStackLogger.debug("callback: called with events " + data.length);
7714
7962
  try {
7715
7963
  this.pendingUploads += 1;
7716
7964
  await batchAndPostEvents(DATA_BATCH_ENDPOINT, "BATCH_DATA", data);
7717
- BStackLogger2.debug("callback: marking events success " + data.length);
7965
+ BStackLogger.debug("callback: marking events success " + data.length);
7718
7966
  this.eventsSuccess(data);
7719
7967
  } catch {
7720
- BStackLogger2.debug("callback: marking events failed " + data.length);
7968
+ BStackLogger.debug("callback: marking events failed " + data.length);
7721
7969
  this.eventsFailed(data);
7722
7970
  } finally {
7723
7971
  this.pendingUploads -= 1;
@@ -7774,7 +8022,7 @@ var init_listener = __esm({
7774
8022
  });
7775
8023
 
7776
8024
  // src/reporter.ts
7777
- import path14 from "node:path";
8025
+ import path15 from "node:path";
7778
8026
  import WDIOReporter from "@wdio/reporter";
7779
8027
  import * as url from "node:url";
7780
8028
  import { v4 as uuidv43 } from "uuid";
@@ -7867,7 +8115,7 @@ var init_reporter = __esm({
7867
8115
  filename = this._suiteName || suiteStats.file;
7868
8116
  }
7869
8117
  } catch {
7870
- BStackLogger2.debug("Error in decoding file name of suite");
8118
+ BStackLogger.debug("Error in decoding file name of suite");
7871
8119
  }
7872
8120
  }
7873
8121
  this._suiteName = filename;
@@ -7997,9 +8245,9 @@ var init_reporter = __esm({
7997
8245
  scope,
7998
8246
  scopes,
7999
8247
  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,
8248
+ file_name: suiteFileName ? path15.relative(process.cwd(), suiteFileName) : void 0,
8249
+ location: suiteFileName ? path15.relative(process.cwd(), suiteFileName) : void 0,
8250
+ vc_filepath: this._gitConfigPath && suiteFileName ? path15.relative(this._gitConfigPath, suiteFileName) : void 0,
8003
8251
  started_at: testStats.start && testStats.start.toISOString(),
8004
8252
  finished_at: testStats.end && testStats.end.toISOString(),
8005
8253
  framework,
@@ -8012,13 +8260,15 @@ var init_reporter = __esm({
8012
8260
  if (eventType.startsWith("TestRun") || eventType === "HookRunStarted") {
8013
8261
  const cloudProvider = getCloudProvider({ options: { hostname: this._config?.hostname } });
8014
8262
  testData.integrations = {};
8263
+ const liveBrowserCaps = globalThis?.browser?.capabilities;
8015
8264
  testData.integrations[cloudProvider] = {
8016
8265
  capabilities: this._capabilities,
8017
8266
  session_id: this._sessionId,
8018
8267
  browser: this._capabilities?.browserName,
8019
8268
  browser_version: this._capabilities?.browserVersion,
8020
8269
  platform: this._capabilities?.platformName,
8021
- platform_version: getPlatformVersion(this._capabilities, this._userCaps)
8270
+ platform_version: getPlatformVersion(this._capabilities, this._userCaps),
8271
+ device: getResolvedDeviceName(liveBrowserCaps, this._userCaps)
8022
8272
  };
8023
8273
  }
8024
8274
  if (eventType === "TestRunFinished" || eventType === "HookRunFinished") {
@@ -8048,7 +8298,7 @@ var init_reporter = __esm({
8048
8298
  });
8049
8299
 
8050
8300
  // src/insights-handler.ts
8051
- import path15 from "node:path";
8301
+ import path16 from "node:path";
8052
8302
  import { v4 as uuidv44 } from "uuid";
8053
8303
  var _InsightsHandler, InsightsHandler, insights_handler_default;
8054
8304
  var init_insights_handler = __esm({
@@ -8328,9 +8578,9 @@ var init_insights_handler = __esm({
8328
8578
  test_run_id: hookData.testRunId,
8329
8579
  scope: feature?.name,
8330
8580
  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,
8581
+ file_name: uri ? path16.relative(process.cwd(), uri) : void 0,
8582
+ location: uri ? path16.relative(process.cwd(), uri) : void 0,
8583
+ vc_filepath: this._gitConfigPath && uri ? path16.relative(this._gitConfigPath, uri) : void 0,
8334
8584
  result: "pending",
8335
8585
  framework: this._framework
8336
8586
  };
@@ -8495,7 +8745,7 @@ var init_insights_handler = __esm({
8495
8745
  this.listener.logCreated([stdLog]);
8496
8746
  }
8497
8747
  } catch (error) {
8498
- BStackLogger2.debug(`Exception in uploading log data to Test Reporting and Analytics with error : ${error}`);
8748
+ BStackLogger.debug(`Exception in uploading log data to Test Reporting and Analytics with error : ${error}`);
8499
8749
  }
8500
8750
  };
8501
8751
  async browserCommand(commandType, args, test) {
@@ -8628,9 +8878,9 @@ var init_insights_handler = __esm({
8628
8878
  scope: fullTitle,
8629
8879
  scopes: this.getHierarchy(test),
8630
8880
  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,
8881
+ file_name: filename ? path16.relative(process.cwd(), filename) : void 0,
8882
+ location: filename ? path16.relative(process.cwd(), filename) : void 0,
8883
+ vc_filepath: this._gitConfigPath && filename ? path16.relative(this._gitConfigPath, filename) : void 0,
8634
8884
  started_at: testMetaData.startedAt,
8635
8885
  finished_at: testMetaData.finishedAt,
8636
8886
  result: "pending",
@@ -8740,9 +8990,9 @@ var init_insights_handler = __esm({
8740
8990
  scope: fullNameWithExamples,
8741
8991
  scopes: [feature?.name || ""],
8742
8992
  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,
8993
+ file_name: feature && feature.path ? path16.relative(process.cwd(), feature.path) : void 0,
8994
+ location: feature && feature.path ? path16.relative(process.cwd(), feature.path) : void 0,
8995
+ vc_filepath: this._gitConfigPath && feature?.path ? path16.relative(this._gitConfigPath, feature?.path) : void 0,
8746
8996
  framework: this._framework,
8747
8997
  result: "pending",
8748
8998
  meta: {
@@ -8795,7 +9045,7 @@ var init_insights_handler = __esm({
8795
9045
  return testData;
8796
9046
  }
8797
9047
  async flushCBTDataQueue() {
8798
- BStackLogger2.debug(`Flushing CBT Data Queue ${this.currentTestId}`);
9048
+ BStackLogger.debug(`Flushing CBT Data Queue ${this.currentTestId}`);
8799
9049
  if (isUndefined(this.currentTestId)) {
8800
9050
  return;
8801
9051
  }
@@ -8815,7 +9065,7 @@ var init_insights_handler = __esm({
8815
9065
  uuid: "",
8816
9066
  integrations: integrationsData
8817
9067
  };
8818
- BStackLogger2.debug(`Sending CBT Data ${this.currentTestId} ${JSON.stringify(cbtData)}`);
9068
+ BStackLogger.debug(`Sending CBT Data ${this.currentTestId} ${JSON.stringify(cbtData)}`);
8819
9069
  if (this.currentTestId !== void 0) {
8820
9070
  cbtData.uuid = this.currentTestId;
8821
9071
  this.listener.cbtSessionCreated(cbtData);
@@ -8826,8 +9076,8 @@ var init_insights_handler = __esm({
8826
9076
  getIntegrationsObject() {
8827
9077
  const caps = this._browser?.capabilities;
8828
9078
  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)}`);
9079
+ BStackLogger.debug(`Driver capabilities used for integration object: ${JSON.stringify(caps)}`);
9080
+ BStackLogger.debug(`User capabilities used for integration object: ${JSON.stringify(this._userCaps)}`);
8831
9081
  return {
8832
9082
  capabilities: caps,
8833
9083
  session_id: sessionId,
@@ -8835,7 +9085,8 @@ var init_insights_handler = __esm({
8835
9085
  browser_version: caps?.browserVersion,
8836
9086
  platform: caps?.platformName,
8837
9087
  product: this._platformMeta?.product,
8838
- platform_version: getPlatformVersion(caps, this._userCaps)
9088
+ platform_version: getPlatformVersion(caps, this._userCaps),
9089
+ device: getResolvedDeviceName(caps, this._userCaps)
8839
9090
  };
8840
9091
  }
8841
9092
  getIdentifier(test) {
@@ -9128,7 +9379,7 @@ var init_percyModule = __esm({
9128
9379
  init_Percy_Handler();
9129
9380
  init_testFrameworkConstants();
9130
9381
  PercyModule = class _PercyModule extends BaseModule {
9131
- logger = BStackLogger;
9382
+ logger = BStackLogger2;
9132
9383
  browser;
9133
9384
  static MODULE_NAME = "PercyModule";
9134
9385
  percyHandler;
@@ -9249,7 +9500,7 @@ var init_cli = __esm({
9249
9500
  cliParams = null;
9250
9501
  automationFramework = null;
9251
9502
  SDK_CLI_BIN_PATH = null;
9252
- logger = BStackLogger;
9503
+ logger = BStackLogger2;
9253
9504
  options;
9254
9505
  constructor() {
9255
9506
  this.initialized = false;
@@ -9308,7 +9559,7 @@ var init_cli = __esm({
9308
9559
  const response = await GrpcClient.getInstance().startBinSession(this.wdioConfig);
9309
9560
  const redactedStartResponse = JSON.parse(JSON.stringify(response));
9310
9561
  CrashReporter.recursivelyRedactKeysFromObject(redactedStartResponse, ["user", "username", "key", "accesskey", "password"]);
9311
- BStackLogger.debug(`start: startBinSession response=${JSON.stringify(redactedStartResponse)}`);
9562
+ BStackLogger2.debug(`start: startBinSession response=${JSON.stringify(redactedStartResponse)}`);
9312
9563
  this.loadModules(response);
9313
9564
  this.isMainConnected = true;
9314
9565
  }
@@ -9320,6 +9571,7 @@ var init_cli = __esm({
9320
9571
  this.binSessionId = startBinResponse.binSessionId;
9321
9572
  this.logger.info(`loadModules: binSessionId=${this.binSessionId}`);
9322
9573
  this.setConfig(startBinResponse);
9574
+ this.logBuildErrors(startBinResponse);
9323
9575
  APIUtils.updateURLSForGRR(this.config.apis);
9324
9576
  this.setupTestFramework();
9325
9577
  this.setupAutomationFramework();
@@ -9341,17 +9593,6 @@ var init_cli = __esm({
9341
9593
  }
9342
9594
  this.modules[ObservabilityModule.MODULE_NAME] = new ObservabilityModule(startBinResponse.observability);
9343
9595
  }
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
9596
  this.modules[TestHubModule.MODULE_NAME] = new TestHubModule(startBinResponse.testhub);
9356
9597
  if (startBinResponse.accessibility?.success) {
9357
9598
  process.env[BROWSERSTACK_ACCESSIBILITY] = "true";
@@ -9366,6 +9607,28 @@ var init_cli = __esm({
9366
9607
  }
9367
9608
  this.configureModules();
9368
9609
  }
9610
+ /**
9611
+ * Log any build errors the binary reported via testhub.errors. The
9612
+ * field is a JSON-encoded { [errorKey]: { message, type } } map. Called
9613
+ * early in loadModules so the user sees the actionable cause (e.g.
9614
+ * invalid credentials) before any downstream bootstrap step that
9615
+ * depends on a fully populated config.
9616
+ */
9617
+ logBuildErrors(startBinResponse) {
9618
+ const rawErrors = startBinResponse.testhub?.errors;
9619
+ if (!rawErrors || !rawErrors.length) {
9620
+ return;
9621
+ }
9622
+ try {
9623
+ const errors = JSON.parse(Buffer.from(rawErrors).toString());
9624
+ for (const [code, detail] of Object.entries(errors)) {
9625
+ const { message } = detail;
9626
+ BStackLogger2.error(`[Build] ${code}: ${message}`);
9627
+ }
9628
+ } catch (e) {
9629
+ BStackLogger2.debug(`Failed to parse testhub errors: ${e}`);
9630
+ }
9631
+ }
9369
9632
  /**
9370
9633
  * Configure modules
9371
9634
  * @returns {Promise<void>}
@@ -9490,7 +9753,7 @@ var init_cli = __esm({
9490
9753
  try {
9491
9754
  if (this.isMainConnected) {
9492
9755
  const response = await GrpcClient.getInstance().stopBinSession();
9493
- BStackLogger.debug(`stop: stopBinSession response=${JSON.stringify(response)}`);
9756
+ BStackLogger2.debug(`stop: stopBinSession response=${JSON.stringify(response)}`);
9494
9757
  }
9495
9758
  await this.unConfigureModules();
9496
9759
  if (this.process && this.process.pid) {
@@ -9672,8 +9935,8 @@ var init_cli = __esm({
9672
9935
  });
9673
9936
 
9674
9937
  // src/testorchestration/helpers.ts
9675
- import os5 from "node:os";
9676
- import path18 from "node:path";
9938
+ import os6 from "node:os";
9939
+ import path19 from "node:path";
9677
9940
  import { spawnSync } from "node:child_process";
9678
9941
  import logger4 from "@wdio/logger";
9679
9942
  function isValidGitRef(ref) {
@@ -9699,11 +9962,11 @@ function safeGitCommand(args, cwd) {
9699
9962
  }
9700
9963
  function getHostInfo() {
9701
9964
  return {
9702
- hostname: os5.hostname(),
9965
+ hostname: os6.hostname(),
9703
9966
  platform: process.platform,
9704
9967
  architecture: process.arch,
9705
- release: os5.release(),
9706
- username: os5.userInfo().username
9968
+ release: os6.release(),
9969
+ username: os6.userInfo().username
9707
9970
  };
9708
9971
  }
9709
9972
  function isValidGitResult(result) {
@@ -9794,7 +10057,7 @@ function getGitMetadataForAISelection(folders = []) {
9794
10057
  if (folders === null) {
9795
10058
  folders = [process.cwd()];
9796
10059
  }
9797
- const uniqueFolders = [...new Set(folders.map((f) => path18.resolve(f)))];
10060
+ const uniqueFolders = [...new Set(folders.map((f) => path19.resolve(f)))];
9798
10061
  log4.debug(`Processing ${uniqueFolders.length} unique folders out of ${folders.length} total`);
9799
10062
  const results = [];
9800
10063
  for (const folder of uniqueFolders) {
@@ -9951,14 +10214,14 @@ var init_request_utils = __esm({
9951
10214
  * Makes a request to the test orchestration split tests endpoint
9952
10215
  */
9953
10216
  static async testOrchestrationSplitTests(reqEndpoint, data) {
9954
- BStackLogger2.debug("Processing Request for testOrchestrationSplitTests");
10217
+ BStackLogger.debug("Processing Request for testOrchestrationSplitTests");
9955
10218
  return _RequestUtils.makeOrchestrationRequest("POST", reqEndpoint, { data });
9956
10219
  }
9957
10220
  /**
9958
10221
  * Gets ordered tests from the test orchestration
9959
10222
  */
9960
10223
  static async getTestOrchestrationOrderedTests(reqEndpoint) {
9961
- BStackLogger2.debug("Processing Request for getTestOrchestrationOrderedTests");
10224
+ BStackLogger.debug("Processing Request for getTestOrchestrationOrderedTests");
9962
10225
  return _RequestUtils.makeOrchestrationRequest("GET", reqEndpoint, {});
9963
10226
  }
9964
10227
  /**
@@ -9995,13 +10258,13 @@ var init_request_utils = __esm({
9995
10258
  throw new Error(`Unsupported HTTP method: ${method}`);
9996
10259
  }
9997
10260
  const response = await fetchWrap(urlObject.toString(), requestInit);
9998
- BStackLogger2.debug(`Orchestration request made to URL: ${urlObject.toString()} with method: ${method}`);
10261
+ BStackLogger.debug(`Orchestration request made to URL: ${urlObject.toString()} with method: ${method}`);
9999
10262
  const rawBody = await response.text();
10000
10263
  let responseObj = rawBody;
10001
10264
  try {
10002
10265
  responseObj = rawBody ? JSON.parse(rawBody) : {};
10003
10266
  } catch (error) {
10004
- BStackLogger2.debug(`Failed to parse JSON response: ${error} - ${rawBody}`);
10267
+ BStackLogger.debug(`Failed to parse JSON response: ${error} - ${rawBody}`);
10005
10268
  }
10006
10269
  if (responseObj && typeof responseObj === "object" && !Array.isArray(responseObj)) {
10007
10270
  return {
@@ -10012,7 +10275,7 @@ var init_request_utils = __esm({
10012
10275
  }
10013
10276
  return typeof responseObj === "string" ? responseObj : rawBody;
10014
10277
  } catch (error) {
10015
- BStackLogger2.error(`Orchestration request failed: ${error} - ${url3}`);
10278
+ BStackLogger.error(`Orchestration request failed: ${error} - ${url3}`);
10016
10279
  return null;
10017
10280
  }
10018
10281
  }
@@ -10021,7 +10284,7 @@ var init_request_utils = __esm({
10021
10284
  });
10022
10285
 
10023
10286
  // src/testorchestration/test-ordering-server.ts
10024
- import path19 from "node:path";
10287
+ import path20 from "node:path";
10025
10288
  function isSplitTestsResponse(value) {
10026
10289
  return typeof value === "object" && value !== null;
10027
10290
  }
@@ -10055,7 +10318,7 @@ var init_test_ordering_server = __esm({
10055
10318
  * Initiates the split tests request and stores the response data for polling.
10056
10319
  */
10057
10320
  async splitTests(testFiles, orchestrationStrategy, orchestrationMetadata = "{}") {
10058
- BStackLogger2.debug(`[splitTests] Initiating split tests with strategy: ${orchestrationStrategy}`);
10321
+ BStackLogger.debug(`[splitTests] Initiating split tests with strategy: ${orchestrationStrategy}`);
10059
10322
  try {
10060
10323
  let prDetails = [];
10061
10324
  const parsedMetadata = JSON.parse(orchestrationMetadata);
@@ -10065,7 +10328,7 @@ var init_test_ordering_server = __esm({
10065
10328
  const multiRepoSource = parsedMetadata.run_smart_selection?.source;
10066
10329
  prDetails = getGitMetadataForAISelection(multiRepoSource);
10067
10330
  }
10068
- BStackLogger2.debug(`PR Details for AI Selection: ${JSON.stringify(prDetails)}`);
10331
+ BStackLogger.debug(`PR Details for AI Selection: ${JSON.stringify(prDetails)}`);
10069
10332
  const payload = {
10070
10333
  tests: testFiles.map((f) => ({ filePath: f })),
10071
10334
  orchestrationStrategy,
@@ -10073,23 +10336,23 @@ var init_test_ordering_server = __esm({
10073
10336
  nodeIndex: parseInt(process.env.BROWSERSTACK_NODE_INDEX || "0"),
10074
10337
  totalNodes: parseInt(process.env.BROWSERSTACK_TOTAL_NODE_COUNT || "1"),
10075
10338
  projectName: this.config.testObservabilityOptions?.projectName || "",
10076
- buildName: this.config.testObservabilityOptions?.buildName || path19.basename(process.cwd()),
10339
+ buildName: this.config.testObservabilityOptions?.buildName || path20.basename(process.cwd()),
10077
10340
  buildRunIdentifier: process.env.BROWSERSTACK_BUILD_RUN_IDENTIFIER || "",
10078
10341
  hostInfo: getHostInfo(),
10079
10342
  prDetails
10080
10343
  };
10081
- BStackLogger2.info(`[splitTests] Split tests payload: ${JSON.stringify(payload)}`);
10344
+ BStackLogger.info(`[splitTests] Split tests payload: ${JSON.stringify(payload)}`);
10082
10345
  const response = await RequestUtils.testOrchestrationSplitTests(this.ORDERING_ENDPOINT, payload);
10083
10346
  if (isSplitTestsResponse(response)) {
10084
10347
  this.requestData = this._processSplitTestsResponse(response);
10085
- BStackLogger2.debug(`[splitTests] Split tests response: ${JSON.stringify(this.requestData)}`);
10348
+ BStackLogger.debug(`[splitTests] Split tests response: ${JSON.stringify(this.requestData)}`);
10086
10349
  } else if (response) {
10087
- BStackLogger2.error("[splitTests] Received unexpected response format from split tests request.");
10350
+ BStackLogger.error("[splitTests] Received unexpected response format from split tests request.");
10088
10351
  } else {
10089
- BStackLogger2.error("[splitTests] Failed to get split tests response.");
10352
+ BStackLogger.error("[splitTests] Failed to get split tests response.");
10090
10353
  }
10091
10354
  } catch (error) {
10092
- BStackLogger2.error(`[splitTests] Exception in sending test files:: ${error}`);
10355
+ BStackLogger.error(`[splitTests] Exception in sending test files:: ${error}`);
10093
10356
  }
10094
10357
  }
10095
10358
  /**
@@ -10107,7 +10370,7 @@ var init_test_ordering_server = __esm({
10107
10370
  const resultUrl = normalizeUrl(response.resultUrl);
10108
10371
  const timeoutUrl = normalizeUrl(response.timeoutUrl);
10109
10372
  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");
10373
+ BStackLogger.debug("[process_split_tests_response] Received null value(s) for some attributes in split tests API response");
10111
10374
  }
10112
10375
  return {
10113
10376
  timeout,
@@ -10121,7 +10384,7 @@ var init_test_ordering_server = __esm({
10121
10384
  */
10122
10385
  async getOrderedTestFiles() {
10123
10386
  if (!this.requestData) {
10124
- BStackLogger2.error("[getOrderedTestFiles] No request data available to fetch ordered test files.");
10387
+ BStackLogger.error("[getOrderedTestFiles] No request data available to fetch ordered test files.");
10125
10388
  return null;
10126
10389
  }
10127
10390
  let testFilesJsonList = null;
@@ -10145,10 +10408,10 @@ var init_test_ordering_server = __esm({
10145
10408
  break;
10146
10409
  }
10147
10410
  await new Promise((resolve) => setTimeout(resolve, timeoutInterval * 1e3));
10148
- BStackLogger2.debug(`[getOrderedTestFiles] Fetching ordered tests from result URL after waiting for ${timeoutInterval} seconds.`);
10411
+ BStackLogger.debug(`[getOrderedTestFiles] Fetching ordered tests from result URL after waiting for ${timeoutInterval} seconds.`);
10149
10412
  }
10150
10413
  if (timeoutUrl && !testFilesJsonList) {
10151
- BStackLogger2.debug("[getOrderedTestFiles] Fetching ordered tests from timeout URL");
10414
+ BStackLogger.debug("[getOrderedTestFiles] Fetching ordered tests from timeout URL");
10152
10415
  const response = await RequestUtils.getTestOrchestrationOrderedTests(timeoutUrl);
10153
10416
  if (isSplitTestsResponse(response) && Array.isArray(response.tests)) {
10154
10417
  testFilesJsonList = response.tests;
@@ -10165,10 +10428,10 @@ var init_test_ordering_server = __esm({
10165
10428
  if (!testFilesJsonList) {
10166
10429
  return null;
10167
10430
  }
10168
- BStackLogger2.debug(`[getOrderedTestFiles] Ordered test files received: ${JSON.stringify(testFiles)}`);
10431
+ BStackLogger.debug(`[getOrderedTestFiles] Ordered test files received: ${JSON.stringify(testFiles)}`);
10169
10432
  return testFiles;
10170
10433
  } catch (error) {
10171
- BStackLogger2.error(`[getOrderedTestFiles] Exception in fetching ordered test files: ${error}`);
10434
+ BStackLogger.error(`[getOrderedTestFiles] Exception in fetching ordered test files: ${error}`);
10172
10435
  return null;
10173
10436
  }
10174
10437
  }
@@ -10260,10 +10523,10 @@ var init_testorcherstrationhandler = __esm({
10260
10523
  return;
10261
10524
  }
10262
10525
  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.");
10526
+ BStackLogger.info("Test Reordering can't work as buildName or projectName is null. Please set a non-null value.");
10264
10527
  }
10265
10528
  if (!this._isObservabilityEnabled()) {
10266
- BStackLogger2.info("Test Reordering can't work as testReporting is disabled. Please enable it from browserstack.yml file.");
10529
+ BStackLogger.info("Test Reordering can't work as testReporting is disabled. Please enable it from browserstack.yml file.");
10267
10530
  }
10268
10531
  }
10269
10532
  /**
@@ -10272,7 +10535,7 @@ var init_testorcherstrationhandler = __esm({
10272
10535
  async reorderTestFiles(testFiles) {
10273
10536
  try {
10274
10537
  if (!testFiles || testFiles.length === 0) {
10275
- BStackLogger2.debug("[reorderTestFiles] No test files provided for ordering.");
10538
+ BStackLogger.debug("[reorderTestFiles] No test files provided for ordering.");
10276
10539
  return null;
10277
10540
  }
10278
10541
  let orchestrationStrategy = null;
@@ -10281,16 +10544,16 @@ var init_testorcherstrationhandler = __esm({
10281
10544
  orchestrationStrategy = this.orchestrationUtils.getTestOrderingName();
10282
10545
  }
10283
10546
  if (orchestrationStrategy === null) {
10284
- BStackLogger2.error("Orchestration strategy is None. Cannot proceed with test orchestration session.");
10547
+ BStackLogger.error("Orchestration strategy is None. Cannot proceed with test orchestration session.");
10285
10548
  return null;
10286
10549
  }
10287
- BStackLogger2.info(`Reordering test files with orchestration strategy: ${orchestrationStrategy}`);
10550
+ BStackLogger.info(`Reordering test files with orchestration strategy: ${orchestrationStrategy}`);
10288
10551
  let orderedTestFiles = [];
10289
10552
  if (BrowserstackCLI.getInstance().isRunning()) {
10290
- BStackLogger2.info("Using CLI flow for test files orchestration.");
10553
+ BStackLogger.info("Using CLI flow for test files orchestration.");
10291
10554
  orderedTestFiles = await GrpcClient.getInstance().testOrchestrationSession(testFiles, orchestrationStrategy, JSON.stringify(orchestrationMetadata)) || [];
10292
10555
  } else {
10293
- BStackLogger2.info("Using SDK flow for test files orchestration.");
10556
+ BStackLogger.info("Using SDK flow for test files orchestration.");
10294
10557
  await this.testOrderingServerHandler.splitTests(testFiles, orchestrationStrategy, JSON.stringify(orchestrationMetadata));
10295
10558
  orderedTestFiles = await this.testOrderingServerHandler.getOrderedTestFiles() || [];
10296
10559
  }
@@ -10301,7 +10564,7 @@ var init_testorcherstrationhandler = __esm({
10301
10564
  this.addToOrderingInstrumentationData("splitTestsAPICallCount", this.testOrderingServerHandler.getSplitTestsApiCallCount());
10302
10565
  return orderedTestFiles;
10303
10566
  } catch (error) {
10304
- BStackLogger2.debug(`[reorderTestFiles] Error in ordering test classes: ${error}`);
10567
+ BStackLogger.debug(`[reorderTestFiles] Error in ordering test classes: ${error}`);
10305
10568
  }
10306
10569
  return null;
10307
10570
  }
@@ -10331,22 +10594,22 @@ import { performance as performance3 } from "node:perf_hooks";
10331
10594
  async function applyOrchestrationIfEnabled(specs, config) {
10332
10595
  const orchestrationHandler = TestOrchestrationHandler.getInstance(config);
10333
10596
  if (!orchestrationHandler) {
10334
- BStackLogger2.debug("Orchestration handler is not initialized. Skipping orchestration.");
10597
+ BStackLogger.debug("Orchestration handler is not initialized. Skipping orchestration.");
10335
10598
  return specs;
10336
10599
  }
10337
10600
  const runSmartSelectionEnabled = isValidEnabledValue(config?.testOrchestrationOptions?.runSmartSelection?.enabled);
10338
10601
  if (!runSmartSelectionEnabled) {
10339
- BStackLogger2.info("runSmartSelection is not enabled in config. Skipping orchestration.");
10602
+ BStackLogger.info("runSmartSelection is not enabled in config. Skipping orchestration.");
10340
10603
  return specs;
10341
10604
  }
10342
10605
  orchestrationHandler.addToOrderingInstrumentationData("enabled", orchestrationHandler.testOrderingEnabled());
10343
10606
  const startTime = performance3.now();
10344
- BStackLogger2.info("Test orchestration is enabled. Attempting to reorder test files.");
10607
+ BStackLogger.info("Test orchestration is enabled. Attempting to reorder test files.");
10345
10608
  const testFiles = specs;
10346
- BStackLogger2.info(`Test files to be reordered: ${testFiles.join(", ")}`);
10609
+ BStackLogger.info(`Test files to be reordered: ${testFiles.join(", ")}`);
10347
10610
  const orderedFiles = await orchestrationHandler.reorderTestFiles(testFiles);
10348
10611
  if (orderedFiles && orderedFiles.length > 0) {
10349
- BStackLogger2.info(`Tests reordered using orchestration: ${orderedFiles.join(", ")}`);
10612
+ BStackLogger.info(`Tests reordered using orchestration: ${orderedFiles.join(", ")}`);
10350
10613
  orchestrationHandler.addToOrderingInstrumentationData(
10351
10614
  "timeTakenToApply",
10352
10615
  Math.floor(performance3.now() - startTime)
@@ -10354,7 +10617,7 @@ async function applyOrchestrationIfEnabled(specs, config) {
10354
10617
  );
10355
10618
  return orderedFiles;
10356
10619
  }
10357
- BStackLogger2.info("No test files were reordered by orchestration.");
10620
+ BStackLogger.info("No test files were reordered by orchestration.");
10358
10621
  orchestrationHandler.addToOrderingInstrumentationData(
10359
10622
  "timeTakenToApply",
10360
10623
  Math.floor(performance3.now() - startTime)
@@ -10376,12 +10639,12 @@ var init_apply_orchestration = __esm({
10376
10639
  // src/launcher.ts
10377
10640
  init_utils();
10378
10641
  init_testOpsConfig();
10379
- import fs14 from "node:fs";
10642
+ import fs15 from "node:fs";
10380
10643
  import { readFile } from "node:fs/promises";
10381
- import path20 from "node:path";
10644
+ import path21 from "node:path";
10382
10645
  import { promisify as promisify4, format as format4 } from "node:util";
10383
10646
  import { performance as performance4, PerformanceObserver as PerformanceObserver2 } from "node:perf_hooks";
10384
- import os6 from "node:os";
10647
+ import os7 from "node:os";
10385
10648
  import { SevereServiceError } from "webdriverio";
10386
10649
  import * as BrowserstackLocalLauncher from "browserstack-local";
10387
10650
 
@@ -10391,9 +10654,9 @@ init_PercyLogger();
10391
10654
  // src/Percy/Percy.ts
10392
10655
  init_util();
10393
10656
  init_PercyLogger();
10394
- import fs10 from "node:fs";
10395
- import path9 from "node:path";
10396
- import os3 from "node:os";
10657
+ import fs11 from "node:fs";
10658
+ import path10 from "node:path";
10659
+ import os4 from "node:os";
10397
10660
  import { spawn as spawn2 } from "node:child_process";
10398
10661
 
10399
10662
  // src/Percy/PercyBinary.ts
@@ -10403,20 +10666,20 @@ init_constants2();
10403
10666
  init_bstackLogger();
10404
10667
  init_fetchWrapper();
10405
10668
  import yauzl2 from "yauzl";
10406
- import fs9 from "node:fs";
10669
+ import fs10 from "node:fs";
10407
10670
  import fsp2 from "node:fs/promises";
10408
10671
  import { pipeline } from "node:stream/promises";
10409
- import path8 from "node:path";
10410
- import os2 from "node:os";
10672
+ import path9 from "node:path";
10673
+ import os3 from "node:os";
10411
10674
  import { spawn } from "node:child_process";
10412
10675
  var PercyBinary = class {
10413
10676
  #hostOS = process.platform;
10414
10677
  #httpPath = null;
10415
10678
  #binaryName = "percy";
10416
10679
  #orderedPaths = [
10417
- path8.join(os2.homedir(), ".browserstack"),
10680
+ path9.join(os3.homedir(), ".browserstack"),
10418
10681
  process.cwd(),
10419
- os2.tmpdir()
10682
+ os3.tmpdir()
10420
10683
  ];
10421
10684
  constructor() {
10422
10685
  const base = "https://github.com/percy/cli/releases/latest/download";
@@ -10429,15 +10692,15 @@ var PercyBinary = class {
10429
10692
  this.#httpPath = base + "/percy-linux.zip";
10430
10693
  }
10431
10694
  }
10432
- async #makePath(path21) {
10433
- if (await this.#checkPath(path21)) {
10695
+ async #makePath(path22) {
10696
+ if (await this.#checkPath(path22)) {
10434
10697
  return true;
10435
10698
  }
10436
- return fsp2.mkdir(path21).then(() => true).catch(() => false);
10699
+ return fsp2.mkdir(path22).then(() => true).catch(() => false);
10437
10700
  }
10438
- async #checkPath(path21) {
10701
+ async #checkPath(path22) {
10439
10702
  try {
10440
- const hasDir = await fsp2.access(path21).then(() => true, () => false);
10703
+ const hasDir = await fsp2.access(path22).then(() => true, () => false);
10441
10704
  if (hasDir) {
10442
10705
  return true;
10443
10706
  }
@@ -10447,7 +10710,7 @@ var PercyBinary = class {
10447
10710
  }
10448
10711
  // Get the path for storing the ETag
10449
10712
  #getETagPath(destParentDir) {
10450
- return path8.join(destParentDir, `${this.#binaryName}.etag`);
10713
+ return path9.join(destParentDir, `${this.#binaryName}.etag`);
10451
10714
  }
10452
10715
  // Load the stored ETag if it exists
10453
10716
  async #loadETag(destParentDir) {
@@ -10457,7 +10720,7 @@ var PercyBinary = class {
10457
10720
  const data = await fsp2.readFile(etagPath, "utf8");
10458
10721
  return data.trim();
10459
10722
  } catch (err) {
10460
- BStackLogger2.warn(`Failed to read ETag file ${err}`);
10723
+ BStackLogger.warn(`Failed to read ETag file ${err}`);
10461
10724
  }
10462
10725
  }
10463
10726
  return null;
@@ -10470,23 +10733,23 @@ var PercyBinary = class {
10470
10733
  try {
10471
10734
  const etagPath = this.#getETagPath(destParentDir);
10472
10735
  await fsp2.writeFile(etagPath, etag);
10473
- BStackLogger2.debug("Saved new ETag for percy binary");
10736
+ BStackLogger.debug("Saved new ETag for percy binary");
10474
10737
  } catch (err) {
10475
- BStackLogger2.error(`Failed to save ETag file ${err}`);
10738
+ BStackLogger.error(`Failed to save ETag file ${err}`);
10476
10739
  }
10477
10740
  }
10478
10741
  async #getAvailableDirs() {
10479
10742
  for (let i = 0; i < this.#orderedPaths.length; i++) {
10480
- const path21 = this.#orderedPaths[i];
10481
- if (await this.#makePath(path21)) {
10482
- return path21;
10743
+ const path22 = this.#orderedPaths[i];
10744
+ if (await this.#makePath(path22)) {
10745
+ return path22;
10483
10746
  }
10484
10747
  }
10485
10748
  throw new Error("Error trying to download percy binary");
10486
10749
  }
10487
10750
  async getBinaryPath() {
10488
10751
  const destParentDir = await this.#getAvailableDirs();
10489
- const binaryPath = path8.join(destParentDir, this.#binaryName);
10752
+ const binaryPath = path9.join(destParentDir, this.#binaryName);
10490
10753
  let response;
10491
10754
  if (await this.#checkPath(binaryPath)) {
10492
10755
  const currentETag = await this.#loadETag(destParentDir);
@@ -10494,13 +10757,13 @@ var PercyBinary = class {
10494
10757
  try {
10495
10758
  const result = await this.#checkForUpdate(currentETag);
10496
10759
  if (!result.needsUpdate) {
10497
- BStackLogger2.debug("Percy binary is up to date (ETag unchanged)");
10760
+ BStackLogger.debug("Percy binary is up to date (ETag unchanged)");
10498
10761
  return binaryPath;
10499
10762
  }
10500
10763
  response = result.response;
10501
- BStackLogger2.debug("New Percy binary version available, downloading update");
10764
+ BStackLogger.debug("New Percy binary version available, downloading update");
10502
10765
  } catch (err) {
10503
- BStackLogger2.warn(`Failed to check for binary updates, using existing binary ${err}`);
10766
+ BStackLogger.warn(`Failed to check for binary updates, using existing binary ${err}`);
10504
10767
  return binaryPath;
10505
10768
  }
10506
10769
  }
@@ -10528,11 +10791,11 @@ var PercyBinary = class {
10528
10791
  }
10529
10792
  const newETag = response.headers.get("eTag");
10530
10793
  if (newETag) {
10531
- await this.#saveETag(path8.dirname(this.#getETagPath(await this.#getAvailableDirs())), newETag);
10794
+ await this.#saveETag(path9.dirname(this.#getETagPath(await this.#getAvailableDirs())), newETag);
10532
10795
  }
10533
10796
  return { needsUpdate: true, response };
10534
10797
  } catch (error) {
10535
- BStackLogger2.warn(`Error checking for Percy binary updates: ${error}`);
10798
+ BStackLogger.warn(`Error checking for Percy binary updates: ${error}`);
10536
10799
  throw error;
10537
10800
  }
10538
10801
  }
@@ -10555,9 +10818,9 @@ var PercyBinary = class {
10555
10818
  await fsp2.mkdir(destParentDir);
10556
10819
  }
10557
10820
  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);
10821
+ const zipFilePath = path9.join(destParentDir, binaryName + ".zip");
10822
+ const binaryPath = path9.join(destParentDir, binaryName);
10823
+ const downloadedFileStream = fs10.createWriteStream(zipFilePath);
10561
10824
  if (!response) {
10562
10825
  response = await _fetch(this.#httpPath);
10563
10826
  }
@@ -10576,8 +10839,8 @@ var PercyBinary = class {
10576
10839
  if (/\/$/.test(entry.fileName)) {
10577
10840
  zipfile.readEntry();
10578
10841
  } else {
10579
- const writeStream = fs9.createWriteStream(
10580
- path8.join(destParentDir, entry.fileName)
10842
+ const writeStream = fs10.createWriteStream(
10843
+ path9.join(destParentDir, entry.fileName)
10581
10844
  );
10582
10845
  zipfile.openReadStream(entry, function(zipErr, readStream) {
10583
10846
  if (zipErr) {
@@ -10598,7 +10861,7 @@ var PercyBinary = class {
10598
10861
  reject(zipErr);
10599
10862
  });
10600
10863
  zipfile.once("end", () => {
10601
- fs9.chmod(binaryPath, "0755", function(zipErr) {
10864
+ fs10.chmod(binaryPath, "0755", function(zipErr) {
10602
10865
  if (zipErr) {
10603
10866
  reject(zipErr);
10604
10867
  }
@@ -10622,7 +10885,7 @@ init_constants2();
10622
10885
  init_apiUtils();
10623
10886
  var logDir = "logs";
10624
10887
  var Percy = class {
10625
- #logfile = path9.join(logDir, "percy.log");
10888
+ #logfile = path10.join(logDir, "percy.log");
10626
10889
  #address = process.env.PERCY_SERVER_ADDRESS || "http://127.0.0.1:5338";
10627
10890
  #binaryPath = null;
10628
10891
  #options;
@@ -10663,7 +10926,7 @@ var Percy = class {
10663
10926
  }
10664
10927
  async start() {
10665
10928
  const binaryPath = await this.#getBinaryPath();
10666
- const logStream = fs10.createWriteStream(this.#logfile, { flags: "a" });
10929
+ const logStream = fs11.createWriteStream(this.#logfile, { flags: "a" });
10667
10930
  const token = await this.fetchPercyToken();
10668
10931
  const configPath = await this.createPercyConfig();
10669
10932
  if (!token) {
@@ -10750,13 +11013,13 @@ var Percy = class {
10750
11013
  if (!this.#options.percyOptions) {
10751
11014
  return null;
10752
11015
  }
10753
- const configPath = path9.join(os3.tmpdir(), "percy.json");
11016
+ const configPath = path10.join(os4.tmpdir(), "percy.json");
10754
11017
  const percyOptions = this.#options.percyOptions;
10755
11018
  if (!percyOptions.version) {
10756
11019
  percyOptions.version = "2";
10757
11020
  }
10758
11021
  return new Promise((resolve) => {
10759
- fs10.writeFile(
11022
+ fs11.writeFile(
10760
11023
  configPath,
10761
11024
  JSON.stringify(
10762
11025
  percyOptions
@@ -10850,6 +11113,7 @@ init_constants();
10850
11113
  init_util();
10851
11114
  init_crash_reporter();
10852
11115
  init_bstackLogger();
11116
+ init_caCert();
10853
11117
  init_PercyLogger();
10854
11118
 
10855
11119
  // src/config.ts
@@ -10857,10 +11121,62 @@ init_testOpsConfig();
10857
11121
  init_util();
10858
11122
  init_bstackLogger();
10859
11123
  import { v4 as uuidv4 } from "uuid";
11124
+ var APP_AUTOMATE_CAP_KEYS = ["appium:app", "appium:bundleId", "appium:appPackage", "appium:appActivity"];
11125
+ function hasAppCap(cap) {
11126
+ if (!cap || typeof cap !== "object") {
11127
+ return false;
11128
+ }
11129
+ const record = cap;
11130
+ if (APP_AUTOMATE_CAP_KEYS.some((key) => !isUndefined(record[key]))) {
11131
+ return true;
11132
+ }
11133
+ const appiumOptions = record["appium:options"];
11134
+ return !!(appiumOptions && !isUndefined(appiumOptions.app));
11135
+ }
11136
+ function detectAppAutomate(capabilities) {
11137
+ if (!capabilities) {
11138
+ return false;
11139
+ }
11140
+ const flat = [];
11141
+ if (Array.isArray(capabilities)) {
11142
+ for (const entry of capabilities) {
11143
+ if (!entry || typeof entry !== "object") {
11144
+ continue;
11145
+ }
11146
+ if ("alwaysMatch" in entry) {
11147
+ const w3c = entry;
11148
+ flat.push(w3c.alwaysMatch);
11149
+ if (Array.isArray(w3c.firstMatch)) {
11150
+ flat.push(...w3c.firstMatch);
11151
+ }
11152
+ continue;
11153
+ }
11154
+ const values = Object.values(entry);
11155
+ const isParallelMultiremote = values.length > 0 && values.every(
11156
+ (v) => v !== null && typeof v === "object" && v.capabilities
11157
+ );
11158
+ if (isParallelMultiremote) {
11159
+ for (const v of values) {
11160
+ flat.push(v.capabilities);
11161
+ }
11162
+ } else {
11163
+ flat.push(entry);
11164
+ }
11165
+ }
11166
+ } else {
11167
+ for (const v of Object.values(capabilities)) {
11168
+ const inner = v.capabilities;
11169
+ if (inner) {
11170
+ flat.push(inner);
11171
+ }
11172
+ }
11173
+ }
11174
+ return flat.some(hasAppCap);
11175
+ }
10860
11176
  var BrowserStackConfig = class _BrowserStackConfig {
10861
- static getInstance(options, config) {
11177
+ static getInstance(options, config, capabilities, isBrowserStackInfra) {
10862
11178
  if (!this._instance && options && config) {
10863
- this._instance = new _BrowserStackConfig(options, config);
11179
+ this._instance = new _BrowserStackConfig(options, config, capabilities, isBrowserStackInfra);
10864
11180
  }
10865
11181
  return this._instance;
10866
11182
  }
@@ -10881,7 +11197,7 @@ var BrowserStackConfig = class _BrowserStackConfig {
10881
11197
  percyBuildId;
10882
11198
  isPercyAutoEnabled = false;
10883
11199
  sdkRunID;
10884
- constructor(options, config) {
11200
+ constructor(options, config, capabilities, isBrowserStackInfra = true) {
10885
11201
  this.framework = config.framework;
10886
11202
  this.userName = config.user;
10887
11203
  this.accessKey = config.key;
@@ -10889,11 +11205,11 @@ var BrowserStackConfig = class _BrowserStackConfig {
10889
11205
  this.percy = options.percy || false;
10890
11206
  this.accessibility = options.accessibility;
10891
11207
  this.app = options.app;
10892
- this.appAutomate = !isUndefined(options.app);
10893
- this.automate = !this.appAutomate;
11208
+ this.appAutomate = isBrowserStackInfra && (!isUndefined(options.app) || detectAppAutomate(capabilities));
11209
+ this.automate = isBrowserStackInfra && !this.appAutomate;
10894
11210
  this.buildIdentifier = options.buildIdentifier;
10895
11211
  this.sdkRunID = uuidv4();
10896
- BStackLogger2.info(`BrowserStack service started with id: ${this.sdkRunID}`);
11212
+ BStackLogger.info(`BrowserStack service started with id: ${this.sdkRunID}`);
10897
11213
  }
10898
11214
  sentFunnelData() {
10899
11215
  this.funnelDataSent = true;
@@ -10903,32 +11219,32 @@ var config_default = BrowserStackConfig;
10903
11219
 
10904
11220
  // src/exitHandler.ts
10905
11221
  import { spawn as spawn4 } from "node:child_process";
10906
- import path16 from "node:path";
11222
+ import path17 from "node:path";
10907
11223
 
10908
11224
  // src/instrumentation/funnelInstrumentation.ts
10909
11225
  init_usageStats();
10910
11226
  init_bstackLogger();
10911
11227
  init_constants();
10912
- import os4 from "node:os";
11228
+ import os5 from "node:os";
10913
11229
  import util4, { format as format2 } from "node:util";
10914
- import path11 from "node:path";
10915
- import fs12 from "node:fs";
11230
+ import path12 from "node:path";
11231
+ import fs13 from "node:fs";
10916
11232
 
10917
11233
  // src/data-store.ts
10918
11234
  init_bstackLogger();
10919
- import path10 from "node:path";
10920
- import fs11 from "node:fs";
10921
- var workersDataDirPath = path10.join(process.cwd(), "logs", "worker_data");
11235
+ import path11 from "node:path";
11236
+ import fs12 from "node:fs";
11237
+ var workersDataDirPath = path11.join(process.cwd(), "logs", "worker_data");
10922
11238
  function getDataFromWorkers() {
10923
11239
  const workersData = [];
10924
- if (!fs11.existsSync(workersDataDirPath)) {
11240
+ if (!fs12.existsSync(workersDataDirPath)) {
10925
11241
  return workersData;
10926
11242
  }
10927
- const files = fs11.readdirSync(workersDataDirPath);
11243
+ const files = fs12.readdirSync(workersDataDirPath);
10928
11244
  files.forEach((file) => {
10929
- BStackLogger2.debug("Reading worker file " + file);
10930
- const filePath = path10.join(workersDataDirPath, file);
10931
- const fileContent = fs11.readFileSync(filePath, "utf8");
11245
+ BStackLogger.debug("Reading worker file " + file);
11246
+ const filePath = path11.join(workersDataDirPath, file);
11247
+ const fileContent = fs12.readFileSync(filePath, "utf8");
10932
11248
  const workerData = JSON.parse(fileContent);
10933
11249
  workersData.push(workerData);
10934
11250
  });
@@ -10936,21 +11252,21 @@ function getDataFromWorkers() {
10936
11252
  return workersData;
10937
11253
  }
10938
11254
  function saveWorkerData(data) {
10939
- const filePath = path10.join(workersDataDirPath, "worker-data-" + process.pid + ".json");
11255
+ const filePath = path11.join(workersDataDirPath, "worker-data-" + process.pid + ".json");
10940
11256
  try {
10941
11257
  createWorkersDataDir();
10942
- fs11.writeFileSync(filePath, JSON.stringify(data));
11258
+ fs12.writeFileSync(filePath, JSON.stringify(data));
10943
11259
  } catch (e) {
10944
- BStackLogger2.debug("Exception in saving worker data: " + e);
11260
+ BStackLogger.debug("Exception in saving worker data: " + e);
10945
11261
  }
10946
11262
  }
10947
11263
  function removeWorkersDataDir() {
10948
- fs11.rmSync(workersDataDirPath, { recursive: true, force: true });
11264
+ fs12.rmSync(workersDataDirPath, { recursive: true, force: true });
10949
11265
  return true;
10950
11266
  }
10951
11267
  function createWorkersDataDir() {
10952
- if (!fs11.existsSync(workersDataDirPath)) {
10953
- fs11.mkdirSync(workersDataDirPath, { recursive: true });
11268
+ if (!fs12.existsSync(workersDataDirPath)) {
11269
+ fs12.mkdirSync(workersDataDirPath, { recursive: true });
10954
11270
  }
10955
11271
  return true;
10956
11272
  }
@@ -10964,16 +11280,16 @@ init_performance_tester();
10964
11280
  init_constants2();
10965
11281
  async function fireFunnelTestEvent(eventType, config, isCLIEnabled = false) {
10966
11282
  if (!config.userName || !config.accessKey) {
10967
- BStackLogger2.debug("username/accesskey not passed");
11283
+ BStackLogger.debug("username/accesskey not passed");
10968
11284
  return;
10969
11285
  }
10970
11286
  try {
10971
11287
  const data = buildEventData(eventType, config, isCLIEnabled);
10972
11288
  await fireFunnelRequest(data);
10973
- BStackLogger2.debug("Funnel event success");
11289
+ BStackLogger.debug("Funnel event success");
10974
11290
  config.sentFunnelData();
10975
11291
  } catch (error) {
10976
- BStackLogger2.debug(`Exception in sending funnel data: ${format2(error)}`);
11292
+ BStackLogger.debug(`Exception in sending funnel data: ${format2(error)}`);
10977
11293
  }
10978
11294
  }
10979
11295
  async function sendStart(config) {
@@ -10998,9 +11314,9 @@ async function sendFinish(config, isCLIEnabled = false) {
10998
11314
  }
10999
11315
  function saveFunnelData(eventType, config, isCLIEnabled = false) {
11000
11316
  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));
11317
+ BStackLogger.ensureLogsFolder();
11318
+ const filePath = path12.join(BStackLogger.logFolderPath, "funnelData.json");
11319
+ fs13.writeFileSync(filePath, JSON.stringify(data));
11004
11320
  return filePath;
11005
11321
  }
11006
11322
  function redactCredentialsFromFunnelData(data) {
@@ -11017,7 +11333,7 @@ function redactCredentialsFromFunnelData(data) {
11017
11333
  async function fireFunnelRequest(data) {
11018
11334
  const { userName, accessKey } = data;
11019
11335
  redactCredentialsFromFunnelData(data);
11020
- BStackLogger2.debug("Sending SDK event with data " + util4.inspect(data, { depth: 6 }));
11336
+ BStackLogger.debug("Sending SDK event with data " + util4.inspect(data, { depth: 6 }));
11021
11337
  const encodedAuth = Buffer.from(`${userName}:${accessKey}`, "utf8").toString("base64");
11022
11338
  const response = await fetchWrap(APIUtils.FUNNEL_INSTRUMENTATION_URL, {
11023
11339
  method: "POST",
@@ -11027,7 +11343,7 @@ async function fireFunnelRequest(data) {
11027
11343
  },
11028
11344
  body: JSON.stringify(data)
11029
11345
  });
11030
- BStackLogger2.debug("Funnel Event Response: " + JSON.stringify(await response.text()));
11346
+ BStackLogger.debug("Funnel Event Response: " + JSON.stringify(await response.text()));
11031
11347
  }
11032
11348
  function getProductList(config) {
11033
11349
  const products = [];
@@ -11061,8 +11377,8 @@ function buildEventData(eventType, config, isCLIEnabled = false) {
11061
11377
  buildName: config.buildName || "undefined",
11062
11378
  buildIdentifier: String(config.buildIdentifier),
11063
11379
  // Host details
11064
- os: os4.type() || "unknown",
11065
- hostname: os4.hostname() || "unknown",
11380
+ os: os5.type() || "unknown",
11381
+ hostname: os5.hostname() || "unknown",
11066
11382
  // Product Details
11067
11383
  productMap: getProductMap(config),
11068
11384
  product: getProductList(config),
@@ -11112,30 +11428,30 @@ function isProxyError(authResult) {
11112
11428
  function handleProxyError(config, isSelfHealEnabled) {
11113
11429
  sendEvent.tcgProxyFailure(config);
11114
11430
  if (isSelfHealEnabled) {
11115
- BStackLogger2.warn("Proxy Error. Disabling Healing for this session.");
11431
+ BStackLogger.warn("Proxy Error. Disabling Healing for this session.");
11116
11432
  }
11117
11433
  }
11118
11434
  function handleUpgradeRequired(isSelfHealEnabled) {
11119
11435
  if (isSelfHealEnabled) {
11120
- BStackLogger2.warn("Please upgrade Browserstack Service to the latest version to use the self-healing feature.");
11436
+ BStackLogger.warn("Please upgrade Browserstack Service to the latest version to use the self-healing feature.");
11121
11437
  }
11122
11438
  }
11123
11439
  function handleAuthenticationFailure(status, config, isSelfHealEnabled) {
11124
11440
  if (status >= 500) {
11125
11441
  if (isSelfHealEnabled) {
11126
- BStackLogger2.warn("Something went wrong. Disabling healing for this session. Please try again later.");
11442
+ BStackLogger.warn("Something went wrong. Disabling healing for this session. Please try again later.");
11127
11443
  }
11128
11444
  sendEvent.tcgDown(config);
11129
11445
  } else {
11130
11446
  if (isSelfHealEnabled) {
11131
- BStackLogger2.warn("Authentication Failed. Disabling Healing for this session.");
11447
+ BStackLogger.warn("Authentication Failed. Disabling Healing for this session.");
11132
11448
  }
11133
11449
  sendEvent.tcgAuthFailure(config);
11134
11450
  }
11135
11451
  }
11136
11452
  function handleAuthenticationSuccess(isHealingEnabledForUser, userId, config, isSelfHealEnabled) {
11137
11453
  if (!isHealingEnabledForUser && isSelfHealEnabled) {
11138
- BStackLogger2.warn("Healing is not enabled for your group, please contact the admin");
11454
+ BStackLogger.warn("Healing is not enabled for your group, please contact the admin");
11139
11455
  } else if (userId && isHealingEnabledForUser) {
11140
11456
  sendEvent.tcgtInitSuccessful(config);
11141
11457
  }
@@ -11147,7 +11463,7 @@ function handleInitializationFailure(status, config, isSelfHealEnabled) {
11147
11463
  sendEvent.invalidTcgAuth(config);
11148
11464
  }
11149
11465
  if (isSelfHealEnabled) {
11150
- BStackLogger2.warn("Authentication Failed. Healing will be disabled for this session.");
11466
+ BStackLogger.warn("Authentication Failed. Healing will be disabled for this session.");
11151
11467
  }
11152
11468
  }
11153
11469
  function handleHealingInstrumentation(authResult, config, isSelfHealEnabled) {
@@ -11174,7 +11490,7 @@ function handleHealingInstrumentation(authResult, config, isSelfHealEnabled) {
11174
11490
  return;
11175
11491
  }
11176
11492
  } catch (err) {
11177
- BStackLogger2.debug("Error in handling healing instrumentation: " + err);
11493
+ BStackLogger.debug("Error in handling healing instrumentation: " + err);
11178
11494
  }
11179
11495
  }
11180
11496
 
@@ -11186,36 +11502,36 @@ init_bstackLogger();
11186
11502
  init_cli();
11187
11503
  import { fileURLToPath as fileURLToPath2 } from "node:url";
11188
11504
  var __filename = fileURLToPath2(import.meta.url);
11189
- var __dirname = path16.dirname(__filename);
11505
+ var __dirname = path17.dirname(__filename);
11190
11506
  function setupExitHandlers() {
11191
11507
  const handleCLICleanup = () => {
11192
- BStackLogger2.debug("Handling CLI cleanup in exit handler");
11508
+ BStackLogger.debug("Handling CLI cleanup in exit handler");
11193
11509
  try {
11194
11510
  const cliProcess = BrowserstackCLI.getInstance()?.process;
11195
11511
  if (cliProcess && cliProcess.pid && cliProcess.exitCode === null) {
11196
- BStackLogger2.debug(`Found CLI process with PID ${cliProcess.pid}, terminating`);
11512
+ BStackLogger.debug(`Found CLI process with PID ${cliProcess.pid}, terminating`);
11197
11513
  try {
11198
11514
  if (process.platform === "win32") {
11199
11515
  cliProcess.kill("SIGTERM");
11200
- BStackLogger2.debug("CLI process terminated successfully with SIGTERM (Windows)");
11516
+ BStackLogger.debug("CLI process terminated successfully with SIGTERM (Windows)");
11201
11517
  } else {
11202
11518
  cliProcess.kill("SIGINT");
11203
- BStackLogger2.debug("CLI process terminated successfully with SIGINT (Unix)");
11519
+ BStackLogger.debug("CLI process terminated successfully with SIGINT (Unix)");
11204
11520
  }
11205
11521
  } catch (processError2) {
11206
- BStackLogger2.debug(`CLI process termination error: ${processError2}`);
11522
+ BStackLogger.debug(`CLI process termination error: ${processError2}`);
11207
11523
  try {
11208
11524
  cliProcess.kill();
11209
- BStackLogger2.debug("CLI process terminated with default signal (fallback)");
11525
+ BStackLogger.debug("CLI process terminated with default signal (fallback)");
11210
11526
  } catch (fallbackError) {
11211
- BStackLogger2.debug(`CLI process fallback termination error: ${fallbackError}`);
11527
+ BStackLogger.debug(`CLI process fallback termination error: ${fallbackError}`);
11212
11528
  }
11213
11529
  }
11214
11530
  } else {
11215
- BStackLogger2.debug("No CLI process found to terminate");
11531
+ BStackLogger.debug("No CLI process found to terminate");
11216
11532
  }
11217
11533
  } catch (error) {
11218
- BStackLogger2.debug(`Error in CLI cleanup: ${error}`);
11534
+ BStackLogger.debug(`Error in CLI cleanup: ${error}`);
11219
11535
  }
11220
11536
  };
11221
11537
  process.on("exit", () => {
@@ -11223,8 +11539,8 @@ function setupExitHandlers() {
11223
11539
  handleCLICleanup();
11224
11540
  const args = shouldCallCleanup(config_default.getInstance(), isCLIEnabled);
11225
11541
  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 } });
11542
+ BStackLogger.debug(`Spawning cleanup.js with args: ${args.join(", ")}`);
11543
+ const childProcess = spawn4("node", [`${path17.join(__dirname, "cleanup.js")}`, ...args], { detached: true, stdio: "inherit", env: { ...process.env } });
11228
11544
  childProcess.unref();
11229
11545
  }
11230
11546
  });
@@ -11250,8 +11566,8 @@ function shouldCallCleanup(config, isCLIEnabled = false) {
11250
11566
  // src/ai-handler.ts
11251
11567
  init_bstackLogger();
11252
11568
  init_constants();
11253
- import path17 from "node:path";
11254
- import fs13 from "node:fs";
11569
+ import path18 from "node:path";
11570
+ import fs14 from "node:fs";
11255
11571
  import url2 from "node:url";
11256
11572
  import aiSDK from "@browserstack/ai-sdk-node";
11257
11573
  init_util();
@@ -11278,7 +11594,7 @@ var AiHandler = class {
11278
11594
  }
11279
11595
  } else if (options.selfHeal === true) {
11280
11596
  const healingWarnMessage = authResult.message;
11281
- BStackLogger2.warn(`Healing Auth failed. Disabling healing for this session. Reason: ${healingWarnMessage}`);
11597
+ BStackLogger.warn(`Healing Auth failed. Disabling healing for this session. Reason: ${healingWarnMessage}`);
11282
11598
  }
11283
11599
  return caps;
11284
11600
  }
@@ -11287,8 +11603,8 @@ var AiHandler = class {
11287
11603
  }
11288
11604
  async installFirefoxExtension(browser) {
11289
11605
  const __dirname2 = url2.fileURLToPath(new URL(".", import.meta.url));
11290
- const extensionPath = path17.resolve(__dirname2, aiSDK.BrowserstackHealing.getFirefoxAddonPath());
11291
- const extFile = fs13.readFileSync(extensionPath);
11606
+ const extensionPath = path18.resolve(__dirname2, aiSDK.BrowserstackHealing.getFirefoxAddonPath());
11607
+ const extFile = fs14.readFileSync(extensionPath);
11292
11608
  await browser.installAddOn(extFile.toString("base64"), true);
11293
11609
  }
11294
11610
  async handleHealing(orginalFunc, using, value, browser, options) {
@@ -11315,7 +11631,7 @@ var AiHandler = class {
11315
11631
  return result;
11316
11632
  }
11317
11633
  if (options.selfHeal === true && this.authResult.isHealingEnabled) {
11318
- BStackLogger2.info("findElement failed, trying to heal");
11634
+ BStackLogger.info("findElement failed, trying to heal");
11319
11635
  PerformanceTester.start(AI_EVENTS.SELF_HEAL_STEP);
11320
11636
  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
11637
  if (script) {
@@ -11325,7 +11641,7 @@ var AiHandler = class {
11325
11641
  PerformanceTester.end(AI_EVENTS.SELF_HEAL_GET_RESULT);
11326
11642
  if (tcgData && tcgData.selector && tcgData.value) {
11327
11643
  const healedResult = await orginalFunc(tcgData.selector, tcgData.value);
11328
- BStackLogger2.info("Healing worked, element found: " + tcgData.selector + ": " + tcgData.value);
11644
+ BStackLogger.info("Healing worked, element found: " + tcgData.selector + ": " + tcgData.value);
11329
11645
  PerformanceTester.end(AI_EVENTS.SELF_HEAL_STEP);
11330
11646
  return healedResult.error ? result : healedResult;
11331
11647
  }
@@ -11337,9 +11653,9 @@ var AiHandler = class {
11337
11653
  } catch (err) {
11338
11654
  PerformanceTester.end(AI_EVENTS.SELF_HEAL_STEP, false, String(err));
11339
11655
  if (options.selfHeal === true) {
11340
- BStackLogger2.warn("Something went wrong while healing. Disabling healing for this command");
11656
+ BStackLogger.warn("Something went wrong while healing. Disabling healing for this command");
11341
11657
  } else {
11342
- BStackLogger2.warn("Error in findElement: " + err + "using: " + using + "value: " + value);
11658
+ BStackLogger.warn("Error in findElement: " + err + "using: " + using + "value: " + value);
11343
11659
  }
11344
11660
  }
11345
11661
  return await orginalFunc(using, value);
@@ -11375,7 +11691,7 @@ var AiHandler = class {
11375
11691
  }
11376
11692
  } catch (err) {
11377
11693
  if (options.selfHeal === true) {
11378
- BStackLogger2.warn(`Error while initiliazing Browserstack healing Extension ${err}`);
11694
+ BStackLogger.warn(`Error while initiliazing Browserstack healing Extension ${err}`);
11379
11695
  }
11380
11696
  }
11381
11697
  return caps;
@@ -11384,7 +11700,7 @@ var AiHandler = class {
11384
11700
  if (SUPPORTED_BROWSERS_FOR_AI.includes(browser.capabilities?.browserName?.toLowerCase())) {
11385
11701
  const authInfo = this.authResult;
11386
11702
  if (Object.keys(authInfo).length === 0 && options.selfHeal === true) {
11387
- BStackLogger2.debug("TCG Auth result is empty");
11703
+ BStackLogger.debug("TCG Auth result is empty");
11388
11704
  return;
11389
11705
  }
11390
11706
  const { isAuthenticated, sessionToken, defaultLogDataEnabled } = authInfo;
@@ -11412,7 +11728,7 @@ var AiHandler = class {
11412
11728
  }
11413
11729
  } catch (err) {
11414
11730
  if (options.selfHeal === true) {
11415
- BStackLogger2.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
11731
+ BStackLogger.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
11416
11732
  }
11417
11733
  }
11418
11734
  }
@@ -11430,9 +11746,10 @@ var BrowserstackLauncherService = class {
11430
11746
  constructor(_options, capabilities, _config) {
11431
11747
  this._options = _options;
11432
11748
  this._config = _config;
11433
- BStackLogger2.clearLogFile();
11749
+ BStackLogger.clearLogFile();
11434
11750
  PercyLogger.clearLogFile();
11435
11751
  setupExitHandlers();
11752
+ configureCaCertificate(this._options);
11436
11753
  if (!this._config) {
11437
11754
  this._config = _options;
11438
11755
  }
@@ -11454,12 +11771,13 @@ var BrowserstackLauncherService = class {
11454
11771
  if (!isUndefined(process.env.TEST_REPORTING_BUILD_TAG)) {
11455
11772
  process.env.TEST_OBSERVABILITY_BUILD_TAG = process.env.TEST_REPORTING_BUILD_TAG;
11456
11773
  }
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)}`);
11774
+ const isBrowserStackInfra = isBrowserstackInfra(_config, capabilities);
11775
+ this.browserStackConfig = config_default.getInstance(_options, _config, capabilities, isBrowserStackInfra);
11776
+ BStackLogger.debug(`_options data: ${JSON.stringify(_options)}`);
11777
+ BStackLogger.debug(`webdriver capabilities data: ${JSON.stringify(capabilities)}`);
11460
11778
  const configCopy = JSON.parse(JSON.stringify(_config));
11461
11779
  CrashReporter.recursivelyRedactKeysFromObject(configCopy, ["user", "username", "key", "accesskey", "password"]);
11462
- BStackLogger2.debug(`_config data: ${JSON.stringify(configCopy)}`);
11780
+ BStackLogger.debug(`_config data: ${JSON.stringify(configCopy)}`);
11463
11781
  if (Array.isArray(capabilities)) {
11464
11782
  capabilities.flatMap((c) => {
11465
11783
  if ("alwaysMatch" in c) {
@@ -11546,7 +11864,7 @@ var BrowserstackLauncherService = class {
11546
11864
  try {
11547
11865
  CrashReporter.setConfigDetails(this._config, capabilities, this._options);
11548
11866
  } catch (error) {
11549
- BStackLogger2.error(`[Crash_Report_Upload] Config processing failed due to ${error}`);
11867
+ BStackLogger.error(`[Crash_Report_Upload] Config processing failed due to ${error}`);
11550
11868
  }
11551
11869
  }
11552
11870
  browserstackLocal;
@@ -11576,7 +11894,7 @@ var BrowserstackLauncherService = class {
11576
11894
  if (config.specs && Array.isArray(config.specs) && isValidEnabledValue(this._options.testOrchestrationOptions?.runSmartSelection?.enabled)) {
11577
11895
  try {
11578
11896
  const glob = (await import("glob")).sync;
11579
- const path21 = await import("node:path");
11897
+ const path22 = await import("node:path");
11580
11898
  const expandedSpecs = [];
11581
11899
  for (const specPattern of config.specs) {
11582
11900
  if (typeof specPattern === "string") {
@@ -11593,21 +11911,21 @@ var BrowserstackLauncherService = class {
11593
11911
  }) || [];
11594
11912
  filenames.forEach((filename) => {
11595
11913
  let absolutePath = filename;
11596
- if (!path21.isAbsolute(filename)) {
11597
- absolutePath = path21.resolve(rootDir, filename);
11914
+ if (!path22.isAbsolute(filename)) {
11915
+ absolutePath = path22.resolve(rootDir, filename);
11598
11916
  }
11599
- let relativePath = path21.relative(cwd, absolutePath);
11917
+ let relativePath = path22.relative(cwd, absolutePath);
11600
11918
  relativePath = relativePath.replace(/\\/g, "/");
11601
11919
  expandedSpecs.push(relativePath);
11602
11920
  });
11603
11921
  }
11604
11922
  }
11605
11923
  if (expandedSpecs.length > 0) {
11606
- BStackLogger2.info(`Expanded specs from glob patterns to ${expandedSpecs.length} files`);
11924
+ BStackLogger.info(`Expanded specs from glob patterns to ${expandedSpecs.length} files`);
11607
11925
  config.specs = expandedSpecs;
11608
11926
  }
11609
11927
  } catch (error) {
11610
- BStackLogger2.error(`Failed to expand spec patterns: ${error}`);
11928
+ BStackLogger.error(`Failed to expand spec patterns: ${error}`);
11611
11929
  }
11612
11930
  }
11613
11931
  try {
@@ -11618,11 +11936,11 @@ var BrowserstackLauncherService = class {
11618
11936
  CLIUtils.setFrameworkDetail(WDIO_NAMING_PREFIX + config.framework, "WebdriverIO");
11619
11937
  const binconfig = CLIUtils.getBinConfig(config, capabilities, this._options, this._buildTag);
11620
11938
  await BrowserstackCLI.getInstance().bootstrap(this._options, config, binconfig);
11621
- BStackLogger2.debug(`Is CLI running ${BrowserstackCLI.getInstance().isRunning()}`);
11939
+ BStackLogger.debug(`Is CLI running ${BrowserstackCLI.getInstance().isRunning()}`);
11622
11940
  PerformanceTester.end(FRAMEWORK_EVENTS.START);
11623
11941
  }
11624
11942
  } catch (err) {
11625
- BStackLogger2.error(`Error while starting CLI ${err}`);
11943
+ BStackLogger.error(`Error while starting CLI ${err}`);
11626
11944
  PerformanceTester.end(FRAMEWORK_EVENTS.START, false, format4(err));
11627
11945
  }
11628
11946
  PerformanceTester.end(FRAMEWORK_EVENTS.INIT);
@@ -11641,13 +11959,13 @@ var BrowserstackLauncherService = class {
11641
11959
  }
11642
11960
  } catch (err) {
11643
11961
  if (this._options.selfHeal === true) {
11644
- BStackLogger2.warn(`Error while setting up Browserstack healing Extension ${err}. Disabling healing for this session.`);
11962
+ BStackLogger.warn(`Error while setting up Browserstack healing Extension ${err}. Disabling healing for this session.`);
11645
11963
  }
11646
11964
  }
11647
11965
  }
11648
11966
  if (!BrowserstackCLI.getInstance().isRunning()) {
11649
11967
  if (!this._options.app) {
11650
- BStackLogger2.debug("app is not defined in browserstack-service config, skipping ...");
11968
+ BStackLogger.debug("app is not defined in browserstack-service config, skipping ...");
11651
11969
  } else {
11652
11970
  let app = {};
11653
11971
  const appConfig = this._options.app;
@@ -11656,10 +11974,10 @@ var BrowserstackLauncherService = class {
11656
11974
  } catch (error) {
11657
11975
  throw new SevereServiceError(error.message);
11658
11976
  }
11659
- if (VALID_APP_EXTENSION.includes(path20.extname(app.app))) {
11660
- if (fs14.existsSync(app.app)) {
11977
+ if (VALID_APP_EXTENSION.includes(path21.extname(app.app))) {
11978
+ if (fs15.existsSync(app.app)) {
11661
11979
  const data = await this._uploadApp(app);
11662
- BStackLogger2.info(`app upload completed: ${JSON.stringify(data)}`);
11980
+ BStackLogger.info(`app upload completed: ${JSON.stringify(data)}`);
11663
11981
  app.app = data.app_url;
11664
11982
  } else if (app.customId) {
11665
11983
  app.app = app.customId;
@@ -11667,7 +11985,7 @@ var BrowserstackLauncherService = class {
11667
11985
  throw new SevereServiceError(`[Invalid app path] app path ${app.app} is not correct, Provide correct path to app under test`);
11668
11986
  }
11669
11987
  }
11670
- BStackLogger2.info(`Using app: ${app.app}`);
11988
+ BStackLogger.info(`Using app: ${app.app}`);
11671
11989
  this._updateCaps(capabilities, "app", app.app);
11672
11990
  }
11673
11991
  }
@@ -11680,7 +11998,7 @@ var BrowserstackLauncherService = class {
11680
11998
  const shouldSetupPercy = this._options.percy || isUndefined(this._options.percy) && this._options.app;
11681
11999
  let buildStartResponse = null;
11682
12000
  if (!BrowserstackCLI.getInstance().isRunning() && (this._options.testObservability || this._accessibilityAutomation || shouldSetupPercy)) {
11683
- BStackLogger2.debug("Sending launch start event");
12001
+ BStackLogger.debug("Sending launch start event");
11684
12002
  buildStartResponse = await launchTestSession(this._options, this._config, {
11685
12003
  projectName: this._projectName,
11686
12004
  buildName: this._buildName,
@@ -11739,15 +12057,15 @@ var BrowserstackLauncherService = class {
11739
12057
  if (typeof spec !== "string") {
11740
12058
  return spec;
11741
12059
  }
11742
- const absolutePath = path20.isAbsolute(spec) ? spec : path20.resolve(cwd, spec);
11743
- const relativePath = path20.relative(rootDir, absolutePath);
12060
+ const absolutePath = path21.isAbsolute(spec) ? spec : path21.resolve(cwd, spec);
12061
+ const relativePath = path21.relative(rootDir, absolutePath);
11744
12062
  return relativePath.replace(/\\/g, "/");
11745
12063
  });
11746
12064
  };
11747
12065
  try {
11748
12066
  const { applyOrchestrationIfEnabled: applyOrchestrationIfEnabled2 } = await Promise.resolve().then(() => (init_apply_orchestration(), apply_orchestration_exports));
11749
12067
  if (config.specs && config.specs.length > 0 && this._options.testObservability && isValidEnabledValue(this._options.testOrchestrationOptions?.runSmartSelection?.enabled)) {
11750
- BStackLogger2.info("Applying test orchestration");
12068
+ BStackLogger.info("Applying test orchestration");
11751
12069
  const specs = config.specs.filter((spec) => typeof spec === "string");
11752
12070
  console.log(`Specs before orchestration: ${specs}`);
11753
12071
  const orderedSpecs = await applyOrchestrationIfEnabled2(specs, this._options);
@@ -11755,14 +12073,14 @@ var BrowserstackLauncherService = class {
11755
12073
  const specsToConvert = orderedSpecs && orderedSpecs.length > 0 ? orderedSpecs : specs;
11756
12074
  config.specs = convertToRootDirRelative(specsToConvert);
11757
12075
  console.log(`Specs after orchestration: ${config.specs}`);
11758
- BStackLogger2.info("Test specs updated with orchestrated order");
12076
+ BStackLogger.info("Test specs updated with orchestrated order");
11759
12077
  }
11760
12078
  } catch (error) {
11761
- BStackLogger2.error(`Error applying test orchestration: ${error}`);
12079
+ BStackLogger.error(`Error applying test orchestration: ${error}`);
11762
12080
  if (config.specs && config.specs.length > 0) {
11763
12081
  const specs = config.specs.filter((spec) => typeof spec === "string");
11764
12082
  config.specs = convertToRootDirRelative(specs);
11765
- BStackLogger2.debug(`Specs converted back to rootDir-relative after error: ${config.specs}`);
12083
+ BStackLogger.debug(`Specs converted back to rootDir-relative after error: ${config.specs}`);
11766
12084
  }
11767
12085
  }
11768
12086
  }
@@ -11770,7 +12088,7 @@ var BrowserstackLauncherService = class {
11770
12088
  return;
11771
12089
  }
11772
12090
  if (!this._options.browserstackLocal) {
11773
- return BStackLogger2.info("browserstackLocal is not enabled - skipping...");
12091
+ return BStackLogger.info("browserstackLocal is not enabled - skipping...");
11774
12092
  }
11775
12093
  const opts = {
11776
12094
  key: this._config.key,
@@ -11783,7 +12101,7 @@ var BrowserstackLauncherService = class {
11783
12101
  }
11784
12102
  const obs = new PerformanceObserver2((list) => {
11785
12103
  const entry = list.getEntries()[0];
11786
- BStackLogger2.info(`Browserstack Local successfully started after ${entry.duration}ms`);
12104
+ BStackLogger.info(`Browserstack Local successfully started after ${entry.duration}ms`);
11787
12105
  });
11788
12106
  obs.observe({ entryTypes: ["measure"] });
11789
12107
  let timer;
@@ -11816,13 +12134,13 @@ var BrowserstackLauncherService = class {
11816
12134
  PerformanceTester.start(FRAMEWORK_EVENTS.STOP);
11817
12135
  try {
11818
12136
  const isCLIEnabled = BrowserstackCLI.getInstance().isRunning();
11819
- BStackLogger2.debug("Inside OnComplete hook..");
11820
- BStackLogger2.debug("Sending stop launch event");
12137
+ BStackLogger.debug("Inside OnComplete hook..");
12138
+ BStackLogger.debug("Sending stop launch event");
11821
12139
  try {
11822
12140
  await (isCLIEnabled ? BrowserstackCLI.getInstance().stop() : stopBuildUpstream());
11823
12141
  PerformanceTester.end(FRAMEWORK_EVENTS.STOP);
11824
12142
  } catch (err) {
11825
- BStackLogger2.error(`Error while stopping CLI ${err}`);
12143
+ BStackLogger.error(`Error while stopping CLI ${err}`);
11826
12144
  PerformanceTester.end(FRAMEWORK_EVENTS.STOP, false, format4(err));
11827
12145
  }
11828
12146
  if (process.env[BROWSERSTACK_OBSERVABILITY] && process.env[BROWSERSTACK_TESTHUB_UUID]) {
@@ -11838,16 +12156,16 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11838
12156
  return;
11839
12157
  }
11840
12158
  const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(process.env.START_TIME).getTime();
11841
- BStackLogger2.info(`Total duration is ${duration / 1e3} s`);
12159
+ BStackLogger.info(`Total duration is ${duration / 1e3} s`);
11842
12160
  }
11843
- BStackLogger2.info(`BrowserStack service run ended for id: ${this.browserStackConfig?.sdkRunID} testhub id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
12161
+ BStackLogger.info(`BrowserStack service run ended for id: ${this.browserStackConfig?.sdkRunID} testhub id: ${testOpsConfig_default.getInstance()?.buildHashedId}`);
11844
12162
  await sendFinish(this.browserStackConfig, isCLIEnabled);
11845
12163
  try {
11846
12164
  PerformanceTester.start(EVENTS.SDK_SEND_LOGS);
11847
12165
  await this._uploadServiceLogs();
11848
12166
  PerformanceTester.end(EVENTS.SDK_SEND_LOGS);
11849
12167
  } catch (error) {
11850
- BStackLogger2.debug(`Failed to upload BrowserStack WDIO Service logs ${error}`);
12168
+ BStackLogger.debug(`Failed to upload BrowserStack WDIO Service logs ${error}`);
11851
12169
  PerformanceTester.end(EVENTS.SDK_SEND_LOGS, false, format4(error));
11852
12170
  }
11853
12171
  PerformanceTester.end(EVENTS.SDK_ON_STOP);
@@ -11857,9 +12175,9 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11857
12175
  PerformanceTester.end(EVENTS.SDK_ON_STOP, false, format4(error));
11858
12176
  PerformanceTester.end(EVENTS.SDK_CLEANUP, false, format4(error));
11859
12177
  await PerformanceTester.stopAndGenerate("performance-launcher.html");
11860
- BStackLogger2.error(`Error in onComplete hook: ${error}`);
12178
+ BStackLogger.error(`Error in onComplete hook: ${error}`);
11861
12179
  }
11862
- BStackLogger2.clearLogger();
12180
+ BStackLogger.clearLogger();
11863
12181
  if (this._options.percy) {
11864
12182
  await this.stopPercy();
11865
12183
  PercyLogger.clearLogger();
@@ -11943,10 +12261,10 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11943
12261
  }
11944
12262
  }
11945
12263
  async _uploadApp(app) {
11946
- BStackLogger2.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ""} to browserstack`);
12264
+ BStackLogger.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ""} to browserstack`);
11947
12265
  const form = new FormData();
11948
12266
  if (app.app) {
11949
- const fileName = path20.basename(app.app);
12267
+ const fileName = path21.basename(app.app);
11950
12268
  const fileBuffer = await readFile(app.app);
11951
12269
  const fileBlob = new Blob([new Uint8Array(fileBuffer)]);
11952
12270
  form.append("file", fileBlob, fileName);
@@ -11995,8 +12313,8 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
11995
12313
  const clientBuildUuid = this._getClientBuildUuid();
11996
12314
  const response = await uploadLogs(getBrowserStackUser(this._config), getBrowserStackKey(this._config), clientBuildUuid);
11997
12315
  if (response) {
11998
- BStackLogger2.info(`Upload response: ${JSON.stringify(response, null, 2)}`);
11999
- BStackLogger2.logToFile(`Response - ${format4(response)}`, "debug");
12316
+ BStackLogger.info(`Upload response: ${JSON.stringify(response, null, 2)}`);
12317
+ BStackLogger.logToFile(`Response - ${format4(response)}`, "debug");
12000
12318
  }
12001
12319
  }
12002
12320
  _removeCliOnlyCapabilityOptions(capabilities) {
@@ -12129,7 +12447,7 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12129
12447
  });
12130
12448
  }
12131
12449
  } catch (error) {
12132
- BStackLogger2.debug(`Exception while retrieving capability value. Error - ${error}`);
12450
+ BStackLogger.debug(`Exception while retrieving capability value. Error - ${error}`);
12133
12451
  }
12134
12452
  }
12135
12453
  _updateCaps(capabilities, capType, value) {
@@ -12265,7 +12583,7 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12265
12583
  }
12266
12584
  if ((!this._buildName || process.env.BROWSERSTACK_BUILD_NAME) && this._buildIdentifier) {
12267
12585
  this._updateCaps(capabilities, "buildIdentifier");
12268
- BStackLogger2.warn("Skipping buildIdentifier as buildName is not passed.");
12586
+ BStackLogger.warn("Skipping buildIdentifier as buildName is not passed.");
12269
12587
  return;
12270
12588
  }
12271
12589
  if (this._buildIdentifier && this._buildIdentifier.includes("${DATE_TIME}")) {
@@ -12308,16 +12626,16 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12308
12626
  * else returns corresponding value in json file (e.g. { "wdio-build": { "identifier" : 2 } } => 2 in this case)
12309
12627
  */
12310
12628
  _getLocalBuildNumber() {
12311
- const browserstackFolderPath = path20.join(os6.homedir(), ".browserstack");
12629
+ const browserstackFolderPath = path21.join(os7.homedir(), ".browserstack");
12312
12630
  try {
12313
- if (!fs14.existsSync(browserstackFolderPath)) {
12314
- fs14.mkdirSync(browserstackFolderPath);
12631
+ if (!fs15.existsSync(browserstackFolderPath)) {
12632
+ fs15.mkdirSync(browserstackFolderPath);
12315
12633
  }
12316
- const filePath = path20.join(browserstackFolderPath, ".build-name-cache.json");
12317
- if (!fs14.existsSync(filePath)) {
12318
- fs14.appendFileSync(filePath, JSON.stringify({}));
12634
+ const filePath = path21.join(browserstackFolderPath, ".build-name-cache.json");
12635
+ if (!fs15.existsSync(filePath)) {
12636
+ fs15.appendFileSync(filePath, JSON.stringify({}));
12319
12637
  }
12320
- const buildCacheFileData = fs14.readFileSync(filePath);
12638
+ const buildCacheFileData = fs15.readFileSync(filePath);
12321
12639
  const parsedBuildCacheFileData = JSON.parse(buildCacheFileData.toString());
12322
12640
  if (this._buildName && this._buildName in parsedBuildCacheFileData) {
12323
12641
  const prevIdentifier = parseInt(parsedBuildCacheFileData[this._buildName].identifier);
@@ -12336,16 +12654,16 @@ Visit https://automation.browserstack.com/builds/${process.env[BROWSERSTACK_TEST
12336
12654
  if (!buildName || !filePath) {
12337
12655
  return;
12338
12656
  }
12339
- const jsonContent = JSON.parse(fs14.readFileSync(filePath).toString());
12657
+ const jsonContent = JSON.parse(fs15.readFileSync(filePath).toString());
12340
12658
  jsonContent[buildName] = { "identifier": buildIdentifier };
12341
- fs14.writeFileSync(filePath, JSON.stringify(jsonContent));
12659
+ fs15.writeFileSync(filePath, JSON.stringify(jsonContent));
12342
12660
  }
12343
12661
  _getClientBuildUuid() {
12344
12662
  if (process.env[BROWSERSTACK_TESTHUB_UUID]) {
12345
12663
  return process.env[BROWSERSTACK_TESTHUB_UUID];
12346
12664
  }
12347
12665
  const uuid = this.browserStackConfig?.sdkRunID;
12348
- BStackLogger2.logToFile(`If facing any issues, please contact BrowserStack support with the Build Run Id - ${uuid}`, "info");
12666
+ BStackLogger.logToFile(`If facing any issues, please contact BrowserStack support with the Build Run Id - ${uuid}`, "info");
12349
12667
  return uuid;
12350
12668
  }
12351
12669
  };
@@ -12367,6 +12685,7 @@ init_util();
12367
12685
  init_insights_handler();
12368
12686
  init_reporter();
12369
12687
  init_constants();
12688
+ init_caCert();
12370
12689
  init_crash_reporter();
12371
12690
 
12372
12691
  // src/accessibility-handler.ts
@@ -12490,7 +12809,7 @@ var _AccessibilityHandler = class {
12490
12809
  };
12491
12810
  browserWithA11y.startA11yScanning = async () => {
12492
12811
  if (this._testIdentifier === null) {
12493
- BStackLogger2.warn("Accessibility scanning cannot be started from outside the test");
12812
+ BStackLogger.warn("Accessibility scanning cannot be started from outside the test");
12494
12813
  return;
12495
12814
  }
12496
12815
  AccessibilityHandler._a11yScanSessionMap[sessionId] = true;
@@ -12502,7 +12821,7 @@ var _AccessibilityHandler = class {
12502
12821
  };
12503
12822
  browserWithA11y.stopA11yScanning = async () => {
12504
12823
  if (this._testIdentifier === null) {
12505
- BStackLogger2.warn("Accessibility scanning cannot be stopped from outside the test");
12824
+ BStackLogger.warn("Accessibility scanning cannot be stopped from outside the test");
12506
12825
  return;
12507
12826
  }
12508
12827
  AccessibilityHandler._a11yScanSessionMap[sessionId] = false;
@@ -12521,7 +12840,7 @@ var _AccessibilityHandler = class {
12521
12840
  const prevImpl = orig ? orig.bind(browser) : void 0;
12522
12841
  browser.overwriteCommand(command.name, this.commandWrapper.bind(this, command, prevImpl), command.class === "Element");
12523
12842
  } catch (error) {
12524
- BStackLogger2.debug(`Exception in overwrite command ${command.name} - ${error}`);
12843
+ BStackLogger.debug(`Exception in overwrite command ${command.name} - ${error}`);
12525
12844
  }
12526
12845
  });
12527
12846
  PerformanceTester.end(CONFIG_EVENTS.ACCESSIBILITY);
@@ -12545,14 +12864,14 @@ var _AccessibilityHandler = class {
12545
12864
  };
12546
12865
  this._testMetadata[testIdentifier].accessibilityScanStarted = shouldScanTest;
12547
12866
  if (shouldScanTest) {
12548
- BStackLogger2.info("Automate test case execution has started.");
12867
+ BStackLogger.info("Automate test case execution has started.");
12549
12868
  }
12550
12869
  } catch (error) {
12551
- BStackLogger2.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12870
+ BStackLogger.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12552
12871
  }
12553
12872
  }
12554
12873
  async afterTest(suiteTitle, test) {
12555
- BStackLogger2.debug("Accessibility after test hook. Before sending test stop event");
12874
+ BStackLogger.debug("Accessibility after test hook. Before sending test stop event");
12556
12875
  if (this._framework !== "mocha" || !this.shouldRunTestHooks(this._browser, this._accessibility)) {
12557
12876
  return;
12558
12877
  }
@@ -12564,17 +12883,17 @@ var _AccessibilityHandler = class {
12564
12883
  return;
12565
12884
  }
12566
12885
  if (shouldScanTestForAccessibility2) {
12567
- BStackLogger2.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12886
+ BStackLogger.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12568
12887
  const dataForExtension = {
12569
12888
  "thTestRunUuid": process.env.TEST_ANALYTICS_ID,
12570
12889
  "thBuildUuid": process.env.BROWSERSTACK_TESTHUB_UUID,
12571
12890
  "thJwtToken": process.env.BROWSERSTACK_TESTHUB_JWT
12572
12891
  };
12573
12892
  await this.sendTestStopEvent(this._browser, dataForExtension);
12574
- BStackLogger2.info("Accessibility testing for this test case has ended.");
12893
+ BStackLogger.info("Accessibility testing for this test case has ended.");
12575
12894
  }
12576
12895
  } catch (error) {
12577
- BStackLogger2.error(`Accessibility results could not be processed for the test case ${test.title}. Error : ${error}`);
12896
+ BStackLogger.error(`Accessibility results could not be processed for the test case ${test.title}. Error : ${error}`);
12578
12897
  }
12579
12898
  }
12580
12899
  /**
@@ -12602,14 +12921,14 @@ var _AccessibilityHandler = class {
12602
12921
  }
12603
12922
  listener_default.setTestRunAccessibilityVar(this._accessibility && shouldScanScenario);
12604
12923
  if (shouldScanScenario) {
12605
- BStackLogger2.info("Automate test case execution has started.");
12924
+ BStackLogger.info("Automate test case execution has started.");
12606
12925
  }
12607
12926
  } catch (error) {
12608
- BStackLogger2.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12927
+ BStackLogger.error(`Exception in starting accessibility automation scan for this test case ${error}`);
12609
12928
  }
12610
12929
  }
12611
12930
  async afterScenario(world) {
12612
- BStackLogger2.debug("Accessibility after scenario hook. Before sending test stop event");
12931
+ BStackLogger.debug("Accessibility after scenario hook. Before sending test stop event");
12613
12932
  if (!this.shouldRunTestHooks(this._browser, this._accessibility)) {
12614
12933
  return;
12615
12934
  }
@@ -12622,17 +12941,17 @@ var _AccessibilityHandler = class {
12622
12941
  return;
12623
12942
  }
12624
12943
  if (shouldScanTestForAccessibility2) {
12625
- BStackLogger2.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12944
+ BStackLogger.info("Automate test case execution has ended. Processing for accessibility testing is underway. ");
12626
12945
  const dataForExtension = {
12627
12946
  "thTestRunUuid": process.env.TEST_ANALYTICS_ID,
12628
12947
  "thBuildUuid": process.env.BROWSERSTACK_TESTHUB_UUID,
12629
12948
  "thJwtToken": process.env.BROWSERSTACK_TESTHUB_JWT
12630
12949
  };
12631
12950
  await this.sendTestStopEvent(this._browser, dataForExtension);
12632
- BStackLogger2.info("Accessibility testing for this test case has ended.");
12951
+ BStackLogger.info("Accessibility testing for this test case has ended.");
12633
12952
  }
12634
12953
  } catch (error) {
12635
- BStackLogger2.error(`Accessibility results could not be processed for the test case ${pickleData.name}. Error : ${error}`);
12954
+ BStackLogger.error(`Accessibility results could not be processed for the test case ${pickleData.name}. Error : ${error}`);
12636
12955
  }
12637
12956
  }
12638
12957
  /*
@@ -12640,14 +12959,14 @@ var _AccessibilityHandler = class {
12640
12959
  */
12641
12960
  async commandWrapper(command, prevImpl, origFunction, ...args) {
12642
12961
  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}`);
12962
+ BStackLogger.debug(`Performing scan for ${command.class} ${command.name}`);
12644
12963
  await performA11yScan(this.isAppAutomate, this._browser, true, true, command.name);
12645
12964
  }
12646
12965
  const impl = prevImpl || origFunction;
12647
12966
  return impl(...args);
12648
12967
  }
12649
12968
  async sendTestStopEvent(browser, dataForExtension) {
12650
- BStackLogger2.debug("Performing scan before saving results");
12969
+ BStackLogger.debug("Performing scan before saving results");
12651
12970
  if (AccessibilityHandler._a11yScanSessionMap[this._sessionId]) {
12652
12971
  await PerformanceTester.measureWrapper(A11Y_EVENTS.PERFORM_SCAN, async () => {
12653
12972
  await performA11yScan(this.isAppAutomate, browser, true, true);
@@ -12659,9 +12978,9 @@ var _AccessibilityHandler = class {
12659
12978
  await PerformanceTester.measureWrapper(A11Y_EVENTS.SAVE_RESULTS, async () => {
12660
12979
  if (accessibility_scripts_default.saveTestResults) {
12661
12980
  const results = await executeAccessibilityScript(browser, accessibility_scripts_default.saveTestResults, dataForExtension);
12662
- BStackLogger2.debug(util11.format(results));
12981
+ BStackLogger.debug(util11.format(results));
12663
12982
  } else {
12664
- BStackLogger2.error("saveTestResults script is null or undefined");
12983
+ BStackLogger.error("saveTestResults script is null or undefined");
12665
12984
  }
12666
12985
  })();
12667
12986
  }
@@ -12738,6 +13057,7 @@ var BrowserstackService = class {
12738
13057
  this._caps = _caps;
12739
13058
  this._config = _config;
12740
13059
  this._options = { ...DEFAULT_OPTIONS, ...options };
13060
+ configureCaCertificate(this._options);
12741
13061
  if (!this._config) {
12742
13062
  this._config = this._options;
12743
13063
  }
@@ -12830,20 +13150,20 @@ var BrowserstackService = class {
12830
13150
  NOT_ALLOWED_KEYS_IN_CAPS.forEach((key) => delete capabilities[`browserstack.${key}`]);
12831
13151
  }
12832
13152
  } catch (err) {
12833
- BStackLogger2.error(`Error while tracking automation framework event: ${err}`);
13153
+ BStackLogger.error(`Error while tracking automation framework event: ${err}`);
12834
13154
  }
12835
13155
  } catch (err) {
12836
- BStackLogger2.error(`Error while connecting to Browserstack CLI: ${err}`);
13156
+ BStackLogger.error(`Error while connecting to Browserstack CLI: ${err}`);
12837
13157
  PerformanceTester.end(DRIVER_EVENT.INIT, false, util12.format(err));
12838
13158
  throw err;
12839
13159
  }
12840
13160
  PerformanceTester.end(DRIVER_EVENT.INIT);
12841
13161
  PerformanceTester.start(EVENTS.SDK_DEVICE_ALLOCATION);
12842
- BStackLogger2.debug("Device allocation tracking started - waiting for WebDriverIO to create remote session");
13162
+ BStackLogger.debug("Device allocation tracking started - waiting for WebDriverIO to create remote session");
12843
13163
  }
12844
13164
  async before(caps, specs, browser) {
12845
13165
  PerformanceTester.end(EVENTS.SDK_DEVICE_ALLOCATION, true, "Device allocated and session created");
12846
- BStackLogger2.debug("Device allocation tracking ended - remote session created successfully");
13166
+ BStackLogger.debug("Device allocation tracking ended - remote session created successfully");
12847
13167
  PerformanceTester.start(DRIVER_EVENT.PRE_INITIALIZE);
12848
13168
  this._browser = browser ? browser : globalThis.browser;
12849
13169
  PerformanceTester.browser = this._browser;
@@ -12852,7 +13172,7 @@ var BrowserstackService = class {
12852
13172
  await ai_handler_default.selfHeal(this._options, caps, this._browser);
12853
13173
  } catch (err) {
12854
13174
  if (this._options.selfHeal === true) {
12855
- BStackLogger2.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
13175
+ BStackLogger.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
12856
13176
  }
12857
13177
  }
12858
13178
  }
@@ -12882,13 +13202,13 @@ var BrowserstackService = class {
12882
13202
  this._options.accessibilityOptions
12883
13203
  );
12884
13204
  if (isBrowserstackSession(this._browser) && BrowserstackCLI.getInstance().isRunning()) {
12885
- BStackLogger2.info(`CLI is running, tracking accessibility event for before: ${sessionId}`);
13205
+ BStackLogger.info(`CLI is running, tracking accessibility event for before: ${sessionId}`);
12886
13206
  } else {
12887
13207
  await this._accessibilityHandler.before(sessionId);
12888
13208
  }
12889
13209
  listener_default.setAccessibilityOptions(this._options.accessibilityOptions);
12890
13210
  } catch (err) {
12891
- BStackLogger2.error(`[Accessibility Test Run] Error in service class before function: ${err}`);
13211
+ BStackLogger.error(`[Accessibility Test Run] Error in service class before function: ${err}`);
12892
13212
  }
12893
13213
  if (shouldProcessEventForTesthub("")) {
12894
13214
  patchConsoleLogs();
@@ -12899,7 +13219,7 @@ var BrowserstackService = class {
12899
13219
  this._options
12900
13220
  );
12901
13221
  if (BrowserstackCLI.getInstance().isRunning()) {
12902
- BStackLogger2.info(`CLI is running, tracking insights event for before: ${sessionId}`);
13222
+ BStackLogger.info(`CLI is running, tracking insights event for before: ${sessionId}`);
12903
13223
  await BrowserstackCLI.getInstance().getAutomationFramework().trackEvent(AutomationFrameworkState.CREATE, HookState.POST, { browser: this._browser, hubUrl: this._config.hostname });
12904
13224
  this._insightsHandler.setGitConfigPath();
12905
13225
  PerformanceTester.end(DRIVER_EVENT.PRE_INITIALIZE);
@@ -12934,7 +13254,7 @@ var BrowserstackService = class {
12934
13254
  });
12935
13255
  }
12936
13256
  } catch (err) {
12937
- BStackLogger2.error(`Error in service class before function: ${err}`);
13257
+ BStackLogger.error(`Error in service class before function: ${err}`);
12938
13258
  if (shouldProcessEventForTesthub("")) {
12939
13259
  CrashReporter.uploadCrashReport(`Error in service class before function: ${err}`, err ? err.stack : "unknown error");
12940
13260
  }
@@ -13118,7 +13438,7 @@ var BrowserstackService = class {
13118
13438
  return;
13119
13439
  }
13120
13440
  } catch (error) {
13121
- BStackLogger2.error(`Error in after hook: ${error}`);
13441
+ BStackLogger.error(`Error in after hook: ${error}`);
13122
13442
  PerformanceTester.end(DRIVER_EVENT.QUIT, false, util12.format(error));
13123
13443
  PerformanceTester.end(HOOK_EVENTS.AFTER, false, util12.format(error));
13124
13444
  await PerformanceTester.stopAndGenerate("performance-service.html");
@@ -13189,14 +13509,14 @@ var BrowserstackService = class {
13189
13509
  failureReason = hasReasons ? this._failReasons.join("\n") : void 0;
13190
13510
  }
13191
13511
  if (!this._browser.isMultiremote) {
13192
- BStackLogger2.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${sessionStatus}`);
13512
+ BStackLogger.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${sessionStatus}`);
13193
13513
  } else {
13194
13514
  const browserName = this._browser.instances.filter(
13195
13515
  (browserName2) => this._browser && this._browser.getInstance(browserName2).sessionId === newSessionId
13196
13516
  )[0];
13197
- BStackLogger2.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${sessionStatus}`);
13517
+ BStackLogger.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${sessionStatus}`);
13198
13518
  }
13199
- BStackLogger2.warn(`Session Reloaded: Old Session Id: ${oldSessionId}, New Session Id: ${newSessionId}`);
13519
+ BStackLogger.warn(`Session Reloaded: Old Session Id: ${oldSessionId}, New Session Id: ${newSessionId}`);
13200
13520
  await this._insightsHandler?.sendCBTInfo();
13201
13521
  if (setSessionStatus) {
13202
13522
  await this._update(oldSessionId, {
@@ -13222,7 +13542,7 @@ var BrowserstackService = class {
13222
13542
  }
13223
13543
  _updateJob(requestBody) {
13224
13544
  return this._multiRemoteAction((sessionId, browserName) => {
13225
- BStackLogger2.info(
13545
+ BStackLogger.info(
13226
13546
  browserName ? `Update multiremote job for browser "${browserName}" and sessionId ${sessionId}` : `Update job with sessionId ${sessionId}`
13227
13547
  );
13228
13548
  return this._update(sessionId, requestBody);
@@ -13248,7 +13568,7 @@ var BrowserstackService = class {
13248
13568
  return Promise.resolve();
13249
13569
  }
13250
13570
  const sessionUrl = `${this._sessionBaseUrl}/${sessionId}.json`;
13251
- BStackLogger2.debug(`Updating Browserstack session at ${sessionUrl} with request body: `, requestBody);
13571
+ BStackLogger.debug(`Updating Browserstack session at ${sessionUrl} with request body: `, requestBody);
13252
13572
  const encodedAuth = Buffer.from(`${this._config.user}:${this._config.key}`, "utf8").toString("base64");
13253
13573
  const headers = {
13254
13574
  "Content-Type": "application/json; charset=utf-8",
@@ -13273,7 +13593,7 @@ var BrowserstackService = class {
13273
13593
  }
13274
13594
  await this._multiRemoteAction(async (sessionId, browserName) => {
13275
13595
  const sessionUrl = `${this._sessionBaseUrl}/${sessionId}.json`;
13276
- BStackLogger2.debug(`Requesting Browserstack session URL at ${sessionUrl}`);
13596
+ BStackLogger.debug(`Requesting Browserstack session URL at ${sessionUrl}`);
13277
13597
  let browserUrl;
13278
13598
  const encodedAuth = Buffer.from(`${this._config.user}:${this._config.key}`, "utf8").toString("base64");
13279
13599
  const headers = {
@@ -13300,7 +13620,7 @@ var BrowserstackService = class {
13300
13620
  }
13301
13621
  const capabilities = getBrowserCapabilities(this._browser, this._caps, browserName);
13302
13622
  const browserString = getBrowserDescription(capabilities);
13303
- BStackLogger2.info(`${browserString} session: ${browserUrl}`);
13623
+ BStackLogger.info(`${browserString} session: ${browserUrl}`);
13304
13624
  });
13305
13625
  }
13306
13626
  async _setSessionName(suiteTitle, test) {