@browserstack/mcp-server 1.2.3 → 1.2.5

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 (164) hide show
  1. package/README.md +96 -6
  2. package/dist/lib/apiClient.d.ts +7 -5
  3. package/dist/lib/apiClient.js +76 -15
  4. package/dist/lib/device-cache.d.ts +3 -1
  5. package/dist/lib/device-cache.js +24 -17
  6. package/dist/lib/inmemory-store.d.ts +1 -0
  7. package/dist/lib/inmemory-store.js +1 -0
  8. package/dist/lib/instrumentation.js +6 -3
  9. package/dist/lib/utils.d.ts +78 -0
  10. package/dist/lib/utils.js +47 -0
  11. package/dist/lib/version-resolver.js +26 -14
  12. package/dist/server-factory.js +6 -0
  13. package/dist/tools/add-percy-snapshots.d.ts +5 -0
  14. package/dist/tools/add-percy-snapshots.js +17 -0
  15. package/dist/tools/appautomate-utils/appium-sdk/config-generator.d.ts +7 -0
  16. package/dist/tools/appautomate-utils/appium-sdk/config-generator.js +70 -0
  17. package/dist/tools/appautomate-utils/appium-sdk/constants.d.ts +23 -0
  18. package/dist/tools/appautomate-utils/appium-sdk/constants.js +64 -0
  19. package/dist/tools/appautomate-utils/appium-sdk/formatter.d.ts +8 -0
  20. package/dist/tools/appautomate-utils/appium-sdk/formatter.js +59 -0
  21. package/dist/tools/appautomate-utils/appium-sdk/handler.d.ts +3 -0
  22. package/dist/tools/appautomate-utils/appium-sdk/handler.js +66 -0
  23. package/dist/tools/appautomate-utils/appium-sdk/index.d.ts +7 -0
  24. package/dist/tools/appautomate-utils/appium-sdk/index.js +8 -0
  25. package/dist/tools/appautomate-utils/appium-sdk/instructions.d.ts +3 -0
  26. package/dist/tools/appautomate-utils/appium-sdk/instructions.js +47 -0
  27. package/dist/tools/appautomate-utils/appium-sdk/languages/csharp.d.ts +2 -0
  28. package/dist/tools/appautomate-utils/appium-sdk/languages/csharp.js +78 -0
  29. package/dist/tools/appautomate-utils/appium-sdk/languages/java.d.ts +10 -0
  30. package/dist/tools/appautomate-utils/appium-sdk/languages/java.js +121 -0
  31. package/dist/tools/appautomate-utils/appium-sdk/languages/nodejs.d.ts +3 -0
  32. package/dist/tools/appautomate-utils/appium-sdk/languages/nodejs.js +194 -0
  33. package/dist/tools/appautomate-utils/appium-sdk/languages/python.d.ts +3 -0
  34. package/dist/tools/appautomate-utils/appium-sdk/languages/python.js +76 -0
  35. package/dist/tools/appautomate-utils/appium-sdk/languages/ruby.d.ts +2 -0
  36. package/dist/tools/appautomate-utils/appium-sdk/languages/ruby.js +85 -0
  37. package/dist/tools/appautomate-utils/appium-sdk/types.d.ts +58 -0
  38. package/dist/tools/appautomate-utils/appium-sdk/types.js +63 -0
  39. package/dist/tools/appautomate-utils/appium-sdk/utils.d.ts +17 -0
  40. package/dist/tools/appautomate-utils/appium-sdk/utils.js +64 -0
  41. package/dist/tools/appautomate-utils/{appautomate.d.ts → native-execution/appautomate.d.ts} +1 -1
  42. package/dist/tools/appautomate-utils/{appautomate.js → native-execution/appautomate.js} +2 -2
  43. package/dist/tools/appautomate-utils/native-execution/constants.d.ts +11 -0
  44. package/dist/tools/appautomate-utils/native-execution/constants.js +58 -0
  45. package/dist/tools/appautomate-utils/native-execution/types.d.ts +19 -0
  46. package/dist/tools/appautomate-utils/{types.js → native-execution/types.js} +5 -1
  47. package/dist/tools/appautomate.js +40 -42
  48. package/dist/tools/bstack-sdk.d.ts +2 -15
  49. package/dist/tools/bstack-sdk.js +10 -119
  50. package/dist/tools/build-insights.d.ts +7 -0
  51. package/dist/tools/build-insights.js +67 -0
  52. package/dist/tools/list-test-files.d.ts +2 -0
  53. package/dist/tools/list-test-files.js +36 -0
  54. package/dist/tools/percy-sdk.d.ts +4 -0
  55. package/dist/tools/percy-sdk.js +98 -0
  56. package/dist/tools/percy-snapshot-utils/constants.d.ts +16 -0
  57. package/dist/tools/percy-snapshot-utils/constants.js +500 -0
  58. package/dist/tools/percy-snapshot-utils/detect-test-files.d.ts +10 -0
  59. package/dist/tools/percy-snapshot-utils/detect-test-files.js +175 -0
  60. package/dist/tools/percy-snapshot-utils/types.d.ts +15 -0
  61. package/dist/tools/percy-snapshot-utils/utils.d.ts +4 -0
  62. package/dist/tools/percy-snapshot-utils/utils.js +30 -0
  63. package/dist/tools/rca-agent-utils/constants.d.ts +13 -0
  64. package/dist/tools/rca-agent-utils/constants.js +24 -0
  65. package/dist/tools/rca-agent-utils/format-rca.d.ts +1 -0
  66. package/dist/tools/rca-agent-utils/format-rca.js +37 -0
  67. package/dist/tools/rca-agent-utils/get-build-id.d.ts +1 -0
  68. package/dist/tools/rca-agent-utils/get-build-id.js +18 -0
  69. package/dist/tools/rca-agent-utils/get-failed-test-id.d.ts +2 -0
  70. package/dist/tools/rca-agent-utils/get-failed-test-id.js +69 -0
  71. package/dist/tools/rca-agent-utils/rca-data.d.ts +9 -0
  72. package/dist/tools/rca-agent-utils/rca-data.js +196 -0
  73. package/dist/tools/rca-agent-utils/types.d.ts +48 -0
  74. package/dist/tools/rca-agent-utils/types.js +20 -0
  75. package/dist/tools/rca-agent.d.ts +14 -0
  76. package/dist/tools/rca-agent.js +119 -0
  77. package/dist/tools/review-agent-utils/build-counts.d.ts +7 -0
  78. package/dist/tools/review-agent-utils/build-counts.js +44 -0
  79. package/dist/tools/review-agent-utils/percy-approve-reject.d.ts +6 -0
  80. package/dist/tools/review-agent-utils/percy-approve-reject.js +39 -0
  81. package/dist/tools/review-agent-utils/percy-diffs.d.ts +9 -0
  82. package/dist/tools/review-agent-utils/percy-diffs.js +35 -0
  83. package/dist/tools/review-agent-utils/percy-snapshots.d.ts +11 -0
  84. package/dist/tools/review-agent-utils/percy-snapshots.js +58 -0
  85. package/dist/tools/review-agent.d.ts +5 -0
  86. package/dist/tools/review-agent.js +56 -0
  87. package/dist/tools/run-percy-scan.d.ts +8 -0
  88. package/dist/tools/run-percy-scan.js +37 -0
  89. package/dist/tools/sdk-utils/{commands.d.ts → bstack/commands.d.ts} +1 -1
  90. package/dist/tools/sdk-utils/bstack/commands.js +88 -0
  91. package/dist/tools/sdk-utils/bstack/configUtils.d.ts +7 -0
  92. package/dist/tools/sdk-utils/bstack/configUtils.js +113 -0
  93. package/dist/tools/sdk-utils/bstack/constants.d.ts +58 -0
  94. package/dist/tools/sdk-utils/{constants.js → bstack/constants.js} +117 -78
  95. package/dist/tools/sdk-utils/{constants.d.ts → bstack/frameworks.d.ts} +1 -1
  96. package/dist/tools/sdk-utils/bstack/frameworks.js +57 -0
  97. package/dist/tools/sdk-utils/bstack/index.d.ts +4 -0
  98. package/dist/tools/sdk-utils/bstack/index.js +5 -0
  99. package/dist/tools/sdk-utils/bstack/sdkHandler.d.ts +4 -0
  100. package/dist/tools/sdk-utils/bstack/sdkHandler.js +82 -0
  101. package/dist/tools/sdk-utils/common/constants.d.ts +11 -0
  102. package/dist/tools/sdk-utils/common/constants.js +87 -0
  103. package/dist/tools/sdk-utils/common/device-validator.d.ts +25 -0
  104. package/dist/tools/sdk-utils/common/device-validator.js +368 -0
  105. package/dist/tools/sdk-utils/common/formatUtils.d.ts +5 -0
  106. package/dist/tools/sdk-utils/common/formatUtils.js +27 -0
  107. package/dist/tools/sdk-utils/common/index.d.ts +3 -0
  108. package/dist/tools/sdk-utils/common/index.js +4 -0
  109. package/dist/tools/sdk-utils/common/instructionUtils.d.ts +8 -0
  110. package/dist/tools/sdk-utils/common/instructionUtils.js +20 -0
  111. package/dist/tools/sdk-utils/common/schema.d.ts +93 -0
  112. package/dist/tools/sdk-utils/common/schema.js +105 -0
  113. package/dist/tools/sdk-utils/common/types.d.ts +66 -0
  114. package/dist/tools/sdk-utils/{types.js → common/types.js} +15 -2
  115. package/dist/tools/sdk-utils/common/utils.d.ts +25 -0
  116. package/dist/tools/sdk-utils/common/utils.js +91 -0
  117. package/dist/tools/sdk-utils/handler.d.ts +5 -0
  118. package/dist/tools/sdk-utils/handler.js +147 -0
  119. package/dist/tools/sdk-utils/percy-automate/constants.d.ts +11 -0
  120. package/dist/tools/sdk-utils/percy-automate/constants.js +338 -0
  121. package/dist/tools/sdk-utils/percy-automate/frameworks.d.ts +8 -0
  122. package/dist/tools/sdk-utils/percy-automate/frameworks.js +50 -0
  123. package/dist/tools/sdk-utils/percy-automate/handler.d.ts +3 -0
  124. package/dist/tools/sdk-utils/percy-automate/handler.js +30 -0
  125. package/dist/tools/sdk-utils/percy-automate/index.d.ts +1 -0
  126. package/dist/tools/sdk-utils/percy-automate/index.js +2 -0
  127. package/dist/tools/sdk-utils/percy-automate/types.d.ts +13 -0
  128. package/dist/tools/sdk-utils/percy-automate/types.js +1 -0
  129. package/dist/tools/sdk-utils/percy-bstack/constants.d.ts +4 -0
  130. package/dist/tools/sdk-utils/{percy → percy-bstack}/constants.js +13 -39
  131. package/dist/tools/sdk-utils/percy-bstack/frameworks.d.ts +2 -0
  132. package/dist/tools/sdk-utils/percy-bstack/frameworks.js +27 -0
  133. package/dist/tools/sdk-utils/percy-bstack/handler.d.ts +4 -0
  134. package/dist/tools/sdk-utils/percy-bstack/handler.js +103 -0
  135. package/dist/tools/sdk-utils/percy-bstack/index.d.ts +4 -0
  136. package/dist/tools/sdk-utils/percy-bstack/index.js +4 -0
  137. package/dist/tools/sdk-utils/percy-bstack/instructions.d.ts +7 -0
  138. package/dist/tools/sdk-utils/{percy → percy-bstack}/instructions.js +5 -9
  139. package/dist/tools/sdk-utils/percy-bstack/types.d.ts +13 -0
  140. package/dist/tools/sdk-utils/percy-bstack/types.js +5 -0
  141. package/dist/tools/sdk-utils/percy-web/constants.d.ts +41 -0
  142. package/dist/tools/sdk-utils/percy-web/constants.js +883 -0
  143. package/dist/tools/sdk-utils/percy-web/fetchPercyToken.d.ts +4 -0
  144. package/dist/tools/sdk-utils/percy-web/fetchPercyToken.js +32 -0
  145. package/dist/tools/sdk-utils/percy-web/frameworks.d.ts +7 -0
  146. package/dist/tools/sdk-utils/percy-web/frameworks.js +103 -0
  147. package/dist/tools/sdk-utils/percy-web/handler.d.ts +4 -0
  148. package/dist/tools/sdk-utils/percy-web/handler.js +29 -0
  149. package/dist/tools/sdk-utils/percy-web/index.d.ts +4 -0
  150. package/dist/tools/sdk-utils/percy-web/index.js +4 -0
  151. package/dist/tools/sdk-utils/percy-web/types.d.ts +12 -0
  152. package/dist/tools/sdk-utils/percy-web/types.js +1 -0
  153. package/dist/tools/testmanagement-utils/create-testrun.d.ts +4 -4
  154. package/dist/tools/testmanagement-utils/update-testrun.d.ts +4 -4
  155. package/package.json +3 -2
  156. package/dist/tools/appautomate-utils/types.d.ts +0 -5
  157. package/dist/tools/sdk-utils/commands.js +0 -65
  158. package/dist/tools/sdk-utils/instructions.d.ts +0 -6
  159. package/dist/tools/sdk-utils/instructions.js +0 -99
  160. package/dist/tools/sdk-utils/percy/constants.d.ts +0 -3
  161. package/dist/tools/sdk-utils/percy/instructions.d.ts +0 -10
  162. package/dist/tools/sdk-utils/percy/types.d.ts +0 -5
  163. package/dist/tools/sdk-utils/types.d.ts +0 -40
  164. /package/dist/tools/{sdk-utils/percy → percy-snapshot-utils}/types.js +0 -0
@@ -0,0 +1,194 @@
1
+ // Node.js instructions and commands for App SDK utilities
2
+ import { AppSDKSupportedTestingFrameworkEnum, createStep, combineInstructions, } from "../index.js";
3
+ export function getNodejsSDKCommand(testingFramework, username, accessKey) {
4
+ switch (testingFramework) {
5
+ case "webdriverio":
6
+ return getWebDriverIOCommand(username, accessKey);
7
+ case "nightwatch":
8
+ return getNightwatchCommand(username, accessKey);
9
+ case "jest":
10
+ return getJestCommand(username, accessKey);
11
+ case "mocha":
12
+ return getMochaCommand(username, accessKey);
13
+ case "cucumberJs":
14
+ return getCucumberJSCommand(username, accessKey);
15
+ default:
16
+ return "";
17
+ }
18
+ }
19
+ export function getNodejsAppInstructions(testingFramework) {
20
+ switch (testingFramework) {
21
+ case AppSDKSupportedTestingFrameworkEnum.webdriverio:
22
+ return createStep("Run your WebdriverIO test suite:", "Your test suite is now ready to run on BrowserStack. Use the commands defined in your package.json file to run the tests");
23
+ case AppSDKSupportedTestingFrameworkEnum.nightwatch:
24
+ return createStep("Run your App Automate test suite:", `For Android:
25
+ \`\`\`bash
26
+ npx nightwatch <path to tests> --env browserstack.android
27
+ \`\`\`
28
+ For iOS:
29
+ \`\`\`bash
30
+ npx nightwatch <path to tests> --env browserstack.ios
31
+ \`\`\``);
32
+ case AppSDKSupportedTestingFrameworkEnum.jest:
33
+ return createStep("Run your Jest test suite with BrowserStack SDK:", `Use the npm script defined in your package.json. For example:\n\n\`\`\`bash\nnpx run browserstack-node-sdk jest specs/single_test.js\n\`\`\``);
34
+ case AppSDKSupportedTestingFrameworkEnum.mocha:
35
+ return createStep("Run your Mocha test suite with BrowserStack SDK:", `Use the npm script defined in your package.json. For example:\n\n\`\`\`bash\nnpx run browserstack-node-sdk mocha specs/single_test.js\n\`\`\``);
36
+ case AppSDKSupportedTestingFrameworkEnum.cucumberJs:
37
+ return createStep("Run your Cucumber JS test suite with BrowserStack SDK:", `Use the npm script defined in your package.json. For example:\n\n\`\`\`bash\nnpx run browserstack-node-sdk cucumber-js specs/single_test.js\n\`\`\``);
38
+ default:
39
+ return "";
40
+ }
41
+ }
42
+ function getWebDriverIOCommand(username, accessKey) {
43
+ const prerequisiteStep = createStep("Prerequisite Setup:", `a. Ensure you do not modify or replace any existing local driver code,
44
+ as it will be automatically managed and overwritten by the BrowserStack SDK/Driver.
45
+ b. Do not create any YML file in this integration as it is not required.
46
+ c. Ensure you create the WDIO config file as per the instructions below.`);
47
+ const envStep = createStep("Set your BrowserStack credentials as environment variables:", `\`\`\`bash
48
+ export BROWSERSTACK_USERNAME=${username}
49
+ export BROWSERSTACK_ACCESS_KEY=${accessKey}
50
+ \`\`\``);
51
+ const installStep = createStep("Install BrowserStack WDIO service:", `\`\`\`bash
52
+ npm install @wdio/browserstack-service@^7 --save-dev
53
+ \`\`\``);
54
+ const configStep = createStep("Update your WebdriverIO config file (e.g., \\`wdio.conf.js\\`) to add the BrowserStack service and capabilities:", `\`\`\`js
55
+ exports.config = {
56
+ user: process.env.BROWSERSTACK_USERNAME || '${username}',
57
+ key: process.env.BROWSERSTACK_ACCESS_KEY || '${accessKey}',
58
+ hostname: 'hub.browserstack.com',
59
+ services: [
60
+ [
61
+ 'browserstack',
62
+ {
63
+ app: 'bs://sample.app',
64
+ browserstackLocal: true,
65
+ accessibility: false,
66
+ testObservabilityOptions: {
67
+ buildName: "bstack-demo",
68
+ projectName: "BrowserStack Sample",
69
+ buildTag: 'Any build tag goes here. For e.g. ["Tag1","Tag2"]'
70
+ },
71
+ },
72
+ ]
73
+ ],
74
+ capabilities: [{
75
+ 'bstack:options': {
76
+ deviceName: 'Samsung Galaxy S22 Ultra',
77
+ platformVersion: '12.0',
78
+ platformName: 'android',
79
+ }
80
+ }],
81
+ commonCapabilities: {
82
+ 'bstack:options': {
83
+ debug: true,
84
+ networkLogs: true,
85
+ percy: false,
86
+ percyCaptureMode: 'auto'
87
+ }
88
+ },
89
+ maxInstances: 10,
90
+ // ...other config
91
+ };
92
+ \`\`\``);
93
+ return combineInstructions(prerequisiteStep, envStep, installStep, configStep);
94
+ }
95
+ function getNightwatchCommand(username, accessKey) {
96
+ const prerequisiteStep = createStep("Prerequisite Setup:", ` a. Ensure you do not modify or replace any existing local driver code,
97
+ as it will be automatically managed and overwritten by the BrowserStack SDK/Driver.
98
+ b. Do not create any YML file in this integration as it is not required.
99
+ c. Ensure you create the WDIO config file as per the instructions below.`);
100
+ const envStep = createStep("Set your BrowserStack credentials as environment variables:", `\`\`\`bash
101
+ export BROWSERSTACK_USERNAME=${username}
102
+ export BROWSERSTACK_ACCESS_KEY=${accessKey}
103
+ \`\`\``);
104
+ const installStep = createStep("Install Nightwatch and BrowserStack integration:", `\`\`\`bash
105
+ npm install --save-dev @nightwatch/browserstack
106
+ \`\`\``);
107
+ const configStep = createStep("Update your Nightwatch config file (e.g., \\`nightwatch.conf.js\\`) to add the BrowserStack settings and capabilities:", `\`\`\`js
108
+
109
+ test_settings:{
110
+ ...
111
+ browserstack: {
112
+ selenium: {
113
+ host: 'hub.browserstack.com',
114
+ port: 443
115
+ },
116
+ desiredCapabilities: {
117
+ 'bstack:options': {
118
+ userName: '',
119
+ accessKey: '',
120
+ appiumVersion: '2.0.0'
121
+ }
122
+ },
123
+ disable_error_log: false,
124
+ webdriver: {
125
+ timeout_options: {
126
+ timeout: 60000,
127
+ retry_attempts: 3
128
+ },
129
+ keep_alive: true,
130
+ start_process: false
131
+ }
132
+ },
133
+ 'browserstack.android': {
134
+ extends: 'browserstack',
135
+ 'desiredCapabilities': {
136
+ browserName: null,
137
+ 'appium:options': {
138
+ automationName: 'UiAutomator2',
139
+ app: 'wikipedia-sample-app',// custom-id of the uploaded app
140
+ appPackage: 'org.wikipedia',
141
+ appActivity: 'org.wikipedia.main.MainActivity',
142
+ appWaitActivity: 'org.wikipedia.onboarding.InitialOnboardingActivity',
143
+ platformVersion: '11.0',
144
+ deviceName: 'Google Pixel 5'
145
+ },
146
+ appUploadUrl: 'https://raw.githubusercontent.com/priyansh3133/wikipedia/main/wikipedia.apk',// URL of the app to be uploaded to BrowserStack before starting the test
147
+ // appUploadPath: '/path/to/app_name.apk' // if the app needs to be uploaded to BrowserStack from a local system
148
+ }
149
+ },
150
+ 'browserstack.ios': {
151
+ extends: 'browserstack',
152
+ 'desiredCapabilities': {
153
+ browserName: null,
154
+ platformName: 'ios',
155
+ 'appium:options': {
156
+ automationName: 'XCUITest',
157
+ app: 'BStackSampleApp',
158
+ platformVersion: '16',
159
+ deviceName: 'iPhone 14'
160
+ },
161
+ appUploadUrl: 'https://www.browserstack.com/app-automate/sample-apps/ios/BStackSampleApp.ipa',
162
+ // appUploadPath: '/path/to/app_name.ipa'
163
+ }
164
+ ...
165
+ }
166
+ \`\`\``);
167
+ return combineInstructions(prerequisiteStep, envStep, installStep, configStep);
168
+ }
169
+ function getJestCommand(username, accessKey) {
170
+ const envStep = createStep("Set your BrowserStack credentials as environment variables:", `\`\`\`bash
171
+ export BROWSERSTACK_USERNAME=${username}
172
+ export BROWSERSTACK_ACCESS_KEY=${accessKey}
173
+ \`\`\``);
174
+ const installStep = createStep("Install Jest and BrowserStack SDK:", `\`\`\`bash
175
+ npm install --save-dev browserstack-node-sdk
176
+ \`\`\``);
177
+ return combineInstructions(envStep, installStep);
178
+ }
179
+ function getMochaCommand(username, accessKey) {
180
+ const envStep = createStep("Set your BrowserStack credentials as environment variables:", `\`\`\`bash
181
+ export BROWSERSTACK_USERNAME=${username}
182
+ export BROWSERSTACK_ACCESS_KEY=${accessKey}
183
+ \`\`\``);
184
+ const installStep = createStep("Install Mocha and BrowserStack SDK:", `\`\`\`bash
185
+ npm install --save-dev browserstack-node-sdk
186
+ \`\`\``);
187
+ return combineInstructions(envStep, installStep);
188
+ }
189
+ function getCucumberJSCommand(username, accessKey) {
190
+ return createStep("Set your BrowserStack credentials as environment variables:", `\`\`\`bash
191
+ export BROWSERSTACK_USERNAME=${username}
192
+ export BROWSERSTACK_ACCESS_KEY=${accessKey}
193
+ \`\`\``);
194
+ }
@@ -0,0 +1,3 @@
1
+ import { AppSDKSupportedTestingFramework } from "../index.js";
2
+ export declare function getPythonAppInstructions(testingFramework: AppSDKSupportedTestingFramework): string;
3
+ export declare function getPythonSDKCommand(framework: string, username: string, accessKey: string): string;
@@ -0,0 +1,76 @@
1
+ // Python instructions and commands for App SDK utilities
2
+ import { AppSDKSupportedTestingFrameworkEnum, createStep, createEnvStep, combineInstructions, PLATFORM_UTILS, } from "../index.js";
3
+ export function getPythonAppInstructions(testingFramework) {
4
+ switch (testingFramework) {
5
+ case AppSDKSupportedTestingFrameworkEnum.robot:
6
+ return createStep("Run your App Automate test suite with Robot Framework:", `\`\`\`bash
7
+ browserstack-sdk robot <path-to-test-files>
8
+ \`\`\``);
9
+ case AppSDKSupportedTestingFrameworkEnum.pytest:
10
+ return createStep("Run your App Automate test suite with Pytest:", `\`\`\`bash
11
+ browserstack-sdk pytest -s <file-name.py>
12
+ \`\`\``);
13
+ case AppSDKSupportedTestingFrameworkEnum.behave:
14
+ return createStep("Run your App Automate test suite with Behave:", `\`\`\`bash
15
+ browserstack-sdk behave <path-to-test-files>
16
+ \`\`\``);
17
+ case AppSDKSupportedTestingFrameworkEnum.lettuce:
18
+ return createStep("Run your test with Lettuce:", `\`\`\`bash
19
+ # Run using paver
20
+ paver run first_test
21
+ \`\`\``);
22
+ default:
23
+ return "";
24
+ }
25
+ }
26
+ export function getPythonSDKCommand(framework, username, accessKey) {
27
+ const { isWindows, getPlatformLabel } = PLATFORM_UTILS;
28
+ switch (framework) {
29
+ case "robot":
30
+ case "pytest":
31
+ case "behave":
32
+ return getPythonCommonSDKCommand(username, accessKey, isWindows, getPlatformLabel());
33
+ case "lettuce":
34
+ return getLettuceCommand(username, accessKey, isWindows, getPlatformLabel());
35
+ default:
36
+ return "";
37
+ }
38
+ }
39
+ function getPythonCommonSDKCommand(username, accessKey, isWindows, platformLabel) {
40
+ const envStep = createEnvStep(username, accessKey, isWindows, platformLabel, "Set your BrowserStack credentials as environment variables:");
41
+ const installStep = createStep("Install BrowserStack Python SDK:", `\`\`\`bash
42
+ python3 -m pip install browserstack-sdk
43
+ \`\`\``);
44
+ const setupStep = createStep("Set up BrowserStack SDK:", `\`\`\`bash
45
+ browserstack-sdk setup --username "${username}" --key "${accessKey}"
46
+ \`\`\``);
47
+ return combineInstructions(envStep, installStep, setupStep);
48
+ }
49
+ function getLettuceCommand(username, accessKey, isWindows, platformLabel) {
50
+ const envStep = createEnvStep(username, accessKey, isWindows, platformLabel, "Set your BrowserStack credentials as environment variables:");
51
+ const configStep = createStep("Configure Appium's desired capabilities in config.json:", `**Android example:**
52
+ \`\`\`json
53
+ {
54
+ "capabilities": {
55
+ "browserstack.user" : "${username}",
56
+ "browserstack.key" : "${accessKey}",
57
+ "project": "First Lettuce Android Project",
58
+ "build": "Lettuce Android",
59
+ "name": "first_test",
60
+ "browserstack.debug": true,
61
+ "app": "bs://<app-id>",
62
+ "device": "Google Pixel 3",
63
+ "os_version": "9.0"
64
+ }
65
+ }
66
+ \`\`\``);
67
+ const initStep = createStep("Initialize remote WebDriver in terrain.py:", `\`\`\`python
68
+ # Initialize the remote Webdriver using BrowserStack remote URL
69
+ # and desired capabilities defined above
70
+ context.browser = webdriver.Remote(
71
+ desired_capabilities=desired_capabilities,
72
+ command_executor="https://hub-cloud.browserstack.com/wd/hub"
73
+ )
74
+ \`\`\``);
75
+ return combineInstructions(envStep, configStep, initStep);
76
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getRubyAppInstructions(): string;
2
+ export declare function getRubySDKCommand(framework: string, username: string, accessKey: string): string;
@@ -0,0 +1,85 @@
1
+ // Ruby instructions and commands for App SDK utilities
2
+ import { createStep, combineInstructions, createEnvStep, PLATFORM_UTILS, } from "../index.js";
3
+ const username = "${process.env.BROWSERSTACK_USERNAME}";
4
+ const accessKey = "${process.env.BROWSERSTACK_ACCESS_KEY}";
5
+ export function getRubyAppInstructions() {
6
+ const configStep = createStep("Create/Update the config file (config.yml) as follows:", `\`\`\`yaml
7
+ server: "hub-cloud.browserstack.com"
8
+
9
+ common_caps:
10
+ "browserstack.user": "${username}"
11
+ "browserstack.key": "${accessKey}"
12
+ "project": "First Cucumber Android Project"
13
+ "build": "Cucumber Android"
14
+ "browserstack.debug": true
15
+
16
+ browser_caps:
17
+ -
18
+ "deviceName": "Google Pixel 3"
19
+ "os_version": "9.0"
20
+ "app": "<replace with the APK path from the upload step>"
21
+ "name": "first_test"
22
+ \`\`\``);
23
+ const envStep = createStep("Create/Update your support/env.rb file:", `\`\`\`ruby
24
+ require 'rubygems'
25
+ require 'appium_lib'
26
+
27
+ # Load configuration from config.yml
28
+ caps = Appium.load_appium_txt file: File.expand_path('./../config.yml', __FILE__)
29
+ username = "${username}"
30
+ password = "${accessKey}"
31
+
32
+ # Create desired capabilities
33
+ desired_caps = {
34
+ caps: caps,
35
+ appium_lib: {
36
+ server_url: "https://#{username}:#{password}@#{caps['server']}/wd/hub"
37
+ }
38
+ }
39
+
40
+ # Initialize Appium driver
41
+ begin
42
+ $appium_driver = Appium::Driver.new(desired_caps, true)
43
+ $driver = $appium_driver.start_driver
44
+ rescue Exception => e
45
+ puts e.message
46
+ Process.exit(0)
47
+ end
48
+
49
+ # Add cleanup hook
50
+ at_exit do
51
+ $driver.quit if $driver
52
+ end
53
+ \`\`\``);
54
+ const runStep = createStep("Run the test:", `\`\`\`bash
55
+ bundle exec cucumber
56
+ \`\`\``);
57
+ return combineInstructions(configStep, envStep, runStep);
58
+ }
59
+ export function getRubySDKCommand(framework, username, accessKey) {
60
+ const { isWindows, getPlatformLabel } = PLATFORM_UTILS;
61
+ const envStep = createEnvStep(username, accessKey, isWindows, getPlatformLabel(), "Set your BrowserStack credentials as environment variables:");
62
+ const installStep = createStep("Install required Ruby gems:", `\`\`\`bash
63
+ # Install Bundler if not already installed
64
+ gem install bundler
65
+
66
+ # Install Appium Ruby client library
67
+ gem install appium_lib
68
+
69
+ # Install Cucumber
70
+ gem install cucumber
71
+ \`\`\``);
72
+ const gemfileStep = createStep("Create a Gemfile for dependency management:", `\`\`\`ruby
73
+ # Gemfile
74
+ source 'https://rubygems.org'
75
+
76
+ gem 'appium_lib'
77
+ gem 'cucumber'
78
+ \`\`\`
79
+
80
+ Then run:
81
+ \`\`\`bash
82
+ bundle install
83
+ \`\`\``);
84
+ return combineInstructions(envStep, installStep, gemfileStep);
85
+ }
@@ -0,0 +1,58 @@
1
+ export declare enum AppSDKSupportedLanguageEnum {
2
+ java = "java",
3
+ nodejs = "nodejs",
4
+ python = "python",
5
+ ruby = "ruby",
6
+ csharp = "csharp"
7
+ }
8
+ export type AppSDKSupportedLanguage = keyof typeof AppSDKSupportedLanguageEnum;
9
+ export declare enum AppSDKSupportedFrameworkEnum {
10
+ appium = "appium"
11
+ }
12
+ export type AppSDKSupportedFramework = keyof typeof AppSDKSupportedFrameworkEnum;
13
+ export declare enum AppSDKSupportedTestingFrameworkEnum {
14
+ testng = "testng",
15
+ junit5 = "junit5",
16
+ junit4 = "junit4",
17
+ selenide = "selenide",
18
+ jbehave = "jbehave",
19
+ serenity = "serenity",
20
+ cucumberTestng = "cucumberTestng",
21
+ cucumberJunit4 = "cucumberJunit4",
22
+ cucumberJunit5 = "cucumberJunit5",
23
+ webdriverio = "webdriverio",
24
+ nightwatch = "nightwatch",
25
+ jest = "jest",
26
+ mocha = "mocha",
27
+ cucumberJs = "cucumberJs",
28
+ robot = "robot",
29
+ pytest = "pytest",
30
+ behave = "behave",
31
+ lettuce = "lettuce",
32
+ rspec = "rspec",
33
+ cucumberRuby = "cucumberRuby",
34
+ nunit = "nunit",
35
+ mstest = "mstest",
36
+ xunit = "xunit",
37
+ specflow = "specflow",
38
+ reqnroll = "reqnroll"
39
+ }
40
+ export type AppSDKSupportedTestingFramework = keyof typeof AppSDKSupportedTestingFrameworkEnum;
41
+ export declare enum AppSDKSupportedPlatformEnum {
42
+ android = "android",
43
+ ios = "ios"
44
+ }
45
+ export type AppSDKSupportedPlatform = keyof typeof AppSDKSupportedPlatformEnum;
46
+ export interface AppSDKInstruction {
47
+ content: string;
48
+ type: "config" | "run" | "setup";
49
+ }
50
+ export declare const SUPPORTED_CONFIGURATIONS: {
51
+ appium: {
52
+ ruby: string[];
53
+ java: string[];
54
+ csharp: never[];
55
+ python: string[];
56
+ nodejs: string[];
57
+ };
58
+ };
@@ -0,0 +1,63 @@
1
+ // Shared types for App SDK utilities
2
+ export var AppSDKSupportedLanguageEnum;
3
+ (function (AppSDKSupportedLanguageEnum) {
4
+ AppSDKSupportedLanguageEnum["java"] = "java";
5
+ AppSDKSupportedLanguageEnum["nodejs"] = "nodejs";
6
+ AppSDKSupportedLanguageEnum["python"] = "python";
7
+ AppSDKSupportedLanguageEnum["ruby"] = "ruby";
8
+ AppSDKSupportedLanguageEnum["csharp"] = "csharp";
9
+ })(AppSDKSupportedLanguageEnum || (AppSDKSupportedLanguageEnum = {}));
10
+ export var AppSDKSupportedFrameworkEnum;
11
+ (function (AppSDKSupportedFrameworkEnum) {
12
+ AppSDKSupportedFrameworkEnum["appium"] = "appium";
13
+ })(AppSDKSupportedFrameworkEnum || (AppSDKSupportedFrameworkEnum = {}));
14
+ export var AppSDKSupportedTestingFrameworkEnum;
15
+ (function (AppSDKSupportedTestingFrameworkEnum) {
16
+ AppSDKSupportedTestingFrameworkEnum["testng"] = "testng";
17
+ AppSDKSupportedTestingFrameworkEnum["junit5"] = "junit5";
18
+ AppSDKSupportedTestingFrameworkEnum["junit4"] = "junit4";
19
+ AppSDKSupportedTestingFrameworkEnum["selenide"] = "selenide";
20
+ AppSDKSupportedTestingFrameworkEnum["jbehave"] = "jbehave";
21
+ AppSDKSupportedTestingFrameworkEnum["serenity"] = "serenity";
22
+ AppSDKSupportedTestingFrameworkEnum["cucumberTestng"] = "cucumberTestng";
23
+ AppSDKSupportedTestingFrameworkEnum["cucumberJunit4"] = "cucumberJunit4";
24
+ AppSDKSupportedTestingFrameworkEnum["cucumberJunit5"] = "cucumberJunit5";
25
+ AppSDKSupportedTestingFrameworkEnum["webdriverio"] = "webdriverio";
26
+ AppSDKSupportedTestingFrameworkEnum["nightwatch"] = "nightwatch";
27
+ AppSDKSupportedTestingFrameworkEnum["jest"] = "jest";
28
+ AppSDKSupportedTestingFrameworkEnum["mocha"] = "mocha";
29
+ AppSDKSupportedTestingFrameworkEnum["cucumberJs"] = "cucumberJs";
30
+ AppSDKSupportedTestingFrameworkEnum["robot"] = "robot";
31
+ AppSDKSupportedTestingFrameworkEnum["pytest"] = "pytest";
32
+ AppSDKSupportedTestingFrameworkEnum["behave"] = "behave";
33
+ AppSDKSupportedTestingFrameworkEnum["lettuce"] = "lettuce";
34
+ AppSDKSupportedTestingFrameworkEnum["rspec"] = "rspec";
35
+ AppSDKSupportedTestingFrameworkEnum["cucumberRuby"] = "cucumberRuby";
36
+ AppSDKSupportedTestingFrameworkEnum["nunit"] = "nunit";
37
+ AppSDKSupportedTestingFrameworkEnum["mstest"] = "mstest";
38
+ AppSDKSupportedTestingFrameworkEnum["xunit"] = "xunit";
39
+ AppSDKSupportedTestingFrameworkEnum["specflow"] = "specflow";
40
+ AppSDKSupportedTestingFrameworkEnum["reqnroll"] = "reqnroll";
41
+ })(AppSDKSupportedTestingFrameworkEnum || (AppSDKSupportedTestingFrameworkEnum = {}));
42
+ export var AppSDKSupportedPlatformEnum;
43
+ (function (AppSDKSupportedPlatformEnum) {
44
+ AppSDKSupportedPlatformEnum["android"] = "android";
45
+ AppSDKSupportedPlatformEnum["ios"] = "ios";
46
+ })(AppSDKSupportedPlatformEnum || (AppSDKSupportedPlatformEnum = {}));
47
+ export const SUPPORTED_CONFIGURATIONS = {
48
+ appium: {
49
+ ruby: ["cucumberRuby"],
50
+ java: [
51
+ "testng",
52
+ "cucumber",
53
+ "junit4",
54
+ "junit5",
55
+ "jbehave",
56
+ "selenide",
57
+ "serenity",
58
+ ],
59
+ csharp: [],
60
+ python: ["pytest", "robot", "behave", "lettuce"],
61
+ nodejs: ["jest", "mocha", "cucumberJs", "webdriverio", "nightwatch"],
62
+ },
63
+ };
@@ -0,0 +1,17 @@
1
+ import { AppSDKSupportedTestingFramework } from "./index.js";
2
+ import { SUPPORTED_CONFIGURATIONS } from "./types.js";
3
+ export declare function isBrowserStackAppUrl(appPath: string): boolean;
4
+ export declare function generateBuildName(baseName?: string): string;
5
+ export declare function createError(message: string, context?: Record<string, any>): Error;
6
+ export declare const PLATFORM_UTILS: {
7
+ isWindows: boolean;
8
+ isMac: boolean;
9
+ isAppleSilicon: boolean;
10
+ getPlatformLabel: () => "Windows" | "macOS";
11
+ };
12
+ export declare function getAppUploadInstruction(appPath: string, username: string, accessKey: string, detectedTestingFramework: AppSDKSupportedTestingFramework): Promise<string>;
13
+ export type SupportedFramework = keyof typeof SUPPORTED_CONFIGURATIONS;
14
+ type SupportedLanguage = keyof (typeof SUPPORTED_CONFIGURATIONS)[SupportedFramework];
15
+ type SupportedTestingFramework = string;
16
+ export declare function validateSupportforAppAutomate(framework: SupportedFramework, language: SupportedLanguage, testingFramework: SupportedTestingFramework): void;
17
+ export {};
@@ -0,0 +1,64 @@
1
+ import { uploadApp } from "../native-execution/appautomate.js";
2
+ import { AppSDKSupportedTestingFrameworkEnum, createStep, } from "./index.js";
3
+ import { SUPPORTED_CONFIGURATIONS } from "./types.js";
4
+ export function isBrowserStackAppUrl(appPath) {
5
+ return appPath.startsWith("bs://");
6
+ }
7
+ export function generateBuildName(baseName = "app-automate") {
8
+ const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, "");
9
+ return `${baseName}-${timestamp}`;
10
+ }
11
+ export function createError(message, context) {
12
+ const error = new Error(message);
13
+ if (context) {
14
+ error.context = context;
15
+ }
16
+ return error;
17
+ }
18
+ // Platform utilities for cross-platform support
19
+ export const PLATFORM_UTILS = {
20
+ isWindows: process.platform === "win32",
21
+ isMac: process.platform === "darwin",
22
+ isAppleSilicon: process.platform === "darwin" && process.arch === "arm64",
23
+ getPlatformLabel: () => {
24
+ switch (process.platform) {
25
+ case "win32":
26
+ return "Windows";
27
+ case "darwin":
28
+ return "macOS";
29
+ default:
30
+ return "macOS";
31
+ }
32
+ },
33
+ };
34
+ export async function getAppUploadInstruction(appPath, username, accessKey, detectedTestingFramework) {
35
+ if (detectedTestingFramework ===
36
+ AppSDKSupportedTestingFrameworkEnum.nightwatch ||
37
+ detectedTestingFramework ===
38
+ AppSDKSupportedTestingFrameworkEnum.webdriverio ||
39
+ detectedTestingFramework ===
40
+ AppSDKSupportedTestingFrameworkEnum.cucumberRuby) {
41
+ const app_url = await uploadApp(appPath, username, accessKey);
42
+ if (app_url) {
43
+ return createStep("Updating app_path with app_url", `Replace the value of app_path in your configuration with: ${app_url}`);
44
+ }
45
+ }
46
+ return "";
47
+ }
48
+ export function validateSupportforAppAutomate(framework, language, testingFramework) {
49
+ const frameworks = Object.keys(SUPPORTED_CONFIGURATIONS);
50
+ if (!SUPPORTED_CONFIGURATIONS[framework]) {
51
+ throw new Error(`Unsupported framework '${framework}'. Supported frameworks: ${frameworks.join(", ")}`);
52
+ }
53
+ const languages = Object.keys(SUPPORTED_CONFIGURATIONS[framework]);
54
+ if (!SUPPORTED_CONFIGURATIONS[framework][language]) {
55
+ throw new Error(`Unsupported language '${language}' for framework '${framework}'. Supported languages: ${languages.join(", ")}`);
56
+ }
57
+ const testingFrameworks = SUPPORTED_CONFIGURATIONS[framework][language];
58
+ if (testingFrameworks.length === 0) {
59
+ throw new Error(`No testing frameworks are supported for language '${language}' and framework '${framework}'.`);
60
+ }
61
+ if (!testingFrameworks.includes(testingFramework)) {
62
+ throw new Error(`Unsupported testing framework '${testingFramework}' for language '${language}' and framework '${framework}'. Supported testing frameworks: ${testingFrameworks.join(", ")}`);
63
+ }
64
+ }
@@ -1,4 +1,4 @@
1
- import { BrowserStackConfig } from "../../lib/types.js";
1
+ import { BrowserStackConfig } from "../../../lib/types.js";
2
2
  interface Device {
3
3
  device: string;
4
4
  display_name: string;
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import FormData from "form-data";
3
- import { apiClient } from "../../lib/apiClient.js";
4
- import { customFuzzySearch } from "../../lib/fuzzy.js";
3
+ import { apiClient } from "../../../lib/apiClient.js";
4
+ import { customFuzzySearch } from "../../../lib/fuzzy.js";
5
5
  /**
6
6
  * Finds devices that exactly match the provided display name.
7
7
  * Uses fuzzy search first, and then filters for exact case-insensitive match.
@@ -0,0 +1,11 @@
1
+ import { z } from "zod";
2
+ import { AppTestPlatform } from "./types.js";
3
+ import { AppSDKSupportedPlatformEnum } from "../appium-sdk/types.js";
4
+ export declare const RUN_APP_AUTOMATE_DESCRIPTION = "Execute pre-built native mobile test suites (Espresso for Android, XCUITest for iOS) by direct upload to BrowserStack. ONLY for compiled .apk/.ipa test files. This is NOT for SDK integration or Appium tests. For Appium-based testing with SDK setup, use 'setupBrowserStackAppAutomateTests' instead.";
5
+ export declare const RUN_APP_AUTOMATE_SCHEMA: {
6
+ appPath: z.ZodString;
7
+ testSuitePath: z.ZodString;
8
+ devices: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodTuple<[z.ZodLiteral<AppSDKSupportedPlatformEnum.android>, z.ZodString, z.ZodString], null>, z.ZodTuple<[z.ZodLiteral<AppSDKSupportedPlatformEnum.ios>, z.ZodString, z.ZodString], null>]>, "many">>;
9
+ project: z.ZodDefault<z.ZodOptional<z.ZodString>>;
10
+ detectedAutomationFramework: z.ZodNativeEnum<typeof AppTestPlatform>;
11
+ };
@@ -0,0 +1,58 @@
1
+ import { z } from "zod";
2
+ import { AppTestPlatform } from "./types.js";
3
+ import { AppSDKSupportedPlatformEnum } from "../appium-sdk/types.js";
4
+ export const RUN_APP_AUTOMATE_DESCRIPTION = `Execute pre-built native mobile test suites (Espresso for Android, XCUITest for iOS) by direct upload to BrowserStack. ONLY for compiled .apk/.ipa test files. This is NOT for SDK integration or Appium tests. For Appium-based testing with SDK setup, use 'setupBrowserStackAppAutomateTests' instead.`;
5
+ export const RUN_APP_AUTOMATE_SCHEMA = {
6
+ appPath: z
7
+ .string()
8
+ .describe("Path to your application file:\n" +
9
+ "If in development IDE directory:\n" +
10
+ "• For Android: 'gradle assembleDebug'\n" +
11
+ "• For iOS:\n" +
12
+ " xcodebuild clean -scheme YOUR_SCHEME && \\\n" +
13
+ " xcodebuild archive -scheme YOUR_SCHEME -configuration Release -archivePath build/app.xcarchive && \\\n" +
14
+ " xcodebuild -exportArchive -archivePath build/app.xcarchive -exportPath build/ipa -exportOptionsPlist exportOptions.plist\n\n" +
15
+ "If in other directory, provide existing app path"),
16
+ testSuitePath: z
17
+ .string()
18
+ .describe("Path to your test suite file:\n" +
19
+ "If in development IDE directory:\n" +
20
+ "• For Android: 'gradle assembleAndroidTest'\n" +
21
+ "• For iOS:\n" +
22
+ " xcodebuild test-without-building -scheme YOUR_SCHEME -destination 'generic/platform=iOS' && \\\n" +
23
+ " cd ~/Library/Developer/Xcode/DerivedData/*/Build/Products/Debug-iphonesimulator/ && \\\n" +
24
+ " zip -r Tests.zip *.xctestrun *-Runner.app\n\n" +
25
+ "If in other directory, provide existing test file path"),
26
+ devices: z
27
+ .array(z.union([
28
+ // Android: [android, deviceName, osVersion]
29
+ z.tuple([
30
+ z
31
+ .literal(AppSDKSupportedPlatformEnum.android)
32
+ .describe("Platform identifier: 'android'"),
33
+ z
34
+ .string()
35
+ .describe("Device name, e.g. 'Samsung Galaxy S24', 'Google Pixel 8'"),
36
+ z.string().describe("Android version, e.g. '14', '16', 'latest'"),
37
+ ]),
38
+ // iOS: [ios, deviceName, osVersion]
39
+ z.tuple([
40
+ z
41
+ .literal(AppSDKSupportedPlatformEnum.ios)
42
+ .describe("Platform identifier: 'ios'"),
43
+ z.string().describe("Device name, e.g. 'iPhone 15', 'iPhone 14 Pro'"),
44
+ z.string().describe("iOS version, e.g. '17', '16', 'latest'"),
45
+ ]),
46
+ ]))
47
+ .max(3)
48
+ .default([])
49
+ .describe("Tuples describing target mobile devices. Add device only when user asks explicitly for it. Defaults to [] . Example: [['android', 'Samsung Galaxy S24', '14'], ['ios', 'iPhone 15', '17']]"),
50
+ project: z
51
+ .string()
52
+ .optional()
53
+ .default("BStack-AppAutomate-Suite")
54
+ .describe("Project name for organizing test runs on BrowserStack."),
55
+ detectedAutomationFramework: z
56
+ .nativeEnum(AppTestPlatform)
57
+ .describe("The automation framework used in the project, such as 'espresso' (Android) or 'xcuitest' (iOS)."),
58
+ };