@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.
- package/README.md +44 -11
- package/build/Percy/Percy-Handler.d.ts.map +1 -1
- package/build/Percy/Percy-Handler.js +4 -1
- package/build/Percy/Percy.d.ts.map +1 -1
- package/build/Percy/Percy.js +2 -1
- package/build/accessibility-handler.d.ts +9 -3
- package/build/accessibility-handler.d.ts.map +1 -1
- package/build/accessibility-handler.js +52 -11
- package/build/cleanup.js +3 -3
- package/build/cli/apiUtils.d.ts +14 -0
- package/build/cli/apiUtils.d.ts.map +1 -0
- package/build/cli/apiUtils.js +24 -0
- package/build/cli/cliLogger.d.ts +16 -0
- package/build/cli/cliLogger.d.ts.map +1 -0
- package/build/cli/cliLogger.js +70 -0
- package/build/cli/cliUtils.d.ts +46 -0
- package/build/cli/cliUtils.d.ts.map +1 -0
- package/build/cli/cliUtils.js +430 -0
- package/build/cli/eventDispatcher.d.ts +28 -0
- package/build/cli/eventDispatcher.d.ts.map +1 -0
- package/build/cli/eventDispatcher.js +48 -0
- package/build/cli/frameworks/automationFramework.d.ts +89 -0
- package/build/cli/frameworks/automationFramework.d.ts.map +1 -0
- package/build/cli/frameworks/automationFramework.js +131 -0
- package/build/cli/frameworks/constants/automationFrameworkConstants.d.ts +18 -0
- package/build/cli/frameworks/constants/automationFrameworkConstants.d.ts.map +1 -0
- package/build/cli/frameworks/constants/automationFrameworkConstants.js +17 -0
- package/build/cli/frameworks/constants/testFrameworkConstants.d.ts +43 -0
- package/build/cli/frameworks/constants/testFrameworkConstants.d.ts.map +1 -0
- package/build/cli/frameworks/constants/testFrameworkConstants.js +42 -0
- package/build/cli/frameworks/testFramework.d.ts +89 -0
- package/build/cli/frameworks/testFramework.d.ts.map +1 -0
- package/build/cli/frameworks/testFramework.js +125 -0
- package/build/cli/frameworks/wdioAutomationFramework.d.ts +28 -0
- package/build/cli/frameworks/wdioAutomationFramework.d.ts.map +1 -0
- package/build/cli/frameworks/wdioAutomationFramework.js +66 -0
- package/build/cli/frameworks/wdioMochaTestFramework.d.ts +82 -0
- package/build/cli/frameworks/wdioMochaTestFramework.d.ts.map +1 -0
- package/build/cli/frameworks/wdioMochaTestFramework.js +319 -0
- package/build/cli/grpcClient.d.ts +70 -0
- package/build/cli/grpcClient.d.ts.map +1 -0
- package/build/cli/grpcClient.js +419 -0
- package/build/cli/index.d.ts +148 -0
- package/build/cli/index.d.ts.map +1 -0
- package/build/cli/index.js +415 -0
- package/build/cli/instances/automationFrameworkInstance.d.ts +33 -0
- package/build/cli/instances/automationFrameworkInstance.d.ts.map +1 -0
- package/build/cli/instances/automationFrameworkInstance.js +44 -0
- package/build/cli/instances/testFrameworkInstance.d.ts +62 -0
- package/build/cli/instances/testFrameworkInstance.d.ts.map +1 -0
- package/build/cli/instances/testFrameworkInstance.js +96 -0
- package/build/cli/instances/trackedContext.d.ts +32 -0
- package/build/cli/instances/trackedContext.d.ts.map +1 -0
- package/build/cli/instances/trackedContext.js +47 -0
- package/build/cli/instances/trackedInstance.d.ts +40 -0
- package/build/cli/instances/trackedInstance.d.ts.map +1 -0
- package/build/cli/instances/trackedInstance.js +63 -0
- package/build/cli/modules/accessibilityModule.d.ts +33 -0
- package/build/cli/modules/accessibilityModule.d.ts.map +1 -0
- package/build/cli/modules/accessibilityModule.js +347 -0
- package/build/cli/modules/automateModule.d.ts +26 -0
- package/build/cli/modules/automateModule.d.ts.map +1 -0
- package/build/cli/modules/automateModule.js +222 -0
- package/build/cli/modules/baseModule.d.ts +33 -0
- package/build/cli/modules/baseModule.d.ts.map +1 -0
- package/build/cli/modules/baseModule.js +51 -0
- package/build/cli/modules/observabilityModule.d.ts +22 -0
- package/build/cli/modules/observabilityModule.d.ts.map +1 -0
- package/build/cli/modules/observabilityModule.js +45 -0
- package/build/cli/modules/percyModule.d.ts +19 -0
- package/build/cli/modules/percyModule.d.ts.map +1 -0
- package/build/cli/modules/percyModule.js +77 -0
- package/build/cli/modules/testHubModule.d.ts +30 -0
- package/build/cli/modules/testHubModule.d.ts.map +1 -0
- package/build/cli/modules/testHubModule.js +232 -0
- package/build/cli/modules/webdriverIOModule.d.ts +29 -0
- package/build/cli/modules/webdriverIOModule.d.ts.map +1 -0
- package/build/cli/modules/webdriverIOModule.js +128 -0
- package/build/cli/states/automationFrameworkState.d.ts +65 -0
- package/build/cli/states/automationFrameworkState.d.ts.map +1 -0
- package/build/cli/states/automationFrameworkState.js +61 -0
- package/build/cli/states/hookState.d.ts +45 -0
- package/build/cli/states/hookState.d.ts.map +1 -0
- package/build/cli/states/hookState.js +43 -0
- package/build/cli/states/testFrameworkState.d.ts +125 -0
- package/build/cli/states/testFrameworkState.d.ts.map +1 -0
- package/build/cli/states/testFrameworkState.js +115 -0
- package/build/constants.d.ts +13 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +21 -1
- package/build/crash-reporter.d.ts.map +1 -1
- package/build/crash-reporter.js +4 -3
- package/build/exitHandler.d.ts.map +1 -1
- package/build/exitHandler.js +47 -5
- package/build/insights-handler.d.ts +8 -0
- package/build/insights-handler.d.ts.map +1 -1
- package/build/insights-handler.js +57 -1
- package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -1
- package/build/instrumentation/funnelInstrumentation.js +5 -4
- package/build/instrumentation/performance/constants.d.ts +8 -0
- package/build/instrumentation/performance/constants.d.ts.map +1 -1
- package/build/instrumentation/performance/constants.js +9 -1
- package/build/instrumentation/performance/performance-tester.d.ts.map +1 -1
- package/build/instrumentation/performance/performance-tester.js +5 -3
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +94 -51
- package/build/request-handler.js +1 -1
- package/build/service.d.ts +3 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +244 -69
- package/build/testOps/requestUtils.js +3 -2
- package/build/types.d.ts +36 -3
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +13 -1
- package/build/util.d.ts.map +1 -1
- package/build/util.js +173 -27
- package/package.json +7 -4
- package/tsconfig.prod.tsbuildinfo +1 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
import BaseModule from './baseModule.js';
|
|
3
|
+
import { BStackLogger } from '../cliLogger.js';
|
|
4
|
+
import TestFramework from '../frameworks/testFramework.js';
|
|
5
|
+
import { TestFrameworkState } from '../states/testFrameworkState.js';
|
|
6
|
+
import { HookState } from '../states/hookState.js';
|
|
7
|
+
import { CLIUtils } from '../cliUtils.js';
|
|
8
|
+
import { TestFrameworkConstants } from '../frameworks/constants/testFrameworkConstants.js';
|
|
9
|
+
import { GrpcClient } from '../grpcClient.js';
|
|
10
|
+
import WdioMochaTestFramework from '../frameworks/wdioMochaTestFramework.js';
|
|
11
|
+
import AutomationFramework from '../frameworks/automationFramework.js';
|
|
12
|
+
import { AutomationFrameworkConstants } from '../frameworks/constants/automationFrameworkConstants.js';
|
|
13
|
+
/**
|
|
14
|
+
* TestHub Module for BrowserStack
|
|
15
|
+
*/
|
|
16
|
+
export default class TestHubModule extends BaseModule {
|
|
17
|
+
logger = BStackLogger;
|
|
18
|
+
testhubConfig;
|
|
19
|
+
name;
|
|
20
|
+
static MODULE_NAME = 'TestHubModule';
|
|
21
|
+
/**
|
|
22
|
+
* Create a new TestHubModule
|
|
23
|
+
*/
|
|
24
|
+
constructor(testhubConfig) {
|
|
25
|
+
super();
|
|
26
|
+
this.name = 'TestHubModule';
|
|
27
|
+
this.testhubConfig = testhubConfig;
|
|
28
|
+
TestFramework.registerObserver(TestFrameworkState.TEST, HookState.PRE, this.onBeforeTest.bind(this));
|
|
29
|
+
Object.values(TestFrameworkState).forEach(state => {
|
|
30
|
+
Object.values(HookState).forEach(hook => {
|
|
31
|
+
TestFramework.registerObserver(state, hook, this.onAllTestEvents.bind(this));
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the module name
|
|
37
|
+
* @returns {string} The module name
|
|
38
|
+
*/
|
|
39
|
+
getModuleName() {
|
|
40
|
+
return TestHubModule.MODULE_NAME;
|
|
41
|
+
}
|
|
42
|
+
onBeforeTest(args) {
|
|
43
|
+
this.logger.debug('onBeforeTest: Called after test hook from cli configured module!!!');
|
|
44
|
+
const autoInstace = AutomationFramework.getTrackedInstance();
|
|
45
|
+
const instances = [autoInstace];
|
|
46
|
+
args.autoInstance = instances;
|
|
47
|
+
this.sendTestSessionEvent(args);
|
|
48
|
+
}
|
|
49
|
+
onAllTestEvents(args) {
|
|
50
|
+
this.logger.debug('onAllTestEvents: Called after all test events from cli configured module!!!');
|
|
51
|
+
const instance = args.instance;
|
|
52
|
+
const testState = instance.getCurrentTestState();
|
|
53
|
+
const hookState = instance.getCurrentHookState();
|
|
54
|
+
const keyTestDeferred = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_DEFERRED);
|
|
55
|
+
if (testState === TestFrameworkState.LOG) {
|
|
56
|
+
this.logger.debug(`onAllTestEvents: TestFrameworkState.LOG - ${testState}`);
|
|
57
|
+
const logEntries = WdioMochaTestFramework.getLogEntries(instance, testState, hookState);
|
|
58
|
+
if (logEntries && logEntries.length > 0) {
|
|
59
|
+
args.logEntries = logEntries;
|
|
60
|
+
this.sendLogCreatedEvent(args);
|
|
61
|
+
WdioMochaTestFramework.clearLogs(instance, testState, hookState);
|
|
62
|
+
// Handle LOG state if needed
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (testState === TestFrameworkState.TEST &&
|
|
66
|
+
hookState === HookState.POST &&
|
|
67
|
+
!TestFramework.hasState(instance, TestFrameworkConstants.KEY_TEST_RESULT_AT)) {
|
|
68
|
+
this.logger.info('onAllTestEvents: dropping due to lack of results');
|
|
69
|
+
TestFramework.setState(instance, TestFrameworkConstants.KEY_TEST_DEFERRED, true);
|
|
70
|
+
}
|
|
71
|
+
else if (keyTestDeferred &&
|
|
72
|
+
testState === TestFrameworkState.LOG_REPORT &&
|
|
73
|
+
hookState === HookState.POST &&
|
|
74
|
+
TestFramework.hasState(instance, TestFrameworkConstants.KEY_TEST_RESULT_AT)) {
|
|
75
|
+
// Create a modified args object with updated test framework state
|
|
76
|
+
instance.setCurrentTestState(TestFrameworkState.TEST);
|
|
77
|
+
this.onAllTestEvents(args);
|
|
78
|
+
}
|
|
79
|
+
if (testState === TestFrameworkState.TEST || CLIUtils.matchHookRegex(testState.toString().split('.')[1])) {
|
|
80
|
+
this.sendTestFrameworkEvent(args);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async sendTestFrameworkEvent(args) {
|
|
84
|
+
try {
|
|
85
|
+
const testArgs = args;
|
|
86
|
+
const instance = testArgs.instance;
|
|
87
|
+
const trackedContext = instance.getContext();
|
|
88
|
+
const testData = instance.getAllData();
|
|
89
|
+
const testFrameworkName = testData.get(TestFrameworkConstants.KEY_TEST_FRAMEWORK_NAME) || '';
|
|
90
|
+
const testFrameworkVersion = testData.get(TestFrameworkConstants.KEY_TEST_FRAMEWORK_VERSION) || '';
|
|
91
|
+
const startedAt = testData.get(TestFrameworkConstants.KEY_TEST_STARTED_AT) || '';
|
|
92
|
+
const endedAt = testData.get(TestFrameworkConstants.KEY_TEST_ENDED_AT) || '';
|
|
93
|
+
const testFrameworkState = instance.getCurrentTestState().toString().split('.')[1];
|
|
94
|
+
const testHookState = instance.getCurrentHookState().toString().split('.')[1];
|
|
95
|
+
this.logger.debug(`sendTestFrameworkEvent for testState: ${testFrameworkState} hookState: ${testHookState}`);
|
|
96
|
+
const platformIndex = process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0;
|
|
97
|
+
const uuid = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_UUID) || instance.getRef();
|
|
98
|
+
const eventJson = Buffer.from(JSON.stringify(Object.fromEntries(testData)));
|
|
99
|
+
const executionContext = { hash: trackedContext.getId(), threadId: trackedContext.getThreadId().toString(), processId: trackedContext.getProcessId().toString() };
|
|
100
|
+
const payload = {
|
|
101
|
+
platformIndex,
|
|
102
|
+
testFrameworkName,
|
|
103
|
+
testFrameworkVersion,
|
|
104
|
+
testFrameworkState,
|
|
105
|
+
testHookState,
|
|
106
|
+
startedAt,
|
|
107
|
+
endedAt,
|
|
108
|
+
uuid,
|
|
109
|
+
eventJson,
|
|
110
|
+
executionContext
|
|
111
|
+
};
|
|
112
|
+
this.logger.debug(`sendTestFrameworkEvent payload: ${JSON.stringify(payload)}`);
|
|
113
|
+
await GrpcClient.getInstance().testFrameworkEvent(payload);
|
|
114
|
+
this.logger.debug(`sendTestFrameworkEvent complete for testState: ${testFrameworkState} hookState: ${testHookState}`);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
this.logger.error(`Error in sendTestFrameworkEvent: ${util.format(error)}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Send test session event to the service
|
|
122
|
+
* @param args containing test session data
|
|
123
|
+
*/
|
|
124
|
+
async sendTestSessionEvent(args) {
|
|
125
|
+
this.logger.debug('sendTestSessionEvent: Called');
|
|
126
|
+
try {
|
|
127
|
+
const instance = args.instance;
|
|
128
|
+
const autoInstances = args.autoInstance || [];
|
|
129
|
+
const trackedContext = instance.getContext();
|
|
130
|
+
const testFWName = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_FRAMEWORK_NAME);
|
|
131
|
+
const testFWVersion = TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_FRAMEWORK_VERSION);
|
|
132
|
+
const testState = instance.getCurrentTestState().toString().split('.')[1];
|
|
133
|
+
const hookState = instance.getCurrentHookState().toString().split('.')[1];
|
|
134
|
+
this.logger.debug('sendTestSessionEvent: setup');
|
|
135
|
+
const executionContext = {
|
|
136
|
+
threadId: trackedContext.getThreadId().toString(),
|
|
137
|
+
processId: trackedContext.getProcessId().toString()
|
|
138
|
+
};
|
|
139
|
+
const payload = {
|
|
140
|
+
testFrameworkName: testFWName,
|
|
141
|
+
testFrameworkVersion: testFWVersion,
|
|
142
|
+
testFrameworkState: testState.toString(),
|
|
143
|
+
testHookState: hookState.toString(),
|
|
144
|
+
testUuid: TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_UUID).toString(),
|
|
145
|
+
executionContext,
|
|
146
|
+
automationSessions: [],
|
|
147
|
+
platformIndex: process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0,
|
|
148
|
+
capabilities: new Uint8Array()
|
|
149
|
+
};
|
|
150
|
+
// Try to get capabilities from the first driver
|
|
151
|
+
try {
|
|
152
|
+
if (autoInstances.length > 0) {
|
|
153
|
+
const driver = AutomationFramework.getDriver(autoInstances[0]); // RemoteWebDriver equivalent
|
|
154
|
+
const userCaps = JSON.stringify(driver.capabilities);
|
|
155
|
+
if (userCaps) {
|
|
156
|
+
payload.capabilities = new TextEncoder().encode(userCaps);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
this.logger.debug(`Error while getting capabilities from driver: ${error}`);
|
|
162
|
+
}
|
|
163
|
+
this.logger.debug(`sendTestSessionEvent: instance iteration ${JSON.stringify(autoInstances)}`);
|
|
164
|
+
// Process automation instances
|
|
165
|
+
for (const autoInstance of autoInstances) {
|
|
166
|
+
const sessionProvider = AutomationFramework.getState(autoInstance, AutomationFrameworkConstants.KEY_IS_BROWSERSTACK_HUB)
|
|
167
|
+
? 'browserstack'
|
|
168
|
+
: 'unknown_grid';
|
|
169
|
+
// eslint-disable-next-line camelcase
|
|
170
|
+
const automationSession = {
|
|
171
|
+
provider: sessionProvider,
|
|
172
|
+
ref: autoInstance.getRef(),
|
|
173
|
+
hubUrl: this.config.hubUrl,
|
|
174
|
+
frameworkSessionId: AutomationFramework.getState(autoInstance, AutomationFrameworkConstants.KEY_FRAMEWORK_SESSION_ID).toString(),
|
|
175
|
+
frameworkName: autoInstance.frameworkName,
|
|
176
|
+
frameworkVersion: autoInstance.frameworkVersion
|
|
177
|
+
};
|
|
178
|
+
this.logger.debug(`sendTestSessionEvent: automationSession: ${JSON.stringify(automationSession)}`);
|
|
179
|
+
payload.platformIndex = process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0;
|
|
180
|
+
payload.automationSessions.push(automationSession);
|
|
181
|
+
}
|
|
182
|
+
this.logger.debug(`sendTestSessionEvent payload: ${JSON.stringify(payload)}`);
|
|
183
|
+
await GrpcClient.getInstance().testSessionEvent(payload);
|
|
184
|
+
this.logger.debug(`sendTestSessionEvent complete for testState: ${testState} hookState: ${hookState}`);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
this.logger.error(`sendTestSessionEvent: Error sending grpc call: event=${JSON.stringify(args)}, error=${error}`);
|
|
188
|
+
throw new Error(`Failed to send test session event: ${error}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async sendLogCreatedEvent(args) {
|
|
192
|
+
try {
|
|
193
|
+
const testArgs = args;
|
|
194
|
+
const logEntries = args.logEntries;
|
|
195
|
+
const instance = testArgs.instance;
|
|
196
|
+
const trackedContext = instance.getContext();
|
|
197
|
+
const testData = instance.getAllData();
|
|
198
|
+
const testFrameworkName = testData.get(TestFrameworkConstants.KEY_TEST_FRAMEWORK_NAME) || '';
|
|
199
|
+
const testFrameworkVersion = testData.get(TestFrameworkConstants.KEY_TEST_FRAMEWORK_VERSION) || '';
|
|
200
|
+
const testFrameworkState = instance.getCurrentTestState().toString().split('.')[1];
|
|
201
|
+
const testHookState = instance.getCurrentHookState().toString().split('.')[1];
|
|
202
|
+
this.logger.debug(`sendLogCreatedEvent testId: testFrameworkState: ${testFrameworkState} testHookState: ${testHookState}`);
|
|
203
|
+
const platformIndex = process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0;
|
|
204
|
+
const executionContext = { hash: trackedContext.getId(), threadId: trackedContext.getThreadId().toString(), processId: trackedContext.getProcessId().toString() };
|
|
205
|
+
const payload = {
|
|
206
|
+
platformIndex,
|
|
207
|
+
logs: [],
|
|
208
|
+
executionContext
|
|
209
|
+
};
|
|
210
|
+
for (const logEntry of logEntries) {
|
|
211
|
+
// eslint-disable-next-line camelcase
|
|
212
|
+
const logData = {
|
|
213
|
+
testFrameworkName,
|
|
214
|
+
testFrameworkVersion,
|
|
215
|
+
testFrameworkState,
|
|
216
|
+
uuid: logEntry[TestFrameworkConstants.KEY_HOOK_ID] || TestFramework.getState(instance, TestFrameworkConstants.KEY_TEST_UUID),
|
|
217
|
+
kind: logEntry.kind,
|
|
218
|
+
message: logEntry.message,
|
|
219
|
+
timestamp: logEntry.timestamp,
|
|
220
|
+
level: logEntry.level,
|
|
221
|
+
};
|
|
222
|
+
payload.logs.push(logData);
|
|
223
|
+
}
|
|
224
|
+
this.logger.debug(`sendLogCreatedEvent payload: ${JSON.stringify(payload)}`);
|
|
225
|
+
await GrpcClient.getInstance().logCreatedEvent(payload);
|
|
226
|
+
this.logger.debug(`sendLogCreatedEvent complete for testState: ${testFrameworkState} hookState: ${testHookState}`);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
this.logger.error(`Error in sendLogCreatedEvent: ${util.format(error)}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import BaseModule from './baseModule.js';
|
|
2
|
+
import { BStackLogger } from '../cliLogger.js';
|
|
3
|
+
import type AutomationFrameworkInstance from '../instances/automationFrameworkInstance.js';
|
|
4
|
+
export default class WebdriverIOModule extends BaseModule {
|
|
5
|
+
name: string;
|
|
6
|
+
browserName: string | null;
|
|
7
|
+
browserVersion: string | null;
|
|
8
|
+
platforms: Array<string>;
|
|
9
|
+
testRunId: string | null;
|
|
10
|
+
logger: typeof BStackLogger;
|
|
11
|
+
static MODULE_NAME: string;
|
|
12
|
+
/**
|
|
13
|
+
* Create a new WebdriverIOModule
|
|
14
|
+
*/
|
|
15
|
+
constructor();
|
|
16
|
+
/**
|
|
17
|
+
* Get the module name
|
|
18
|
+
* @returns {string} The module name
|
|
19
|
+
*/
|
|
20
|
+
getModuleName(): string;
|
|
21
|
+
onBeforeDriverCreate(args: Record<string, unknown>): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Handle driver creation event
|
|
24
|
+
* @param args Event arguments containing driver and instance information
|
|
25
|
+
*/
|
|
26
|
+
onDriverCreated(args: Record<string, unknown>): Promise<void>;
|
|
27
|
+
getBinDriverCapabilities(instance: AutomationFrameworkInstance, caps: WebdriverIO.Capabilities): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=webdriverIOModule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webdriverIOModule.d.ts","sourceRoot":"","sources":["../../../src/cli/modules/webdriverIOModule.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAI9C,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAA;AAM1F,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,UAAU;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAExB,MAAM,sBAAe;IACrB,MAAM,CAAC,WAAW,SAAsB;IAExC;;SAEK;;IAaL;;;SAGK;IACL,aAAa;IAIP,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAiBxD;;;OAGG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqD7D,wBAAwB,CAAC,QAAQ,EAAE,2BAA2B,EAAE,IAAI,EAAE,WAAW,CAAC,YAAY;CAqBvG"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
import BaseModule from './baseModule.js';
|
|
3
|
+
import { BStackLogger } from '../cliLogger.js';
|
|
4
|
+
import AutomationFramework from '../frameworks/automationFramework.js';
|
|
5
|
+
import { AutomationFrameworkState } from '../states/automationFrameworkState.js';
|
|
6
|
+
import { HookState } from '../states/hookState.js';
|
|
7
|
+
import { AutomationFrameworkConstants } from '../frameworks/constants/automationFrameworkConstants.js';
|
|
8
|
+
import { isBrowserstackSession } from '../../util.js';
|
|
9
|
+
import { GrpcClient } from '../grpcClient.js';
|
|
10
|
+
export default class WebdriverIOModule extends BaseModule {
|
|
11
|
+
name;
|
|
12
|
+
browserName;
|
|
13
|
+
browserVersion;
|
|
14
|
+
platforms;
|
|
15
|
+
testRunId;
|
|
16
|
+
logger = BStackLogger;
|
|
17
|
+
static MODULE_NAME = 'WebdriverIOModule';
|
|
18
|
+
/**
|
|
19
|
+
* Create a new WebdriverIOModule
|
|
20
|
+
*/
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this.name = 'WebdriverIOModule';
|
|
24
|
+
this.browserName = null;
|
|
25
|
+
this.browserVersion = null;
|
|
26
|
+
this.platforms = [];
|
|
27
|
+
this.testRunId = null;
|
|
28
|
+
AutomationFramework.registerObserver(AutomationFrameworkState.CREATE, HookState.PRE, this.onBeforeDriverCreate.bind(this));
|
|
29
|
+
AutomationFramework.registerObserver(AutomationFrameworkState.CREATE, HookState.POST, this.onDriverCreated.bind(this));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the module name
|
|
33
|
+
* @returns {string} The module name
|
|
34
|
+
*/
|
|
35
|
+
getModuleName() {
|
|
36
|
+
return WebdriverIOModule.MODULE_NAME;
|
|
37
|
+
}
|
|
38
|
+
async onBeforeDriverCreate(args) {
|
|
39
|
+
try {
|
|
40
|
+
const instance = args.instance;
|
|
41
|
+
this.logger.debug('onBeforeDriverCreate: driver is about to be created');
|
|
42
|
+
const capabilities = args.caps;
|
|
43
|
+
if (!capabilities) {
|
|
44
|
+
this.logger.warn('onBeforeDriverCreate: No capabilities provided');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
AutomationFramework.setState(instance, AutomationFrameworkConstants.KEY_INPUT_CAPABILITIES, capabilities);
|
|
48
|
+
await this.getBinDriverCapabilities(instance, capabilities);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
this.logger.error(`Error in onBeforeDriverCreate: ${util.format(e)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Handle driver creation event
|
|
56
|
+
* @param args Event arguments containing driver and instance information
|
|
57
|
+
*/
|
|
58
|
+
async onDriverCreated(args) {
|
|
59
|
+
this.logger.debug('onDriverCreated: Called');
|
|
60
|
+
try {
|
|
61
|
+
const instance = args.instance;
|
|
62
|
+
const browser = args.browser;
|
|
63
|
+
if (!instance || !browser) {
|
|
64
|
+
this.logger.warn('onDriverCreated: Missing instance or driver');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
AutomationFramework.setState(instance, AutomationFrameworkConstants.KEY_HUB_URL, args.hubUrl);
|
|
68
|
+
// Get session ID from driver
|
|
69
|
+
let sessionId = null;
|
|
70
|
+
try {
|
|
71
|
+
sessionId = browser.sessionId;
|
|
72
|
+
if (sessionId) {
|
|
73
|
+
this.logger.debug(`onDriverCreated: Driver session ID: ${sessionId}`);
|
|
74
|
+
AutomationFramework.setState(instance, AutomationFrameworkConstants.KEY_FRAMEWORK_SESSION_ID, sessionId);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
this.logger.debug(`onDriverCreated: Could not get session ID: ${error}`);
|
|
79
|
+
}
|
|
80
|
+
// Get capabilities from driver
|
|
81
|
+
try {
|
|
82
|
+
const capabilities = browser.capabilities;
|
|
83
|
+
if (capabilities) {
|
|
84
|
+
this.logger.debug(`onDriverCreated: Driver capabilities: ${JSON.stringify(capabilities)}`);
|
|
85
|
+
AutomationFramework.setState(instance, AutomationFrameworkConstants.KEY_CAPABILITIES, capabilities);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
this.logger.debug(`onDriverCreated: Could not get capabilities: ${error}`);
|
|
90
|
+
}
|
|
91
|
+
// Check if this is a BrowserStack hub
|
|
92
|
+
try {
|
|
93
|
+
const isBrowserStackHub = isBrowserstackSession(browser);
|
|
94
|
+
AutomationFramework.setState(instance, AutomationFrameworkConstants.KEY_IS_BROWSERSTACK_HUB, isBrowserStackHub);
|
|
95
|
+
this.logger.debug(`onDriverCreated: Is BrowserStack hub: ${isBrowserStackHub}`);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
this.logger.debug(`onDriverCreated: Could not determine hub type: ${error}`);
|
|
99
|
+
}
|
|
100
|
+
AutomationFramework.setDriver(instance, browser);
|
|
101
|
+
this.logger.info(`onDriverCreated: Successfully processed driver creation for session: ${sessionId}`);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
this.logger.error(`onDriverCreated: Error processing driver creation: ${error}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async getBinDriverCapabilities(instance, caps) {
|
|
108
|
+
try {
|
|
109
|
+
const payload = {
|
|
110
|
+
platformIndex: process.env.WDIO_WORKER_ID ? parseInt(process.env.WDIO_WORKER_ID.split('-')[0]) : 0,
|
|
111
|
+
ref: instance.getRef(),
|
|
112
|
+
userInputParams: Buffer.from(JSON.stringify(caps).toString())
|
|
113
|
+
};
|
|
114
|
+
const response = await GrpcClient.getInstance().driverInitEvent(payload);
|
|
115
|
+
if (response.success) {
|
|
116
|
+
if (response.capabilities.length > 0) {
|
|
117
|
+
const capabilitiesStr = response.capabilities.toString('utf8');
|
|
118
|
+
const capabilitiesObj = JSON.parse(capabilitiesStr);
|
|
119
|
+
AutomationFramework.setState(instance, AutomationFrameworkConstants.KEY_CAPABILITIES, capabilitiesObj);
|
|
120
|
+
}
|
|
121
|
+
this.logger.debug(`getBinDriverCapabilities: got hub url ${response.hubUrl}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
this.logger.error(`getBinDriverCapabilities: Error getting capabilities: ${error}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum representing different states of an automation framework
|
|
3
|
+
* @readonly
|
|
4
|
+
* @enum {Object}
|
|
5
|
+
*/
|
|
6
|
+
export declare const AutomationFrameworkState: Readonly<{
|
|
7
|
+
/**
|
|
8
|
+
* Initial state, no session created
|
|
9
|
+
*/
|
|
10
|
+
NONE: {
|
|
11
|
+
value: number;
|
|
12
|
+
toString(): string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Framework instance is being created
|
|
16
|
+
*/
|
|
17
|
+
CREATE: {
|
|
18
|
+
value: number;
|
|
19
|
+
toString(): string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Framework is executing tests
|
|
23
|
+
*/
|
|
24
|
+
EXECUTE: {
|
|
25
|
+
value: number;
|
|
26
|
+
toString(): string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Framework is idle, not executing any tests
|
|
30
|
+
*/
|
|
31
|
+
IDLE: {
|
|
32
|
+
value: number;
|
|
33
|
+
toString(): string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Framework is shutting down
|
|
37
|
+
*/
|
|
38
|
+
QUIT: {
|
|
39
|
+
value: number;
|
|
40
|
+
toString(): string;
|
|
41
|
+
};
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Get state by value
|
|
45
|
+
*
|
|
46
|
+
* @param {number} value - The numeric value of the state
|
|
47
|
+
* @returns {Object|undefined} The state object or undefined if not found
|
|
48
|
+
*/
|
|
49
|
+
export declare const fromValue: (value: number) => {
|
|
50
|
+
value: number;
|
|
51
|
+
toString(): string;
|
|
52
|
+
} | {
|
|
53
|
+
value: number;
|
|
54
|
+
toString(): string;
|
|
55
|
+
} | {
|
|
56
|
+
value: number;
|
|
57
|
+
toString(): string;
|
|
58
|
+
} | {
|
|
59
|
+
value: number;
|
|
60
|
+
toString(): string;
|
|
61
|
+
} | {
|
|
62
|
+
value: number;
|
|
63
|
+
toString(): string;
|
|
64
|
+
} | undefined;
|
|
65
|
+
//# sourceMappingURL=automationFrameworkState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automationFrameworkState.d.ts","sourceRoot":"","sources":["../../../src/cli/states/automationFrameworkState.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;IACjC;;KAEC;;;;;IAQD;;KAEC;;;;;IAQD;;KAEC;;;;;IAQD;;KAEC;;;;;IAQD;;KAEC;;;;;EAOH,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,UAAmB,MAAM;;;;;;;;;;;;;;;aAE9C,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum representing different states of an automation framework
|
|
3
|
+
* @readonly
|
|
4
|
+
* @enum {Object}
|
|
5
|
+
*/
|
|
6
|
+
export const AutomationFrameworkState = Object.freeze({
|
|
7
|
+
/**
|
|
8
|
+
* Initial state, no session created
|
|
9
|
+
*/
|
|
10
|
+
NONE: {
|
|
11
|
+
value: 0,
|
|
12
|
+
toString() {
|
|
13
|
+
return 'AutomationFrameworkState.NONE';
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
/**
|
|
17
|
+
* Framework instance is being created
|
|
18
|
+
*/
|
|
19
|
+
CREATE: {
|
|
20
|
+
value: 1,
|
|
21
|
+
toString() {
|
|
22
|
+
return 'AutomationFrameworkState.CREATE';
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* Framework is executing tests
|
|
27
|
+
*/
|
|
28
|
+
EXECUTE: {
|
|
29
|
+
value: 2,
|
|
30
|
+
toString() {
|
|
31
|
+
return 'AutomationFrameworkState.EXECUTE';
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Framework is idle, not executing any tests
|
|
36
|
+
*/
|
|
37
|
+
IDLE: {
|
|
38
|
+
value: 3,
|
|
39
|
+
toString() {
|
|
40
|
+
return 'AutomationFrameworkState.IDLE';
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Framework is shutting down
|
|
45
|
+
*/
|
|
46
|
+
QUIT: {
|
|
47
|
+
value: 4,
|
|
48
|
+
toString() {
|
|
49
|
+
return 'AutomationFrameworkState.QUIT';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Get state by value
|
|
55
|
+
*
|
|
56
|
+
* @param {number} value - The numeric value of the state
|
|
57
|
+
* @returns {Object|undefined} The state object or undefined if not found
|
|
58
|
+
*/
|
|
59
|
+
export const fromValue = function (value) {
|
|
60
|
+
return Object.values(AutomationFrameworkState).find(state => state.value === value);
|
|
61
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum representing different states of a hook
|
|
3
|
+
* @readonly
|
|
4
|
+
* @enum {Object}
|
|
5
|
+
*/
|
|
6
|
+
export declare const HookState: Readonly<{
|
|
7
|
+
/**
|
|
8
|
+
* No hook, initial state
|
|
9
|
+
*/
|
|
10
|
+
NONE: {
|
|
11
|
+
value: number;
|
|
12
|
+
toString(): string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Pre-execution hook
|
|
16
|
+
*/
|
|
17
|
+
PRE: {
|
|
18
|
+
value: number;
|
|
19
|
+
toString(): string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Post-execution hook
|
|
23
|
+
*/
|
|
24
|
+
POST: {
|
|
25
|
+
value: number;
|
|
26
|
+
toString(): string;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Get hook state by value
|
|
31
|
+
*
|
|
32
|
+
* @param {number} value - The numeric value of the hook state
|
|
33
|
+
* @returns {Object|undefined} The hook state object or undefined if not found
|
|
34
|
+
*/
|
|
35
|
+
export declare const fromValue: (value: number) => {
|
|
36
|
+
value: number;
|
|
37
|
+
toString(): string;
|
|
38
|
+
} | {
|
|
39
|
+
value: number;
|
|
40
|
+
toString(): string;
|
|
41
|
+
} | {
|
|
42
|
+
value: number;
|
|
43
|
+
toString(): string;
|
|
44
|
+
} | undefined;
|
|
45
|
+
//# sourceMappingURL=hookState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookState.d.ts","sourceRoot":"","sources":["../../../src/cli/states/hookState.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,SAAS;IAClB;;OAEG;;;;;IAQH;;OAEG;;;;;IAQH;;OAEG;;;;;EAOL,CAAA;AAEF;;;;;KAKK;AACL,eAAO,MAAM,SAAS,UAAmB,MAAM;;;;;;;;;aAE9C,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum representing different states of a hook
|
|
3
|
+
* @readonly
|
|
4
|
+
* @enum {Object}
|
|
5
|
+
*/
|
|
6
|
+
export const HookState = Object.freeze({
|
|
7
|
+
/**
|
|
8
|
+
* No hook, initial state
|
|
9
|
+
*/
|
|
10
|
+
NONE: {
|
|
11
|
+
value: 0,
|
|
12
|
+
toString() {
|
|
13
|
+
return 'HookState.NONE';
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
/**
|
|
17
|
+
* Pre-execution hook
|
|
18
|
+
*/
|
|
19
|
+
PRE: {
|
|
20
|
+
value: 1,
|
|
21
|
+
toString() {
|
|
22
|
+
return 'HookState.PRE';
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* Post-execution hook
|
|
27
|
+
*/
|
|
28
|
+
POST: {
|
|
29
|
+
value: 2,
|
|
30
|
+
toString() {
|
|
31
|
+
return 'HookState.POST';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Get hook state by value
|
|
37
|
+
*
|
|
38
|
+
* @param {number} value - The numeric value of the hook state
|
|
39
|
+
* @returns {Object|undefined} The hook state object or undefined if not found
|
|
40
|
+
*/
|
|
41
|
+
export const fromValue = function (value) {
|
|
42
|
+
return Object.values(HookState).find(state => state.value === value);
|
|
43
|
+
};
|