@wdio/browserstack-service 9.0.0-alpha.78 → 9.0.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 (72) hide show
  1. package/README.md +1 -1
  2. package/build/Percy/Percy-Handler.d.ts +1 -1
  3. package/build/Percy/Percy-Handler.d.ts.map +1 -1
  4. package/build/Percy/PercyHelper.d.ts +1 -1
  5. package/build/Percy/PercyHelper.d.ts.map +1 -1
  6. package/build/accessibility-handler.d.ts +2 -2
  7. package/build/accessibility-handler.d.ts.map +1 -1
  8. package/build/ai-handler.d.ts +23 -0
  9. package/build/ai-handler.d.ts.map +1 -0
  10. package/build/constants.d.ts +10 -1
  11. package/build/constants.d.ts.map +1 -1
  12. package/build/crash-reporter.d.ts +2 -2
  13. package/build/crash-reporter.d.ts.map +1 -1
  14. package/build/fileStream.d.ts +0 -2
  15. package/build/fileStream.d.ts.map +1 -1
  16. package/build/index.js +5822 -12
  17. package/build/insights-handler.d.ts +5 -1
  18. package/build/insights-handler.d.ts.map +1 -1
  19. package/build/instrumentation/funnelInstrumentation.d.ts +2 -0
  20. package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -1
  21. package/build/launcher.d.ts +6 -6
  22. package/build/launcher.d.ts.map +1 -1
  23. package/build/performance-tester.d.ts +0 -1
  24. package/build/performance-tester.d.ts.map +1 -1
  25. package/build/reporter.d.ts.map +1 -1
  26. package/build/service.d.ts +4 -4
  27. package/build/service.d.ts.map +1 -1
  28. package/build/testOps/listener.d.ts +1 -0
  29. package/build/testOps/listener.d.ts.map +1 -1
  30. package/build/types.d.ts +9 -3
  31. package/build/types.d.ts.map +1 -1
  32. package/build/util.d.ts +43 -30
  33. package/build/util.d.ts.map +1 -1
  34. package/package.json +13 -10
  35. package/build/Percy/Percy-Handler.js +0 -156
  36. package/build/Percy/Percy.js +0 -123
  37. package/build/Percy/PercyBinary.js +0 -142
  38. package/build/Percy/PercyCaptureMap.js +0 -35
  39. package/build/Percy/PercyHelper.js +0 -67
  40. package/build/Percy/PercyLogger.js +0 -67
  41. package/build/Percy/PercySDK.js +0 -39
  42. package/build/accessibility-handler.js +0 -287
  43. package/build/bstackLogger.js +0 -70
  44. package/build/cleanup.js +0 -89
  45. package/build/config.js +0 -39
  46. package/build/constants.js +0 -73
  47. package/build/crash-reporter.js +0 -138
  48. package/build/cucumber-types.js +0 -1
  49. package/build/data-store.js +0 -41
  50. package/build/exitHandler.js +0 -29
  51. package/build/fetchWrapper.js +0 -14
  52. package/build/fileStream.js +0 -12
  53. package/build/insights-handler.js +0 -719
  54. package/build/instrumentation/funnelInstrumentation.js +0 -120
  55. package/build/launcher.js +0 -741
  56. package/build/log4jsAppender.js +0 -19
  57. package/build/logPatcher.js +0 -38
  58. package/build/logReportingAPI.js +0 -56
  59. package/build/performance-tester.js +0 -94
  60. package/build/reporter.js +0 -251
  61. package/build/request-handler.js +0 -74
  62. package/build/scripts/accessibility-scripts.js +0 -61
  63. package/build/service.js +0 -428
  64. package/build/testOps/featureStats.js +0 -116
  65. package/build/testOps/featureUsage.js +0 -47
  66. package/build/testOps/listener.js +0 -222
  67. package/build/testOps/requestUtils.js +0 -39
  68. package/build/testOps/testOpsConfig.js +0 -19
  69. package/build/testOps/usageStats.js +0 -114
  70. package/build/types.js +0 -1
  71. package/build/util.js +0 -1132
  72. /package/{LICENSE-MIT → LICENSE} +0 -0
@@ -1,138 +0,0 @@
1
- import { BSTACK_SERVICE_VERSION, DATA_ENDPOINT, TESTOPS_BUILD_ID_ENV } from './constants.js';
2
- import { DEFAULT_REQUEST_CONFIG, getObservabilityKey, getObservabilityUser } from './util.js';
3
- import { BStackLogger } from './bstackLogger.js';
4
- export default class CrashReporter {
5
- /* User test config for build run minus PII */
6
- static userConfigForReporting = {};
7
- /* User credentials used for reporting crashes in browserstack service */
8
- static credentialsForCrashReportUpload = {};
9
- static setCredentialsForCrashReportUpload(options, config) {
10
- this.credentialsForCrashReportUpload = {
11
- username: getObservabilityUser(options, config),
12
- password: getObservabilityKey(options, config)
13
- };
14
- process.env.CREDENTIALS_FOR_CRASH_REPORTING = JSON.stringify(this.credentialsForCrashReportUpload);
15
- }
16
- static setConfigDetails(userConfig, capabilities, options) {
17
- const configWithoutPII = this.filterPII(userConfig);
18
- const filteredCapabilities = this.filterCapabilities(capabilities);
19
- this.userConfigForReporting = {
20
- framework: userConfig.framework,
21
- services: configWithoutPII.services,
22
- capabilities: filteredCapabilities,
23
- env: {
24
- 'BROWSERSTACK_BUILD': process.env.BROWSERSTACK_BUILD,
25
- 'BROWSERSTACK_BUILD_NAME': process.env.BROWSERSTACK_BUILD_NAME,
26
- 'BUILD_TAG': process.env.BUILD_TAG
27
- }
28
- };
29
- process.env.USER_CONFIG_FOR_REPORTING = JSON.stringify(this.userConfigForReporting);
30
- this.setCredentialsForCrashReportUpload(options, userConfig);
31
- }
32
- static async uploadCrashReport(exception, stackTrace) {
33
- try {
34
- if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
35
- this.credentialsForCrashReportUpload = process.env.CREDENTIALS_FOR_CRASH_REPORTING !== undefined ? JSON.parse(process.env.CREDENTIALS_FOR_CRASH_REPORTING) : this.credentialsForCrashReportUpload;
36
- }
37
- }
38
- catch (error) {
39
- return BStackLogger.error(`[Crash_Report_Upload] Failed to parse user credentials while reporting crash due to ${error}`);
40
- }
41
- if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
42
- return BStackLogger.error('[Crash_Report_Upload] Failed to parse user credentials while reporting crash');
43
- }
44
- try {
45
- if (Object.keys(this.userConfigForReporting).length === 0) {
46
- this.userConfigForReporting = process.env.USER_CONFIG_FOR_REPORTING !== undefined ? JSON.parse(process.env.USER_CONFIG_FOR_REPORTING) : {};
47
- }
48
- }
49
- catch (error) {
50
- BStackLogger.error(`[Crash_Report_Upload] Failed to parse user config while reporting crash due to ${error}`);
51
- this.userConfigForReporting = {};
52
- }
53
- const data = {
54
- hashed_id: process.env[TESTOPS_BUILD_ID_ENV],
55
- observability_version: {
56
- frameworkName: 'WebdriverIO-' + (this.userConfigForReporting.framework || 'null'),
57
- sdkVersion: BSTACK_SERVICE_VERSION
58
- },
59
- exception: {
60
- error: exception.toString(),
61
- stackTrace: stackTrace
62
- },
63
- config: this.userConfigForReporting
64
- };
65
- const url = `${DATA_ENDPOINT}/api/v1/analytics`;
66
- const encodedAuth = Buffer.from(`${this.credentialsForCrashReportUpload.username}:${this.credentialsForCrashReportUpload.password}`, 'utf8').toString('base64');
67
- const headers = {
68
- ...DEFAULT_REQUEST_CONFIG.headers,
69
- Authorization: `Basic ${encodedAuth}`,
70
- };
71
- const response = await fetch(url, {
72
- method: 'POST',
73
- body: JSON.stringify(data),
74
- headers
75
- });
76
- if (response.ok) {
77
- BStackLogger.debug(`[Crash_Report_Upload] Success response: ${JSON.stringify(await response.json())}`);
78
- }
79
- else {
80
- BStackLogger.error(`[Crash_Report_Upload] Failed due to ${response.body}`);
81
- }
82
- }
83
- static recursivelyRedactKeysFromObject(obj, keys) {
84
- if (!obj) {
85
- return;
86
- }
87
- if (Array.isArray(obj)) {
88
- obj.map(ele => this.recursivelyRedactKeysFromObject(ele, keys));
89
- }
90
- else {
91
- for (const prop in obj) {
92
- if (keys.includes(prop.toLowerCase())) {
93
- obj[prop] = '[REDACTED]';
94
- }
95
- else if (typeof obj[prop] === 'object') {
96
- this.recursivelyRedactKeysFromObject(obj[prop], keys);
97
- }
98
- }
99
- }
100
- }
101
- static deletePIIKeysFromObject(obj) {
102
- if (!obj) {
103
- return;
104
- }
105
- ['user', 'username', 'key', 'accessKey'].forEach(key => delete obj[key]);
106
- }
107
- static filterCapabilities(capabilities) {
108
- const capsCopy = JSON.parse(JSON.stringify(capabilities));
109
- this.recursivelyRedactKeysFromObject(capsCopy, ['extensions']);
110
- return capsCopy;
111
- }
112
- static filterPII(userConfig) {
113
- const configWithoutPII = JSON.parse(JSON.stringify(userConfig));
114
- this.deletePIIKeysFromObject(configWithoutPII);
115
- const finalServices = [];
116
- const initialServices = configWithoutPII.services;
117
- delete configWithoutPII.services;
118
- try {
119
- for (const serviceArray of initialServices) {
120
- if (Array.isArray(serviceArray) && serviceArray.length >= 2 && serviceArray[0] === 'browserstack') {
121
- for (let idx = 1; idx < serviceArray.length; idx++) {
122
- this.deletePIIKeysFromObject(serviceArray[idx]);
123
- serviceArray[idx] && this.deletePIIKeysFromObject(serviceArray[idx].testObservabilityOptions);
124
- }
125
- finalServices.push(serviceArray);
126
- break;
127
- }
128
- }
129
- }
130
- catch (err) {
131
- /* Wrong configuration like strings instead of json objects could break this method, needs no action */
132
- BStackLogger.error(`Error in parsing user config PII with error ${err ? (err.stack || err) : err}`);
133
- return configWithoutPII;
134
- }
135
- configWithoutPII.services = finalServices;
136
- return configWithoutPII;
137
- }
138
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,41 +0,0 @@
1
- import path from 'node:path';
2
- import fs from 'node:fs';
3
- import { BStackLogger } from './bstackLogger.js';
4
- const workersDataDirPath = path.join(process.cwd(), 'logs', 'worker_data');
5
- export function getDataFromWorkers() {
6
- const workersData = [];
7
- if (!fs.existsSync(workersDataDirPath)) {
8
- return workersData;
9
- }
10
- const files = fs.readdirSync(workersDataDirPath);
11
- files.forEach((file) => {
12
- BStackLogger.debug('Reading worker file ' + file);
13
- const filePath = path.join(workersDataDirPath, file);
14
- const fileContent = fs.readFileSync(filePath, 'utf8');
15
- const workerData = JSON.parse(fileContent);
16
- workersData.push(workerData);
17
- });
18
- // Remove worker data after all reading
19
- removeWorkersDataDir();
20
- return workersData;
21
- }
22
- export function saveWorkerData(data) {
23
- const filePath = path.join(workersDataDirPath, 'worker-data-' + process.pid + '.json');
24
- try {
25
- createWorkersDataDir();
26
- fs.writeFileSync(filePath, JSON.stringify(data));
27
- }
28
- catch (e) {
29
- BStackLogger.debug('Exception in saving worker data: ' + e);
30
- }
31
- }
32
- function removeWorkersDataDir() {
33
- fs.rmSync(workersDataDirPath, { recursive: true, force: true });
34
- return true;
35
- }
36
- function createWorkersDataDir() {
37
- if (!fs.existsSync(workersDataDirPath)) {
38
- fs.mkdirSync(workersDataDirPath, { recursive: true });
39
- }
40
- return true;
41
- }
@@ -1,29 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import path from 'node:path';
3
- import BrowserStackConfig from './config.js';
4
- import { saveFunnelData } from './instrumentation/funnelInstrumentation.js';
5
- import { fileURLToPath } from 'node:url';
6
- import { TESTOPS_JWT_ENV } from './constants.js';
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = path.dirname(__filename);
9
- export function setupExitHandlers() {
10
- process.on('exit', (code) => {
11
- const args = shouldCallCleanup(BrowserStackConfig.getInstance());
12
- if (Array.isArray(args) && args.length) {
13
- const childProcess = spawn('node', [`${path.join(__dirname, 'cleanup.js')}`, ...args], { detached: true, stdio: 'inherit', env: { ...process.env } });
14
- childProcess.unref();
15
- process.exit(code);
16
- }
17
- });
18
- }
19
- export function shouldCallCleanup(config) {
20
- const args = [];
21
- if (!!process.env[TESTOPS_JWT_ENV] && !config.testObservability.buildStopped) {
22
- args.push('--observability');
23
- }
24
- if (config.userName && config.accessKey && !config.funnelDataSent) {
25
- const savedFilePath = saveFunnelData('SDKTestSuccessful', config);
26
- args.push('--funnelData', savedFilePath);
27
- }
28
- return args;
29
- }
@@ -1,14 +0,0 @@
1
- export class ResponseError extends Error {
2
- response;
3
- constructor(message, res) {
4
- super(message);
5
- this.response = res;
6
- }
7
- }
8
- export default async function fetchWrap(input, init) {
9
- const res = await fetch(input, init);
10
- if (!res.ok) {
11
- throw new ResponseError(`Error response from server ${res.status}: ${await res.text()}`, res);
12
- }
13
- return res;
14
- }
@@ -1,12 +0,0 @@
1
- export class FileStream {
2
- readableStream;
3
- constructor(readableStream) {
4
- this.readableStream = readableStream;
5
- }
6
- stream() {
7
- return this.readableStream;
8
- }
9
- get [Symbol.toStringTag]() {
10
- return 'File';
11
- }
12
- }