@wdio/browserstack-service 7.34.0 → 7.35.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 (39) 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/constants.d.ts +3 -0
  23. package/build/constants.d.ts.map +1 -1
  24. package/build/constants.js +12 -1
  25. package/build/index.d.ts +2 -0
  26. package/build/index.d.ts.map +1 -1
  27. package/build/index.js +15 -1
  28. package/build/launcher.d.ts +7 -2
  29. package/build/launcher.d.ts.map +1 -1
  30. package/build/launcher.js +68 -0
  31. package/build/service.d.ts +2 -0
  32. package/build/service.d.ts.map +1 -1
  33. package/build/service.js +38 -14
  34. package/build/types.d.ts +15 -0
  35. package/build/types.d.ts.map +1 -1
  36. package/build/util.d.ts +2 -0
  37. package/build/util.d.ts.map +1 -1
  38. package/build/util.js +23 -2
  39. 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;
@@ -14,4 +14,7 @@ export declare const DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = 5000;
14
14
  export declare const DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = 100;
15
15
  export declare const ACCESSIBILITY_API_URL = "https://accessibility.browserstack.com/api";
16
16
  export declare const NOT_ALLOWED_KEYS_IN_CAPS: string[];
17
+ export declare const PERCY_LOGS_FILE = "logs/percy.log";
18
+ export declare const PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS: string[];
19
+ export declare const CAPTURE_MODES: string[];
17
20
  //# 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;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;AAElG,eAAO,MAAM,eAAe,mBAAmB,CAAA;AAE/C,eAAO,MAAM,qCAAqC,UAQjD,CAAA;AAED,eAAO,MAAM,aAAa,UAAwD,CAAA"}
@@ -1,6 +1,6 @@
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.CAPTURE_MODES = exports.PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS = exports.PERCY_LOGS_FILE = 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;
4
4
  exports.BROWSER_DESCRIPTION = [
5
5
  'device',
6
6
  'os',
@@ -34,3 +34,14 @@ exports.DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = 5000; // 5s
34
34
  exports.DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = 100; // 100ms
35
35
  exports.ACCESSIBILITY_API_URL = 'https://accessibility.browserstack.com/api';
36
36
  exports.NOT_ALLOWED_KEYS_IN_CAPS = ['includeTagsInTestingScope', 'excludeTagsInTestingScope'];
37
+ exports.PERCY_LOGS_FILE = 'logs/percy.log';
38
+ exports.PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS = [
39
+ '/session/:sessionId/url',
40
+ '/session/:sessionId/forward',
41
+ '/session/:sessionId/back',
42
+ '/session/:sessionId/refresh',
43
+ '/session/:sessionId/screenshot',
44
+ '/session/:sessionId/actions',
45
+ '/session/:sessionId/appium/device/shake'
46
+ ];
47
+ exports.CAPTURE_MODES = ['click', 'auto', 'screenshot', 'manual', 'testcase'];
package/build/index.d.ts CHANGED
@@ -8,6 +8,8 @@ export declare const log4jsAppender: {
8
8
  configure: (config: any, layouts: any) => Function;
9
9
  };
10
10
  export declare const BStackTestOpsLogger: typeof logReportingAPI;
11
+ import * as Percy from './Percy/PercySDK';
12
+ export declare const PercySDK: typeof Percy;
11
13
  export * from './types';
12
14
  declare global {
13
15
  namespace WebdriverIO {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,MAAM,YAAY,CAAA;AAC7C,OAAO,mBAAmB,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAE/C,eAAe,mBAAmB,CAAA;AAClC,eAAO,MAAM,QAAQ,6BAAuB,CAAA;AAC5C,eAAO,MAAM,cAAc;;CAAgB,CAAA;AAC3C,eAAO,MAAM,mBAAmB,wBAAkB,CAAA;AAClD,cAAc,SAAS,CAAA;AAEvB,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,aAAc,SAAQ,kBAAkB;SAAG;KACxD;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,MAAM,YAAY,CAAA;AAC7C,OAAO,mBAAmB,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAE/C,eAAe,mBAAmB,CAAA;AAClC,eAAO,MAAM,QAAQ,6BAAuB,CAAA;AAC5C,eAAO,MAAM,cAAc;;CAAgB,CAAA;AAC3C,eAAO,MAAM,mBAAmB,wBAAkB,CAAA;AAElD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AACzC,eAAO,MAAM,QAAQ,cAAQ,CAAA;AAE7B,cAAc,SAAS,CAAA;AAEvB,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,aAAc,SAAQ,kBAAkB;SAAG;KACxD;CACJ"}
package/build/index.js CHANGED
@@ -11,6 +11,18 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
11
11
  if (k2 === undefined) k2 = k;
12
12
  o[k2] = m[k];
13
13
  }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
14
26
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
27
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
28
  };
@@ -18,7 +30,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
30
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
31
  };
20
32
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.BStackTestOpsLogger = exports.log4jsAppender = exports.launcher = void 0;
33
+ exports.PercySDK = exports.BStackTestOpsLogger = exports.log4jsAppender = exports.launcher = void 0;
22
34
  const launcher_1 = __importDefault(require("./launcher"));
23
35
  const service_1 = __importDefault(require("./service"));
24
36
  const log4jsAppender_1 = require("./log4jsAppender");
@@ -27,4 +39,6 @@ exports.default = service_1.default;
27
39
  exports.launcher = launcher_1.default;
28
40
  exports.log4jsAppender = { configure: log4jsAppender_1.configure };
29
41
  exports.BStackTestOpsLogger = logReportingAPI_1.default;
42
+ const Percy = __importStar(require("./Percy/PercySDK"));
43
+ exports.PercySDK = Percy;
30
44
  __exportStar(require("./types"), exports);
@@ -1,9 +1,9 @@
1
1
  import * as BrowserstackLocalLauncher from 'browserstack-local';
2
2
  import type { Capabilities, Services, Options } from '@wdio/types';
3
- import type { App, AppConfig, AppUploadResponse, BrowserstackConfig } from './types';
3
+ import type { App, AppConfig, AppUploadResponse, BrowserstackConfig, UserConfig } from './types';
4
4
  type BrowserstackLocal = BrowserstackLocalLauncher.Local & {
5
5
  pid?: number;
6
- stop(callback: (err?: any) => void): void;
6
+ stop(callback: (err?: Error) => void): void;
7
7
  };
8
8
  export default class BrowserstackLauncherService implements Services.ServiceInstance {
9
9
  private _options;
@@ -14,11 +14,16 @@ export default class BrowserstackLauncherService implements Services.ServiceInst
14
14
  private _buildTag?;
15
15
  private _buildIdentifier?;
16
16
  private _accessibilityAutomation?;
17
+ private _percy?;
18
+ private _percyBestPlatformCaps?;
17
19
  _testOpsBuildStopped?: boolean;
18
20
  constructor(_options: BrowserstackConfig & Options.Testrunner, capabilities: Capabilities.RemoteCapability, _config: Options.Testrunner);
21
+ onWorkerStart(cid: any, caps: any): Promise<void>;
19
22
  setupExitHandlers(): void;
20
23
  onPrepare(config?: Options.Testrunner, capabilities?: Capabilities.RemoteCapabilities): Promise<unknown>;
21
24
  onComplete(): Promise<unknown>;
25
+ setupPercy(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner, bsConfig: UserConfig): Promise<void>;
26
+ stopPercy(): Promise<void>;
22
27
  _uploadApp(app: App): Promise<AppUploadResponse>;
23
28
  /**
24
29
  * @param {String | AppConfig} appConfig <string>: should be "app file path" or "app_url" or "custom_id" or "shareable_id".
@@ -1 +1 @@
1
- {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAMlE,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAkBpF,KAAK,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7C,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,2BAA4B,YAAW,QAAQ,CAAC,eAAe;IAU5E,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,OAAO;IAXnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAQ;IACjC,OAAO,CAAC,wBAAwB,CAAC,CAAS;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAA;gBAGzB,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACzD,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IA+FvC,iBAAiB;IAUX,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IA4ItF,UAAU;IA6DV,UAAU,CAAC,GAAG,EAAC,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkBrD;;;OAGG;IACG,YAAY,CAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBhE,qBAAqB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KAAE;IAiFvH,WAAW,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAC,MAAM;IAoF3F,sBAAsB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IAyCrE;;;OAGG;IACH,oBAAoB;IA6BpB,sBAAsB,CAAC,QAAQ,CAAC,EAAC,MAAM,EAAE,SAAS,CAAC,EAAC,MAAM,EAAE,eAAe,CAAC,EAAC,MAAM;CAQtF"}
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAOlE,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAqBhG,KAAK,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CAC/C,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,2BAA4B,YAAW,QAAQ,CAAC,eAAe;IAY5E,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,OAAO;IAbnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAQ;IACjC,OAAO,CAAC,wBAAwB,CAAC,CAAS;IAC1C,OAAO,CAAC,MAAM,CAAC,CAAO;IACtB,OAAO,CAAC,sBAAsB,CAAC,CAAkC;IAC1D,oBAAoB,CAAC,EAAE,OAAO,CAAA;gBAGzB,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACzD,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IAgGjC,aAAa,CAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;IAaxC,iBAAiB;IAUX,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IAwJtF,UAAU;IAmEV,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU;IAuB7G,SAAS;IAYT,UAAU,CAAC,GAAG,EAAC,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkBrD;;;OAGG;IACG,YAAY,CAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBhE,qBAAqB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KAAE;IAiFvH,WAAW,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAC,MAAM;IAoF3F,sBAAsB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IAyCrE;;;OAGG;IACH,oBAAoB;IA6BpB,sBAAsB,CAAC,QAAQ,CAAC,EAAC,MAAM,EAAE,SAAS,CAAC,EAAC,MAAM,EAAE,eAAe,CAAC,EAAC,MAAM;CAQtF"}
package/build/launcher.js CHANGED
@@ -40,14 +40,17 @@ const node_child_process_1 = require("node:child_process");
40
40
  // @ts-ignore
41
41
  const package_json_1 = require("../package.json");
42
42
  const crash_reporter_1 = __importDefault(require("./crash-reporter"));
43
+ const PercyHelper_1 = require("./Percy/PercyHelper");
43
44
  const constants_1 = require("./constants");
44
45
  const util_2 = require("./util");
45
46
  const performance_tester_1 = __importDefault(require("./performance-tester"));
47
+ const PercyLogger_1 = require("./Percy/PercyLogger");
46
48
  const log = (0, logger_1.default)('@wdio/browserstack-service');
47
49
  class BrowserstackLauncherService {
48
50
  constructor(_options, capabilities, _config) {
49
51
  this._options = _options;
50
52
  this._config = _config;
53
+ PercyLogger_1.PercyLogger.clearLogFile();
51
54
  // added to maintain backward compatibility with webdriverIO v5
52
55
  this.setupExitHandlers();
53
56
  this._config || (this._config = _options);
@@ -143,6 +146,19 @@ class BrowserstackLauncherService {
143
146
  log.error(`[Crash_Report_Upload] Config processing failed due to ${error}`);
144
147
  }
145
148
  }
149
+ async onWorkerStart(cid, caps) {
150
+ try {
151
+ if (this._options.percy && this._percyBestPlatformCaps) {
152
+ const isThisBestPercyPlatform = (0, util_2.ObjectsAreEqual)(caps, this._percyBestPlatformCaps);
153
+ if (isThisBestPercyPlatform) {
154
+ process.env.BEST_PLATFORM_CID = cid;
155
+ }
156
+ }
157
+ }
158
+ catch (err) {
159
+ PercyLogger_1.PercyLogger.error(`Error while setting best platform for Percy snapshot at worker start ${err}`);
160
+ }
161
+ }
146
162
  setupExitHandlers() {
147
163
  process.on('exit', (code) => {
148
164
  if (!!process.env.BS_TESTOPS_JWT && !this._testOpsBuildStopped) {
@@ -239,6 +255,18 @@ class BrowserstackLauncherService {
239
255
  buildIdentifier: this._buildIdentifier
240
256
  });
241
257
  }
258
+ if (this._options.percy) {
259
+ try {
260
+ const bestPlatformPercyCaps = (0, PercyHelper_1.getBestPlatformForPercySnapshot)(capabilities);
261
+ this._percyBestPlatformCaps = bestPlatformPercyCaps;
262
+ await this.setupPercy(this._options, this._config, {
263
+ projectName: this._projectName
264
+ });
265
+ }
266
+ catch (err) {
267
+ PercyLogger_1.PercyLogger.error(`Error while setting up Percy ${err}`);
268
+ }
269
+ }
242
270
  if (!this._options.browserstackLocal) {
243
271
  return log.info('browserstackLocal is not enabled - skipping...');
244
272
  }
@@ -302,6 +330,10 @@ class BrowserstackLauncherService {
302
330
  const duration = (new Date()).getTime() - (new Date(process.env.START_TIME)).getTime();
303
331
  log.info(`Total duration is ${duration / 1000} s`);
304
332
  }
333
+ if (this._options.percy) {
334
+ await this.stopPercy();
335
+ }
336
+ PercyLogger_1.PercyLogger.clearLogger();
305
337
  if (!this.browserstackLocal || !this.browserstackLocal.isRunning()) {
306
338
  return;
307
339
  }
@@ -331,6 +363,42 @@ class BrowserstackLauncherService {
331
363
  return Promise.reject(err);
332
364
  });
333
365
  }
366
+ async setupPercy(options, config, bsConfig) {
367
+ var _a;
368
+ if ((_a = this._percy) === null || _a === void 0 ? void 0 : _a.isRunning()) {
369
+ return;
370
+ }
371
+ try {
372
+ this._percy = await (0, PercyHelper_1.startPercy)(options, config, bsConfig);
373
+ if (!this._percy) {
374
+ throw new Error('Could not start percy, check percy logs for info.');
375
+ }
376
+ PercyLogger_1.PercyLogger.info('Percy started successfully');
377
+ let signal = 0;
378
+ const handler = async () => {
379
+ signal++;
380
+ signal === 1 && await this.stopPercy();
381
+ };
382
+ process.on('beforeExit', handler);
383
+ process.on('SIGINT', handler);
384
+ process.on('SIGTERM', handler);
385
+ }
386
+ catch (err) {
387
+ PercyLogger_1.PercyLogger.debug(`Error in percy setup ${err}`);
388
+ }
389
+ }
390
+ async stopPercy() {
391
+ if (!this._percy || !this._percy.isRunning()) {
392
+ return;
393
+ }
394
+ try {
395
+ await (0, PercyHelper_1.stopPercy)(this._percy);
396
+ PercyLogger_1.PercyLogger.info('Percy stopped');
397
+ }
398
+ catch (err) {
399
+ PercyLogger_1.PercyLogger.error(`Error occured while stopping percy : ${err}`);
400
+ }
401
+ }
334
402
  async _uploadApp(app) {
335
403
  log.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ''} to browserstack`);
336
404
  const form = new form_data_1.default();
@@ -20,6 +20,8 @@ export default class BrowserstackService implements Services.ServiceInstance {
20
20
  private _accessibility;
21
21
  private _accessibilityHandler?;
22
22
  private _turboScale;
23
+ private _percy;
24
+ private _percyHandler?;
23
25
  constructor(options: BrowserstackConfig & Options.Testrunner, _caps: Capabilities.RemoteCapability, _config: Options.Testrunner);
24
26
  _updateCaps(fn: (caps: Capabilities.Capabilities | Capabilities.DesiredCapabilities) => void): void;
25
27
  beforeSession(config: Omit<Options.Testrunner, 'capabilities'>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAA8C,MAAM,SAAS,CAAA;AAKhH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAiB7F,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,QAAQ,CAAC,eAAe;IAqBpE,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IArBnB,OAAO,CAAC,eAAe,CAAmD;IAC1E,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,gBAAgB,CAA4D;IACpF,OAAO,CAAC,QAAQ,CAAC,CAAgD;IACjE,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,cAAc,CAAA;IACtB,OAAO,CAAC,YAAY,CAAC,CAA0C;IAC/D,OAAO,CAAC,gBAAgB,CAAC,CAAiB;IAC1C,OAAO,CAAC,cAAc,CAAA;IACtB,OAAO,CAAC,qBAAqB,CAAC,CAAsB;IACpD,OAAO,CAAC,WAAW,CAAA;IACnB,OAAO,CAAC,MAAM,CAAA;IACd,OAAO,CAAC,aAAa,CAAC,CAAc;gBAGhC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACxC,KAAK,EAAE,YAAY,CAAC,gBAAgB,EACpC,OAAO,EAAE,OAAO,CAAC,UAAU;IAiCvC,WAAW,CAAE,EAAE,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,GAAG,YAAY,CAAC,mBAAmB,KAAK,IAAI;IAU7F,aAAa,CAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC;IAgBzD,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;IA4F1H;;;;;;OAMG;IACG,WAAW,CAAE,KAAK,EAAE,UAAU,CAAC,KAAK;IAQpC,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI,GAAC,YAAY,EAAE,OAAO,EAAE,GAAG;IAK5D,SAAS,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI,GAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,UAAU;IAI9F,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI;IAoBjC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,UAAU;IAY/E,KAAK,CAAE,MAAM,EAAE,MAAM;IAiC3B;;OAEG;IAEG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAOjD;;;OAGG;IACG,cAAc,CAAE,KAAK,EAAE,sBAAsB;IAQ7C,aAAa,CAAE,KAAK,EAAE,sBAAsB;IAwB5C,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM;IAKzD,SAAS,CAAE,IAAI,EAAE,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,YAAY;IAIzF,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IA+BzD,cAAc,IAAI,OAAO;IAOzB,UAAU,CAAE,WAAW,EAAE,GAAG;IAU5B,kBAAkB,CAAE,MAAM,EAAE,iBAAiB;IAqB7C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG;IAsBrC,gBAAgB;YAiCR,eAAe;IA4B7B,OAAO,CAAC,cAAc;YAIR,eAAe;CAqBhC"}
package/build/service.js CHANGED
@@ -12,6 +12,7 @@ const util_1 = require("./util");
12
12
  const reporter_1 = __importDefault(require("./reporter"));
13
13
  const performance_tester_1 = __importDefault(require("./performance-tester"));
14
14
  const accessibility_handler_1 = __importDefault(require("./accessibility-handler"));
15
+ const Percy_Handler_1 = __importDefault(require("./Percy/Percy-Handler"));
15
16
  const log = (0, logger_1.default)('@wdio/browserstack-service');
16
17
  class BrowserstackService {
17
18
  constructor(options, _caps, _config) {
@@ -28,6 +29,7 @@ class BrowserstackService {
28
29
  this._config || (this._config = this._options);
29
30
  this._observability = this._options.testObservability;
30
31
  this._accessibility = this._options.accessibility;
32
+ this._percy = this._options.percy;
31
33
  this._turboScale = this._options.turboScale;
32
34
  if (this._observability) {
33
35
  (_a = this._config.reporters) === null || _a === void 0 ? void 0 : _a.push(reporter_1.default);
@@ -44,6 +46,9 @@ class BrowserstackService {
44
46
  if (strict) {
45
47
  this._failureStatuses.push('pending');
46
48
  }
49
+ if (process.env.WDIO_WORKER_ID === process.env.BEST_PLATFORM_CID) {
50
+ process.env.PERCY_SNAPSHOT = 'true';
51
+ }
47
52
  }
48
53
  _updateCaps(fn) {
49
54
  const multiRemoteCap = this._caps;
@@ -77,29 +82,43 @@ class BrowserstackService {
77
82
  this._sessionBaseUrl = 'https://api.browserstack.com/automate-turboscale/v1/sessions';
78
83
  }
79
84
  this._scenariosThatRan = [];
80
- if (this._observability && this._browser) {
85
+ if (this._browser) {
86
+ if (this._percy) {
87
+ this._percyHandler = new Percy_Handler_1.default(this._options.percyCaptureMode, this._browser, this._caps, this._isAppAutomate(), this._config.framework);
88
+ this._percyHandler.before();
89
+ }
81
90
  try {
82
- (0, util_1.patchConsoleLogs)();
83
- this._insightsHandler = new insights_handler_1.default(this._browser, this._browser.capabilities, this._isAppAutomate(), this._browser.sessionId, this._config.framework);
84
- await this._insightsHandler.before();
91
+ if (this._observability) {
92
+ (0, util_1.patchConsoleLogs)();
93
+ this._insightsHandler = new insights_handler_1.default(this._browser, this._browser.capabilities, this._isAppAutomate(), this._browser.sessionId, this._config.framework);
94
+ await this._insightsHandler.before();
95
+ }
85
96
  /**
86
97
  * register command event
87
98
  */
88
99
  this._browser.on('command', async (command) => {
89
- var _a, _b;
90
- return await ((_a = this._insightsHandler) === null || _a === void 0 ? void 0 : _a.browserCommand('client:beforeCommand', Object.assign(command, { sessionId: (_b = this._browser) === null || _b === void 0 ? void 0 : _b.sessionId }), this._currentTest));
100
+ var _a, _b, _c, _d;
101
+ if (this._observability) {
102
+ await ((_a = this._insightsHandler) === null || _a === void 0 ? void 0 : _a.browserCommand('client:beforeCommand', Object.assign(command, { sessionId: (_b = this._browser) === null || _b === void 0 ? void 0 : _b.sessionId }), this._currentTest));
103
+ }
104
+ await ((_c = this._percyHandler) === null || _c === void 0 ? void 0 : _c.browserBeforeCommand(Object.assign(command, { sessionId: (_d = this._browser) === null || _d === void 0 ? void 0 : _d.sessionId })));
91
105
  });
92
106
  /**
93
107
  * register result event
94
108
  */
95
109
  this._browser.on('result', async (result) => {
96
- var _a, _b;
97
- return await ((_a = this._insightsHandler) === null || _a === void 0 ? void 0 : _a.browserCommand('client:afterCommand', Object.assign(result, { sessionId: (_b = this._browser) === null || _b === void 0 ? void 0 : _b.sessionId }), this._currentTest));
110
+ var _a, _b, _c, _d;
111
+ if (this._observability) {
112
+ await ((_a = this._insightsHandler) === null || _a === void 0 ? void 0 : _a.browserCommand('client:afterCommand', Object.assign(result, { sessionId: (_b = this._browser) === null || _b === void 0 ? void 0 : _b.sessionId }), this._currentTest));
113
+ }
114
+ (_c = this._percyHandler) === null || _c === void 0 ? void 0 : _c.browserAfterCommand(Object.assign(result, { sessionId: (_d = this._browser) === null || _d === void 0 ? void 0 : _d.sessionId }));
98
115
  });
99
116
  }
100
117
  catch (err) {
101
118
  log.error(`Error in service class before function: ${err}`);
102
- crash_reporter_1.default.uploadCrashReport(`Error in service class before function: ${err}`, err && err.stack);
119
+ if (this._observability) {
120
+ crash_reporter_1.default.uploadCrashReport(`Error in service class before function: ${err}`, err && err.stack);
121
+ }
103
122
  }
104
123
  }
105
124
  if (this._browser && (0, util_1.isBrowserstackSession)(this._browser)) {
@@ -159,17 +178,18 @@ class BrowserstackService {
159
178
  await ((_c = this._accessibilityHandler) === null || _c === void 0 ? void 0 : _c.beforeTest(suiteTitle, test));
160
179
  }
161
180
  async afterTest(test, context, results) {
162
- var _a, _b;
181
+ var _a, _b, _c;
163
182
  this._specsRan = true;
164
183
  const { error, passed } = results;
165
184
  if (!passed) {
166
185
  this._failReasons.push((error && error.message) || 'Unknown Error');
167
186
  }
168
187
  await ((_a = this._insightsHandler) === null || _a === void 0 ? void 0 : _a.afterTest(test, results));
169
- await ((_b = this._accessibilityHandler) === null || _b === void 0 ? void 0 : _b.afterTest(this._suiteTitle, test));
188
+ await ((_b = this._percyHandler) === null || _b === void 0 ? void 0 : _b.afterTest());
189
+ await ((_c = this._accessibilityHandler) === null || _c === void 0 ? void 0 : _c.afterTest(this._suiteTitle, test));
170
190
  }
171
191
  async after(result) {
172
- var _a, _b;
192
+ var _a, _b, _c;
173
193
  const { preferScenarioName, setSessionName, setSessionStatus } = this._options;
174
194
  // For Cucumber: Checks scenarios that ran (i.e. not skipped) on the session
175
195
  // Only 1 Scenario ran and option enabled => Redefine session name to Scenario's name
@@ -186,6 +206,7 @@ class BrowserstackService {
186
206
  }
187
207
  await ((_a = this._insightsHandler) === null || _a === void 0 ? void 0 : _a.uploadPending());
188
208
  await ((_b = this._insightsHandler) === null || _b === void 0 ? void 0 : _b.teardown());
209
+ await ((_c = this._percyHandler) === null || _c === void 0 ? void 0 : _c.teardown());
189
210
  if (process.env.BROWSERSTACK_O11Y_PERF_MEASUREMENT) {
190
211
  await performance_tester_1.default.stopAndGenerate('performance-service.html');
191
212
  performance_tester_1.default.calculateTimes([
@@ -219,7 +240,7 @@ class BrowserstackService {
219
240
  await this._setAnnotation(`Scenario: ${scenarioName}`);
220
241
  }
221
242
  async afterScenario(world) {
222
- var _a, _b, _c;
243
+ var _a, _b, _c, _d;
223
244
  this._specsRan = true;
224
245
  const status = (_a = world.result) === null || _a === void 0 ? void 0 : _a.status.toLowerCase();
225
246
  if (status !== 'skipped') {
@@ -233,7 +254,8 @@ class BrowserstackService {
233
254
  this._failReasons.push(exception);
234
255
  }
235
256
  await ((_b = this._insightsHandler) === null || _b === void 0 ? void 0 : _b.afterScenario(world));
236
- await ((_c = this._accessibilityHandler) === null || _c === void 0 ? void 0 : _c.afterScenario(world));
257
+ await ((_c = this._percyHandler) === null || _c === void 0 ? void 0 : _c.afterScenario());
258
+ await ((_d = this._accessibilityHandler) === null || _d === void 0 ? void 0 : _d.afterScenario(world));
237
259
  }
238
260
  async beforeStep(step, scenario) {
239
261
  var _a;
@@ -348,6 +370,7 @@ class BrowserstackService {
348
370
  });
349
371
  }
350
372
  async _setSessionName(suiteTitle, test) {
373
+ var _a;
351
374
  if (!this._options.setSessionName || !suiteTitle) {
352
375
  return;
353
376
  }
@@ -361,6 +384,7 @@ class BrowserstackService {
361
384
  const post = !this._options.sessionNameOmitTestTitle ? ` - ${test.title}` : '';
362
385
  name = `${pre}${test.parent}${post}`;
363
386
  }
387
+ (_a = this._percyHandler) === null || _a === void 0 ? void 0 : _a._setSessionName(name);
364
388
  if (name !== this._fullTitle) {
365
389
  this._fullTitle = name;
366
390
  await this._updateJob({ name });