@wdio/browserstack-service 7.34.0 → 7.36.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 (85) hide show
  1. package/build/Percy/Percy-Handler.d.ts +34 -0
  2. package/build/Percy/Percy-Handler.d.ts.map +1 -0
  3. package/build/Percy/Percy-Handler.js +187 -0
  4. package/build/Percy/Percy.d.ts +24 -0
  5. package/build/Percy/Percy.d.ts.map +1 -0
  6. package/build/Percy/Percy.js +128 -0
  7. package/build/Percy/PercyBinary.d.ts +17 -0
  8. package/build/Percy/PercyBinary.d.ts.map +1 -0
  9. package/build/Percy/PercyBinary.js +151 -0
  10. package/build/Percy/PercyCaptureMap.d.ts +9 -0
  11. package/build/Percy/PercyCaptureMap.d.ts.map +1 -0
  12. package/build/Percy/PercyCaptureMap.js +46 -0
  13. package/build/Percy/PercyHelper.d.ts +8 -0
  14. package/build/Percy/PercyHelper.d.ts.map +1 -0
  15. package/build/Percy/PercyHelper.js +78 -0
  16. package/build/Percy/PercyLogger.d.ts +15 -0
  17. package/build/Percy/PercyLogger.d.ts.map +1 -0
  18. package/build/Percy/PercyLogger.js +76 -0
  19. package/build/Percy/PercySDK.d.ts +4 -0
  20. package/build/Percy/PercySDK.d.ts.map +1 -0
  21. package/build/Percy/PercySDK.js +42 -0
  22. package/build/bstackLogger.d.ts +14 -0
  23. package/build/bstackLogger.d.ts.map +1 -0
  24. package/build/bstackLogger.js +52 -0
  25. package/build/cleanup.d.ts +6 -2
  26. package/build/cleanup.d.ts.map +1 -1
  27. package/build/cleanup.js +104 -12
  28. package/build/config.d.ts +23 -0
  29. package/build/config.d.ts.map +1 -0
  30. package/build/config.js +32 -0
  31. package/build/constants.d.ts +20 -0
  32. package/build/constants.d.ts.map +1 -1
  33. package/build/constants.js +45 -1
  34. package/build/crash-reporter.js +1 -1
  35. package/build/data-store.d.ts +3 -0
  36. package/build/data-store.d.ts.map +1 -0
  37. package/build/data-store.js +49 -0
  38. package/build/exitHandler.d.ts +4 -0
  39. package/build/exitHandler.d.ts.map +1 -0
  40. package/build/exitHandler.js +37 -0
  41. package/build/index.d.ts +2 -0
  42. package/build/index.d.ts.map +1 -1
  43. package/build/index.js +15 -1
  44. package/build/insights-handler.d.ts +5 -11
  45. package/build/insights-handler.d.ts.map +1 -1
  46. package/build/insights-handler.js +45 -106
  47. package/build/instrumentation/funnelInstrumentation.d.ts +6 -0
  48. package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -0
  49. package/build/instrumentation/funnelInstrumentation.js +127 -0
  50. package/build/launcher.d.ts +8 -4
  51. package/build/launcher.d.ts.map +1 -1
  52. package/build/launcher.js +87 -18
  53. package/build/reporter.d.ts +3 -3
  54. package/build/reporter.d.ts.map +1 -1
  55. package/build/reporter.js +10 -23
  56. package/build/request-handler.d.ts +5 -13
  57. package/build/request-handler.d.ts.map +1 -1
  58. package/build/request-handler.js +27 -48
  59. package/build/service.d.ts +3 -0
  60. package/build/service.d.ts.map +1 -1
  61. package/build/service.js +50 -18
  62. package/build/testOps/featureStats.d.ts +45 -0
  63. package/build/testOps/featureStats.d.ts.map +1 -0
  64. package/build/testOps/featureStats.js +120 -0
  65. package/build/testOps/featureUsage.d.ts +22 -0
  66. package/build/testOps/featureUsage.d.ts.map +1 -0
  67. package/build/testOps/featureUsage.js +46 -0
  68. package/build/testOps/listener.d.ts +33 -0
  69. package/build/testOps/listener.d.ts.map +1 -0
  70. package/build/testOps/listener.js +228 -0
  71. package/build/testOps/requestUtils.d.ts +4 -0
  72. package/build/testOps/requestUtils.d.ts.map +1 -0
  73. package/build/testOps/requestUtils.js +47 -0
  74. package/build/testOps/testOpsConfig.d.ts +11 -0
  75. package/build/testOps/testOpsConfig.d.ts.map +1 -0
  76. package/build/testOps/testOpsConfig.js +17 -0
  77. package/build/testOps/usageStats.d.ts +404 -0
  78. package/build/testOps/usageStats.d.ts.map +1 -0
  79. package/build/testOps/usageStats.js +110 -0
  80. package/build/types.d.ts +48 -7
  81. package/build/types.d.ts.map +1 -1
  82. package/build/util.d.ts +4 -6
  83. package/build/util.d.ts.map +1 -1
  84. package/build/util.js +82 -67
  85. package/package.json +7 -4
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ // ======= Percy helper methods start =======
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getBestPlatformForPercySnapshot = exports.stopPercy = exports.startPercy = void 0;
8
+ const PercyLogger_1 = require("./PercyLogger");
9
+ const Percy_1 = __importDefault(require("./Percy"));
10
+ const startPercy = async (options, config, bsConfig) => {
11
+ PercyLogger_1.PercyLogger.debug('Starting percy');
12
+ const percy = new Percy_1.default(options, config, bsConfig);
13
+ const response = await percy.start();
14
+ if (response) {
15
+ return percy;
16
+ }
17
+ return {};
18
+ };
19
+ exports.startPercy = startPercy;
20
+ const stopPercy = async (percy) => {
21
+ PercyLogger_1.PercyLogger.debug('Stopping percy');
22
+ return percy.stop();
23
+ };
24
+ exports.stopPercy = stopPercy;
25
+ const getBestPlatformForPercySnapshot = (capabilities) => {
26
+ try {
27
+ const percyBrowserPreference = { 'chrome': 0, 'firefox': 1, 'edge': 2, 'safari': 3 };
28
+ let bestPlatformCaps = null;
29
+ let bestBrowser = null;
30
+ if (Array.isArray(capabilities)) {
31
+ capabilities
32
+ .flatMap((c) => {
33
+ if (Object.values(c).length > 0 && Object.values(c).every(c => typeof c === 'object' && c.capabilities)) {
34
+ return Object.values(c).map((o) => o.capabilities);
35
+ }
36
+ return c;
37
+ }).forEach((capability) => {
38
+ var _a;
39
+ let currBrowserName = capability.browserName;
40
+ if (capability['bstack:options']) {
41
+ currBrowserName = capability['bstack:options'].browserName || currBrowserName;
42
+ }
43
+ if (!bestBrowser || !bestPlatformCaps || (bestPlatformCaps.deviceName || ((_a = bestPlatformCaps['bstack:options']) === null || _a === void 0 ? void 0 : _a.deviceName))) {
44
+ bestBrowser = currBrowserName;
45
+ bestPlatformCaps = capability;
46
+ }
47
+ else if (currBrowserName && percyBrowserPreference[currBrowserName.toLowerCase()] < percyBrowserPreference[bestBrowser.toLowerCase()]) {
48
+ bestBrowser = currBrowserName;
49
+ bestPlatformCaps = capability;
50
+ }
51
+ });
52
+ return bestPlatformCaps;
53
+ }
54
+ else if (typeof capabilities === 'object') {
55
+ Object.entries(capabilities).forEach(([, caps]) => {
56
+ var _a, _b;
57
+ let currBrowserName = caps.capabilities.browserName;
58
+ if (caps.capabilities['bstack:options']) {
59
+ currBrowserName = ((_a = caps.capabilities['bstack:options']) === null || _a === void 0 ? void 0 : _a.browserName) || currBrowserName;
60
+ }
61
+ if (!bestBrowser || !bestPlatformCaps || (bestPlatformCaps.deviceName || ((_b = bestPlatformCaps['bstack:options']) === null || _b === void 0 ? void 0 : _b.deviceName))) {
62
+ bestBrowser = currBrowserName;
63
+ bestPlatformCaps = caps.capabilities;
64
+ }
65
+ else if (currBrowserName && percyBrowserPreference[currBrowserName.toLowerCase()] < percyBrowserPreference[bestBrowser.toLowerCase()]) {
66
+ bestBrowser = currBrowserName;
67
+ bestPlatformCaps = caps.capabilities;
68
+ }
69
+ });
70
+ return bestPlatformCaps;
71
+ }
72
+ }
73
+ catch (err) {
74
+ PercyLogger_1.PercyLogger.error(`Error while trying to determine best platform for Percy snapshot ${err}`);
75
+ return null;
76
+ }
77
+ };
78
+ exports.getBestPlatformForPercySnapshot = getBestPlatformForPercySnapshot;
@@ -0,0 +1,15 @@
1
+ export declare class PercyLogger {
2
+ static logFilePath: string;
3
+ private static logFolderPath;
4
+ private static logFileStream;
5
+ static logToFile(logMessage: string, logLevel: string): void;
6
+ private static formatLog;
7
+ static info(message: string): void;
8
+ static error(message: string): void;
9
+ static debug(message: string, param?: any): void;
10
+ static warn(message: string): void;
11
+ static trace(message: string): void;
12
+ static clearLogger(): void;
13
+ static clearLogFile(): void;
14
+ }
15
+ //# sourceMappingURL=PercyLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PercyLogger.d.ts","sourceRoot":"","sources":["../../src/Percy/PercyLogger.ts"],"names":[],"mappings":"AASA,qBAAa,WAAW;IACpB,OAAc,WAAW,SAA4C;IACrE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAmC;IAC/D,OAAO,CAAC,MAAM,CAAC,aAAa,CAAuB;IAEnD,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAgBrD,OAAO,CAAC,MAAM,CAAC,SAAS;WAIV,IAAI,CAAC,OAAO,EAAE,MAAM;WAKpB,KAAK,CAAC,OAAO,EAAE,MAAM;WAKrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG;WASlC,IAAI,CAAC,OAAO,EAAE,MAAM;WAKpB,KAAK,CAAC,OAAO,EAAE,MAAM;WAKrB,WAAW;WAOX,YAAY;CAS7B"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PercyLogger = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const logger_1 = __importDefault(require("@wdio/logger"));
10
+ const constants_1 = require("../constants");
11
+ const log = (0, logger_1.default)('@wdio/browserstack-service');
12
+ class PercyLogger {
13
+ static logToFile(logMessage, logLevel) {
14
+ try {
15
+ if (!this.logFileStream) {
16
+ if (!node_fs_1.default.existsSync(this.logFolderPath)) {
17
+ node_fs_1.default.mkdirSync(this.logFolderPath);
18
+ }
19
+ this.logFileStream = node_fs_1.default.createWriteStream(this.logFilePath, { flags: 'a' });
20
+ }
21
+ if (this.logFileStream && this.logFileStream.writable) {
22
+ this.logFileStream.write(this.formatLog(logMessage, logLevel));
23
+ }
24
+ }
25
+ catch (error) {
26
+ log.debug(`Failed to log to file. Error ${error}`);
27
+ }
28
+ }
29
+ static formatLog(logMessage, level) {
30
+ return `${new Date().toISOString()} ${level.toUpperCase()} @wdio/browserstack-service ${logMessage}\n`;
31
+ }
32
+ static info(message) {
33
+ this.logToFile(message, 'info');
34
+ log.info(message);
35
+ }
36
+ static error(message) {
37
+ this.logToFile(message, 'error');
38
+ log.error(message);
39
+ }
40
+ static debug(message, param) {
41
+ this.logToFile(message, 'debug');
42
+ if (param) {
43
+ log.debug(message, param);
44
+ }
45
+ else {
46
+ log.debug(message);
47
+ }
48
+ }
49
+ static warn(message) {
50
+ this.logToFile(message, 'warn');
51
+ log.warn(message);
52
+ }
53
+ static trace(message) {
54
+ this.logToFile(message, 'trace');
55
+ log.trace(message);
56
+ }
57
+ static clearLogger() {
58
+ if (this.logFileStream) {
59
+ this.logFileStream.end();
60
+ }
61
+ this.logFileStream = null;
62
+ }
63
+ static clearLogFile() {
64
+ try {
65
+ if (node_fs_1.default.existsSync(this.logFilePath)) {
66
+ node_fs_1.default.truncateSync(this.logFilePath);
67
+ }
68
+ }
69
+ catch (err) {
70
+ log.error(`Failed to clear percy.log file. Error ${err}`);
71
+ }
72
+ }
73
+ }
74
+ exports.PercyLogger = PercyLogger;
75
+ PercyLogger.logFilePath = node_path_1.default.join(process.cwd(), constants_1.PERCY_LOGS_FILE);
76
+ PercyLogger.logFolderPath = node_path_1.default.join(process.cwd(), 'logs');
@@ -0,0 +1,4 @@
1
+ export declare const snapshot: (...args: any[]) => void;
2
+ export declare const screenshot: (...args: any[]) => Promise<void>;
3
+ export declare const screenshotApp: (...args: any[]) => Promise<void>;
4
+ //# sourceMappingURL=PercySDK.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PercySDK.d.ts","sourceRoot":"","sources":["../../src/Percy/PercySDK.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,QAAQ,YAVW,GAAG,EAAE,SAUE,CAAA;AASvC,eAAO,MAAM,UAAU,YANiB,GAAG,EAAE,kBAMF,CAAA;AAS3C,eAAO,MAAM,aAAa,YANiB,GAAG,EAAE,kBAMC,CAAA"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.screenshotApp = exports.screenshot = exports.snapshot = void 0;
4
+ const tryRequire = function (pkg, fallback) {
5
+ try {
6
+ return require(pkg);
7
+ }
8
+ catch {
9
+ return fallback;
10
+ }
11
+ };
12
+ const percySnapshot = tryRequire('@percy/selenium-webdriver', null);
13
+ const percyAppScreenshot = tryRequire('@percy/appium-app', {});
14
+ const PercyLogger_1 = require("./PercyLogger");
15
+ /* eslint-disable @typescript-eslint/no-unused-vars */
16
+ let snapshotHandler = (...args) => {
17
+ PercyLogger_1.PercyLogger.error('Unsupported driver for percy');
18
+ };
19
+ if (percySnapshot) {
20
+ snapshotHandler = (browser, name) => {
21
+ if (process.env.PERCY_SNAPSHOT === 'true') {
22
+ return percySnapshot(browser, name);
23
+ }
24
+ };
25
+ }
26
+ exports.snapshot = snapshotHandler;
27
+ /* eslint-disable @typescript-eslint/no-unused-vars */
28
+ let screenshotHandler = async (...args) => {
29
+ PercyLogger_1.PercyLogger.error('Unsupported driver for percy');
30
+ };
31
+ if (percySnapshot && percySnapshot.percyScreenshot) {
32
+ screenshotHandler = percySnapshot.percyScreenshot;
33
+ }
34
+ exports.screenshot = screenshotHandler;
35
+ /* eslint-disable @typescript-eslint/no-unused-vars */
36
+ let screenshotAppHandler = async (...args) => {
37
+ PercyLogger_1.PercyLogger.error('Unsupported driver for percy');
38
+ };
39
+ if (percyAppScreenshot) {
40
+ screenshotAppHandler = percyAppScreenshot;
41
+ }
42
+ exports.screenshotApp = screenshotAppHandler;
@@ -0,0 +1,14 @@
1
+ export declare class BStackLogger {
2
+ static logFilePath: string;
3
+ static logFolderPath: string;
4
+ private static logFileStream;
5
+ static info(message: string): void;
6
+ static error(message: string): void;
7
+ static debug(message: string, param?: any): void;
8
+ static warn(message: string): void;
9
+ static trace(message: string): void;
10
+ static clearLogger(): void;
11
+ static clearLogFile(): void;
12
+ static ensureLogsFolder(): void;
13
+ }
14
+ //# sourceMappingURL=bstackLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bstackLogger.d.ts","sourceRoot":"","sources":["../src/bstackLogger.ts"],"names":[],"mappings":"AASA,qBAAa,YAAY;IACrB,OAAc,WAAW,SAAsC;IAC/D,OAAc,aAAa,SAAmC;IAC9D,OAAO,CAAC,MAAM,CAAC,aAAa,CAAuB;WAErC,IAAI,CAAC,OAAO,EAAE,MAAM;WAIpB,KAAK,CAAC,OAAO,EAAE,MAAM;WAIrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG;WAQlC,IAAI,CAAC,OAAO,EAAE,MAAM;WAIpB,KAAK,CAAC,OAAO,EAAE,MAAM;WAIrB,WAAW;WAOX,YAAY;WAMZ,gBAAgB;CAKjC"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BStackLogger = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const logger_1 = __importDefault(require("@wdio/logger"));
10
+ const constants_1 = require("./constants");
11
+ const log = (0, logger_1.default)('@wdio/browserstack-service');
12
+ class BStackLogger {
13
+ static info(message) {
14
+ log.info(message);
15
+ }
16
+ static error(message) {
17
+ log.error(message);
18
+ }
19
+ static debug(message, param) {
20
+ if (param) {
21
+ log.debug(message, param);
22
+ }
23
+ else {
24
+ log.debug(message);
25
+ }
26
+ }
27
+ static warn(message) {
28
+ log.warn(message);
29
+ }
30
+ static trace(message) {
31
+ log.trace(message);
32
+ }
33
+ static clearLogger() {
34
+ if (this.logFileStream) {
35
+ this.logFileStream.end();
36
+ }
37
+ this.logFileStream = null;
38
+ }
39
+ static clearLogFile() {
40
+ if (node_fs_1.default.existsSync(this.logFilePath)) {
41
+ node_fs_1.default.truncateSync(this.logFilePath);
42
+ }
43
+ }
44
+ static ensureLogsFolder() {
45
+ if (!node_fs_1.default.existsSync(this.logFolderPath)) {
46
+ node_fs_1.default.mkdirSync(this.logFolderPath);
47
+ }
48
+ }
49
+ }
50
+ exports.BStackLogger = BStackLogger;
51
+ BStackLogger.logFilePath = node_path_1.default.join(process.cwd(), constants_1.LOGS_FILE);
52
+ BStackLogger.logFolderPath = node_path_1.default.join(process.cwd(), 'logs');
@@ -1,5 +1,9 @@
1
1
  export default class BStackCleanup {
2
- static startCleanup(): void;
3
- static executeObservabilityCleanup(): void;
2
+ static startCleanup(): Promise<void>;
3
+ static executeObservabilityCleanup(funnelData: any): Promise<void>;
4
+ static updateO11yStopData(funnelData: any, status: string, error?: unknown): void;
5
+ static sendFunnelData(funnelData: any): Promise<void>;
6
+ static removeFunnelDataFile(filePath?: string): void;
7
+ static getFunnelDataFromFile(filePath: string): any;
4
8
  }
5
9
  //# sourceMappingURL=cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,aAAa;IAC9B,MAAM,CAAC,YAAY;IAGnB,MAAM,CAAC,2BAA2B;CAarC"}
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,OAAO,OAAO,aAAa;WACjB,YAAY;WAmBZ,2BAA2B,CAAC,UAAU,EAAE,GAAG;IAsBxD,MAAM,CAAC,kBAAkB,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,OAAmB;WAkBxE,cAAc,CAAC,UAAU,EAAE,GAAG;IAS3C,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM;IAO7C,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM;CAWhD"}
package/build/cleanup.js CHANGED
@@ -1,23 +1,115 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
2
28
  Object.defineProperty(exports, "__esModule", { value: true });
3
29
  const util_1 = require("./util");
30
+ const fs_1 = __importDefault(require("fs"));
31
+ const bstackLogger_1 = require("./bstackLogger");
32
+ const funnelInstrumentation_1 = require("./instrumentation/funnelInstrumentation");
33
+ const constants_1 = require("./constants");
34
+ const process = __importStar(require("process"));
4
35
  class BStackCleanup {
5
- static startCleanup() {
6
- this.executeObservabilityCleanup();
36
+ static async startCleanup() {
37
+ // Get funnel data object from saved file
38
+ const funnelDataCleanup = process.argv.includes('--funnelData');
39
+ let funnelData = null;
40
+ if (funnelDataCleanup) {
41
+ const index = process.argv.indexOf('--funnelData');
42
+ const filePath = process.argv[index + 1];
43
+ funnelData = this.getFunnelDataFromFile(filePath);
44
+ }
45
+ if (process.argv.includes('--observability')) {
46
+ await this.executeObservabilityCleanup(funnelData);
47
+ }
48
+ if (funnelDataCleanup && funnelData) {
49
+ await this.sendFunnelData(funnelData);
50
+ }
7
51
  }
8
- static executeObservabilityCleanup() {
9
- if (!process.env.BS_TESTOPS_JWT) {
52
+ static async executeObservabilityCleanup(funnelData) {
53
+ if (!process.env[constants_1.TESTOPS_JWT_ENV]) {
10
54
  return;
11
55
  }
12
- console.log('Executing observability cleanup');
13
- (0, util_1.stopBuildUpstream)().then(() => {
14
- if (process.env.BS_TESTOPS_BUILD_HASHED_ID) {
15
- console.log(`\nVisit https://observability.browserstack.com/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID} to view build report, insights, and many more debugging information all at one place!\n`);
56
+ bstackLogger_1.BStackLogger.debug('Executing observability cleanup');
57
+ try {
58
+ const result = await (0, util_1.stopBuildUpstream)();
59
+ if (process.env[constants_1.TESTOPS_BUILD_ID_ENV]) {
60
+ bstackLogger_1.BStackLogger.info(`\nVisit https://observability.browserstack.com/builds/${process.env[constants_1.TESTOPS_BUILD_ID_ENV]} to view build report, insights, and many more debugging information all at one place!\n`);
16
61
  }
17
- }).catch((err) => {
18
- console.error(err);
19
- });
62
+ const status = (result && result.status) || 'failed';
63
+ const message = (result && result.message);
64
+ this.updateO11yStopData(funnelData, status, status === 'failed' ? message : undefined);
65
+ }
66
+ catch (e) {
67
+ bstackLogger_1.BStackLogger.error('Error in stopping Observability build: ' + e);
68
+ this.updateO11yStopData(funnelData, 'failed', e);
69
+ }
70
+ }
71
+ static updateO11yStopData(funnelData, status, error = undefined) {
72
+ var _a, _b;
73
+ const toData = (_b = (_a = funnelData === null || funnelData === void 0 ? void 0 : funnelData.event_properties) === null || _a === void 0 ? void 0 : _a.productUsage) === null || _b === void 0 ? void 0 : _b.testObservability;
74
+ // Return if no O11y data in funnel data
75
+ if (!toData) {
76
+ return;
77
+ }
78
+ let existingStopData = toData.events.buildEvents.finished;
79
+ existingStopData = existingStopData || {};
80
+ existingStopData = {
81
+ ...existingStopData,
82
+ status,
83
+ error: (0, util_1.getErrorString)(error),
84
+ stoppedFrom: 'exitHook'
85
+ };
86
+ toData.events.buildEvents.finished = existingStopData;
87
+ }
88
+ static async sendFunnelData(funnelData) {
89
+ try {
90
+ await (0, funnelInstrumentation_1.fireFunnelRequest)(funnelData);
91
+ bstackLogger_1.BStackLogger.debug('Funnel data sent successfully from cleanup');
92
+ }
93
+ catch (e) {
94
+ bstackLogger_1.BStackLogger.error('Error in sending funnel data: ' + e);
95
+ }
96
+ }
97
+ static removeFunnelDataFile(filePath) {
98
+ if (!filePath) {
99
+ return;
100
+ }
101
+ fs_1.default.rmSync(filePath, { force: true });
102
+ }
103
+ static getFunnelDataFromFile(filePath) {
104
+ if (!filePath) {
105
+ return null;
106
+ }
107
+ bstackLogger_1.BStackLogger.debug('Getting saved funnel data from file ' + filePath);
108
+ const content = fs_1.default.readFileSync(filePath, 'utf8');
109
+ const data = JSON.parse(content);
110
+ this.removeFunnelDataFile(filePath);
111
+ return data;
20
112
  }
21
113
  }
22
114
  exports.default = BStackCleanup;
23
- BStackCleanup.startCleanup();
115
+ (async () => await BStackCleanup.startCleanup())();
@@ -0,0 +1,23 @@
1
+ import type { AppConfig, BrowserstackConfig } from './types';
2
+ import type { Options } from '@wdio/types';
3
+ import TestOpsConfig from './testOps/testOpsConfig';
4
+ declare class BrowserStackConfig {
5
+ static getInstance(options?: BrowserstackConfig & Options.Testrunner, config?: Options.Testrunner): BrowserStackConfig;
6
+ userName?: string;
7
+ accessKey?: string;
8
+ framework?: string;
9
+ buildName?: string;
10
+ buildIdentifier?: string;
11
+ testObservability: TestOpsConfig;
12
+ percy: boolean;
13
+ accessibility: boolean;
14
+ app?: string | AppConfig;
15
+ private static _instance;
16
+ appAutomate: boolean;
17
+ automate: boolean;
18
+ funnelDataSent: boolean;
19
+ constructor(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner);
20
+ sentFunnelData(): void;
21
+ }
22
+ export default BrowserStackConfig;
23
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAGnD,cAAM,kBAAkB;IACpB,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,GAAG,kBAAkB;IAO/G,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,aAAa,CAAA;IAChC,KAAK,EAAE,OAAO,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,GAAC,SAAS,CAAA;IAC7B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAoB;IACrC,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,EAAE,OAAO,CAAQ;gBAE1B,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IAaxF,cAAc;CAIjB;AAED,eAAe,kBAAkB,CAAA"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const testOpsConfig_1 = __importDefault(require("./testOps/testOpsConfig"));
7
+ const util_1 = require("./util");
8
+ class BrowserStackConfig {
9
+ static getInstance(options, config) {
10
+ if (!this._instance && options && config) {
11
+ this._instance = new BrowserStackConfig(options, config);
12
+ }
13
+ return this._instance;
14
+ }
15
+ constructor(options, config) {
16
+ this.funnelDataSent = false;
17
+ this.framework = config.framework;
18
+ this.userName = config.user;
19
+ this.accessKey = config.key;
20
+ this.testObservability = new testOpsConfig_1.default(options.testObservability !== false, !(0, util_1.isUndefined)(options.testObservability));
21
+ this.percy = options.percy || false;
22
+ this.accessibility = options.accessibility || false;
23
+ this.app = options.app;
24
+ this.appAutomate = !(0, util_1.isUndefined)(options.app);
25
+ this.automate = !this.appAutomate;
26
+ this.buildIdentifier = options.buildIdentifier;
27
+ }
28
+ sentFunnelData() {
29
+ this.funnelDataSent = true;
30
+ }
31
+ }
32
+ exports.default = BrowserStackConfig;
@@ -12,6 +12,26 @@ export declare const DATA_BATCH_INTERVAL = 2000;
12
12
  export declare const BATCH_EVENT_TYPES: string[];
13
13
  export declare const DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = 5000;
14
14
  export declare const DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = 100;
15
+ export declare const BSTACK_SERVICE_VERSION: string;
15
16
  export declare const ACCESSIBILITY_API_URL = "https://accessibility.browserstack.com/api";
16
17
  export declare const NOT_ALLOWED_KEYS_IN_CAPS: string[];
18
+ export declare const LOGS_FILE = "logs/bstack-wdio-service.log";
19
+ export declare const COLORS: Record<string, string>;
20
+ export declare const PERCY_LOGS_FILE = "logs/percy.log";
21
+ export declare const PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS: string[];
22
+ export declare const CAPTURE_MODES: string[];
23
+ export declare const LOG_KIND_USAGE_MAP: {
24
+ TEST_LOG: string;
25
+ TEST_SCREENSHOT: string;
26
+ TEST_STEP: string;
27
+ HTTP: string;
28
+ };
29
+ export declare const FUNNEL_INSTRUMENTATION_URL = "https://api.browserstack.com/sdk/v1/event";
30
+ export declare const TESTOPS_JWT_ENV = "BS_TESTOPS_JWT";
31
+ export declare const TESTOPS_SCREENSHOT_ENV = "BS_TESTOPS_ALLOW_SCREENSHOTS";
32
+ export declare const TESTOPS_BUILD_ID_ENV = "BS_TESTOPS_BUILD_HASHED_ID";
33
+ export declare const PERF_MEASUREMENT_ENV = "BROWSERSTACK_O11Y_PERF_MEASUREMENT";
34
+ export declare const RERUN_TESTS_ENV = "BROWSERSTACK_RERUN_TESTS";
35
+ export declare const RERUN_ENV = "BROWSERSTACK_RERUN";
36
+ export declare const TESTOPS_BUILD_COMPLETED_ENV = "BS_TESTOPS_BUILD_COMPLETED";
17
37
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,eAAO,MAAM,mBAAmB,qHAStB,CAAA;AAEV,eAAO,MAAM,mBAAmB,UAI/B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,kBAAkB,CAKvD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,OAAO,OAAoC,CAAA;AACvE,eAAO,MAAM,aAAa,qDAAqD,CAAA;AAC/E,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,iBAAiB,UAAgH,CAAA;AAC9I,eAAO,MAAM,wCAAwC,OAAO,CAAA;AAC5D,eAAO,MAAM,yCAAyC,MAAM,CAAA;AAE5D,eAAO,MAAM,qBAAqB,+CAA+C,CAAA;AACjF,eAAO,MAAM,wBAAwB,UAA6D,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGjD,eAAO,MAAM,mBAAmB,qHAStB,CAAA;AAEV,eAAO,MAAM,mBAAmB,UAI/B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,kBAAkB,CAKvD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,OAAO,OAAoC,CAAA;AACvE,eAAO,MAAM,aAAa,qDAAqD,CAAA;AAC/E,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,iBAAiB,UAAgH,CAAA;AAC9I,eAAO,MAAM,wCAAwC,OAAO,CAAA;AAC5D,eAAO,MAAM,yCAAyC,MAAM,CAAA;AAE5D,eAAO,MAAM,sBAAsB,QAAuB,CAAA;AAE1D,eAAO,MAAM,qBAAqB,+CAA+C,CAAA;AACjF,eAAO,MAAM,wBAAwB,UAA6D,CAAA;AAElG,eAAO,MAAM,SAAS,iCAAiC,CAAA;AACvD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOzC,CAAA;AAED,eAAO,MAAM,eAAe,mBAAmB,CAAA;AAE/C,eAAO,MAAM,qCAAqC,UAQjD,CAAA;AAED,eAAO,MAAM,aAAa,UAAwD,CAAA;AAElF,eAAO,MAAM,kBAAkB;;;;;CAK9B,CAAA;AAED,eAAO,MAAM,0BAA0B,8CAA8C,CAAA;AAKrF,eAAO,MAAM,eAAe,mBAAmB,CAAA;AAG/C,eAAO,MAAM,sBAAsB,iCAAiC,CAAA;AAGpE,eAAO,MAAM,oBAAoB,+BAA+B,CAAA;AAGhE,eAAO,MAAM,oBAAoB,uCAAuC,CAAA;AAGxE,eAAO,MAAM,eAAe,6BAA6B,CAAA;AAGzD,eAAO,MAAM,SAAS,uBAAuB,CAAA;AAG7C,eAAO,MAAM,2BAA2B,+BAA+B,CAAA"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NOT_ALLOWED_KEYS_IN_CAPS = exports.ACCESSIBILITY_API_URL = exports.DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = exports.DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = exports.BATCH_EVENT_TYPES = exports.DATA_BATCH_INTERVAL = exports.DATA_BATCH_SIZE = exports.DATA_SCREENSHOT_ENDPOINT = exports.DATA_BATCH_ENDPOINT = exports.DATA_EVENT_ENDPOINT = exports.DATA_ENDPOINT = exports.consoleHolder = exports.DEFAULT_OPTIONS = exports.VALID_APP_EXTENSION = exports.BROWSER_DESCRIPTION = void 0;
3
+ exports.TESTOPS_BUILD_COMPLETED_ENV = exports.RERUN_ENV = exports.RERUN_TESTS_ENV = exports.PERF_MEASUREMENT_ENV = exports.TESTOPS_BUILD_ID_ENV = exports.TESTOPS_SCREENSHOT_ENV = exports.TESTOPS_JWT_ENV = exports.FUNNEL_INSTRUMENTATION_URL = exports.LOG_KIND_USAGE_MAP = exports.CAPTURE_MODES = exports.PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS = exports.PERCY_LOGS_FILE = exports.COLORS = exports.LOGS_FILE = exports.NOT_ALLOWED_KEYS_IN_CAPS = exports.ACCESSIBILITY_API_URL = exports.BSTACK_SERVICE_VERSION = exports.DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = exports.DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = exports.BATCH_EVENT_TYPES = exports.DATA_BATCH_INTERVAL = exports.DATA_BATCH_SIZE = exports.DATA_SCREENSHOT_ENDPOINT = exports.DATA_BATCH_ENDPOINT = exports.DATA_EVENT_ENDPOINT = exports.DATA_ENDPOINT = exports.consoleHolder = exports.DEFAULT_OPTIONS = exports.VALID_APP_EXTENSION = exports.BROWSER_DESCRIPTION = void 0;
4
+ const package_json_1 = require("../package.json");
4
5
  exports.BROWSER_DESCRIPTION = [
5
6
  'device',
6
7
  'os',
@@ -32,5 +33,48 @@ exports.DATA_BATCH_INTERVAL = 2000;
32
33
  exports.BATCH_EVENT_TYPES = ['LogCreated', 'TestRunStarted', 'TestRunFinished', 'HookRunFinished', 'HookRunStarted', 'ScreenshotCreated'];
33
34
  exports.DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = 5000; // 5s
34
35
  exports.DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = 100; // 100ms
36
+ exports.BSTACK_SERVICE_VERSION = package_json_1.version;
35
37
  exports.ACCESSIBILITY_API_URL = 'https://accessibility.browserstack.com/api';
36
38
  exports.NOT_ALLOWED_KEYS_IN_CAPS = ['includeTagsInTestingScope', 'excludeTagsInTestingScope'];
39
+ exports.LOGS_FILE = 'logs/bstack-wdio-service.log';
40
+ exports.COLORS = {
41
+ error: 'red',
42
+ warn: 'yellow',
43
+ info: 'cyanBright',
44
+ debug: 'green',
45
+ trace: 'cyan',
46
+ progress: 'magenta'
47
+ };
48
+ exports.PERCY_LOGS_FILE = 'logs/percy.log';
49
+ exports.PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS = [
50
+ '/session/:sessionId/url',
51
+ '/session/:sessionId/forward',
52
+ '/session/:sessionId/back',
53
+ '/session/:sessionId/refresh',
54
+ '/session/:sessionId/screenshot',
55
+ '/session/:sessionId/actions',
56
+ '/session/:sessionId/appium/device/shake'
57
+ ];
58
+ exports.CAPTURE_MODES = ['click', 'auto', 'screenshot', 'manual', 'testcase'];
59
+ exports.LOG_KIND_USAGE_MAP = {
60
+ 'TEST_LOG': 'log',
61
+ 'TEST_SCREENSHOT': 'screenshot',
62
+ 'TEST_STEP': 'step',
63
+ 'HTTP': 'http'
64
+ };
65
+ exports.FUNNEL_INSTRUMENTATION_URL = 'https://api.browserstack.com/sdk/v1/event';
66
+ // Env variables - Define all the env variable constants over here
67
+ // To store the JWT token returned the session launch
68
+ exports.TESTOPS_JWT_ENV = 'BS_TESTOPS_JWT';
69
+ // To store the setting of whether to send screenshots or not
70
+ exports.TESTOPS_SCREENSHOT_ENV = 'BS_TESTOPS_ALLOW_SCREENSHOTS';
71
+ // To store build hashed id
72
+ exports.TESTOPS_BUILD_ID_ENV = 'BS_TESTOPS_BUILD_HASHED_ID';
73
+ // Whether to collect performance instrumentation or not
74
+ exports.PERF_MEASUREMENT_ENV = 'BROWSERSTACK_O11Y_PERF_MEASUREMENT';
75
+ // Whether the current run is rerun or not
76
+ exports.RERUN_TESTS_ENV = 'BROWSERSTACK_RERUN_TESTS';
77
+ // The tests that needs to be rerun
78
+ exports.RERUN_ENV = 'BROWSERSTACK_RERUN';
79
+ // To store whether the build launch has completed or not
80
+ exports.TESTOPS_BUILD_COMPLETED_ENV = 'BS_TESTOPS_BUILD_COMPLETED';
@@ -55,7 +55,7 @@ class CrashReporter {
55
55
  this.userConfigForReporting = {};
56
56
  }
57
57
  const data = {
58
- hashed_id: process.env.BS_TESTOPS_BUILD_HASHED_ID,
58
+ hashed_id: process.env[constants_1.TESTOPS_BUILD_ID_ENV],
59
59
  observability_version: {
60
60
  frameworkName: 'WebdriverIO-' + (this.userConfigForReporting.framework || 'null'),
61
61
  sdkVersion: package_json_1.version
@@ -0,0 +1,3 @@
1
+ export declare function getDataFromWorkers(): Record<string, object>[];
2
+ export declare function saveWorkerData(data: Record<string, any>): void;
3
+ //# sourceMappingURL=data-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-store.d.ts","sourceRoot":"","sources":["../src/data-store.ts"],"names":[],"mappings":"AAOA,wBAAgB,kBAAkB,6BAoBjC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QASvD"}