@wdio/browserstack-service 8.45.0 → 8.47.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.
Files changed (118) hide show
  1. package/README.md +44 -11
  2. package/build/Percy/Percy-Handler.d.ts.map +1 -1
  3. package/build/Percy/Percy-Handler.js +4 -1
  4. package/build/Percy/Percy.d.ts.map +1 -1
  5. package/build/Percy/Percy.js +2 -1
  6. package/build/accessibility-handler.d.ts +9 -3
  7. package/build/accessibility-handler.d.ts.map +1 -1
  8. package/build/accessibility-handler.js +52 -11
  9. package/build/cleanup.js +3 -3
  10. package/build/cli/apiUtils.d.ts +14 -0
  11. package/build/cli/apiUtils.d.ts.map +1 -0
  12. package/build/cli/apiUtils.js +24 -0
  13. package/build/cli/cliLogger.d.ts +16 -0
  14. package/build/cli/cliLogger.d.ts.map +1 -0
  15. package/build/cli/cliLogger.js +70 -0
  16. package/build/cli/cliUtils.d.ts +46 -0
  17. package/build/cli/cliUtils.d.ts.map +1 -0
  18. package/build/cli/cliUtils.js +430 -0
  19. package/build/cli/eventDispatcher.d.ts +28 -0
  20. package/build/cli/eventDispatcher.d.ts.map +1 -0
  21. package/build/cli/eventDispatcher.js +48 -0
  22. package/build/cli/frameworks/automationFramework.d.ts +89 -0
  23. package/build/cli/frameworks/automationFramework.d.ts.map +1 -0
  24. package/build/cli/frameworks/automationFramework.js +131 -0
  25. package/build/cli/frameworks/constants/automationFrameworkConstants.d.ts +18 -0
  26. package/build/cli/frameworks/constants/automationFrameworkConstants.d.ts.map +1 -0
  27. package/build/cli/frameworks/constants/automationFrameworkConstants.js +17 -0
  28. package/build/cli/frameworks/constants/testFrameworkConstants.d.ts +43 -0
  29. package/build/cli/frameworks/constants/testFrameworkConstants.d.ts.map +1 -0
  30. package/build/cli/frameworks/constants/testFrameworkConstants.js +42 -0
  31. package/build/cli/frameworks/testFramework.d.ts +89 -0
  32. package/build/cli/frameworks/testFramework.d.ts.map +1 -0
  33. package/build/cli/frameworks/testFramework.js +125 -0
  34. package/build/cli/frameworks/wdioAutomationFramework.d.ts +28 -0
  35. package/build/cli/frameworks/wdioAutomationFramework.d.ts.map +1 -0
  36. package/build/cli/frameworks/wdioAutomationFramework.js +66 -0
  37. package/build/cli/frameworks/wdioMochaTestFramework.d.ts +82 -0
  38. package/build/cli/frameworks/wdioMochaTestFramework.d.ts.map +1 -0
  39. package/build/cli/frameworks/wdioMochaTestFramework.js +319 -0
  40. package/build/cli/grpcClient.d.ts +70 -0
  41. package/build/cli/grpcClient.d.ts.map +1 -0
  42. package/build/cli/grpcClient.js +419 -0
  43. package/build/cli/index.d.ts +148 -0
  44. package/build/cli/index.d.ts.map +1 -0
  45. package/build/cli/index.js +415 -0
  46. package/build/cli/instances/automationFrameworkInstance.d.ts +33 -0
  47. package/build/cli/instances/automationFrameworkInstance.d.ts.map +1 -0
  48. package/build/cli/instances/automationFrameworkInstance.js +44 -0
  49. package/build/cli/instances/testFrameworkInstance.d.ts +62 -0
  50. package/build/cli/instances/testFrameworkInstance.d.ts.map +1 -0
  51. package/build/cli/instances/testFrameworkInstance.js +96 -0
  52. package/build/cli/instances/trackedContext.d.ts +32 -0
  53. package/build/cli/instances/trackedContext.d.ts.map +1 -0
  54. package/build/cli/instances/trackedContext.js +47 -0
  55. package/build/cli/instances/trackedInstance.d.ts +40 -0
  56. package/build/cli/instances/trackedInstance.d.ts.map +1 -0
  57. package/build/cli/instances/trackedInstance.js +63 -0
  58. package/build/cli/modules/accessibilityModule.d.ts +33 -0
  59. package/build/cli/modules/accessibilityModule.d.ts.map +1 -0
  60. package/build/cli/modules/accessibilityModule.js +347 -0
  61. package/build/cli/modules/automateModule.d.ts +26 -0
  62. package/build/cli/modules/automateModule.d.ts.map +1 -0
  63. package/build/cli/modules/automateModule.js +222 -0
  64. package/build/cli/modules/baseModule.d.ts +33 -0
  65. package/build/cli/modules/baseModule.d.ts.map +1 -0
  66. package/build/cli/modules/baseModule.js +51 -0
  67. package/build/cli/modules/observabilityModule.d.ts +22 -0
  68. package/build/cli/modules/observabilityModule.d.ts.map +1 -0
  69. package/build/cli/modules/observabilityModule.js +45 -0
  70. package/build/cli/modules/percyModule.d.ts +19 -0
  71. package/build/cli/modules/percyModule.d.ts.map +1 -0
  72. package/build/cli/modules/percyModule.js +77 -0
  73. package/build/cli/modules/testHubModule.d.ts +30 -0
  74. package/build/cli/modules/testHubModule.d.ts.map +1 -0
  75. package/build/cli/modules/testHubModule.js +232 -0
  76. package/build/cli/modules/webdriverIOModule.d.ts +29 -0
  77. package/build/cli/modules/webdriverIOModule.d.ts.map +1 -0
  78. package/build/cli/modules/webdriverIOModule.js +128 -0
  79. package/build/cli/states/automationFrameworkState.d.ts +65 -0
  80. package/build/cli/states/automationFrameworkState.d.ts.map +1 -0
  81. package/build/cli/states/automationFrameworkState.js +61 -0
  82. package/build/cli/states/hookState.d.ts +45 -0
  83. package/build/cli/states/hookState.d.ts.map +1 -0
  84. package/build/cli/states/hookState.js +43 -0
  85. package/build/cli/states/testFrameworkState.d.ts +125 -0
  86. package/build/cli/states/testFrameworkState.d.ts.map +1 -0
  87. package/build/cli/states/testFrameworkState.js +115 -0
  88. package/build/constants.d.ts +13 -0
  89. package/build/constants.d.ts.map +1 -1
  90. package/build/constants.js +21 -1
  91. package/build/crash-reporter.d.ts.map +1 -1
  92. package/build/crash-reporter.js +4 -3
  93. package/build/exitHandler.d.ts.map +1 -1
  94. package/build/exitHandler.js +47 -5
  95. package/build/insights-handler.d.ts +8 -0
  96. package/build/insights-handler.d.ts.map +1 -1
  97. package/build/insights-handler.js +57 -1
  98. package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -1
  99. package/build/instrumentation/funnelInstrumentation.js +5 -4
  100. package/build/instrumentation/performance/constants.d.ts +8 -0
  101. package/build/instrumentation/performance/constants.d.ts.map +1 -1
  102. package/build/instrumentation/performance/constants.js +9 -1
  103. package/build/instrumentation/performance/performance-tester.d.ts.map +1 -1
  104. package/build/instrumentation/performance/performance-tester.js +5 -3
  105. package/build/launcher.d.ts.map +1 -1
  106. package/build/launcher.js +94 -51
  107. package/build/request-handler.js +1 -1
  108. package/build/service.d.ts +3 -1
  109. package/build/service.d.ts.map +1 -1
  110. package/build/service.js +244 -69
  111. package/build/testOps/requestUtils.js +3 -2
  112. package/build/types.d.ts +36 -3
  113. package/build/types.d.ts.map +1 -1
  114. package/build/util.d.ts +13 -1
  115. package/build/util.d.ts.map +1 -1
  116. package/build/util.js +173 -27
  117. package/package.json +7 -4
  118. package/tsconfig.prod.tsbuildinfo +1 -1
@@ -0,0 +1,415 @@
1
+ import util from 'node:util';
2
+ import { spawn } from 'node:child_process';
3
+ import { CLIUtils } from './cliUtils.js';
4
+ import PerformanceTester from '../instrumentation/performance/performance-tester.js';
5
+ import { EVENTS as PerformanceEvents } from '../instrumentation/performance/constants.js';
6
+ import { BStackLogger } from './cliLogger.js';
7
+ import { GrpcClient } from './grpcClient.js';
8
+ import AutomateModule from './modules/automateModule.js';
9
+ import TestHubModule from './modules/testHubModule.js';
10
+ import { BROWSERSTACK_ACCESSIBILITY, BROWSERSTACK_OBSERVABILITY, BROWSERSTACK_TESTHUB_JWT, BROWSERSTACK_TESTHUB_UUID, CLI_STOP_TIMEOUT, TESTOPS_BUILD_COMPLETED_ENV, TESTOPS_SCREENSHOT_ENV } from '../constants.js';
11
+ import TestOpsConfig from '../testOps/testOpsConfig.js';
12
+ import WdioMochaTestFramework from './frameworks/wdioMochaTestFramework.js';
13
+ import WdioAutomationFramework from './frameworks/wdioAutomationFramework.js';
14
+ import WebdriverIOModule from './modules/webdriverIOModule.js';
15
+ import AccessibilityModule from './modules/accessibilityModule.js';
16
+ import { isTurboScale, processAccessibilityResponse, shouldAddServiceVersion } from '../util.js';
17
+ import ObservabilityModule from './modules/observabilityModule.js';
18
+ import PercyModule from './modules/percyModule.js';
19
+ import APIUtils from './apiUtils.js';
20
+ /**
21
+ * BrowserstackCLI - Singleton class for managing CLI operations
22
+ *
23
+ * This class uses the singleton pattern to ensure only one instance exists
24
+ * throughout the application lifecycle.
25
+ */
26
+ export class BrowserstackCLI {
27
+ static #instance = null;
28
+ static enabled = false;
29
+ initialized;
30
+ config;
31
+ wdioConfig;
32
+ cliArgs;
33
+ browserstackConfig;
34
+ process = null;
35
+ isMainConnected = false;
36
+ isChildConnected = false;
37
+ binSessionId = null;
38
+ modules = {};
39
+ testFramework = null;
40
+ cliParams = null;
41
+ automationFramework = null;
42
+ SDK_CLI_BIN_PATH = null;
43
+ logger = BStackLogger;
44
+ options;
45
+ constructor() {
46
+ this.initialized = false;
47
+ this.config = {};
48
+ this.cliArgs = {};
49
+ this.browserstackConfig = {};
50
+ this.wdioConfig = '';
51
+ this.options = {};
52
+ }
53
+ /**
54
+ * Get the singleton instance of BrowserstackCLI
55
+ * @returns {BrowserstackCLI} The singleton instance
56
+ */
57
+ static getInstance() {
58
+ if (!BrowserstackCLI.#instance) {
59
+ BrowserstackCLI.#instance = new BrowserstackCLI();
60
+ }
61
+ return BrowserstackCLI.#instance;
62
+ }
63
+ /**
64
+ * Bootstrap the CLI
65
+ * Initializes and starts the CLI based on environment settings
66
+ * @returns {Promise<void>}
67
+ */
68
+ async bootstrap(options, config, wdioConfig = '') {
69
+ PerformanceTester.start(PerformanceEvents.SDK_CLI_ON_BOOTSTRAP);
70
+ BrowserstackCLI.enabled = true;
71
+ this.options = options;
72
+ if (config) {
73
+ BrowserstackCLI.getInstance().setBrowserstackConfig(config);
74
+ }
75
+ try {
76
+ const binSessionId = process.env.BROWSERSTACK_CLI_BIN_SESSION_ID || null;
77
+ if (binSessionId) {
78
+ await this.startChild(binSessionId);
79
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_ON_BOOTSTRAP);
80
+ return;
81
+ }
82
+ this.wdioConfig = wdioConfig;
83
+ await this.startMain();
84
+ }
85
+ catch (error) {
86
+ const errorMessage = error instanceof Error ? error.stack || error.message : String(error);
87
+ this.logger.error(`bootstrap: failed to bootstrap ${errorMessage}`);
88
+ await this.stop();
89
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_ON_BOOTSTRAP, false, util.format(error));
90
+ }
91
+ }
92
+ /**
93
+ * Start as a main process
94
+ * @returns {Promise<void>}
95
+ */
96
+ async startMain() {
97
+ this.logger.info('startMain: Starting main process');
98
+ await this.start();
99
+ this.logger.debug('startMain: main-process started');
100
+ const response = await GrpcClient.getInstance().startBinSession(this.wdioConfig);
101
+ BStackLogger.debug(`start: startBinSession response=${JSON.stringify(response)}`);
102
+ this.loadModules(response);
103
+ this.isMainConnected = true;
104
+ }
105
+ /**
106
+ * Load modules
107
+ * @param {Object} startBinResponse - StartBinSession response
108
+ */
109
+ loadModules(startBinResponse) {
110
+ // Defer imports to avoid circular dependencies
111
+ this.binSessionId = startBinResponse.binSessionId;
112
+ this.logger.info(`loadModules: binSessionId=${this.binSessionId}`);
113
+ this.setConfig(startBinResponse);
114
+ APIUtils.updateURLSForGRR(this.config.apis);
115
+ this.setupTestFramework();
116
+ this.setupAutomationFramework();
117
+ this.modules[WebdriverIOModule.MODULE_NAME] = new WebdriverIOModule();
118
+ this.modules[AutomateModule.MODULE_NAME] = new AutomateModule(this.browserstackConfig);
119
+ if (startBinResponse.testhub) {
120
+ process.env[TESTOPS_BUILD_COMPLETED_ENV] = 'true';
121
+ if (startBinResponse.testhub.jwt) {
122
+ process.env[BROWSERSTACK_TESTHUB_JWT] = startBinResponse.testhub.jwt;
123
+ }
124
+ if (startBinResponse.testhub.buildHashedId) {
125
+ process.env[BROWSERSTACK_TESTHUB_UUID] = startBinResponse.testhub.buildHashedId;
126
+ TestOpsConfig.getInstance().buildHashedId = startBinResponse.testhub.buildHashedId;
127
+ }
128
+ if (startBinResponse.observability?.success) {
129
+ process.env[BROWSERSTACK_OBSERVABILITY] = 'true';
130
+ if (startBinResponse.observability.options?.allowScreenshots) {
131
+ process.env[TESTOPS_SCREENSHOT_ENV] = startBinResponse.observability.options.allowScreenshots.toString();
132
+ }
133
+ this.modules[ObservabilityModule.MODULE_NAME] = new ObservabilityModule(startBinResponse.observability);
134
+ }
135
+ this.modules[TestHubModule.MODULE_NAME] = new TestHubModule(startBinResponse.testhub);
136
+ if (startBinResponse.accessibility?.success) {
137
+ process.env[BROWSERSTACK_ACCESSIBILITY] = 'true';
138
+ const options = this.options;
139
+ const isNonBstackA11y = isTurboScale(options) || !shouldAddServiceVersion(this.browserstackConfig, options.testObservability);
140
+ processAccessibilityResponse(startBinResponse, this.options);
141
+ this.modules[AccessibilityModule.MODULE_NAME] = new AccessibilityModule(startBinResponse.accessibility, isNonBstackA11y);
142
+ }
143
+ }
144
+ if (startBinResponse.percy?.success) {
145
+ this.modules[PercyModule.MODULE_NAME] = new PercyModule(startBinResponse.percy);
146
+ }
147
+ this.configureModules();
148
+ }
149
+ /**
150
+ * Configure modules
151
+ * @returns {Promise<void>}
152
+ */
153
+ async configureModules() {
154
+ this.logger.debug('configureModules: Configuring modules');
155
+ for (const moduleName in this.modules) {
156
+ const module = this.modules[moduleName];
157
+ const platformIndex = process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0;
158
+ this.logger.debug(`configureModules: Configuring module=${moduleName} platformIndex=${platformIndex}`);
159
+ await module.configure(this.binSessionId, platformIndex, GrpcClient.getInstance().client, this.config);
160
+ }
161
+ }
162
+ /**
163
+ * Start the CLI process and return a promise that resolves when it's ready
164
+ * @returns {Promise<void>}
165
+ * @throws {Error} If the process fails to start
166
+ */
167
+ async start() {
168
+ PerformanceTester.start(PerformanceEvents.SDK_CLI_START);
169
+ if (CLIUtils.isDevelopmentEnv()) {
170
+ this.loadCliParams(CLIUtils.getCLIParamsForDevEnv());
171
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_START);
172
+ return Promise.resolve();
173
+ }
174
+ // Skip if process is already running
175
+ if (this.process && this.process.connected) {
176
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_START);
177
+ return Promise.resolve();
178
+ }
179
+ const SDK_CLI_BIN_PATH = await this.getCliBinPath();
180
+ const cmd = [SDK_CLI_BIN_PATH, 'sdk'];
181
+ this.logger.debug(`spawning command='${cmd}'`);
182
+ // Create a child process
183
+ this.process = spawn(cmd[0], cmd.slice(1), {
184
+ env: process.env
185
+ });
186
+ // Check if process started successfully
187
+ if (!this.process.pid) {
188
+ throw new Error('failed to start CLI, no PID found');
189
+ }
190
+ // Return a promise that resolves when CLI is ready
191
+ return new Promise((resolve, reject) => {
192
+ const cliOut = {};
193
+ this.process.stdout.on('data', (data) => {
194
+ const lines = data.toString().trim().split('\n');
195
+ for (const line of lines) {
196
+ // Parse key=value pairs
197
+ if (/^(id|listen|port)=.*$/.test(line)) {
198
+ const [key, value] = line.split('=', 2);
199
+ if (value !== undefined) {
200
+ cliOut[key] = value;
201
+ }
202
+ }
203
+ // Check for ready message
204
+ if (line.toLowerCase().includes('ready')) {
205
+ this.loadCliParams(cliOut);
206
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_START);
207
+ resolve();
208
+ return;
209
+ }
210
+ }
211
+ });
212
+ this.process.stderr.on('data', (data) => {
213
+ this.logger.error(`CLI stderr: ${data.toString().trim()}`);
214
+ });
215
+ this.process.on('error', (err) => {
216
+ cliOut.error = `Error in start: ${err.message}`;
217
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_START, false, err);
218
+ reject(new Error(`Failed to start CLI process: ${err.message}`));
219
+ });
220
+ this.process.on('close', (code) => {
221
+ if (code !== 0) {
222
+ reject(new Error(`CLI process exited with code ${code}`));
223
+ }
224
+ });
225
+ });
226
+ }
227
+ /**
228
+ * Stop the CLI
229
+ * @returns {Promise<void>}
230
+ */
231
+ async stop() {
232
+ PerformanceTester.start(PerformanceEvents.SDK_CLI_ON_STOP);
233
+ this.logger.debug('stop: CLI stop triggered');
234
+ try {
235
+ if (this.isMainConnected) {
236
+ const response = await GrpcClient.getInstance().stopBinSession();
237
+ BStackLogger.debug(`stop: stopBinSession response=${JSON.stringify(response)}`);
238
+ }
239
+ await this.unConfigureModules();
240
+ if (this.process && this.process.pid) {
241
+ this.logger.debug('stop: shutting down CLI');
242
+ this.process.kill();
243
+ // Wait for process to fully exit
244
+ await new Promise((resolve) => {
245
+ let exited = false;
246
+ // Listen for exit event
247
+ this.process.on('exit', () => {
248
+ this.logger.debug('stop: CLI process exited');
249
+ exited = true;
250
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_ON_STOP);
251
+ resolve();
252
+ });
253
+ // Set a timeout in case process doesn't exit cleanly
254
+ setTimeout(() => {
255
+ if (!exited) {
256
+ this.logger.warn('stop: process exit timeout, forcing kill');
257
+ this.process.kill('SIGKILL');
258
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_ON_STOP);
259
+ resolve();
260
+ }
261
+ }, CLI_STOP_TIMEOUT);
262
+ });
263
+ }
264
+ }
265
+ catch (error) {
266
+ PerformanceTester.end(PerformanceEvents.SDK_CLI_ON_STOP, false, util.format(error));
267
+ const errorMessage = error instanceof Error ? error.stack || error.message : String(error);
268
+ this.logger.error(`stop: error in stop session exception=${errorMessage}`);
269
+ }
270
+ }
271
+ /**
272
+ * Unconfigure modules
273
+ * @returns {Promise<void>}
274
+ * @private
275
+ */
276
+ async unConfigureModules() {
277
+ this.logger.debug('Unconfiguring modules');
278
+ for (const moduleName in this.modules) {
279
+ const module = this.modules[moduleName];
280
+ const platformIndex = process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0;
281
+ await module.configure(null, platformIndex, GrpcClient.getInstance().client);
282
+ }
283
+ }
284
+ /**
285
+ * Load CLI parameters from the output
286
+ * @param {Object} params - Parameters parsed from CLI output
287
+ * @private
288
+ */
289
+ loadCliParams(params) {
290
+ this.logger.debug(`CLI params loaded: ${JSON.stringify(params)}`);
291
+ this.cliParams = params;
292
+ GrpcClient.getInstance().init(params);
293
+ }
294
+ /**
295
+ * Start as a child process with the specified binSessionId
296
+ * @param {string} binSessionId - session ID to connect to the CLI process
297
+ * @returns {Promise<void>}
298
+ */
299
+ async startChild(binSessionId) {
300
+ PerformanceTester.start(PerformanceEvents.SDK_CONNECT_BIN_SESSION);
301
+ try {
302
+ this.logger.info(`Starting as child process with session ID: ${binSessionId}`);
303
+ GrpcClient.getInstance().connect();
304
+ const response = await GrpcClient.getInstance().connectBinSession();
305
+ this.logger.info(`Connected to bin session: ${JSON.stringify(response)}`);
306
+ this.loadModules(response);
307
+ this.isChildConnected = true;
308
+ PerformanceTester.end(PerformanceEvents.SDK_CONNECT_BIN_SESSION);
309
+ }
310
+ catch (error) {
311
+ PerformanceTester.end(PerformanceEvents.SDK_CONNECT_BIN_SESSION, false, util.format(error));
312
+ this.logger.error(`Failed to start as child process: ${util.format(error)}`);
313
+ }
314
+ }
315
+ /**
316
+ * Check if the CLI is running
317
+ * @returns {boolean} True if the CLI is running
318
+ */
319
+ isRunning() {
320
+ return (
321
+ // is Dev mode
322
+ CLIUtils.isDevelopmentEnv() ||
323
+ // Main process connection check
324
+ (this.isMainConnected && this.process !== null && this.process.exitCode === null && GrpcClient.getInstance().getClient() !== null && GrpcClient.getInstance().getChannel().getConnectivityState(false) !== 4) ||
325
+ // Child process connection check
326
+ (this.isChildConnected && GrpcClient.getInstance().getChannel() !== null && GrpcClient.getInstance().getChannel().getConnectivityState(false) !== 4));
327
+ }
328
+ /**
329
+ * Get the Browserstack configuration
330
+ * @returns {Object} The Browserstack configuration
331
+ */
332
+ getBrowserstackConfig() {
333
+ return this.browserstackConfig;
334
+ }
335
+ /**
336
+ * Set the Browserstack configuration
337
+ * @param {Object}
338
+ * @returns {void}
339
+ */
340
+ setBrowserstackConfig(browserstackConfig) {
341
+ this.browserstackConfig = browserstackConfig;
342
+ }
343
+ /**
344
+ * Get the CLI binary path
345
+ * @returns {string} The CLI binary path
346
+ */
347
+ async getCliBinPath() {
348
+ if (!this.SDK_CLI_BIN_PATH) {
349
+ this.SDK_CLI_BIN_PATH = await CLIUtils.setupCliPath(this.browserstackConfig);
350
+ }
351
+ return this.SDK_CLI_BIN_PATH || ''; // TODO: Type hack
352
+ }
353
+ /**
354
+ * Check if the CLI is enabled
355
+ * @returns {boolean} True if the CLI is enabled
356
+ */
357
+ isCliEnabled() {
358
+ return BrowserstackCLI.enabled;
359
+ }
360
+ /**
361
+ * Get the configuration
362
+ * @returns {Object} The configuration
363
+ */
364
+ getConfig() {
365
+ return this.config;
366
+ }
367
+ /**
368
+ * Set the configuration
369
+ * @param {Object}
370
+ * @returns {void}
371
+ */
372
+ setConfig(response) {
373
+ try {
374
+ this.config = JSON.parse(response.config);
375
+ this.logger.debug(`loadModules: config=${JSON.stringify(this.config)}`);
376
+ }
377
+ catch (error) {
378
+ this.logger.error(`setConfig: error=${util.format(error)}`);
379
+ }
380
+ }
381
+ /**
382
+ * Setup the test framework
383
+ * @returns {void}
384
+ */
385
+ setupTestFramework() {
386
+ const testFrameworkDetail = CLIUtils.getTestFrameworkDetail();
387
+ if (testFrameworkDetail.name.toLowerCase() === 'webdriverio-mocha') {
388
+ this.testFramework = new WdioMochaTestFramework([testFrameworkDetail.name], testFrameworkDetail.version, this.binSessionId);
389
+ }
390
+ }
391
+ /**
392
+ * Setup the automation framework
393
+ * @returns {void}
394
+ */
395
+ setupAutomationFramework() {
396
+ const automationFrameworkDetail = CLIUtils.getAutomationFrameworkDetail();
397
+ if (automationFrameworkDetail.name.toLowerCase() === 'webdriverio') {
398
+ this.automationFramework = new WdioAutomationFramework(automationFrameworkDetail.name, automationFrameworkDetail.version);
399
+ }
400
+ }
401
+ /**
402
+ * Get the test framework
403
+ * @returns {Object} The test framework
404
+ */
405
+ getTestFramework() {
406
+ return this.testFramework;
407
+ }
408
+ /**
409
+ * Get the automation framework
410
+ * @returns {Object} The automation framework
411
+ */
412
+ getAutomationFramework() {
413
+ return this.automationFramework;
414
+ }
415
+ }
@@ -0,0 +1,33 @@
1
+ import type TrackedContext from './trackedContext.js';
2
+ import TrackedInstance from './trackedInstance.js';
3
+ /**
4
+ * Class representing an automation framework instance
5
+ * @extends TrackedInstance
6
+ */
7
+ export default class AutomationFrameworkInstance extends TrackedInstance {
8
+ frameworkName: string;
9
+ frameworkVersion: string;
10
+ state: State;
11
+ constructor(context: TrackedContext, frameworkName: string, frameworkVersion: string, state: State);
12
+ /**
13
+ * Get the framework name
14
+ * @returns {string} The name of the automation framework
15
+ */
16
+ getFrameworkName(): string;
17
+ /**
18
+ * Get the framework version
19
+ * @returns {string} The version of the automation framework
20
+ */
21
+ getFrameworkVersion(): string;
22
+ /**
23
+ * Get the current state
24
+ * @returns {AutomationFrameworkState} The current state of the automation framework
25
+ */
26
+ getState(): State;
27
+ /**
28
+ * Set the current state
29
+ * @param {AutomationFrameworkState} state - The new state to set
30
+ */
31
+ setState(state: State): void;
32
+ }
33
+ //# sourceMappingURL=automationFrameworkInstance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automationFrameworkInstance.d.ts","sourceRoot":"","sources":["../../../src/cli/instances/automationFrameworkInstance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD,OAAO,eAAe,MAAM,sBAAsB,CAAA;AAElD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,2BAA4B,SAAQ,eAAe;IACpE,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,KAAK,EAAE,KAAK,CAAA;gBAEA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAOlG;;;KAGC;IACD,gBAAgB;IAIhB;;;KAGC;IACD,mBAAmB;IAInB;;;KAGC;IACD,QAAQ;IAIR;;;KAGC;IACD,QAAQ,CAAC,KAAK,EAAE,KAAK;CAGxB"}
@@ -0,0 +1,44 @@
1
+ import TrackedInstance from './trackedInstance.js';
2
+ /**
3
+ * Class representing an automation framework instance
4
+ * @extends TrackedInstance
5
+ */
6
+ export default class AutomationFrameworkInstance extends TrackedInstance {
7
+ frameworkName;
8
+ frameworkVersion;
9
+ state;
10
+ constructor(context, frameworkName, frameworkVersion, state) {
11
+ super(context);
12
+ this.frameworkName = frameworkName;
13
+ this.frameworkVersion = frameworkVersion;
14
+ this.state = state;
15
+ }
16
+ /**
17
+ * Get the framework name
18
+ * @returns {string} The name of the automation framework
19
+ */
20
+ getFrameworkName() {
21
+ return this.frameworkName;
22
+ }
23
+ /**
24
+ * Get the framework version
25
+ * @returns {string} The version of the automation framework
26
+ */
27
+ getFrameworkVersion() {
28
+ return this.frameworkVersion;
29
+ }
30
+ /**
31
+ * Get the current state
32
+ * @returns {AutomationFrameworkState} The current state of the automation framework
33
+ */
34
+ getState() {
35
+ return this.state;
36
+ }
37
+ /**
38
+ * Set the current state
39
+ * @param {AutomationFrameworkState} state - The new state to set
40
+ */
41
+ setState(state) {
42
+ this.state = state;
43
+ }
44
+ }
@@ -0,0 +1,62 @@
1
+ import TrackedInstance from './trackedInstance.js';
2
+ import type TrackedContext from './trackedContext.js';
3
+ export default class TestFrameworkInstance extends TrackedInstance {
4
+ #private;
5
+ testFrameworks: Array<string>;
6
+ testFrameworksVersions: Record<string, string>;
7
+ /**
8
+ * create TestFrameworkInstance
9
+ * @param {TrackedContext} context
10
+ * @param {Array} testFrameworks
11
+ * @param {Map} testFrameworksVersions
12
+ * @param {TestFrameworkState} testFrameworkState
13
+ * @param {HookState} hookState
14
+ */
15
+ constructor(context: TrackedContext, testFrameworks: Array<string>, testFrameworksVersions: Record<string, string>, testFrameworkState: State, hookState: State);
16
+ /**
17
+ * get CurrentTestState of instance
18
+ * @returns {*} - returns TestFramework State
19
+ */
20
+ getCurrentTestState(): State;
21
+ /**
22
+ * set CurrentTestState of instance
23
+ * @param {TestFrameworkState} currentTestState - Set Current TestFramework State
24
+ */
25
+ setCurrentTestState(currentTestState: State): void;
26
+ /**
27
+ * get CurrentHookState of instance
28
+ * @returns {HookState} - return current hook state.
29
+ */
30
+ getCurrentHookState(): State;
31
+ /**
32
+ * set CurrentHookState of instance
33
+ * @param {HookState} currentHookState - set current hook state.
34
+ */
35
+ setCurrentHookState(currentHookState: State): void;
36
+ /**
37
+ * get LastTestState of instance
38
+ * @returns {TestFrameworkState} - return last test framework state
39
+ */
40
+ getLastTestState(): State;
41
+ /**
42
+ * set LastTestState of instance
43
+ * @param {TestFrameworkState} lastTestState - set last test framework state
44
+ */
45
+ setLastTestState(lastTestState: State): void;
46
+ /**
47
+ * get LastHookState of instance
48
+ * @returns {HookState} get last hook state
49
+ */
50
+ getLastHookState(): State;
51
+ /**
52
+ * set LastHookState of instance
53
+ * @param {HookState} lastHookState - returns late hook state
54
+ */
55
+ setLastHookState(lastHookState: State): void;
56
+ /**
57
+ * get CreatedAt of instance
58
+ * @returns {string} - return created time
59
+ */
60
+ getCreatedAt(): string;
61
+ }
62
+ //# sourceMappingURL=testFrameworkInstance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testFrameworkInstance.d.ts","sourceRoot":"","sources":["../../../src/cli/instances/testFrameworkInstance.ts"],"names":[],"mappings":"AAGA,OAAO,eAAe,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAIrD,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,eAAe;;IAC9D,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7B,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAO9C;;;;;;;KAOC;gBACW,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK;IAW/J;;;KAGC;IACD,mBAAmB;IAInB;;;KAGC;IACD,mBAAmB,CAAC,gBAAgB,EAAE,KAAK;IAK3C;;;KAGC;IACD,mBAAmB;IAInB;;;KAGC;IACD,mBAAmB,CAAC,gBAAgB,EAAE,KAAK;IAK3C;;;KAGC;IACD,gBAAgB;IAIhB;;;KAGC;IACD,gBAAgB,CAAC,aAAa,EAAE,KAAK;IAIrC;;;KAGC;IACD,gBAAgB;IAIhB;;;KAGC;IACD,gBAAgB,CAAC,aAAa,EAAE,KAAK;IAIrC;;;KAGC;IACD,YAAY;CAIf"}
@@ -0,0 +1,96 @@
1
+ import { HookState } from '../states/hookState.js';
2
+ import { TestFrameworkState } from '../states/testFrameworkState.js';
3
+ import TrackedInstance from './trackedInstance.js';
4
+ const now = new Date();
5
+ export default class TestFrameworkInstance extends TrackedInstance {
6
+ testFrameworks;
7
+ testFrameworksVersions;
8
+ #currentTestState;
9
+ #currentHookState;
10
+ #lastTestState;
11
+ #lastHookState;
12
+ #createdAt;
13
+ /**
14
+ * create TestFrameworkInstance
15
+ * @param {TrackedContext} context
16
+ * @param {Array} testFrameworks
17
+ * @param {Map} testFrameworksVersions
18
+ * @param {TestFrameworkState} testFrameworkState
19
+ * @param {HookState} hookState
20
+ */
21
+ constructor(context, testFrameworks, testFrameworksVersions, testFrameworkState, hookState) {
22
+ super(context);
23
+ this.testFrameworks = testFrameworks;
24
+ this.testFrameworksVersions = testFrameworksVersions;
25
+ this.#currentTestState = testFrameworkState;
26
+ this.#currentHookState = hookState;
27
+ this.#lastTestState = TestFrameworkState.NONE;
28
+ this.#lastHookState = HookState.NONE;
29
+ this.#createdAt = now.toLocaleString();
30
+ }
31
+ /**
32
+ * get CurrentTestState of instance
33
+ * @returns {*} - returns TestFramework State
34
+ */
35
+ getCurrentTestState() {
36
+ return this.#currentTestState;
37
+ }
38
+ /**
39
+ * set CurrentTestState of instance
40
+ * @param {TestFrameworkState} currentTestState - Set Current TestFramework State
41
+ */
42
+ setCurrentTestState(currentTestState) {
43
+ this.setLastTestState(this.#currentTestState);
44
+ this.#currentTestState = currentTestState;
45
+ }
46
+ /**
47
+ * get CurrentHookState of instance
48
+ * @returns {HookState} - return current hook state.
49
+ */
50
+ getCurrentHookState() {
51
+ return this.#currentHookState;
52
+ }
53
+ /**
54
+ * set CurrentHookState of instance
55
+ * @param {HookState} currentHookState - set current hook state.
56
+ */
57
+ setCurrentHookState(currentHookState) {
58
+ this.setLastHookState(this.#currentHookState);
59
+ this.#currentHookState = currentHookState;
60
+ }
61
+ /**
62
+ * get LastTestState of instance
63
+ * @returns {TestFrameworkState} - return last test framework state
64
+ */
65
+ getLastTestState() {
66
+ return this.#lastTestState;
67
+ }
68
+ /**
69
+ * set LastTestState of instance
70
+ * @param {TestFrameworkState} lastTestState - set last test framework state
71
+ */
72
+ setLastTestState(lastTestState) {
73
+ this.#lastTestState = lastTestState;
74
+ }
75
+ /**
76
+ * get LastHookState of instance
77
+ * @returns {HookState} get last hook state
78
+ */
79
+ getLastHookState() {
80
+ return this.#lastHookState;
81
+ }
82
+ /**
83
+ * set LastHookState of instance
84
+ * @param {HookState} lastHookState - returns late hook state
85
+ */
86
+ setLastHookState(lastHookState) {
87
+ this.#lastHookState = lastHookState;
88
+ }
89
+ /**
90
+ * get CreatedAt of instance
91
+ * @returns {string} - return created time
92
+ */
93
+ getCreatedAt() {
94
+ return this.#createdAt;
95
+ }
96
+ }
@@ -0,0 +1,32 @@
1
+ export default class TrackedContext {
2
+ #private;
3
+ /**
4
+ * Create TrackedContext
5
+ * @param {number} string - string Id for context - VERIFY
6
+ * @param {number} threadId- Integer Thread Id for context
7
+ * @param {number} processId - Integer Process Id for context
8
+ * @param {string} type
9
+ */
10
+ constructor(id: string, threadId: number, processId: number, type: string);
11
+ /**
12
+ * get TrackedContext thread id
13
+ * @returns {number} - return thread id of context
14
+ */
15
+ getThreadId(): number;
16
+ /**
17
+ * get TrackedContext process id
18
+ * @returns {number} - return process id of context
19
+ */
20
+ getProcessId(): number;
21
+ /**
22
+ * get TrackedContext id
23
+ * @returns {string} - returns context id
24
+ */
25
+ getId(): string;
26
+ /**
27
+ * get TrackedContext type
28
+ * @returns {string}
29
+ */
30
+ getType(): string;
31
+ }
32
+ //# sourceMappingURL=trackedContext.d.ts.map