@wdio/browserstack-service 8.32.4 → 8.33.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/build/bstackLogger.d.ts +2 -1
- package/build/bstackLogger.d.ts.map +1 -1
- package/build/bstackLogger.js +6 -3
- package/build/cleanup.d.ts +5 -1
- package/build/cleanup.d.ts.map +1 -1
- package/build/cleanup.js +72 -7
- package/build/config.d.ts +23 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +39 -0
- package/build/constants.d.ts +14 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +22 -0
- package/build/crash-reporter.js +2 -2
- package/build/data-store.d.ts +4 -0
- package/build/data-store.d.ts.map +1 -0
- package/build/data-store.js +41 -0
- package/build/exitHandler.d.ts +4 -0
- package/build/exitHandler.d.ts.map +1 -0
- package/build/exitHandler.js +32 -0
- package/build/insights-handler.d.ts +5 -8
- package/build/insights-handler.d.ts.map +1 -1
- package/build/insights-handler.js +40 -93
- package/build/instrumentation/funnelInstrumentation.d.ts +6 -0
- package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -0
- package/build/instrumentation/funnelInstrumentation.js +119 -0
- package/build/launcher.d.ts +1 -1
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +22 -13
- package/build/reporter.d.ts +3 -3
- package/build/reporter.d.ts.map +1 -1
- package/build/reporter.js +11 -27
- package/build/request-handler.d.ts +5 -13
- package/build/request-handler.d.ts.map +1 -1
- package/build/request-handler.js +30 -48
- package/build/service.d.ts +1 -0
- package/build/service.d.ts.map +1 -1
- package/build/service.js +13 -5
- package/build/testOps/featureStats.d.ts +45 -0
- package/build/testOps/featureStats.d.ts.map +1 -0
- package/build/testOps/featureStats.js +116 -0
- package/build/testOps/featureUsage.d.ts +22 -0
- package/build/testOps/featureUsage.d.ts.map +1 -0
- package/build/testOps/featureUsage.js +47 -0
- package/build/testOps/listener.d.ts +33 -0
- package/build/testOps/listener.d.ts.map +1 -0
- package/build/testOps/listener.js +222 -0
- package/build/testOps/requestUtils.d.ts +4 -0
- package/build/testOps/requestUtils.d.ts.map +1 -0
- package/build/testOps/requestUtils.js +39 -0
- package/build/testOps/testOpsConfig.d.ts +11 -0
- package/build/testOps/testOpsConfig.d.ts.map +1 -0
- package/build/testOps/testOpsConfig.js +19 -0
- package/build/testOps/usageStats.d.ts +404 -0
- package/build/testOps/usageStats.d.ts.map +1 -0
- package/build/testOps/usageStats.js +114 -0
- package/build/types.d.ts +33 -7
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +3 -7
- package/build/util.d.ts.map +1 -1
- package/build/util.js +57 -77
- package/package.json +4 -4
package/build/util.js
CHANGED
|
@@ -6,24 +6,20 @@ import http from 'node:http';
|
|
|
6
6
|
import https from 'node:https';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import util from 'node:util';
|
|
9
|
-
import { spawn } from 'node:child_process';
|
|
10
|
-
import { fileURLToPath } from 'node:url';
|
|
11
9
|
import got, { HTTPError } from 'got';
|
|
12
10
|
import gitRepoInfo from 'git-repo-info';
|
|
13
11
|
import gitconfig from 'gitconfiglocal';
|
|
14
12
|
import { FormData } from 'formdata-node';
|
|
15
13
|
import logPatcher from './logPatcher.js';
|
|
16
14
|
import PerformanceTester from './performance-tester.js';
|
|
17
|
-
import { ACCESSIBILITY_API_URL, BROWSER_DESCRIPTION, DATA_ENDPOINT,
|
|
18
|
-
import RequestQueueHandler from './request-handler.js';
|
|
15
|
+
import { ACCESSIBILITY_API_URL, BROWSER_DESCRIPTION, DATA_ENDPOINT, UPLOAD_LOGS_ADDRESS, UPLOAD_LOGS_ENDPOINT, consoleHolder, TESTOPS_SCREENSHOT_ENV, TESTOPS_BUILD_ID_ENV, PERF_MEASUREMENT_ENV, RERUN_ENV, TESTOPS_BUILD_COMPLETED_ENV, TESTOPS_JWT_ENV } from './constants.js';
|
|
19
16
|
import CrashReporter from './crash-reporter.js';
|
|
20
17
|
import { accessibilityResults, accessibilityResultsSummary } from './scripts/test-event-scripts.js';
|
|
21
18
|
import { BStackLogger } from './bstackLogger.js';
|
|
22
19
|
import { FileStream } from './fileStream.js';
|
|
23
|
-
import
|
|
20
|
+
import UsageStats from './testOps/usageStats.js';
|
|
21
|
+
import TestOpsConfig from './testOps/testOpsConfig.js';
|
|
24
22
|
const pGitconfig = promisify(gitconfig);
|
|
25
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
26
|
-
const __dirname = path.dirname(__filename);
|
|
27
23
|
export const DEFAULT_REQUEST_CONFIG = {
|
|
28
24
|
agent: {
|
|
29
25
|
http: new http.Agent({ keepAlive: true }),
|
|
@@ -112,7 +108,7 @@ export function o11yErrorHandler(fn) {
|
|
|
112
108
|
return function (...args) {
|
|
113
109
|
try {
|
|
114
110
|
let functionToHandle = fn;
|
|
115
|
-
if (process.env
|
|
111
|
+
if (process.env[PERF_MEASUREMENT_ENV]) {
|
|
116
112
|
functionToHandle = PerformanceTester.getPerformance().timerify(functionToHandle);
|
|
117
113
|
}
|
|
118
114
|
const result = functionToHandle(...args);
|
|
@@ -191,7 +187,7 @@ export function o11yClassErrorHandler(errorClass) {
|
|
|
191
187
|
writable: true,
|
|
192
188
|
value: function (...args) {
|
|
193
189
|
try {
|
|
194
|
-
const result = (process.env
|
|
190
|
+
const result = (process.env[PERF_MEASUREMENT_ENV] ? PerformanceTester.getPerformance().timerify(method) : method).call(this, ...args);
|
|
195
191
|
if (result instanceof Promise) {
|
|
196
192
|
return result.catch(error => processError(error, method, args));
|
|
197
193
|
}
|
|
@@ -207,6 +203,8 @@ export function o11yClassErrorHandler(errorClass) {
|
|
|
207
203
|
return errorClass;
|
|
208
204
|
}
|
|
209
205
|
export const launchTestSession = o11yErrorHandler(async function launchTestSession(options, config, bsConfig) {
|
|
206
|
+
const launchBuildUsage = UsageStats.getInstance().launchBuildUsage;
|
|
207
|
+
launchBuildUsage.triggered();
|
|
210
208
|
const data = {
|
|
211
209
|
format: 'json',
|
|
212
210
|
project_name: getObservabilityProject(options, bsConfig.projectName),
|
|
@@ -223,7 +221,7 @@ export const launchTestSession = o11yErrorHandler(async function launchTestSessi
|
|
|
223
221
|
},
|
|
224
222
|
ci_info: getCiInfo(),
|
|
225
223
|
build_run_identifier: process.env.BROWSERSTACK_BUILD_RUN_IDENTIFIER,
|
|
226
|
-
failed_tests_rerun: process.env
|
|
224
|
+
failed_tests_rerun: process.env[RERUN_ENV] || false,
|
|
227
225
|
version_control: await getGitMetaData(),
|
|
228
226
|
observability_version: {
|
|
229
227
|
frameworkName: 'WebdriverIO-' + config.framework,
|
|
@@ -249,18 +247,21 @@ export const launchTestSession = o11yErrorHandler(async function launchTestSessi
|
|
|
249
247
|
json: data
|
|
250
248
|
}).json();
|
|
251
249
|
BStackLogger.debug(`[Start_Build] Success response: ${JSON.stringify(response)}`);
|
|
252
|
-
process.env
|
|
250
|
+
process.env[TESTOPS_BUILD_COMPLETED_ENV] = 'true';
|
|
253
251
|
if (response.jwt) {
|
|
254
|
-
|
|
252
|
+
launchBuildUsage.success();
|
|
253
|
+
process.env[TESTOPS_JWT_ENV] = response.jwt;
|
|
255
254
|
}
|
|
256
255
|
if (response.build_hashed_id) {
|
|
257
|
-
process.env
|
|
256
|
+
process.env[TESTOPS_BUILD_ID_ENV] = response.build_hashed_id;
|
|
257
|
+
TestOpsConfig.getInstance().buildHashedId = response.build_hashed_id;
|
|
258
258
|
}
|
|
259
259
|
if (response.allow_screenshots) {
|
|
260
|
-
process.env
|
|
260
|
+
process.env[TESTOPS_SCREENSHOT_ENV] = response.allow_screenshots.toString();
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
catch (error) {
|
|
264
|
+
launchBuildUsage.failed(error);
|
|
264
265
|
if (error instanceof HTTPError && error.response) {
|
|
265
266
|
const errorMessageJson = error.response.body ? JSON.parse(error.response.body.toString()) : null;
|
|
266
267
|
const errorMessage = errorMessageJson ? errorMessageJson.message : null, errorType = errorMessageJson ? errorMessageJson.errorType : null;
|
|
@@ -486,10 +487,18 @@ export const stopAccessibilityTestRun = errorHandler(async function stopAccessib
|
|
|
486
487
|
}
|
|
487
488
|
});
|
|
488
489
|
export const stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstream() {
|
|
489
|
-
|
|
490
|
-
|
|
490
|
+
const stopBuildUsage = UsageStats.getInstance().stopBuildUsage;
|
|
491
|
+
stopBuildUsage.triggered();
|
|
492
|
+
if (!process.env[TESTOPS_BUILD_COMPLETED_ENV]) {
|
|
493
|
+
stopBuildUsage.failed('Build is not completed yet');
|
|
494
|
+
return {
|
|
495
|
+
status: 'error',
|
|
496
|
+
message: 'Build is not completed yet'
|
|
497
|
+
};
|
|
491
498
|
}
|
|
492
|
-
|
|
499
|
+
const jwtToken = process.env[TESTOPS_JWT_ENV];
|
|
500
|
+
if (!jwtToken) {
|
|
501
|
+
stopBuildUsage.failed('Token/buildID is undefined, build creation might have failed');
|
|
493
502
|
BStackLogger.debug('[STOP_BUILD] Missing Authentication Token/ Build ID');
|
|
494
503
|
return {
|
|
495
504
|
status: 'error',
|
|
@@ -500,22 +509,24 @@ export const stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstre
|
|
|
500
509
|
'stop_time': (new Date()).toISOString()
|
|
501
510
|
};
|
|
502
511
|
try {
|
|
503
|
-
const url = `${DATA_ENDPOINT}/api/v1/builds/${process.env
|
|
512
|
+
const url = `${DATA_ENDPOINT}/api/v1/builds/${process.env[TESTOPS_BUILD_ID_ENV]}/stop`;
|
|
504
513
|
const response = await got.put(url, {
|
|
505
514
|
agent: DEFAULT_REQUEST_CONFIG.agent,
|
|
506
515
|
headers: {
|
|
507
516
|
...DEFAULT_REQUEST_CONFIG.headers,
|
|
508
|
-
'Authorization': `Bearer ${
|
|
517
|
+
'Authorization': `Bearer ${jwtToken}`
|
|
509
518
|
},
|
|
510
519
|
json: data
|
|
511
520
|
}).json();
|
|
512
521
|
BStackLogger.debug(`[STOP_BUILD] Success response: ${JSON.stringify(response)}`);
|
|
522
|
+
stopBuildUsage.success();
|
|
513
523
|
return {
|
|
514
524
|
status: 'success',
|
|
515
525
|
message: ''
|
|
516
526
|
};
|
|
517
527
|
}
|
|
518
528
|
catch (error) {
|
|
529
|
+
stopBuildUsage.failed(error);
|
|
519
530
|
BStackLogger.debug(`[STOP_BUILD] Failed. Error: ${error}`);
|
|
520
531
|
return {
|
|
521
532
|
status: 'error',
|
|
@@ -848,43 +859,6 @@ export function getLogTag(eventType) {
|
|
|
848
859
|
}
|
|
849
860
|
return 'undefined';
|
|
850
861
|
}
|
|
851
|
-
export async function uploadEventData(eventData, eventUrl = DATA_EVENT_ENDPOINT) {
|
|
852
|
-
let logTag = 'BATCH_UPLOAD';
|
|
853
|
-
if (!Array.isArray(eventData)) {
|
|
854
|
-
logTag = getLogTag(eventData.event_type);
|
|
855
|
-
}
|
|
856
|
-
if (eventUrl === DATA_SCREENSHOT_ENDPOINT) {
|
|
857
|
-
logTag = 'screenshot_upload';
|
|
858
|
-
}
|
|
859
|
-
if (!process.env.BS_TESTOPS_BUILD_COMPLETED) {
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
if (!process.env.BS_TESTOPS_JWT) {
|
|
863
|
-
BStackLogger.debug(`[${logTag}] Missing Authentication Token/ Build ID`);
|
|
864
|
-
return {
|
|
865
|
-
status: 'error',
|
|
866
|
-
message: 'Token/buildID is undefined, build creation might have failed'
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
try {
|
|
870
|
-
const url = `${DATA_ENDPOINT}/${eventUrl}`;
|
|
871
|
-
RequestQueueHandler.getInstance().pendingUploads += 1;
|
|
872
|
-
const data = await got.post(url, {
|
|
873
|
-
agent: DEFAULT_REQUEST_CONFIG.agent,
|
|
874
|
-
headers: {
|
|
875
|
-
...DEFAULT_REQUEST_CONFIG.headers,
|
|
876
|
-
'Authorization': `Bearer ${process.env.BS_TESTOPS_JWT}`
|
|
877
|
-
},
|
|
878
|
-
json: eventData
|
|
879
|
-
}).json();
|
|
880
|
-
BStackLogger.debug(`[${logTag}] Success response: ${JSON.stringify(data)}`);
|
|
881
|
-
RequestQueueHandler.getInstance().pendingUploads -= 1;
|
|
882
|
-
}
|
|
883
|
-
catch (error) {
|
|
884
|
-
BStackLogger.debug(`[${logTag}] Failed. Error: ${error}`);
|
|
885
|
-
RequestQueueHandler.getInstance().pendingUploads -= 1;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
862
|
// get hierarchy for a particular test (called by reporter for skipped tests)
|
|
889
863
|
export function getHierarchy(fullTitle) {
|
|
890
864
|
if (!fullTitle) {
|
|
@@ -923,8 +897,12 @@ export function shouldAddServiceVersion(config, testObservability) {
|
|
|
923
897
|
return true;
|
|
924
898
|
}
|
|
925
899
|
export async function batchAndPostEvents(eventUrl, kind, data) {
|
|
926
|
-
if (!process.env
|
|
927
|
-
|
|
900
|
+
if (!process.env[TESTOPS_BUILD_COMPLETED_ENV]) {
|
|
901
|
+
throw new Error('Build not completed yet');
|
|
902
|
+
}
|
|
903
|
+
const jwtToken = process.env[TESTOPS_JWT_ENV];
|
|
904
|
+
if (!jwtToken) {
|
|
905
|
+
throw new Error('Missing authentication Token');
|
|
928
906
|
}
|
|
929
907
|
try {
|
|
930
908
|
const url = `${DATA_ENDPOINT}/${eventUrl}`;
|
|
@@ -932,7 +910,7 @@ export async function batchAndPostEvents(eventUrl, kind, data) {
|
|
|
932
910
|
agent: DEFAULT_REQUEST_CONFIG.agent,
|
|
933
911
|
headers: {
|
|
934
912
|
...DEFAULT_REQUEST_CONFIG.headers,
|
|
935
|
-
'Authorization': `Bearer ${
|
|
913
|
+
'Authorization': `Bearer ${jwtToken}`
|
|
936
914
|
},
|
|
937
915
|
json: data
|
|
938
916
|
}).json();
|
|
@@ -940,6 +918,7 @@ export async function batchAndPostEvents(eventUrl, kind, data) {
|
|
|
940
918
|
}
|
|
941
919
|
catch (error) {
|
|
942
920
|
BStackLogger.debug(`[${kind}] EXCEPTION IN ${kind} REQUEST TO TEST OBSERVABILITY : ${error}`);
|
|
921
|
+
throw new Error('Exception in request ' + error);
|
|
943
922
|
}
|
|
944
923
|
}
|
|
945
924
|
export function getObservabilityUser(options, config) {
|
|
@@ -1008,6 +987,9 @@ export function isUndefined(value) {
|
|
|
1008
987
|
export function isTrue(value) {
|
|
1009
988
|
return (value + '').toLowerCase() === 'true';
|
|
1010
989
|
}
|
|
990
|
+
export function isFalse(value) {
|
|
991
|
+
return (value + '').toLowerCase() === 'false';
|
|
992
|
+
}
|
|
1011
993
|
export function frameworkSupportsHook(hook, framework) {
|
|
1012
994
|
if (framework === 'mocha' && (hook === 'before' || hook === 'after' || hook === 'beforeEach' || hook === 'afterEach')) {
|
|
1013
995
|
return true;
|
|
@@ -1042,15 +1024,6 @@ export function getFailureObject(error) {
|
|
|
1042
1024
|
failure_type: message ? (message.toString().match(/AssertionError/) ? 'AssertionError' : 'UnhandledError') : null
|
|
1043
1025
|
};
|
|
1044
1026
|
}
|
|
1045
|
-
export async function pushDataToQueue(data, requestQueueHandler = undefined) {
|
|
1046
|
-
if (!requestQueueHandler) {
|
|
1047
|
-
requestQueueHandler = RequestQueueHandler.getInstance();
|
|
1048
|
-
}
|
|
1049
|
-
const req = requestQueueHandler.add(data);
|
|
1050
|
-
if (req.proceed && req.data) {
|
|
1051
|
-
await uploadEventData(req.data, req.url);
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
1027
|
export const sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1055
1028
|
export async function uploadLogs(user, key, clientBuildUuid) {
|
|
1056
1029
|
if (!user || !key) {
|
|
@@ -1090,15 +1063,6 @@ export const ObjectsAreEqual = (object1, object2) => {
|
|
|
1090
1063
|
}
|
|
1091
1064
|
return true;
|
|
1092
1065
|
};
|
|
1093
|
-
export function setupExitHandlers() {
|
|
1094
|
-
process.on('exit', (code) => {
|
|
1095
|
-
if (!!process.env.BS_TESTOPS_JWT && !BrowserstackLauncherService._testOpsBuildStopped) {
|
|
1096
|
-
const childProcess = spawn('node', [`${path.join(__dirname, 'cleanup.js')}`], { detached: true, stdio: 'inherit', env: { ...process.env } });
|
|
1097
|
-
childProcess.unref();
|
|
1098
|
-
process.exit(code);
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
}
|
|
1102
1066
|
export const getPlatformVersion = o11yErrorHandler(function getPlatformVersion(caps) {
|
|
1103
1067
|
if (!caps) {
|
|
1104
1068
|
return undefined;
|
|
@@ -1115,3 +1079,19 @@ export const getPlatformVersion = o11yErrorHandler(function getPlatformVersion(c
|
|
|
1115
1079
|
}
|
|
1116
1080
|
return undefined;
|
|
1117
1081
|
});
|
|
1082
|
+
export const isObjectEmpty = (objectName) => {
|
|
1083
|
+
return (objectName &&
|
|
1084
|
+
Object.keys(objectName).length === 0 &&
|
|
1085
|
+
objectName.constructor === Object);
|
|
1086
|
+
};
|
|
1087
|
+
export const getErrorString = (err) => {
|
|
1088
|
+
if (!err) {
|
|
1089
|
+
return undefined;
|
|
1090
|
+
}
|
|
1091
|
+
if (typeof err === 'string') {
|
|
1092
|
+
return err; // works, `e` narrowed to string
|
|
1093
|
+
}
|
|
1094
|
+
else if (err instanceof Error) {
|
|
1095
|
+
return err.message; // works, `e` narrowed to Error
|
|
1096
|
+
}
|
|
1097
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browserstack-service",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.33.0",
|
|
4
4
|
"description": "WebdriverIO service for better Browserstack integration",
|
|
5
5
|
"author": "Adam Bjerstedt <abjerstedt@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"gitconfiglocal": "^2.1.0",
|
|
45
45
|
"got": "^12.6.1",
|
|
46
46
|
"uuid": "^9.0.0",
|
|
47
|
-
"webdriverio": "8.
|
|
47
|
+
"webdriverio": "8.33.0",
|
|
48
48
|
"winston-transport": "^4.5.0",
|
|
49
49
|
"yauzl": "^3.0.0"
|
|
50
50
|
},
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/node": "^20.1.0",
|
|
56
|
-
"@wdio/globals": "8.
|
|
56
|
+
"@wdio/globals": "8.33.0"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "b00f5062e9ca87d6b2d01b1e9fa66ab15d8636b4"
|
|
62
62
|
}
|