@wdio/browserstack-service 8.46.0 → 8.47.1

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 +6 -3
  7. package/build/accessibility-handler.d.ts.map +1 -1
  8. package/build/accessibility-handler.js +8 -5
  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 +2 -0
  96. package/build/insights-handler.d.ts.map +1 -1
  97. package/build/insights-handler.js +29 -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 +1 -1
  109. package/build/service.d.ts.map +1 -1
  110. package/build/service.js +190 -108
  111. package/build/testOps/requestUtils.js +3 -2
  112. package/build/types.d.ts +29 -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 +5 -2
  118. package/tsconfig.prod.tsbuildinfo +1 -1
@@ -0,0 +1,222 @@
1
+ import BaseModule from './baseModule.js';
2
+ import { BStackLogger } from '../cliLogger.js';
3
+ import TestFramework from '../frameworks/testFramework.js';
4
+ import { TestFrameworkState } from '../states/testFrameworkState.js';
5
+ import { HookState } from '../states/hookState.js';
6
+ import got from 'got';
7
+ import AutomationFramework from '../frameworks/automationFramework.js';
8
+ import { AutomationFrameworkConstants } from '../frameworks/constants/automationFrameworkConstants.js';
9
+ import { isBrowserstackSession } from '../../util.js';
10
+ import { TestFrameworkConstants } from '../frameworks/constants/testFrameworkConstants.js';
11
+ import PerformanceTester from '../../instrumentation/performance/performance-tester.js';
12
+ import * as PERFORMANCE_SDK_EVENTS from '../../instrumentation/performance/constants.js';
13
+ import APIUtils from '../apiUtils.js';
14
+ import { AutomationFrameworkState } from '../states/automationFrameworkState.js';
15
+ export default class AutomateModule extends BaseModule {
16
+ logger = BStackLogger;
17
+ browserStackConfig;
18
+ sessionMap = new Map();
19
+ static MODULE_NAME = 'AutomateModule';
20
+ /**
21
+ * Create a new AutomateModule
22
+ */
23
+ constructor(browserStackConfig) {
24
+ super();
25
+ this.browserStackConfig = browserStackConfig;
26
+ this.logger.info('AutomateModule: Initializing Automate Module');
27
+ TestFramework.registerObserver(TestFrameworkState.TEST, HookState.PRE, this.onBeforeTest.bind(this));
28
+ TestFramework.registerObserver(TestFrameworkState.TEST, HookState.POST, this.onAfterTest.bind(this));
29
+ TestFramework.registerObserver(AutomationFrameworkState.EXECUTE, HookState.POST, this.onAfterExecute.bind(this));
30
+ }
31
+ getModuleName() {
32
+ return AutomateModule.MODULE_NAME;
33
+ }
34
+ async onBeforeTest(args) {
35
+ this.logger.info('onbeforeTest: inside automate module before test hook!');
36
+ const instace = args.instance;
37
+ const autoInstance = AutomationFramework.getTrackedInstance();
38
+ const sessionId = AutomationFramework.getState(autoInstance, AutomationFrameworkConstants.KEY_FRAMEWORK_SESSION_ID);
39
+ const browser = AutomationFramework.getDriver(autoInstance);
40
+ const test = args.test;
41
+ const testTitle = test.title;
42
+ const suiteTitle = args.suiteTitle;
43
+ const testContextOptions = this.config.testContextOptions;
44
+ if (testContextOptions.skipSessionName || !isBrowserstackSession(browser)) {
45
+ this.logger.info('Skipping session name update as per configuration');
46
+ return;
47
+ }
48
+ let name = suiteTitle;
49
+ if (testContextOptions.sessionNameFormat) {
50
+ const caps = AutomationFramework.getState(autoInstance, AutomationFrameworkConstants.KEY_CAPABILITIES);
51
+ name = testContextOptions.sessionNameFormat(this.browserStackConfig, caps, suiteTitle, testTitle);
52
+ }
53
+ else if (test && !test.fullName) {
54
+ // Mocha
55
+ const pre = testContextOptions.sessionNamePrependTopLevelSuiteTitle ? `${suiteTitle} - ` : '';
56
+ const post = !testContextOptions.sessionNameOmitTestTitle ? ` - ${testTitle}` : '';
57
+ name = `${pre}${test.parent}${post}`;
58
+ }
59
+ const existingSession = this.sessionMap.get(sessionId);
60
+ if (!existingSession) {
61
+ this.sessionMap.set(sessionId, {
62
+ lastTestName: name,
63
+ testResults: new Map()
64
+ });
65
+ }
66
+ else {
67
+ existingSession.lastTestName = name;
68
+ this.sessionMap.set(sessionId, existingSession);
69
+ }
70
+ TestFramework.setState(instace, TestFrameworkConstants.KEY_AUTOMATE_SESSION_NAME, name);
71
+ }
72
+ async onAfterTest(args) {
73
+ this.logger.debug('onAfterTest: inside automate module after test hook!');
74
+ const instace = args.instance;
75
+ const { error, passed } = args.result;
76
+ const _failReasons = [];
77
+ if (!passed) {
78
+ _failReasons.push((error && error.message) || 'Unknown Error');
79
+ }
80
+ const status = passed ? 'passed' : 'failed';
81
+ const reason = _failReasons.length > 0 ? _failReasons.join('\n') : undefined;
82
+ const autoInstance = AutomationFramework.getTrackedInstance();
83
+ const sessionId = AutomationFramework.getState(autoInstance, AutomationFrameworkConstants.KEY_FRAMEWORK_SESSION_ID);
84
+ const browser = AutomationFramework.getDriver(autoInstance);
85
+ const test = args.test;
86
+ const testTitle = test.title;
87
+ const suiteTitle = args.suiteTitle;
88
+ const testContextOptions = this.config.testContextOptions;
89
+ if (testContextOptions.skipSessionStatus || !isBrowserstackSession(browser)) {
90
+ this.logger.info('Skipping session status update as per configuration');
91
+ return;
92
+ }
93
+ let name = suiteTitle;
94
+ if (testContextOptions.sessionNameFormat) {
95
+ const caps = AutomationFramework.getState(autoInstance, AutomationFrameworkConstants.KEY_CAPABILITIES);
96
+ name = testContextOptions.sessionNameFormat(this.browserStackConfig, caps, suiteTitle, testTitle);
97
+ }
98
+ else if (test && !test.fullName) {
99
+ // Mocha
100
+ const pre = testContextOptions.sessionNamePrependTopLevelSuiteTitle ? `${suiteTitle} - ` : '';
101
+ const post = !testContextOptions.sessionNameOmitTestTitle ? ` - ${testTitle}` : '';
102
+ name = `${pre}${test.parent}${post}`;
103
+ }
104
+ const sessionData = this.sessionMap.get(sessionId);
105
+ if (sessionData) {
106
+ const testResult = {
107
+ testName: name,
108
+ status: status,
109
+ reason: reason
110
+ };
111
+ sessionData.testResults.set(name, testResult);
112
+ this.sessionMap.set(sessionId, sessionData);
113
+ }
114
+ TestFramework.setState(instace, TestFrameworkConstants.KEY_AUTOMATE_SESSION_STATUS, status);
115
+ TestFramework.setState(instace, TestFrameworkConstants.KEY_AUTOMATE_SESSION_REASON, reason);
116
+ }
117
+ async onAfterExecute() {
118
+ this.logger.debug('onAfterExecute: inside automate module after execute hook!');
119
+ const userName = this.config.userName;
120
+ const accessKey = this.config.accessKey;
121
+ const testContextOptions = this.config.testContextOptions;
122
+ for (const [sessionId, sessionData] of this.sessionMap.entries()) {
123
+ try {
124
+ const failedTests = Array.from(sessionData.testResults.values()).filter(test => test.status === 'failed');
125
+ const hasFailures = failedTests.length > 0;
126
+ const sessionStatus = hasFailures ? 'failed' : 'passed';
127
+ let failureReason;
128
+ if (hasFailures) {
129
+ if (failedTests.length === 1) {
130
+ failureReason = failedTests[0].reason || 'Test failed';
131
+ }
132
+ else {
133
+ const reasonLines = failedTests.map(test => `${test.testName}: ${test.reason || 'Unknown Error'}`);
134
+ failureReason = reasonLines.join(',\n');
135
+ }
136
+ }
137
+ if (!testContextOptions.skipSessionName) {
138
+ await this.markSessionName(sessionId, sessionData.lastTestName, { user: userName, key: accessKey });
139
+ }
140
+ if (!testContextOptions.skipSessionStatus) {
141
+ await this.markSessionStatus(sessionId, sessionStatus, failureReason, { user: userName, key: accessKey });
142
+ }
143
+ }
144
+ catch (error) {
145
+ this.logger.error(`Failed to process session ${sessionId}: ${error}`);
146
+ }
147
+ }
148
+ this.sessionMap.clear();
149
+ }
150
+ async markSessionName(sessionId, sessionName, config) {
151
+ return await PerformanceTester.measureWrapper(PERFORMANCE_SDK_EVENTS.AUTOMATE_EVENTS.SESSION_NAME, async (sessionId, sessionName, config) => {
152
+ try {
153
+ const auth = Buffer.from(`${config.user}:${config.key}`).toString('base64');
154
+ const isAppAutomate = this.config.app;
155
+ if (isAppAutomate) {
156
+ this.logger.info('Marking session name for App Automate');
157
+ }
158
+ else {
159
+ this.logger.info('Marking session name for Automate');
160
+ }
161
+ const sessionStatusApiUrl = isAppAutomate
162
+ ? `${APIUtils.BROWSERSTACK_AA_API_URL}/app-automate/sessions/${sessionId}.json`
163
+ : `${APIUtils.BROWSERSTACK_AUTOMATE_API_URL}/automate/sessions/${sessionId}.json`;
164
+ const requestBody = {
165
+ name: sessionName
166
+ };
167
+ const options = {
168
+ method: 'PUT',
169
+ url: sessionStatusApiUrl,
170
+ headers: {
171
+ Authorization: `Basic ${auth}`,
172
+ 'Content-Type': 'application/json'
173
+ },
174
+ json: requestBody,
175
+ responseType: 'json'
176
+ };
177
+ const response = await got(options);
178
+ this.logger.debug('Session name updated:', response.body);
179
+ this.logger.debug(`Done for sessionId ${sessionId}`);
180
+ }
181
+ catch (err) {
182
+ this.logger.error(`Failed to update session name on BrowserStack: ${err}`);
183
+ }
184
+ })(sessionId, sessionName, config);
185
+ }
186
+ async markSessionStatus(sessionId, sessionStatus, sessionErrorMessage, config) {
187
+ return await PerformanceTester.measureWrapper(PERFORMANCE_SDK_EVENTS.AUTOMATE_EVENTS.SESSION_STATUS, async (sessionId, sessionStatus, sessionErrorMessage, config) => {
188
+ try {
189
+ const auth = Buffer.from(`${config.user}:${config.key}`).toString('base64');
190
+ const isAppAutomate = this.config.app;
191
+ if (isAppAutomate) {
192
+ this.logger.info('Marking session status for App Automate');
193
+ }
194
+ else {
195
+ this.logger.info('Marking session status for Automate');
196
+ }
197
+ const sessionStatusApiUrl = isAppAutomate
198
+ ? `${APIUtils.BROWSERSTACK_AA_API_URL}/app-automate/sessions/${sessionId}.json`
199
+ : `${APIUtils.BROWSERSTACK_AUTOMATE_API_URL}/automate/sessions/${sessionId}.json`;
200
+ const body = {
201
+ status: sessionStatus,
202
+ ...(sessionErrorMessage ? { reason: sessionErrorMessage } : {})
203
+ };
204
+ const options = {
205
+ method: 'PUT',
206
+ url: sessionStatusApiUrl,
207
+ headers: {
208
+ Authorization: `Basic ${auth}`,
209
+ 'Content-Type': 'application/json'
210
+ },
211
+ json: body,
212
+ responseType: 'json'
213
+ };
214
+ const response = await got(options);
215
+ this.logger.debug('Session update response:', response.body);
216
+ }
217
+ catch (err) {
218
+ this.logger.error(`Failed to update session status on BrowserStack: ${err}`);
219
+ }
220
+ })(sessionId, sessionStatus, sessionErrorMessage, config);
221
+ }
222
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Base class for BrowserStack modules
3
+ */
4
+ export default class BaseModule {
5
+ #private;
6
+ binSessionId: string | null;
7
+ platformIndex: number;
8
+ config: Record<string, unknown>;
9
+ client: any;
10
+ /**
11
+ * Create a new BaseModule
12
+ */
13
+ constructor();
14
+ /**
15
+ * Ensure that a bin session ID is available
16
+ * @throws {Error} If binSessionId is missing
17
+ */
18
+ ensureBinSession(): void;
19
+ /**
20
+ * Get the name of the module
21
+ * @returns {string} The module name
22
+ */
23
+ getModuleName(): string;
24
+ /**
25
+ * Configure the module with session information
26
+ * @param {string} binSessionId - The bin session ID
27
+ * @param {number} platformIndex - The platform index
28
+ * @param {Object} client - The gRPC client service
29
+ * @param {Object} config - Configuration options
30
+ */
31
+ configure(binSessionId: string | null, platformIndex: number, client: unknown, config?: {}): void;
32
+ }
33
+ //# sourceMappingURL=baseModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseModule.d.ts","sourceRoot":"","sources":["../../../src/cli/modules/baseModule.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU;;IAE3B,YAAY,EAAE,MAAM,GAAC,IAAI,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,EAAE,GAAG,CAAA;IACX;;OAEG;;IASH;;;OAGG;IACH,gBAAgB;IAMhB;;;OAGG;IACH,aAAa;IAIb;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK;CAQ3F"}
@@ -0,0 +1,51 @@
1
+ import { BStackLogger } from '../cliLogger.js';
2
+ /**
3
+ * Base class for BrowserStack modules
4
+ */
5
+ export default class BaseModule {
6
+ #name;
7
+ binSessionId;
8
+ platformIndex;
9
+ config;
10
+ client;
11
+ /**
12
+ * Create a new BaseModule
13
+ */
14
+ constructor() {
15
+ this.#name = 'BaseModule';
16
+ this.binSessionId = null;
17
+ this.platformIndex = 0;
18
+ this.config = {};
19
+ this.client = null;
20
+ }
21
+ /**
22
+ * Ensure that a bin session ID is available
23
+ * @throws {Error} If binSessionId is missing
24
+ */
25
+ ensureBinSession() {
26
+ if (!this.binSessionId) {
27
+ throw new Error('Missing binSessionId');
28
+ }
29
+ }
30
+ /**
31
+ * Get the name of the module
32
+ * @returns {string} The module name
33
+ */
34
+ getModuleName() {
35
+ return this.#name;
36
+ }
37
+ /**
38
+ * Configure the module with session information
39
+ * @param {string} binSessionId - The bin session ID
40
+ * @param {number} platformIndex - The platform index
41
+ * @param {Object} client - The gRPC client service
42
+ * @param {Object} config - Configuration options
43
+ */
44
+ configure(binSessionId, platformIndex, client, config = {}) {
45
+ this.binSessionId = binSessionId;
46
+ this.platformIndex = platformIndex;
47
+ this.client = client;
48
+ this.config = config;
49
+ BStackLogger.debug(`Configured module ${this.getModuleName()} with binSessionId=${binSessionId}, platformIndex=${platformIndex}`);
50
+ }
51
+ }
@@ -0,0 +1,22 @@
1
+ import BaseModule from './baseModule.js';
2
+ import { BStackLogger } from '../cliLogger.js';
3
+ /**
4
+ * Observability Module for BrowserStack
5
+ */
6
+ export default class ObservabilityModule extends BaseModule {
7
+ logger: typeof BStackLogger;
8
+ observabilityConfig: unknown;
9
+ name: string;
10
+ static MODULE_NAME: string;
11
+ /**
12
+ * Create a new ObservabilityModule
13
+ */
14
+ constructor(observabilityConfig: unknown);
15
+ /**
16
+ * Get the module name
17
+ * @returns {string} The module name
18
+ */
19
+ getModuleName(): string;
20
+ onBeforeTest(args: Record<string, unknown>): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=observabilityModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observabilityModule.d.ts","sourceRoot":"","sources":["../../../src/cli/modules/observabilityModule.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAiB,CAAA;AAMxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,UAAU;IACvD,MAAM,sBAAe;IACrB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,WAAW,SAAwB;IAE1C;;OAEG;gBACS,mBAAmB,EAAE,OAAO;IAQxC;;;OAGG;IACH,aAAa;IAIP,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAYnD"}
@@ -0,0 +1,45 @@
1
+ import BaseModule from './baseModule.js';
2
+ import AutomationFramework from '../frameworks/automationFramework.js';
3
+ import { AutomationFrameworkState } from '../states/automationFrameworkState.js';
4
+ import { HookState } from '../states/hookState.js';
5
+ import PerformanceTester from '../../instrumentation/performance/performance-tester.js';
6
+ import { O11Y_EVENTS } from '../../instrumentation/performance/constants.js';
7
+ import { BStackLogger } from '../cliLogger.js';
8
+ import { performO11ySync } from '../../util.js';
9
+ /**
10
+ * Observability Module for BrowserStack
11
+ */
12
+ export default class ObservabilityModule extends BaseModule {
13
+ logger = BStackLogger;
14
+ observabilityConfig;
15
+ name;
16
+ static MODULE_NAME = 'ObservabilityModule';
17
+ /**
18
+ * Create a new ObservabilityModule
19
+ */
20
+ constructor(observabilityConfig) {
21
+ super();
22
+ this.name = 'ObservabilityModule';
23
+ this.observabilityConfig = observabilityConfig;
24
+ AutomationFramework.registerObserver(AutomationFrameworkState.CREATE, HookState.POST, this.onBeforeTest.bind(this));
25
+ }
26
+ /**
27
+ * Get the module name
28
+ * @returns {string} The module name
29
+ */
30
+ getModuleName() {
31
+ return ObservabilityModule.MODULE_NAME;
32
+ }
33
+ async onBeforeTest(args) {
34
+ if (args.browser) {
35
+ const browser = args.browser;
36
+ PerformanceTester.start(O11Y_EVENTS.SYNC);
37
+ performO11ySync(browser);
38
+ PerformanceTester.end(O11Y_EVENTS.SYNC);
39
+ this.logger.info('onBeforeTest: Observability sync done');
40
+ }
41
+ else {
42
+ this.logger.error('onBeforeTest: page is not defined');
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,19 @@
1
+ import BaseModule from './baseModule.js';
2
+ import { BStackLogger } from '../cliLogger.js';
3
+ export default class PercyModule extends BaseModule {
4
+ logger: typeof BStackLogger;
5
+ private browser?;
6
+ static readonly MODULE_NAME = "PercyModule";
7
+ private percyHandler;
8
+ private percyConfig;
9
+ private isAppAutomate;
10
+ /**
11
+ * Create a new PercyModule
12
+ */
13
+ constructor(percyConfig: unknown);
14
+ getModuleName(): string;
15
+ onAfterCreate(args: Record<string, unknown>): Promise<void>;
16
+ onBeforeTest(args: Record<string, unknown>): Promise<void>;
17
+ onAfterTest(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=percyModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"percyModule.d.ts","sourceRoot":"","sources":["../../../src/cli/modules/percyModule.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAW9C,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,UAAU;IAE/C,MAAM,sBAAe;IACrB,OAAO,CAAC,OAAO,CAAC,CAAiC;IACjD,MAAM,CAAC,QAAQ,CAAC,WAAW,iBAAgB;IAC3C,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAS;IAC9B;;OAEG;gBACS,WAAW,EAAE,OAAO;IAUhC,aAAa,IAAI,MAAM;IAIjB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAmC3C,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAU1C,WAAW;CAcpB"}
@@ -0,0 +1,77 @@
1
+ import BaseModule from './baseModule.js';
2
+ import { BStackLogger } from '../cliLogger.js';
3
+ import TestFramework from '../frameworks/testFramework.js';
4
+ import AutomationFramework from '../frameworks/automationFramework.js';
5
+ import { TestFrameworkState } from '../states/testFrameworkState.js';
6
+ import { HookState } from '../states/hookState.js';
7
+ import { AutomationFrameworkState } from '../states/automationFrameworkState.js';
8
+ import PercyHandler from '../../Percy/Percy-Handler.js';
9
+ import { TestFrameworkConstants } from '../frameworks/constants/testFrameworkConstants.js';
10
+ export default class PercyModule extends BaseModule {
11
+ logger = BStackLogger;
12
+ browser;
13
+ static MODULE_NAME = 'PercyModule';
14
+ percyHandler;
15
+ percyConfig;
16
+ isAppAutomate;
17
+ /**
18
+ * Create a new PercyModule
19
+ */
20
+ constructor(percyConfig) {
21
+ super();
22
+ this.percyConfig = percyConfig;
23
+ this.isAppAutomate = false;
24
+ this.logger.info('PercyModule: Initializing Percy Module');
25
+ AutomationFramework.registerObserver(AutomationFrameworkState.CREATE, HookState.POST, this.onAfterCreate.bind(this));
26
+ TestFramework.registerObserver(TestFrameworkState.TEST, HookState.PRE, this.onBeforeTest.bind(this));
27
+ TestFramework.registerObserver(TestFrameworkState.TEST, HookState.POST, this.onAfterTest.bind(this));
28
+ }
29
+ getModuleName() {
30
+ return PercyModule.MODULE_NAME;
31
+ }
32
+ async onAfterCreate(args) {
33
+ this.browser = args.browser;
34
+ if (!this.browser) {
35
+ this.logger.error('PercyModule: Browser instance is not defined in onAfterCreate');
36
+ return;
37
+ }
38
+ if (!this.percyConfig || !this.percyConfig.percyCaptureMode) {
39
+ this.logger.warn('PercyModule: Percy capture mode is not defined in the configuration, skipping Percy initialization');
40
+ return;
41
+ }
42
+ this.isAppAutomate = this.isAppAutomate || 'app' in this.config;
43
+ this.percyHandler = new PercyHandler(this.percyConfig.percyCaptureMode, this.browser, {}, this.isAppAutomate, '');
44
+ await this.percyHandler.before();
45
+ const sessionId = this.browser.sessionId;
46
+ this.browser.on('command', async (command) => {
47
+ await this.percyHandler?.browserBeforeCommand(Object.assign(command, { sessionId }));
48
+ });
49
+ this.browser.on('result', (result) => {
50
+ this.percyHandler?.browserAfterCommand(Object.assign(result, { sessionId }));
51
+ });
52
+ }
53
+ async onBeforeTest(args) {
54
+ const instace = args.instance;
55
+ const sessionName = TestFramework.getState(instace, TestFrameworkConstants.KEY_AUTOMATE_SESSION_NAME);
56
+ if (!this.percyHandler) {
57
+ this.logger.warn('PercyModule: Percy handler is not initialized, skipping pre execute actions');
58
+ return;
59
+ }
60
+ this.percyHandler._setSessionName(sessionName);
61
+ }
62
+ async onAfterTest() {
63
+ try {
64
+ if (!this.percyHandler) {
65
+ this.logger.warn('PercyModule: Percy handler is not initialized, skipping post execute actions');
66
+ return;
67
+ }
68
+ if (this.percyConfig.percyCaptureMode === 'testcase') {
69
+ await this.percyHandler.percyAutoCapture('testcase', null);
70
+ }
71
+ await this.percyHandler.teardown();
72
+ }
73
+ catch (error) {
74
+ this.logger.error(`Percy post execute failed: ${error}`);
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,30 @@
1
+ import BaseModule from './baseModule.js';
2
+ import { BStackLogger } from '../cliLogger.js';
3
+ /**
4
+ * TestHub Module for BrowserStack
5
+ */
6
+ export default class TestHubModule extends BaseModule {
7
+ logger: typeof BStackLogger;
8
+ testhubConfig: unknown;
9
+ name: string;
10
+ static MODULE_NAME: string;
11
+ /**
12
+ * Create a new TestHubModule
13
+ */
14
+ constructor(testhubConfig: unknown);
15
+ /**
16
+ * Get the module name
17
+ * @returns {string} The module name
18
+ */
19
+ getModuleName(): string;
20
+ onBeforeTest(args: Record<string, unknown>): void;
21
+ onAllTestEvents(args: Record<string, unknown>): void;
22
+ sendTestFrameworkEvent(args: Record<string, unknown>): Promise<void>;
23
+ /**
24
+ * Send test session event to the service
25
+ * @param args containing test session data
26
+ */
27
+ sendTestSessionEvent(args: Record<string, unknown>): Promise<void>;
28
+ sendLogCreatedEvent(args: Record<string, unknown>): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=testHubModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testHubModule.d.ts","sourceRoot":"","sources":["../../../src/cli/modules/testHubModule.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAgB9C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,UAAU;IAEjD,MAAM,sBAAe;IACrB,aAAa,EAAE,OAAO,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,WAAW,SAAkB;IAEpC;;OAEG;gBACS,aAAa,EAAE,OAAO;IAclC;;;OAGG;IACH,aAAa;IAIb,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQ1C,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAsCvC,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAsC1D;;;OAGG;IACG,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA4ElE,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAyC1D"}