@wdio/browserstack-service 8.48.0 → 8.48.3

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.
Files changed (68) hide show
  1. package/build/accessibility-handler.d.ts.map +1 -1
  2. package/build/accessibility-handler.js +13 -11
  3. package/build/ai-handler.d.ts.map +1 -1
  4. package/build/ai-handler.js +11 -0
  5. package/build/cli/cliLogger.d.ts +1 -0
  6. package/build/cli/cliLogger.d.ts.map +1 -1
  7. package/build/cli/cliLogger.js +23 -12
  8. package/build/cli/cliUtils.d.ts +18 -0
  9. package/build/cli/cliUtils.d.ts.map +1 -1
  10. package/build/cli/cliUtils.js +29 -0
  11. package/build/cli/frameworks/wdioMochaTestFramework.d.ts.map +1 -1
  12. package/build/cli/frameworks/wdioMochaTestFramework.js +4 -2
  13. package/build/cli/grpcClient.d.ts +19 -3
  14. package/build/cli/grpcClient.d.ts.map +1 -1
  15. package/build/cli/grpcClient.js +133 -21
  16. package/build/cli/index.d.ts +2 -0
  17. package/build/cli/index.d.ts.map +1 -1
  18. package/build/cli/index.js +52 -4
  19. package/build/cli/modules/accessibilityModule.d.ts +3 -0
  20. package/build/cli/modules/accessibilityModule.d.ts.map +1 -1
  21. package/build/cli/modules/accessibilityModule.js +75 -10
  22. package/build/constants.d.ts +28 -0
  23. package/build/constants.d.ts.map +1 -1
  24. package/build/constants.js +37 -1
  25. package/build/exitHandler.d.ts +1 -1
  26. package/build/exitHandler.d.ts.map +1 -1
  27. package/build/exitHandler.js +6 -5
  28. package/build/insights-handler.d.ts.map +1 -1
  29. package/build/insights-handler.js +33 -7
  30. package/build/instrumentation/funnelInstrumentation.d.ts +2 -2
  31. package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -1
  32. package/build/instrumentation/funnelInstrumentation.js +30 -8
  33. package/build/instrumentation/performance/constants.d.ts +64 -0
  34. package/build/instrumentation/performance/constants.d.ts.map +1 -1
  35. package/build/instrumentation/performance/constants.js +73 -2
  36. package/build/instrumentation/performance/performance-tester.d.ts +11 -0
  37. package/build/instrumentation/performance/performance-tester.d.ts.map +1 -1
  38. package/build/instrumentation/performance/performance-tester.js +115 -12
  39. package/build/launcher.d.ts +1 -0
  40. package/build/launcher.d.ts.map +1 -1
  41. package/build/launcher.js +151 -6
  42. package/build/service.d.ts.map +1 -1
  43. package/build/service.js +77 -5
  44. package/build/testorchestration/apply-orchestration.d.ts +7 -0
  45. package/build/testorchestration/apply-orchestration.d.ts.map +1 -0
  46. package/build/testorchestration/apply-orchestration.js +42 -0
  47. package/build/testorchestration/helpers.d.ts +20 -0
  48. package/build/testorchestration/helpers.d.ts.map +1 -0
  49. package/build/testorchestration/helpers.js +412 -0
  50. package/build/testorchestration/request-utils.d.ts +23 -0
  51. package/build/testorchestration/request-utils.d.ts.map +1 -0
  52. package/build/testorchestration/request-utils.js +81 -0
  53. package/build/testorchestration/test-ordering-server.d.ts +33 -0
  54. package/build/testorchestration/test-ordering-server.d.ts.map +1 -0
  55. package/build/testorchestration/test-ordering-server.js +168 -0
  56. package/build/testorchestration/testorcherstrationhandler.d.ts +50 -0
  57. package/build/testorchestration/testorcherstrationhandler.d.ts.map +1 -0
  58. package/build/testorchestration/testorcherstrationhandler.js +133 -0
  59. package/build/testorchestration/testorcherstrationutils.d.ts +86 -0
  60. package/build/testorchestration/testorcherstrationutils.d.ts.map +1 -0
  61. package/build/testorchestration/testorcherstrationutils.js +379 -0
  62. package/build/types.d.ts +21 -0
  63. package/build/types.d.ts.map +1 -1
  64. package/build/util.d.ts +33 -4
  65. package/build/util.d.ts.map +1 -1
  66. package/build/util.js +112 -18
  67. package/package.json +3 -2
  68. package/tsconfig.prod.tsbuildinfo +1 -1
package/build/util.js CHANGED
@@ -1,29 +1,29 @@
1
- import { hostname, platform, type, version, arch } from 'node:os';
2
1
  import fs from 'node:fs';
3
- import zlib from 'node:zlib';
4
- import { promisify } from 'node:util';
5
2
  import http from 'node:http';
6
3
  import https from 'node:https';
4
+ import { arch, hostname, platform, type, version } from 'node:os';
7
5
  import path from 'node:path';
8
- import util from 'node:util';
9
- import got, { HTTPError } from 'got';
6
+ import util, { promisify } from 'node:util';
7
+ import zlib from 'node:zlib';
8
+ import { FormData } from 'formdata-node';
9
+ import { fileFromPath } from 'formdata-node/file-from-path';
10
10
  import gitRepoInfo from 'git-repo-info';
11
11
  import gitconfig from 'gitconfiglocal';
12
- import { FormData } from 'formdata-node';
12
+ import got, { HTTPError } from 'got';
13
13
  import { performance } from 'node:perf_hooks';
14
- import logPatcher from './logPatcher.js';
15
- import PerformanceTester from './instrumentation/performance/performance-tester.js';
16
- import * as PERFORMANCE_SDK_EVENTS from './instrumentation/performance/constants.js';
17
- import { logBuildError, handleErrorForObservability, handleErrorForAccessibility, getProductMapForBuildStartCall } from './testHub/utils.js';
18
- import { BROWSER_DESCRIPTION, UPLOAD_LOGS_ENDPOINT, consoleHolder, BSTACK_A11Y_POLLING_TIMEOUT, TESTOPS_SCREENSHOT_ENV, BROWSERSTACK_TESTHUB_UUID, PERF_MEASUREMENT_ENV, RERUN_ENV, TESTOPS_BUILD_COMPLETED_ENV, BROWSERSTACK_TESTHUB_JWT, BROWSERSTACK_OBSERVABILITY, BROWSERSTACK_TEST_REPORTING, BROWSERSTACK_ACCESSIBILITY, MAX_GIT_META_DATA_SIZE_IN_BYTES, GIT_META_DATA_TRUNCATED, APP_ALLY_ISSUES_SUMMARY_ENDPOINT, APP_ALLY_ISSUES_ENDPOINT, TEST_REPORTING_PROJECT_NAME, CLI_DEBUG_LOGS_FILE, WDIO_NAMING_PREFIX } from './constants.js';
19
- import CrashReporter from './crash-reporter.js';
14
+ import tar from 'tar';
20
15
  import { BStackLogger } from './bstackLogger.js';
16
+ import APIUtils from './cli/apiUtils.js';
17
+ import { APP_ALLY_ISSUES_ENDPOINT, APP_ALLY_ISSUES_SUMMARY_ENDPOINT, BROWSERSTACK_ACCESSIBILITY, BROWSERSTACK_OBSERVABILITY, BROWSERSTACK_TESTHUB_JWT, BROWSERSTACK_TESTHUB_UUID, BROWSERSTACK_TEST_PLAN_ID, BROWSERSTACK_TEST_REPORTING, BROWSER_DESCRIPTION, BSTACK_A11Y_POLLING_TIMEOUT, CLI_DEBUG_LOGS_FILE, GIT_META_DATA_TRUNCATED, MAX_GIT_META_DATA_SIZE_IN_BYTES, PERF_MEASUREMENT_ENV, RERUN_ENV, TESTOPS_BUILD_COMPLETED_ENV, TESTOPS_SCREENSHOT_ENV, TEST_REPORTING_PROJECT_NAME, UPLOAD_LOGS_ENDPOINT, WDIO_NAMING_PREFIX, consoleHolder } from './constants.js';
18
+ import CrashReporter from './crash-reporter.js';
19
+ import * as PERFORMANCE_SDK_EVENTS from './instrumentation/performance/constants.js';
20
+ import PerformanceTester from './instrumentation/performance/performance-tester.js';
21
+ import logPatcher from './logPatcher.js';
21
22
  import AccessibilityScripts from './scripts/accessibility-scripts.js';
22
- import UsageStats from './testOps/usageStats.js';
23
+ import { getProductMapForBuildStartCall, handleErrorForAccessibility, handleErrorForObservability, logBuildError } from './testHub/utils.js';
23
24
  import TestOpsConfig from './testOps/testOpsConfig.js';
24
- import APIUtils from './cli/apiUtils.js';
25
- import tar from 'tar';
26
- import { fileFromPath } from 'formdata-node/file-from-path';
25
+ import UsageStats from './testOps/usageStats.js';
26
+ import { OrchestrationUtils } from './testorchestration/testorcherstrationutils.js';
27
27
  const pGitconfig = promisify(gitconfig);
28
28
  export const DEFAULT_REQUEST_CONFIG = {
29
29
  agent: {
@@ -317,7 +317,11 @@ export const launchTestSession = PerformanceTester.measureWrapper(PERFORMANCE_SD
317
317
  }
318
318
  },
319
319
  product_map: getProductMapForBuildStartCall(bStackConfig, accessibilityAutomation),
320
- config: {}
320
+ config: {},
321
+ test_orchestration: OrchestrationUtils.getInstance(config)?.getBuildStartData() || {},
322
+ test_management: {
323
+ test_plan_id: getTestPlanId(options)
324
+ }
321
325
  };
322
326
  if (accessibilityAutomation && (isTurboScale(options) || data.browserstackAutomation === false)) {
323
327
  data.accessibility.settings ??= {};
@@ -342,6 +346,7 @@ export const launchTestSession = PerformanceTester.measureWrapper(PERFORMANCE_SD
342
346
  }).json();
343
347
  delete data?.accessibility?.settings?.includeEncodedExtension;
344
348
  BStackLogger.debug(`[Start_Build] Success response: ${JSON.stringify(response)}`);
349
+ BStackLogger.debug(`Test Plan Id sent in request: ${getTestPlanId(options)}`);
345
350
  process.env[TESTOPS_BUILD_COMPLETED_ENV] = 'true';
346
351
  if (response.jwt) {
347
352
  process.env[BROWSERSTACK_TESTHUB_JWT] = response.jwt;
@@ -897,7 +902,16 @@ export function getUniqueIdentifierForCucumber(world) {
897
902
  return world.pickle.uri + '_' + world.pickle.astNodeIds.join(',');
898
903
  }
899
904
  export function getCloudProvider(browser) {
900
- if (browser.options && browser.options.hostname && browser.options.hostname.includes('browserstack')) {
905
+ if (browser && 'instances' in browser) {
906
+ // Loop through all instances
907
+ for (const instanceName of browser.instances) {
908
+ const instance = browser[instanceName];
909
+ if (instance.options && instance.options.hostname && instance.options.hostname.includes('browserstack')) {
910
+ return 'browserstack';
911
+ }
912
+ }
913
+ }
914
+ else if (browser.options && browser.options.hostname && browser.options.hostname.includes('browserstack')) { // Single browser instance
901
915
  return 'browserstack';
902
916
  }
903
917
  return 'unknown_grid';
@@ -905,6 +919,23 @@ export function getCloudProvider(browser) {
905
919
  export function isBrowserstackSession(browser) {
906
920
  return browser && getCloudProvider(browser).toLowerCase() === 'browserstack';
907
921
  }
922
+ /**
923
+ * Sets a BrowserStack annotation with the provided message
924
+ * @param browser - The WebDriver browser instance
925
+ * @param message - The annotation message to set
926
+ * @param isAccessibilityEnabled - Whether accessibility is enabled for the session
927
+ */
928
+ export async function setBrowserstackAnnotation(browser, message, isAccessibilityEnabled) {
929
+ if (isAccessibilityEnabled && isBrowserstackSession(browser)) {
930
+ await browser.execute(`browserstack_executor: ${JSON.stringify({
931
+ action: 'annotate',
932
+ arguments: {
933
+ data: message,
934
+ level: 'info'
935
+ }
936
+ })}`);
937
+ }
938
+ }
908
939
  export function getScenarioExamples(world) {
909
940
  const scenario = world.pickle;
910
941
  // no examples present
@@ -1149,6 +1180,25 @@ export function getObservabilityBuildTags(options, bstackBuildTag) {
1149
1180
  }
1150
1181
  return [];
1151
1182
  }
1183
+ export function getTestPlanId(options) {
1184
+ if (process.env[BROWSERSTACK_TEST_PLAN_ID]) {
1185
+ return process.env[BROWSERSTACK_TEST_PLAN_ID];
1186
+ }
1187
+ const CLI_ARG = '--browserstack.testManagementOptions.testPlanId';
1188
+ const argIndex = process.argv.indexOf(CLI_ARG);
1189
+ if (argIndex !== -1 && process.argv[argIndex + 1]) {
1190
+ return process.argv[argIndex + 1];
1191
+ }
1192
+ const argWithEquals = process.argv.find((arg) => arg.startsWith(`${CLI_ARG}=`));
1193
+ if (argWithEquals) {
1194
+ return argWithEquals.split('=')[1];
1195
+ }
1196
+ const testPlanId = options.testManagementOptions?.testPlanId;
1197
+ if (typeof testPlanId === 'string' && testPlanId.trim().length > 0) {
1198
+ return testPlanId.trim();
1199
+ }
1200
+ return undefined;
1201
+ }
1152
1202
  export function getBrowserStackUser(config) {
1153
1203
  if (process.env.BROWSERSTACK_USERNAME) {
1154
1204
  return process.env.BROWSERSTACK_USERNAME;
@@ -1460,6 +1510,22 @@ export function getBooleanValueFromString(value) {
1460
1510
  }
1461
1511
  return ['true'].includes(value.trim().toLowerCase());
1462
1512
  }
1513
+ /**
1514
+ * Validate boolean value from mixed types (boolean or string)
1515
+ * Only accepts true boolean or string "true" (case insensitive)
1516
+ */
1517
+ export function isValidEnabledValue(value) {
1518
+ if (value === undefined || value === null) {
1519
+ return false;
1520
+ }
1521
+ if (typeof value === 'boolean') {
1522
+ return value === true;
1523
+ }
1524
+ if (typeof value === 'string') {
1525
+ return getBooleanValueFromString(value);
1526
+ }
1527
+ return false;
1528
+ }
1463
1529
  export function mergeDeep(target, ...sources) {
1464
1530
  if (!sources.length) {
1465
1531
  return target;
@@ -1564,3 +1630,31 @@ export function getMochaTestHierarchy(test) {
1564
1630
  }
1565
1631
  return value.reverse();
1566
1632
  }
1633
+ /**
1634
+ * Checks if the capabilities represent a multiremote configuration
1635
+ * @param capabilities - The capabilities to check
1636
+ * @returns true if capabilities represent any multiremote configuration (regular or parallel)
1637
+ *
1638
+ * @example
1639
+ * Regular multiremote (object):
1640
+ * { browserA: { capabilities: {...} }, browserB: { capabilities: {...} } }
1641
+ *
1642
+ * Parallel multiremote (array with nested structure):
1643
+ * [{ browserA: { capabilities: {...} }, browserB: { capabilities: {...} } }]
1644
+ *
1645
+ * Regular capabilities (array):
1646
+ * [{ browserName: 'chrome', ... }]
1647
+ */
1648
+ export function isMultiRemoteCaps(capabilities) {
1649
+ // Regular multiremote is an object (not array)
1650
+ if (!Array.isArray(capabilities)) {
1651
+ return true;
1652
+ }
1653
+ // Empty array is not multiremote
1654
+ if (capabilities.length === 0) {
1655
+ return false;
1656
+ }
1657
+ // Parallel multiremote is an array with nested capabilities structure
1658
+ return capabilities.every(cap => Object.values(cap).length > 0 &&
1659
+ Object.values(cap).every(c => c !== null && typeof c === 'object' && c.capabilities));
1660
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/browserstack-service",
3
- "version": "8.48.0",
3
+ "version": "8.48.3",
4
4
  "description": "WebdriverIO service for better Browserstack integration",
5
5
  "author": "Adam Bjerstedt <abjerstedt@gmail.com>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
@@ -44,6 +44,7 @@
44
44
  "formdata-node": "5.0.1",
45
45
  "git-repo-info": "^2.1.1",
46
46
  "gitconfiglocal": "^2.1.0",
47
+ "glob": "^10.3.10",
47
48
  "got": "^12.6.1",
48
49
  "tar": "^6.1.15",
49
50
  "uuid": "^10.0.0",
@@ -62,5 +63,5 @@
62
63
  "publishConfig": {
63
64
  "access": "public"
64
65
  },
65
- "gitHead": "9a4aeb53bad8f86e8caa232f67a5b51fcde1fdf2"
66
+ "gitHead": "fe872d88706a42cd9653abfc99079d5ab80197dc"
66
67
  }
@@ -1 +1 @@
1
- {"root":["./src/accessibility-handler.ts","./src/ai-handler.ts","./src/bstackLogger.ts","./src/cleanup.ts","./src/config.ts","./src/constants.ts","./src/crash-reporter.ts","./src/cucumber-types.ts","./src/data-store.ts","./src/exitHandler.ts","./src/fileStream.ts","./src/index.ts","./src/insights-handler.ts","./src/launcher.ts","./src/log4jsAppender.ts","./src/logPatcher.ts","./src/logReportingAPI.ts","./src/reporter.ts","./src/request-handler.ts","./src/service.ts","./src/types.ts","./src/util.ts","./src/@types/bstack-service-types.d.ts","./src/@types/cucumber-framework.d.ts","./src/Percy/Percy-Handler.ts","./src/Percy/Percy.ts","./src/Percy/PercyBinary.ts","./src/Percy/PercyCaptureMap.ts","./src/Percy/PercyHelper.ts","./src/Percy/PercyLogger.ts","./src/Percy/PercySDK.ts","./src/cli/apiUtils.ts","./src/cli/cliLogger.ts","./src/cli/cliUtils.ts","./src/cli/eventDispatcher.ts","./src/cli/grpcClient.ts","./src/cli/index.ts","./src/cli/frameworks/automationFramework.ts","./src/cli/frameworks/testFramework.ts","./src/cli/frameworks/wdioAutomationFramework.ts","./src/cli/frameworks/wdioMochaTestFramework.ts","./src/cli/frameworks/constants/automationFrameworkConstants.ts","./src/cli/frameworks/constants/testFrameworkConstants.ts","./src/cli/instances/automationFrameworkInstance.ts","./src/cli/instances/testFrameworkInstance.ts","./src/cli/instances/trackedContext.ts","./src/cli/instances/trackedInstance.ts","./src/cli/modules/accessibilityModule.ts","./src/cli/modules/automateModule.ts","./src/cli/modules/baseModule.ts","./src/cli/modules/observabilityModule.ts","./src/cli/modules/percyModule.ts","./src/cli/modules/testHubModule.ts","./src/cli/modules/webdriverIOModule.ts","./src/cli/states/automationFrameworkState.ts","./src/cli/states/hookState.ts","./src/cli/states/testFrameworkState.ts","./src/instrumentation/funnelInstrumentation.ts","./src/instrumentation/performance/constants.ts","./src/instrumentation/performance/performance-tester.ts","./src/scripts/accessibility-scripts.ts","./src/testHub/utils.ts","./src/testOps/featureStats.ts","./src/testOps/featureUsage.ts","./src/testOps/listener.ts","./src/testOps/requestUtils.ts","./src/testOps/testOpsConfig.ts","./src/testOps/usageStats.ts","../../@types/css-shorthand-properties.d.ts","../../@types/css-value.d.ts","../../@types/custom.d.ts","../../@types/junit-report-builder.d.ts","../../@types/lerna-changelog.d.ts","../../@types/query-selector-shadow-dom.d.ts"],"version":"5.6.2"}
1
+ {"root":["./src/accessibility-handler.ts","./src/ai-handler.ts","./src/bstackLogger.ts","./src/cleanup.ts","./src/config.ts","./src/constants.ts","./src/crash-reporter.ts","./src/cucumber-types.ts","./src/data-store.ts","./src/exitHandler.ts","./src/fileStream.ts","./src/index.ts","./src/insights-handler.ts","./src/launcher.ts","./src/log4jsAppender.ts","./src/logPatcher.ts","./src/logReportingAPI.ts","./src/reporter.ts","./src/request-handler.ts","./src/service.ts","./src/types.ts","./src/util.ts","./src/@types/bstack-service-types.d.ts","./src/@types/cucumber-framework.d.ts","./src/Percy/Percy-Handler.ts","./src/Percy/Percy.ts","./src/Percy/PercyBinary.ts","./src/Percy/PercyCaptureMap.ts","./src/Percy/PercyHelper.ts","./src/Percy/PercyLogger.ts","./src/Percy/PercySDK.ts","./src/cli/apiUtils.ts","./src/cli/cliLogger.ts","./src/cli/cliUtils.ts","./src/cli/eventDispatcher.ts","./src/cli/grpcClient.ts","./src/cli/index.ts","./src/cli/frameworks/automationFramework.ts","./src/cli/frameworks/testFramework.ts","./src/cli/frameworks/wdioAutomationFramework.ts","./src/cli/frameworks/wdioMochaTestFramework.ts","./src/cli/frameworks/constants/automationFrameworkConstants.ts","./src/cli/frameworks/constants/testFrameworkConstants.ts","./src/cli/instances/automationFrameworkInstance.ts","./src/cli/instances/testFrameworkInstance.ts","./src/cli/instances/trackedContext.ts","./src/cli/instances/trackedInstance.ts","./src/cli/modules/accessibilityModule.ts","./src/cli/modules/automateModule.ts","./src/cli/modules/baseModule.ts","./src/cli/modules/observabilityModule.ts","./src/cli/modules/percyModule.ts","./src/cli/modules/testHubModule.ts","./src/cli/modules/webdriverIOModule.ts","./src/cli/states/automationFrameworkState.ts","./src/cli/states/hookState.ts","./src/cli/states/testFrameworkState.ts","./src/instrumentation/funnelInstrumentation.ts","./src/instrumentation/performance/constants.ts","./src/instrumentation/performance/performance-tester.ts","./src/scripts/accessibility-scripts.ts","./src/testHub/utils.ts","./src/testOps/featureStats.ts","./src/testOps/featureUsage.ts","./src/testOps/listener.ts","./src/testOps/requestUtils.ts","./src/testOps/testOpsConfig.ts","./src/testOps/usageStats.ts","./src/testorchestration/apply-orchestration.ts","./src/testorchestration/helpers.ts","./src/testorchestration/request-utils.ts","./src/testorchestration/test-ordering-server.ts","./src/testorchestration/testorcherstrationhandler.ts","./src/testorchestration/testorcherstrationutils.ts","../../@types/css-shorthand-properties.d.ts","../../@types/css-value.d.ts","../../@types/custom.d.ts","../../@types/junit-report-builder.d.ts","../../@types/lerna-changelog.d.ts","../../@types/query-selector-shadow-dom.d.ts"],"version":"5.6.2"}