@wdio/browserstack-service 7.37.1 → 7.38.1
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/ai-handler.d.ts +24 -0
- package/build/ai-handler.d.ts.map +1 -0
- package/build/ai-handler.js +175 -0
- package/build/constants.d.ts +9 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +15 -1
- package/build/insights-handler.d.ts.map +1 -1
- package/build/insights-handler.js +2 -2
- package/build/instrumentation/funnelInstrumentation.d.ts +2 -0
- package/build/instrumentation/funnelInstrumentation.d.ts.map +1 -1
- package/build/instrumentation/funnelInstrumentation.js +85 -1
- package/build/launcher.d.ts +3 -3
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +34 -2
- package/build/reporter.js +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +17 -3
- package/build/types.d.ts +3 -0
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +35 -39
- package/build/util.d.ts.map +1 -1
- package/build/util.js +121 -6
- package/package.json +3 -2
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Capabilities } from '@wdio/types';
|
|
2
|
+
import type BrowserStackConfig from './config';
|
|
3
|
+
import type { Options } from '@wdio/types';
|
|
4
|
+
import type { BrowserstackHealing } from '@browserstack/ai-sdk-node';
|
|
5
|
+
import { Browser, MultiRemoteBrowser } from 'webdriverio';
|
|
6
|
+
import type { BrowserstackOptions } from './types';
|
|
7
|
+
declare class AiHandler {
|
|
8
|
+
authResult: BrowserstackHealing.InitSuccessResponse | BrowserstackHealing.InitErrorResponse;
|
|
9
|
+
wdioBstackVersion: string;
|
|
10
|
+
constructor();
|
|
11
|
+
authenticateUser(user: string, key: string): Promise<BrowserstackHealing.InitErrorResponse | BrowserstackHealing.InitSuccessResponse>;
|
|
12
|
+
updateCaps(authResult: BrowserstackHealing.InitSuccessResponse | BrowserstackHealing.InitErrorResponse, options: BrowserstackOptions, caps: Array<Capabilities.RemoteCapability> | Capabilities.RemoteCapability): Capabilities.RemoteCapability | Capabilities.RemoteCapability[];
|
|
13
|
+
setToken(sessionId: string, sessionToken: string): Promise<void>;
|
|
14
|
+
installFirefoxExtension(browser: Browser<'async'> | MultiRemoteBrowser<'async'>): Promise<void>;
|
|
15
|
+
handleHealing(orginalFunc: (arg0: string, arg1: string) => any, using: string, value: string, browser: Browser<'async'> | MultiRemoteBrowser<'async'>, options: BrowserstackOptions): Promise<any>;
|
|
16
|
+
addMultiRemoteCaps(authResult: BrowserstackHealing.InitSuccessResponse | BrowserstackHealing.InitErrorResponse, config: Options.Testrunner, browserStackConfig: BrowserStackConfig, options: BrowserstackOptions, caps: any, browser: string): void;
|
|
17
|
+
handleMultiRemoteSetup(authResult: BrowserstackHealing.InitSuccessResponse | BrowserstackHealing.InitErrorResponse, config: Options.Testrunner, browserStackConfig: BrowserStackConfig, options: BrowserstackOptions, caps: any): void;
|
|
18
|
+
setup(config: Options.Testrunner, browserStackConfig: BrowserStackConfig, options: BrowserstackOptions, caps: any, isMultiremote: boolean): Promise<any>;
|
|
19
|
+
handleSelfHeal(options: BrowserstackOptions, browser: Browser<'async'> | MultiRemoteBrowser<'async'>): Promise<void>;
|
|
20
|
+
selfHeal(options: BrowserstackOptions, caps: Capabilities.RemoteCapability, browser: Browser<'async'> | MultiRemoteBrowser<'async'>): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
declare const _default: AiHandler;
|
|
23
|
+
export default _default;
|
|
24
|
+
//# sourceMappingURL=ai-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-handler.d.ts","sourceRoot":"","sources":["../src/ai-handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,kBAAkB,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD,cAAM,SAAS;IACX,UAAU,EAAE,mBAAmB,CAAC,mBAAmB,GAAG,mBAAmB,CAAC,iBAAiB,CAAA;IAC3F,iBAAiB,EAAE,MAAM,CAAA;;IAMnB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAIhD,UAAU,CACN,UAAU,EAAE,mBAAmB,CAAC,mBAAmB,GAAG,mBAAmB,CAAC,iBAAiB,EAC3F,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAC,gBAAgB;IAkBxE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IAIhD,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;IAM/E,aAAa,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,mBAAmB;IAoDzL,kBAAkB,CACd,UAAU,EAAE,mBAAmB,CAAC,mBAAmB,GAAG,mBAAmB,CAAC,iBAAiB,EAC3F,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,kBAAkB,EAAE,kBAAkB,EACtC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,MAAM;IAcnB,sBAAsB,CAClB,UAAU,EAAE,mBAAmB,CAAC,mBAAmB,GAAG,mBAAmB,CAAC,iBAAiB,EAC3F,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,kBAAkB,EAAE,kBAAkB,EACtC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,GAAG;IASP,KAAK,CACP,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,kBAAkB,EAAE,kBAAkB,EACtC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,GAAG,EACT,aAAa,EAAE,OAAO;IA0BpB,cAAc,CAAC,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;IA0BpG,QAAQ,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;CAmB5I;;AAED,wBAA8B"}
|
|
@@ -0,0 +1,175 @@
|
|
|
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 node_fs_1 = __importDefault(require("node:fs"));
|
|
7
|
+
const ai_sdk_node_1 = __importDefault(require("@browserstack/ai-sdk-node"));
|
|
8
|
+
const bstackLogger_1 = require("./bstackLogger");
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
const funnelInstrumentation_1 = require("./instrumentation/funnelInstrumentation");
|
|
11
|
+
const util_1 = require("./util");
|
|
12
|
+
class AiHandler {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.authResult = JSON.parse(process.env[constants_1.BSTACK_TCG_AUTH_RESULT] || '{}');
|
|
15
|
+
this.wdioBstackVersion = constants_1.BSTACK_SERVICE_VERSION;
|
|
16
|
+
}
|
|
17
|
+
async authenticateUser(user, key) {
|
|
18
|
+
return await ai_sdk_node_1.default.BrowserstackHealing.init(key, user, constants_1.TCG_URL, this.wdioBstackVersion);
|
|
19
|
+
}
|
|
20
|
+
updateCaps(authResult, options, caps) {
|
|
21
|
+
const installExtCondition = authResult.isAuthenticated === true && (authResult.defaultLogDataEnabled === true || options.selfHeal === true);
|
|
22
|
+
if (installExtCondition) {
|
|
23
|
+
if (Array.isArray(caps)) {
|
|
24
|
+
const newCaps = ai_sdk_node_1.default.BrowserstackHealing.initializeCapabilities(caps[0]);
|
|
25
|
+
caps[0] = newCaps;
|
|
26
|
+
}
|
|
27
|
+
else if (typeof caps === 'object') {
|
|
28
|
+
caps = ai_sdk_node_1.default.BrowserstackHealing.initializeCapabilities(caps);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (options.selfHeal === true) {
|
|
32
|
+
const healingWarnMessage = authResult.message;
|
|
33
|
+
bstackLogger_1.BStackLogger.warn(`Healing Auth failed. Disabling healing for this session. Reason: ${healingWarnMessage}`);
|
|
34
|
+
}
|
|
35
|
+
return caps;
|
|
36
|
+
}
|
|
37
|
+
async setToken(sessionId, sessionToken) {
|
|
38
|
+
await ai_sdk_node_1.default.BrowserstackHealing.setToken(sessionId, sessionToken, constants_1.TCG_URL);
|
|
39
|
+
}
|
|
40
|
+
async installFirefoxExtension(browser) {
|
|
41
|
+
const extensionPath = ai_sdk_node_1.default.BrowserstackHealing.getFirefoxAddonPath();
|
|
42
|
+
const extFile = node_fs_1.default.readFileSync(extensionPath);
|
|
43
|
+
await browser.installAddOn(extFile.toString('base64'), true);
|
|
44
|
+
}
|
|
45
|
+
async handleHealing(orginalFunc, using, value, browser, options) {
|
|
46
|
+
const sessionId = browser.sessionId;
|
|
47
|
+
// a utility function to escape single and double quotes
|
|
48
|
+
const escapeString = (str) => str.replace(/'/g, "\\'").replace(/"/g, '\\"');
|
|
49
|
+
const tcgDetails = escapeString(JSON.stringify({
|
|
50
|
+
region: constants_1.TCG_INFO.tcgRegion,
|
|
51
|
+
tcgUrls: {
|
|
52
|
+
[constants_1.TCG_INFO.tcgRegion]: {
|
|
53
|
+
endpoint: constants_1.TCG_INFO.tcgUrl.split('://')[1]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
const locatorType = escapeString(using);
|
|
58
|
+
const locatorValue = escapeString(value);
|
|
59
|
+
this.authResult = this.authResult;
|
|
60
|
+
try {
|
|
61
|
+
const result = await orginalFunc(using, value);
|
|
62
|
+
if (!result.error) {
|
|
63
|
+
const script = await ai_sdk_node_1.default.BrowserstackHealing.logData(locatorType, locatorValue, undefined, undefined, this.authResult.groupId, sessionId, undefined, tcgDetails);
|
|
64
|
+
if (script) {
|
|
65
|
+
await browser.execute(script);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
if (options.selfHeal === true && this.authResult.isHealingEnabled) {
|
|
70
|
+
bstackLogger_1.BStackLogger.info('findElement failed, trying to heal');
|
|
71
|
+
const script = await ai_sdk_node_1.default.BrowserstackHealing.healFailure(locatorType, locatorValue, undefined, undefined, this.authResult.userId, this.authResult.groupId, sessionId, undefined, undefined, this.authResult.isGroupAIEnabled, tcgDetails);
|
|
72
|
+
if (script) {
|
|
73
|
+
await browser.execute(script);
|
|
74
|
+
const tcgData = await ai_sdk_node_1.default.BrowserstackHealing.pollResult(constants_1.TCG_URL, sessionId, this.authResult.sessionToken);
|
|
75
|
+
if (tcgData && tcgData.selector && tcgData.value) {
|
|
76
|
+
const healedResult = await orginalFunc(tcgData.selector, tcgData.value);
|
|
77
|
+
bstackLogger_1.BStackLogger.info('Healing worked, element found: ' + tcgData.selector + ': ' + tcgData.value);
|
|
78
|
+
return healedResult.error ? result : healedResult;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (options.selfHeal === true) {
|
|
85
|
+
bstackLogger_1.BStackLogger.warn('Something went wrong while healing. Disabling healing for this command');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
bstackLogger_1.BStackLogger.warn('Error in findElement: ' + err + 'using: ' + using + 'value: ' + value);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return await orginalFunc(using, value);
|
|
92
|
+
}
|
|
93
|
+
addMultiRemoteCaps(authResult, config, browserStackConfig, options, caps, browser) {
|
|
94
|
+
var _a, _b, _c;
|
|
95
|
+
if (caps[browser].capabilities &&
|
|
96
|
+
!((0, util_1.isBrowserstackInfra)(caps[browser])) &&
|
|
97
|
+
constants_1.SUPPORTED_BROWSERS_FOR_AI.includes((_c = (_b = (_a = caps[browser]) === null || _a === void 0 ? void 0 : _a.capabilities) === null || _b === void 0 ? void 0 : _b.browserName) === null || _c === void 0 ? void 0 : _c.toLowerCase())) {
|
|
98
|
+
const innerConfig = (0, util_1.getBrowserStackUserAndKey)(config, options);
|
|
99
|
+
if ((innerConfig === null || innerConfig === void 0 ? void 0 : innerConfig.user) && innerConfig.key) {
|
|
100
|
+
(0, funnelInstrumentation_1.handleHealingInstrumentation)(authResult, browserStackConfig, options.selfHeal);
|
|
101
|
+
caps[browser].capabilities = this.updateCaps(authResult, options, caps[browser].capabilities);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
handleMultiRemoteSetup(authResult, config, browserStackConfig, options, caps) {
|
|
106
|
+
const browserNames = Object.keys(caps);
|
|
107
|
+
for (let i = 0; i < browserNames.length; i++) {
|
|
108
|
+
const browser = browserNames[i];
|
|
109
|
+
this.addMultiRemoteCaps(authResult, config, browserStackConfig, options, caps, browser);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async setup(config, browserStackConfig, options, caps, isMultiremote) {
|
|
113
|
+
var _a;
|
|
114
|
+
try {
|
|
115
|
+
const innerConfig = (0, util_1.getBrowserStackUserAndKey)(config, options);
|
|
116
|
+
if ((innerConfig === null || innerConfig === void 0 ? void 0 : innerConfig.user) && innerConfig.key) {
|
|
117
|
+
const authResult = await this.authenticateUser(innerConfig.user, innerConfig.key);
|
|
118
|
+
process.env[constants_1.BSTACK_TCG_AUTH_RESULT] = JSON.stringify(authResult);
|
|
119
|
+
if (!isMultiremote && constants_1.SUPPORTED_BROWSERS_FOR_AI.includes((_a = caps === null || caps === void 0 ? void 0 : caps.browserName) === null || _a === void 0 ? void 0 : _a.toLowerCase())) {
|
|
120
|
+
(0, funnelInstrumentation_1.handleHealingInstrumentation)(authResult, browserStackConfig, options.selfHeal);
|
|
121
|
+
this.updateCaps(authResult, options, caps);
|
|
122
|
+
}
|
|
123
|
+
else if (isMultiremote) {
|
|
124
|
+
this.handleMultiRemoteSetup(authResult, config, browserStackConfig, options, caps);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
if (options.selfHeal === true) {
|
|
130
|
+
bstackLogger_1.BStackLogger.warn(`Error while initiliazing Browserstack healing Extension ${err}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return caps;
|
|
134
|
+
}
|
|
135
|
+
async handleSelfHeal(options, browser) {
|
|
136
|
+
var _a, _b;
|
|
137
|
+
if (constants_1.SUPPORTED_BROWSERS_FOR_AI.includes((_b = (_a = browser.capabilities) === null || _a === void 0 ? void 0 : _a.browserName) === null || _b === void 0 ? void 0 : _b.toLowerCase())) {
|
|
138
|
+
const authInfo = this.authResult;
|
|
139
|
+
if (Object.keys(authInfo).length === 0 && options.selfHeal === true) {
|
|
140
|
+
bstackLogger_1.BStackLogger.debug('TCG Auth result is empty');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const { isAuthenticated, sessionToken, defaultLogDataEnabled } = authInfo;
|
|
144
|
+
if (isAuthenticated && (defaultLogDataEnabled === true || options.selfHeal === true)) {
|
|
145
|
+
await this.setToken(browser.sessionId, sessionToken);
|
|
146
|
+
if (browser.capabilities.browserName === 'firefox') {
|
|
147
|
+
await this.installFirefoxExtension(browser);
|
|
148
|
+
}
|
|
149
|
+
browser.overwriteCommand('findElement', async (orginalFunc, using, value) => {
|
|
150
|
+
return await this.handleHealing(orginalFunc, using, value, browser, options);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async selfHeal(options, caps, browser) {
|
|
156
|
+
try {
|
|
157
|
+
const multiRemoteBrowsers = Object.keys(caps).filter(e => Object.keys(browser).includes(e));
|
|
158
|
+
if (multiRemoteBrowsers.length > 0) {
|
|
159
|
+
for (let i = 0; i < multiRemoteBrowsers.length; i++) {
|
|
160
|
+
const remoteBrowser = browser[multiRemoteBrowsers[i]];
|
|
161
|
+
await this.handleSelfHeal(options, remoteBrowser);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
await this.handleSelfHeal(options, browser);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
if (options.selfHeal === true) {
|
|
170
|
+
bstackLogger_1.BStackLogger.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.default = new AiHandler();
|
package/build/constants.d.ts
CHANGED
|
@@ -27,11 +27,20 @@ export declare const LOG_KIND_USAGE_MAP: {
|
|
|
27
27
|
HTTP: string;
|
|
28
28
|
};
|
|
29
29
|
export declare const FUNNEL_INSTRUMENTATION_URL = "https://api.browserstack.com/sdk/v1/event";
|
|
30
|
+
export declare const SUPPORTED_BROWSERS_FOR_AI: string[];
|
|
31
|
+
export declare const TCG_URL = "https://tcg.browserstack.com";
|
|
32
|
+
export declare const TCG_INFO: {
|
|
33
|
+
tcgRegion: string;
|
|
34
|
+
tcgUrl: string;
|
|
35
|
+
};
|
|
30
36
|
export declare const TESTOPS_JWT_ENV = "BS_TESTOPS_JWT";
|
|
37
|
+
export declare const BSTACK_TCG_AUTH_RESULT = "BSTACK_TCG_AUTH_RESULT";
|
|
31
38
|
export declare const TESTOPS_SCREENSHOT_ENV = "BS_TESTOPS_ALLOW_SCREENSHOTS";
|
|
32
39
|
export declare const TESTOPS_BUILD_ID_ENV = "BS_TESTOPS_BUILD_HASHED_ID";
|
|
33
40
|
export declare const PERF_MEASUREMENT_ENV = "BROWSERSTACK_O11Y_PERF_MEASUREMENT";
|
|
34
41
|
export declare const RERUN_TESTS_ENV = "BROWSERSTACK_RERUN_TESTS";
|
|
35
42
|
export declare const RERUN_ENV = "BROWSERSTACK_RERUN";
|
|
36
43
|
export declare const TESTOPS_BUILD_COMPLETED_ENV = "BS_TESTOPS_BUILD_COMPLETED";
|
|
44
|
+
export declare const MAX_GIT_META_DATA_SIZE_IN_BYTES: number;
|
|
45
|
+
export declare const GIT_META_DATA_TRUNCATED = "...[TRUNCATED]";
|
|
37
46
|
//# sourceMappingURL=constants.d.ts.map
|
package/build/constants.d.ts.map
CHANGED
|
@@ -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;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;
|
|
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;AAErF,eAAO,MAAM,yBAAyB,UAAyC,CAAA;AAE/E,eAAO,MAAM,OAAO,iCAAiC,CAAA;AAErD,eAAO,MAAM,QAAQ;;;CAGpB,CAAA;AAKD,eAAO,MAAM,eAAe,mBAAmB,CAAA;AAG/C,eAAO,MAAM,sBAAsB,2BAA2B,CAAA;AAG9D,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;AAGvE,eAAO,MAAM,+BAA+B,QAAY,CAAA;AAKxD,eAAO,MAAM,uBAAuB,mBAAmB,CAAA"}
|
package/build/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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;
|
|
3
|
+
exports.GIT_META_DATA_TRUNCATED = exports.MAX_GIT_META_DATA_SIZE_IN_BYTES = 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.BSTACK_TCG_AUTH_RESULT = exports.TESTOPS_JWT_ENV = exports.TCG_INFO = exports.TCG_URL = exports.SUPPORTED_BROWSERS_FOR_AI = 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
4
|
const package_json_1 = require("../package.json");
|
|
5
5
|
exports.BROWSER_DESCRIPTION = [
|
|
6
6
|
'device',
|
|
@@ -63,9 +63,17 @@ exports.LOG_KIND_USAGE_MAP = {
|
|
|
63
63
|
'HTTP': 'http'
|
|
64
64
|
};
|
|
65
65
|
exports.FUNNEL_INSTRUMENTATION_URL = 'https://api.browserstack.com/sdk/v1/event';
|
|
66
|
+
exports.SUPPORTED_BROWSERS_FOR_AI = ['chrome', 'microsoftedge', 'firefox'];
|
|
67
|
+
exports.TCG_URL = 'https://tcg.browserstack.com';
|
|
68
|
+
exports.TCG_INFO = {
|
|
69
|
+
tcgRegion: 'use',
|
|
70
|
+
tcgUrl: exports.TCG_URL,
|
|
71
|
+
};
|
|
66
72
|
// Env variables - Define all the env variable constants over here
|
|
67
73
|
// To store the JWT token returned the session launch
|
|
68
74
|
exports.TESTOPS_JWT_ENV = 'BS_TESTOPS_JWT';
|
|
75
|
+
// To store tcg auth result for selfHealing feature:
|
|
76
|
+
exports.BSTACK_TCG_AUTH_RESULT = 'BSTACK_TCG_AUTH_RESULT';
|
|
69
77
|
// To store the setting of whether to send screenshots or not
|
|
70
78
|
exports.TESTOPS_SCREENSHOT_ENV = 'BS_TESTOPS_ALLOW_SCREENSHOTS';
|
|
71
79
|
// To store build hashed id
|
|
@@ -78,3 +86,9 @@ exports.RERUN_TESTS_ENV = 'BROWSERSTACK_RERUN_TESTS';
|
|
|
78
86
|
exports.RERUN_ENV = 'BROWSERSTACK_RERUN';
|
|
79
87
|
// To store whether the build launch has completed or not
|
|
80
88
|
exports.TESTOPS_BUILD_COMPLETED_ENV = 'BS_TESTOPS_BUILD_COMPLETED';
|
|
89
|
+
// Maximum size of VCS info which is allowed
|
|
90
|
+
exports.MAX_GIT_META_DATA_SIZE_IN_BYTES = 64 * 1024;
|
|
91
|
+
/* The value to be appended at the end if git metadata is larger than
|
|
92
|
+
MAX_GIT_META_DATA_SIZE_IN_BYTES
|
|
93
|
+
*/
|
|
94
|
+
exports.GIT_META_DATA_TRUNCATED = '...[TRUNCATED]';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insights-handler.d.ts","sourceRoot":"","sources":["../src/insights-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAIzE,OAAO,KAAK,EAAiB,OAAO,EAAE,QAAQ,EAAsB,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"insights-handler.d.ts","sourceRoot":"","sources":["../src/insights-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,7 @@ class _InsightsHandler {
|
|
|
66
66
|
await this._browser.execute(`browserstack_executor: {"action": "annotate", "arguments": {"data": "ObservabilitySync:${Date.now()}","level": "debug"}}`);
|
|
67
67
|
}
|
|
68
68
|
const gitMeta = await (0, util_1.getGitMetaData)();
|
|
69
|
-
if (gitMeta) {
|
|
69
|
+
if (gitMeta && !(0, util_1.isObjectEmpty)(gitMeta)) {
|
|
70
70
|
this._gitConfigPath = gitMeta.root;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -537,7 +537,7 @@ class _InsightsHandler {
|
|
|
537
537
|
if (error && testData.result != 'skipped') {
|
|
538
538
|
testData.failure = [{ backtrace: [(0, util_1.removeAnsiColors)(error.message)] }]; // add all errors here
|
|
539
539
|
testData.failure_reason = (0, util_1.removeAnsiColors)(error.message);
|
|
540
|
-
testData.failure_type = error.message
|
|
540
|
+
testData.failure_type = (0, util_1.isUndefined)(error.message) ? null : error.message.toString().match(/AssertionError/) ? 'AssertionError' : 'UnhandledError'; //verify if this is working
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
543
|
else {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type BrowserStackConfig from '../config';
|
|
2
|
+
import type { BrowserstackHealing } from '@browserstack/ai-sdk-node';
|
|
2
3
|
export declare function sendStart(config: BrowserStackConfig): Promise<void>;
|
|
3
4
|
export declare function sendFinish(config: BrowserStackConfig): Promise<void>;
|
|
4
5
|
export declare function saveFunnelData(eventType: string, config: BrowserStackConfig): string;
|
|
5
6
|
export declare function fireFunnelRequest(data: any): Promise<void>;
|
|
7
|
+
export declare function handleHealingInstrumentation(authResult: BrowserstackHealing.InitErrorResponse | BrowserstackHealing.InitSuccessResponse, config: BrowserStackConfig, isSelfHealEnabled: boolean | undefined): void;
|
|
6
8
|
//# sourceMappingURL=funnelInstrumentation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funnelInstrumentation.d.ts","sourceRoot":"","sources":["../../src/instrumentation/funnelInstrumentation.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,kBAAkB,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"funnelInstrumentation.d.ts","sourceRoot":"","sources":["../../src/instrumentation/funnelInstrumentation.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,kBAAkB,MAAM,WAAW,CAAA;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAoBpE,wBAAsB,SAAS,CAAC,MAAM,EAAE,kBAAkB,iBAEzD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,kBAAkB,iBAE1D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAOpF;AAGD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhE;AAwJD,wBAAgB,4BAA4B,CACxC,UAAU,EAAE,mBAAmB,CAAC,iBAAiB,GAAG,mBAAmB,CAAC,mBAAmB,EAC3F,MAAM,EAAE,kBAAkB,EAC1B,iBAAiB,EAAE,OAAO,GAAG,SAAS,QAiCzC"}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fireFunnelRequest = exports.saveFunnelData = exports.sendFinish = exports.sendStart = void 0;
|
|
6
|
+
exports.handleHealingInstrumentation = exports.fireFunnelRequest = exports.saveFunnelData = exports.sendFinish = exports.sendStart = void 0;
|
|
7
7
|
const node_os_1 = __importDefault(require("node:os"));
|
|
8
8
|
const node_util_1 = __importDefault(require("node:util"));
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -125,3 +125,87 @@ function getReferrer(framework) {
|
|
|
125
125
|
const fullName = framework ? 'WebdriverIO-' + framework : 'WebdriverIO';
|
|
126
126
|
return `${fullName}/${constants_1.BSTACK_SERVICE_VERSION}`;
|
|
127
127
|
}
|
|
128
|
+
const sendEvent = {
|
|
129
|
+
tcgDown: (config) => fireFunnelTestEvent('SDKTestTcgDownResponse', config),
|
|
130
|
+
invalidTcgAuth: (config) => fireFunnelTestEvent('SDKTestInvalidTcgAuthResponseWithUserImpact', config),
|
|
131
|
+
tcgAuthFailure: (config) => fireFunnelTestEvent('SDKTestTcgAuthFailure', config),
|
|
132
|
+
tcgtInitSuccessful: (config) => fireFunnelTestEvent('SDKTestTcgtInitSuccessful', config),
|
|
133
|
+
initFailed: (config) => fireFunnelTestEvent('SDKTestInitFailedResponse', config),
|
|
134
|
+
tcgProxyFailure: (config) => fireFunnelTestEvent('SDKTestTcgProxyFailure', config),
|
|
135
|
+
};
|
|
136
|
+
function isProxyError(authResult) {
|
|
137
|
+
return authResult.status === 502;
|
|
138
|
+
}
|
|
139
|
+
function handleProxyError(config, isSelfHealEnabled) {
|
|
140
|
+
sendEvent.tcgProxyFailure(config);
|
|
141
|
+
if (isSelfHealEnabled) {
|
|
142
|
+
bstackLogger_1.BStackLogger.warn('Proxy Error. Disabling Healing for this session.');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function handleUpgradeRequired(isSelfHealEnabled) {
|
|
146
|
+
if (isSelfHealEnabled) {
|
|
147
|
+
bstackLogger_1.BStackLogger.warn('Please upgrade Browserstack Service to the latest version to use the self-healing feature.');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function handleAuthenticationFailure(status, config, isSelfHealEnabled) {
|
|
151
|
+
if (status >= 500) {
|
|
152
|
+
if (isSelfHealEnabled) {
|
|
153
|
+
bstackLogger_1.BStackLogger.warn('Something went wrong. Disabling healing for this session. Please try again later.');
|
|
154
|
+
}
|
|
155
|
+
sendEvent.tcgDown(config);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
if (isSelfHealEnabled) {
|
|
159
|
+
bstackLogger_1.BStackLogger.warn('Authentication Failed. Disabling Healing for this session.');
|
|
160
|
+
}
|
|
161
|
+
sendEvent.tcgAuthFailure(config);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function handleAuthenticationSuccess(isHealingEnabledForUser, userId, config, isSelfHealEnabled) {
|
|
165
|
+
if (!isHealingEnabledForUser && isSelfHealEnabled) {
|
|
166
|
+
bstackLogger_1.BStackLogger.warn('Healing is not enabled for your group, please contact the admin');
|
|
167
|
+
}
|
|
168
|
+
else if (userId && isHealingEnabledForUser) {
|
|
169
|
+
sendEvent.tcgtInitSuccessful(config);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function handleInitializationFailure(status, config, isSelfHealEnabled) {
|
|
173
|
+
if (status >= 400) {
|
|
174
|
+
sendEvent.initFailed(config);
|
|
175
|
+
}
|
|
176
|
+
else if (!status && isSelfHealEnabled) {
|
|
177
|
+
sendEvent.invalidTcgAuth(config);
|
|
178
|
+
}
|
|
179
|
+
if (isSelfHealEnabled) {
|
|
180
|
+
bstackLogger_1.BStackLogger.warn('Authentication Failed. Healing will be disabled for this session.');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function handleHealingInstrumentation(authResult, config, isSelfHealEnabled) {
|
|
184
|
+
try {
|
|
185
|
+
if (isProxyError(authResult)) {
|
|
186
|
+
handleProxyError(config, isSelfHealEnabled);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const { message, isAuthenticated, status, userId, groupId, isHealingEnabled: isHealingEnabledForUser } = authResult;
|
|
190
|
+
if (message === 'Upgrade required') {
|
|
191
|
+
handleUpgradeRequired(isSelfHealEnabled);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (!isAuthenticated) {
|
|
195
|
+
handleAuthenticationFailure(status, config, isSelfHealEnabled);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (isAuthenticated && userId && groupId) {
|
|
199
|
+
handleAuthenticationSuccess(isHealingEnabledForUser, userId, config, isSelfHealEnabled);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (status >= 400 || !status) {
|
|
203
|
+
handleInitializationFailure(status, config, isSelfHealEnabled);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
bstackLogger_1.BStackLogger.debug('Error in handling healing instrumentation: ' + err);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.handleHealingInstrumentation = handleHealingInstrumentation;
|
package/build/launcher.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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, UserConfig } from './types';
|
|
3
|
+
import type { App, AppConfig, AppUploadResponse, BrowserstackConfig, BrowserstackOptions, UserConfig } from './types';
|
|
4
4
|
type BrowserstackLocal = BrowserstackLocalLauncher.Local & {
|
|
5
5
|
pid?: number;
|
|
6
6
|
stop(callback: (err?: Error) => void): void;
|
|
@@ -17,9 +17,9 @@ export default class BrowserstackLauncherService implements Services.ServiceInst
|
|
|
17
17
|
private _percy?;
|
|
18
18
|
private _percyBestPlatformCaps?;
|
|
19
19
|
private readonly browserStackConfig;
|
|
20
|
-
constructor(_options: BrowserstackConfig &
|
|
20
|
+
constructor(_options: BrowserstackConfig & BrowserstackOptions, capabilities: Capabilities.RemoteCapability, _config: Options.Testrunner);
|
|
21
21
|
onWorkerStart(cid: any, caps: any): Promise<void>;
|
|
22
|
-
onPrepare(config
|
|
22
|
+
onPrepare(config: Options.Testrunner, capabilities: Capabilities.RemoteCapabilities): Promise<unknown>;
|
|
23
23
|
onComplete(): Promise<unknown>;
|
|
24
24
|
setupPercy(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner, bsConfig: UserConfig): Promise<void>;
|
|
25
25
|
stopPercy(): Promise<void>;
|
package/build/launcher.d.ts.map
CHANGED
|
@@ -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,UAAU,EAAE,MAAM,SAAS,CAAA;
|
|
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,mBAAmB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAiCrH,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;IACjE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;gBAG3C,QAAQ,EAAE,kBAAkB,GAAG,mBAAmB,EAC1D,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IA4GjC,aAAa,CAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;IAalC,SAAS,CAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,kBAAkB;IAmLpF,UAAU;IAqEV,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;IAqBrD;;;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
|
@@ -47,6 +47,8 @@ const PercyLogger_1 = require("./Percy/PercyLogger");
|
|
|
47
47
|
const exitHandler_1 = require("./exitHandler");
|
|
48
48
|
const config_1 = __importDefault(require("./config"));
|
|
49
49
|
const funnelInstrumentation_1 = require("./instrumentation/funnelInstrumentation");
|
|
50
|
+
const ai_handler_1 = __importDefault(require("./ai-handler"));
|
|
51
|
+
const bstackLogger_1 = require("./bstackLogger");
|
|
50
52
|
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
51
53
|
class BrowserstackLauncherService {
|
|
52
54
|
constructor(_options, capabilities, _config) {
|
|
@@ -59,7 +61,7 @@ class BrowserstackLauncherService {
|
|
|
59
61
|
this.browserStackConfig = config_1.default.getInstance(_options, _config);
|
|
60
62
|
if (Array.isArray(capabilities)) {
|
|
61
63
|
capabilities.forEach((capability) => {
|
|
62
|
-
var _a, _b;
|
|
64
|
+
var _a, _b, _c;
|
|
63
65
|
if (!capability['bstack:options']) {
|
|
64
66
|
if ((0, util_2.isBStackSession)(this._config)) {
|
|
65
67
|
const extensionCaps = Object.keys(capability).filter((cap) => cap.includes(':'));
|
|
@@ -78,6 +80,8 @@ class BrowserstackLauncherService {
|
|
|
78
80
|
}
|
|
79
81
|
this._buildIdentifier = (_a = capability['browserstack.buildIdentifier']) === null || _a === void 0 ? void 0 : _a.toString();
|
|
80
82
|
this._buildName = (_b = capability['build']) === null || _b === void 0 ? void 0 : _b.toString();
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
this._projectName = (_c = capability['project']) === null || _c === void 0 ? void 0 : _c.toString();
|
|
81
85
|
}
|
|
82
86
|
else {
|
|
83
87
|
capability['bstack:options'].wdioService = package_json_1.version;
|
|
@@ -113,6 +117,10 @@ class BrowserstackLauncherService {
|
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
this._buildIdentifier = caps.capabilities['browserstack.buildIdentifier'];
|
|
120
|
+
// @ts-ignore
|
|
121
|
+
this._buildName = caps.capabilities['build'];
|
|
122
|
+
// @ts-ignore
|
|
123
|
+
this._projectName = caps.capabilities['project'];
|
|
116
124
|
}
|
|
117
125
|
else {
|
|
118
126
|
const bstackOptions = caps.capabilities['bstack:options'];
|
|
@@ -167,12 +175,36 @@ class BrowserstackLauncherService {
|
|
|
167
175
|
async onPrepare(config, capabilities) {
|
|
168
176
|
// // Send Funnel start request
|
|
169
177
|
await (0, funnelInstrumentation_1.sendStart)(this.browserStackConfig);
|
|
178
|
+
// Setting up healing for those sessions where we don't add the service version capability as it indicates that the session is not being run on BrowserStack
|
|
179
|
+
if (!(0, util_2.shouldAddServiceVersion)(this._config, this._options.testObservability, capabilities)) {
|
|
180
|
+
try {
|
|
181
|
+
if (capabilities.browserName) {
|
|
182
|
+
capabilities = await ai_handler_1.default.setup(this._config, this.browserStackConfig, this._options, capabilities, false);
|
|
183
|
+
}
|
|
184
|
+
else if (Array.isArray(capabilities)) {
|
|
185
|
+
for (let i = 0; i < capabilities.length; i++) {
|
|
186
|
+
if (capabilities[i].browserName) {
|
|
187
|
+
capabilities[i] = await ai_handler_1.default.setup(this._config, this.browserStackConfig, this._options, capabilities[i], false);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else if ((0, util_2.isValidCapsForHealing)(capabilities)) {
|
|
192
|
+
// setting up healing in case capabilities.xyz.capabilities.browserName where xyz can be anything:
|
|
193
|
+
capabilities = await ai_handler_1.default.setup(this._config, this.browserStackConfig, this._options, capabilities, true);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
if (this._options.selfHeal === true) {
|
|
198
|
+
bstackLogger_1.BStackLogger.warn(`Error while setting up Browserstack healing Extension ${err}. Disabling healing for this session.`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
170
202
|
/**
|
|
171
203
|
* Upload app to BrowserStack if valid file path to app is given.
|
|
172
204
|
* Update app value of capability directly if app_url, custom_id, shareable_id is given
|
|
173
205
|
*/
|
|
174
206
|
if (!this._options.app) {
|
|
175
|
-
log.
|
|
207
|
+
log.debug('app is not defined in browserstack-service config, skipping ...');
|
|
176
208
|
}
|
|
177
209
|
else {
|
|
178
210
|
let app = {};
|
package/build/reporter.js
CHANGED
|
@@ -73,7 +73,7 @@ class _TestReporter extends reporter_1.default {
|
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
const gitMeta = await (0, util_1.getGitMetaData)();
|
|
76
|
-
if (gitMeta) {
|
|
76
|
+
if (gitMeta && !(0, util_1.isObjectEmpty)(gitMeta)) {
|
|
77
77
|
this._gitConfigPath = gitMeta.root;
|
|
78
78
|
}
|
|
79
79
|
this._gitConfigured = true;
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/build/service.js
CHANGED
|
@@ -16,6 +16,8 @@ const Percy_Handler_1 = __importDefault(require("./Percy/Percy-Handler"));
|
|
|
16
16
|
const listener_1 = __importDefault(require("./testOps/listener"));
|
|
17
17
|
const data_store_1 = require("./data-store");
|
|
18
18
|
const usageStats_1 = __importDefault(require("./testOps/usageStats"));
|
|
19
|
+
const ai_handler_1 = __importDefault(require("./ai-handler"));
|
|
20
|
+
const bstackLogger_1 = require("./bstackLogger");
|
|
19
21
|
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
20
22
|
class BrowserstackService {
|
|
21
23
|
constructor(options, _caps, _config) {
|
|
@@ -77,6 +79,17 @@ class BrowserstackService {
|
|
|
77
79
|
async before(caps, specs, browser) {
|
|
78
80
|
// added to maintain backward compatibility with webdriverIO v5
|
|
79
81
|
this._browser = browser ? browser : global.browser;
|
|
82
|
+
// Healing Support:
|
|
83
|
+
if (!(0, util_1.shouldAddServiceVersion)(this._config, this._options.testObservability, caps)) {
|
|
84
|
+
try {
|
|
85
|
+
await ai_handler_1.default.selfHeal(this._options, caps, this._browser);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (this._options.selfHeal === true) {
|
|
89
|
+
bstackLogger_1.BStackLogger.warn(`Error while setting up self-healing: ${err}. Disabling healing for this session.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
80
93
|
// Ensure capabilities are not null in case of multiremote
|
|
81
94
|
if (this._isAppAutomate()) {
|
|
82
95
|
this._sessionBaseUrl = 'https://api-cloud.browserstack.com/app-automate/sessions';
|
|
@@ -204,7 +217,8 @@ class BrowserstackService {
|
|
|
204
217
|
await this._updateJob({
|
|
205
218
|
status: result === 0 && this._specsRan ? 'passed' : 'failed',
|
|
206
219
|
...(setSessionName ? { name: this._fullTitle } : {}),
|
|
207
|
-
...(
|
|
220
|
+
...(result === 0 && this._specsRan ?
|
|
221
|
+
{} : hasReasons ? { reason: this._failReasons.join('\n') } : {})
|
|
208
222
|
});
|
|
209
223
|
}
|
|
210
224
|
await listener_1.default.getInstance().onWorkerEnd();
|
|
@@ -296,10 +310,10 @@ class BrowserstackService {
|
|
|
296
310
|
await this._printSessionURL();
|
|
297
311
|
}
|
|
298
312
|
_isAppAutomate() {
|
|
299
|
-
var _a, _b, _c;
|
|
313
|
+
var _a, _b, _c, _d;
|
|
300
314
|
const browserDesiredCapabilities = ((_b = (_a = this._browser) === null || _a === void 0 ? void 0 : _a.capabilities) !== null && _b !== void 0 ? _b : {});
|
|
301
315
|
const desiredCapabilities = ((_c = this._caps) !== null && _c !== void 0 ? _c : {});
|
|
302
|
-
return !!browserDesiredCapabilities['appium:app'] || !!desiredCapabilities['appium:app'] || !!browserDesiredCapabilities.app || !!desiredCapabilities.app;
|
|
316
|
+
return !!browserDesiredCapabilities['appium:app'] || !!desiredCapabilities['appium:app'] || !!browserDesiredCapabilities.app || !!desiredCapabilities.app || !!((_d = desiredCapabilities['appium:options']) === null || _d === void 0 ? void 0 : _d.app);
|
|
303
317
|
}
|
|
304
318
|
_updateJob(requestBody) {
|
|
305
319
|
return this._multiRemoteAction((sessionId, browserName) => {
|
package/build/types.d.ts
CHANGED
|
@@ -30,6 +30,9 @@ export interface TestObservabilityOptions {
|
|
|
30
30
|
user?: string;
|
|
31
31
|
key?: string;
|
|
32
32
|
}
|
|
33
|
+
export interface BrowserstackOptions extends Options.Testrunner {
|
|
34
|
+
selfHeal?: boolean;
|
|
35
|
+
}
|
|
33
36
|
export interface BrowserstackConfig {
|
|
34
37
|
/**
|
|
35
38
|
*`buildIdentifier` is a unique id to differentiate every execution that gets appended to
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEpE,MAAM,WAAW,eAAe;IAE5B,kBAAkB,EAAE;QAEhB,WAAW,EAAE,MAAM,CAAA;KACtB,CAAA;CACJ;AAED,MAAM,WAAW,yBAAyB;IACtC,GAAG,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAE1F,MAAM,MAAM,SAAS,GAAG;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/util.d.ts
CHANGED
|
@@ -8,6 +8,27 @@ import { BeforeCommandArgs, AfterCommandArgs } from '@wdio/reporter';
|
|
|
8
8
|
import type { Method } from 'got';
|
|
9
9
|
import type { ITestCaseHookParameter } from './cucumber-types';
|
|
10
10
|
import { UploadType, BrowserstackConfig } from './types';
|
|
11
|
+
export type GitMetaData = {
|
|
12
|
+
name: string;
|
|
13
|
+
sha: string;
|
|
14
|
+
short_sha: string;
|
|
15
|
+
branch: string;
|
|
16
|
+
tag: string | null;
|
|
17
|
+
committer: string;
|
|
18
|
+
committer_date: string;
|
|
19
|
+
author: string;
|
|
20
|
+
author_date: string;
|
|
21
|
+
commit_message: string;
|
|
22
|
+
root: string;
|
|
23
|
+
common_git_dir: string;
|
|
24
|
+
worktree_git_dir: string;
|
|
25
|
+
last_tag: string | null;
|
|
26
|
+
commits_since_last_tag: number;
|
|
27
|
+
remotes: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
url: string;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
11
32
|
export declare const DEFAULT_REQUEST_CONFIG: {
|
|
12
33
|
agent: {
|
|
13
34
|
http: http.Agent;
|
|
@@ -76,44 +97,7 @@ export declare function getCiInfo(): {
|
|
|
76
97
|
build_number: string | null;
|
|
77
98
|
} | null;
|
|
78
99
|
export declare function nodeRequest(requestType: Method, apiEndpoint: string, options: any, apiUrl: string, timeout?: number): Promise<Object>;
|
|
79
|
-
export declare function getGitMetaData(): Promise<{
|
|
80
|
-
name?: undefined;
|
|
81
|
-
sha?: undefined;
|
|
82
|
-
short_sha?: undefined;
|
|
83
|
-
branch?: undefined;
|
|
84
|
-
tag?: undefined;
|
|
85
|
-
committer?: undefined;
|
|
86
|
-
committer_date?: undefined;
|
|
87
|
-
author?: undefined;
|
|
88
|
-
author_date?: undefined;
|
|
89
|
-
commit_message?: undefined;
|
|
90
|
-
root?: undefined;
|
|
91
|
-
common_git_dir?: undefined;
|
|
92
|
-
worktree_git_dir?: undefined;
|
|
93
|
-
last_tag?: undefined;
|
|
94
|
-
commits_since_last_tag?: undefined;
|
|
95
|
-
remotes?: undefined;
|
|
96
|
-
} | {
|
|
97
|
-
name: string;
|
|
98
|
-
sha: string;
|
|
99
|
-
short_sha: string;
|
|
100
|
-
branch: string;
|
|
101
|
-
tag: string | null;
|
|
102
|
-
committer: string;
|
|
103
|
-
committer_date: string;
|
|
104
|
-
author: string;
|
|
105
|
-
author_date: string;
|
|
106
|
-
commit_message: string;
|
|
107
|
-
root: string;
|
|
108
|
-
common_git_dir: string;
|
|
109
|
-
worktree_git_dir: string;
|
|
110
|
-
last_tag: string | null;
|
|
111
|
-
commits_since_last_tag: number;
|
|
112
|
-
remotes: {
|
|
113
|
-
name: string;
|
|
114
|
-
url: any;
|
|
115
|
-
}[];
|
|
116
|
-
}>;
|
|
100
|
+
export declare function getGitMetaData(): Promise<{}>;
|
|
117
101
|
export declare function getUniqueIdentifier(test: Frameworks.Test, framework?: string): string;
|
|
118
102
|
export declare function getUniqueIdentifierForCucumber(world: ITestCaseHookParameter): string;
|
|
119
103
|
export declare function getCloudProvider(browser: Browser<'async'> | MultiRemoteBrowser<'async'>): string;
|
|
@@ -125,7 +109,12 @@ export declare function getHierarchy(fullTitle?: string): string[];
|
|
|
125
109
|
export declare function getHookType(hookName: string): string;
|
|
126
110
|
export declare function isScreenshotCommand(args: BeforeCommandArgs & AfterCommandArgs): boolean | "" | undefined;
|
|
127
111
|
export declare function isBStackSession(config: Options.Testrunner): boolean;
|
|
128
|
-
export declare function
|
|
112
|
+
export declare function isBrowserstackInfra(config: BrowserstackConfig & Options.Testrunner, caps?: Capabilities.BrowserStackCapabilities): boolean;
|
|
113
|
+
export declare function getBrowserStackUserAndKey(config: Options.Testrunner, options: Options.Testrunner): {
|
|
114
|
+
user: string | undefined;
|
|
115
|
+
key: string | undefined;
|
|
116
|
+
};
|
|
117
|
+
export declare function shouldAddServiceVersion(config: Options.Testrunner, testObservability?: boolean, caps?: Capabilities.BrowserStackCapabilities): boolean;
|
|
129
118
|
export declare function batchAndPostEvents(eventUrl: string, kind: string, data: UploadType[]): Promise<void>;
|
|
130
119
|
export declare function getObservabilityUser(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner): string | undefined;
|
|
131
120
|
export declare function getObservabilityKey(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner): string | undefined;
|
|
@@ -169,5 +158,12 @@ export declare const ObjectsAreEqual: (object1: any, object2: any) => boolean;
|
|
|
169
158
|
export declare const getPlatformVersion: (...args: any) => any;
|
|
170
159
|
export declare const isObjectEmpty: (objectName: unknown) => unknown;
|
|
171
160
|
export declare const getErrorString: (err: unknown) => string | undefined;
|
|
161
|
+
export declare function truncateString(field: string, truncateSizeInBytes: number): string;
|
|
162
|
+
export declare function getSizeOfJsonObjectInBytes(jsonData: GitMetaData): number;
|
|
163
|
+
export declare function checkAndTruncateVCSInfo(gitMetaData: GitMetaData): GitMetaData;
|
|
164
|
+
export declare const hasBrowserName: (cap: WebdriverIO.Config) => boolean;
|
|
165
|
+
export declare const isValidCapsForHealing: (caps: {
|
|
166
|
+
[key: string]: Options.Testrunner;
|
|
167
|
+
}) => boolean;
|
|
172
168
|
export {};
|
|
173
169
|
//# sourceMappingURL=util.d.ts.map
|
package/build/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAEA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAIpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAIjC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAG9D,OAAO,EAAc,UAAU,EAAkB,kBAAkB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAEA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAIpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAIjC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAG9D,OAAO,EAAc,UAAU,EAAkB,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAuBpF,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;CASlC,CAAA;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,CAAC,mBAAmB,UAa1E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,YAAY,CAAC,gBAAgB,EAAE,WAAW,CAAC,EAAE,MAAM,6BASzJ;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,YAAY,WAWvE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAUpF;AAaD,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,aACX,GAAG,SAYhC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,aACf,GAAG,SAehC;AAOD,KAAK,SAAS,GAAG;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;CAAE,CAAC;AAC/C,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,SAAS,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CA8B3E;AAED,eAAO,MAAM,iBAAiB,YAvDA,GAAG,QAuI/B,CAAA;AAEF,eAAO,MAAM,iBAAiB,YAzIA,GAAG,QAyL/B,CAAA;AAEF,wBAAgB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA4NxB;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAe,mBAyBjI;AAED,wBAAsB,cAAc,gBA0BnC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAYrF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAEpF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,MAAM,CAahG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,OAAO,CAKvG;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,wBA8BhE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAWnD;AAGD,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,YAG9C;AAED,wBAAgB,WAAW,CAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED,wBAAgB,mBAAmB,CAAE,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,4BAE9E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,WAKzD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,YAAY,CAAC,wBAAwB,GAAG,OAAO,CAiC1I;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU;;;EAoBhG;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,CAAC,wBAAwB,GAAG,OAAO,CAKtJ;AAED,wBAAsB,kBAAkB,CAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,iBAyB3F;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,sBAQhH;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,sBAQ/G;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC,EAAE,MAAM,sBAQnH;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,EAAE,MAAM,UAQ/G;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAW7H;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,WAUrE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAC,KAAK;;;;;;EAUnD;AAED,wBAAgB,gBAAgB,SAiB/B;AAED,eAAO,MAAM,KAAK,mCAAkE,CAAA;AAEpF,eAAO,MAAM,oBAAoB,gBAAiB,GAAG;;+BAA0D,GAAG,YA0BjH,CAAA;AAED,eAAO,MAAM,8BAA8B,eAAgB,MAAM,GAAG,SAAS,aAAa,MAAM;;qCAc/F,CAAA;AAED,eAAO,MAAM,gCAAgC,uBAAwB,OAAO,GAAG,MAAM,6BAQpF,CAAA;AAED,eAAO,MAAM,0BAA0B,YA30BT,GAAG,QAu6B/B,CAAA;AAEF,eAAO,MAAM,eAAe,YAAmB,GAAG,0BAA0B,OAAO,oBAAoB,OAAO,GAAG,MAAM,gBAAgB,MAAM;;cAmB5I,CAAA;AAED,eAAO,MAAM,cAAc,YAAmB,GAAG,0BAA0B,OAAO,oBAAoB,OAAO,GAAG,MAAM;;IAoBrH,CAAA;AAED,eAAO,MAAM,qBAAqB,YAAmB,GAAG,0BAA0B,OAAO,oBAAoB,OAAO,GAAG,MAAM;;EAmB5H,CAAA;AAED,eAAO,MAAM,wBAAwB,YAz+BP,GAAG,QAshC/B,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,sBAK7D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,sBAK5D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,WAErC;AAED,wBAAgB,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,WAEjC;AAED,eAAO,MAAM,QAAQ,WAAY,GAAG,YAEnC,CAAA;AAED,eAAO,MAAM,eAAe,YAAa,GAAG,WAAW,GAAG,YAezD,CAAA;AAED,eAAO,MAAM,kBAAkB,YApjCD,GAAG,QAmkC/B,CAAA;AACF,eAAO,MAAM,aAAa,eAAgB,OAAO,YAMhD,CAAA;AAED,eAAO,MAAM,cAAc,QAAS,OAAO,uBAS1C,CAAA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAejF;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CASxE;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW,CAW7E;AAED,eAAO,MAAM,cAAc,QAAS,YAAY,MAAM,KAAG,OAMxD,CAAA;AAED,eAAO,MAAM,qBAAqB;;MAAkD,OAOnF,CAAA"}
|
package/build/util.js
CHANGED
|
@@ -26,8 +26,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
30
|
-
exports.getErrorString = exports.isObjectEmpty = void 0;
|
|
29
|
+
exports.isObject = exports.isTrue = exports.isUndefined = exports.getBrowserStackKey = exports.getBrowserStackUser = exports.stopAccessibilityTestRun = exports.getA11yResultsSummary = exports.getA11yResults = exports.performA11yScan = exports.createAccessibilityTestRun = exports.isAccessibilityAutomationSession = exports.shouldScanTestForAccessibility = exports.validateCapsWithA11y = exports.sleep = exports.patchConsoleLogs = exports.getFailureObject = exports.frameworkSupportsHook = exports.getObservabilityBuildTags = exports.getObservabilityBuild = exports.getObservabilityProject = exports.getObservabilityKey = exports.getObservabilityUser = exports.batchAndPostEvents = exports.shouldAddServiceVersion = exports.getBrowserStackUserAndKey = exports.isBrowserstackInfra = exports.isBStackSession = exports.isScreenshotCommand = exports.getHookType = exports.getHierarchy = exports.getLogTag = exports.removeAnsiColors = exports.getScenarioExamples = exports.isBrowserstackSession = exports.getCloudProvider = exports.getUniqueIdentifierForCucumber = exports.getUniqueIdentifier = exports.getGitMetaData = exports.nodeRequest = exports.getCiInfo = exports.stopBuildUpstream = exports.launchTestSession = exports.o11yClassErrorHandler = exports.o11yErrorHandler = exports.errorHandler = exports.getParentSuiteName = exports.isBrowserstackCapability = exports.getBrowserCapabilities = exports.getBrowserDescription = exports.DEFAULT_REQUEST_CONFIG = void 0;
|
|
30
|
+
exports.isValidCapsForHealing = exports.hasBrowserName = exports.checkAndTruncateVCSInfo = exports.getSizeOfJsonObjectInBytes = exports.truncateString = exports.getErrorString = exports.isObjectEmpty = exports.getPlatformVersion = exports.ObjectsAreEqual = void 0;
|
|
31
31
|
const os_1 = require("os");
|
|
32
32
|
const util_1 = require("util");
|
|
33
33
|
const http_1 = __importDefault(require("http"));
|
|
@@ -578,7 +578,7 @@ async function getGitMetaData() {
|
|
|
578
578
|
return {};
|
|
579
579
|
const { remote } = await pGitconfig(info.commonGitDir);
|
|
580
580
|
const remotes = remote ? Object.keys(remote).map(remoteName => ({ name: remoteName, url: remote[remoteName]['url'] })) : [];
|
|
581
|
-
|
|
581
|
+
let gitMetaData = {
|
|
582
582
|
name: 'git',
|
|
583
583
|
sha: info.sha,
|
|
584
584
|
short_sha: info.abbreviatedSha,
|
|
@@ -596,6 +596,8 @@ async function getGitMetaData() {
|
|
|
596
596
|
commits_since_last_tag: info.commitsSinceLastTag,
|
|
597
597
|
remotes: remotes
|
|
598
598
|
};
|
|
599
|
+
gitMetaData = checkAndTruncateVCSInfo(gitMetaData);
|
|
600
|
+
return gitMetaData;
|
|
599
601
|
}
|
|
600
602
|
exports.getGitMetaData = getGitMetaData;
|
|
601
603
|
function getUniqueIdentifier(test, framework) {
|
|
@@ -616,7 +618,16 @@ function getUniqueIdentifierForCucumber(world) {
|
|
|
616
618
|
}
|
|
617
619
|
exports.getUniqueIdentifierForCucumber = getUniqueIdentifierForCucumber;
|
|
618
620
|
function getCloudProvider(browser) {
|
|
619
|
-
if (browser
|
|
621
|
+
if (browser && 'instances' in browser) {
|
|
622
|
+
// Loop through all instances
|
|
623
|
+
for (const instanceName of browser.instances) {
|
|
624
|
+
const instance = browser[instanceName];
|
|
625
|
+
if (instance.options && instance.options.hostname && instance.options.hostname.includes('browserstack')) {
|
|
626
|
+
return 'browserstack';
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
else if (browser.options && browser.options.hostname && browser.options.hostname.includes('browserstack')) { // Single browser instance
|
|
620
631
|
return 'browserstack';
|
|
621
632
|
}
|
|
622
633
|
return 'unknown_grid';
|
|
@@ -720,8 +731,58 @@ function isBStackSession(config) {
|
|
|
720
731
|
return false;
|
|
721
732
|
}
|
|
722
733
|
exports.isBStackSession = isBStackSession;
|
|
723
|
-
function
|
|
724
|
-
|
|
734
|
+
function isBrowserstackInfra(config, caps) {
|
|
735
|
+
// a utility function to check if the hostname is browserstack
|
|
736
|
+
const isBrowserstack = (str) => {
|
|
737
|
+
return str.includes('browserstack.com');
|
|
738
|
+
};
|
|
739
|
+
if ((config.hostname) && !isBrowserstack(config.hostname)) {
|
|
740
|
+
return false;
|
|
741
|
+
}
|
|
742
|
+
if (caps && typeof caps === 'object') {
|
|
743
|
+
if (Array.isArray(caps)) {
|
|
744
|
+
for (const capability of caps) {
|
|
745
|
+
if ((capability.hostname) && !isBrowserstack(capability.hostname)) {
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
for (const key in caps) {
|
|
752
|
+
const capability = caps[key];
|
|
753
|
+
if ((capability.hostname) && !isBrowserstack(capability.hostname)) {
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
if (!isBStackSession(config)) {
|
|
760
|
+
return false;
|
|
761
|
+
}
|
|
762
|
+
return true;
|
|
763
|
+
}
|
|
764
|
+
exports.isBrowserstackInfra = isBrowserstackInfra;
|
|
765
|
+
function getBrowserStackUserAndKey(config, options) {
|
|
766
|
+
// Fallback 1: Env variables
|
|
767
|
+
// Fallback 2: Service variables in wdio.conf.js (that are received inside options object)
|
|
768
|
+
const envOrServiceVariables = {
|
|
769
|
+
user: getBrowserStackUser(options),
|
|
770
|
+
key: getBrowserStackKey(options)
|
|
771
|
+
};
|
|
772
|
+
if (envOrServiceVariables.user && envOrServiceVariables.key) {
|
|
773
|
+
return envOrServiceVariables;
|
|
774
|
+
}
|
|
775
|
+
// Fallback 3: Service variables in testObservabilityOptions object
|
|
776
|
+
// Fallback 4: Service variables in the top level config object
|
|
777
|
+
const o11yVariables = {
|
|
778
|
+
user: getObservabilityUser(options, config),
|
|
779
|
+
key: getObservabilityKey(options, config)
|
|
780
|
+
};
|
|
781
|
+
return o11yVariables;
|
|
782
|
+
}
|
|
783
|
+
exports.getBrowserStackUserAndKey = getBrowserStackUserAndKey;
|
|
784
|
+
function shouldAddServiceVersion(config, testObservability, caps) {
|
|
785
|
+
if ((config.services && config.services.toString().includes('chromedriver') && testObservability !== false) || !isBrowserstackInfra(config, caps)) {
|
|
725
786
|
return false;
|
|
726
787
|
}
|
|
727
788
|
return true;
|
|
@@ -1155,3 +1216,57 @@ const getErrorString = (err) => {
|
|
|
1155
1216
|
}
|
|
1156
1217
|
};
|
|
1157
1218
|
exports.getErrorString = getErrorString;
|
|
1219
|
+
function truncateString(field, truncateSizeInBytes) {
|
|
1220
|
+
try {
|
|
1221
|
+
const bufferSizeInBytes = Buffer.from(constants_1.GIT_META_DATA_TRUNCATED).length;
|
|
1222
|
+
const fieldBufferObj = Buffer.from(field);
|
|
1223
|
+
const lenOfFieldBufferObj = fieldBufferObj.length;
|
|
1224
|
+
const finalLen = Math.ceil(lenOfFieldBufferObj - truncateSizeInBytes - bufferSizeInBytes);
|
|
1225
|
+
if (finalLen > 0) {
|
|
1226
|
+
const truncatedString = fieldBufferObj.subarray(0, finalLen).toString() + constants_1.GIT_META_DATA_TRUNCATED;
|
|
1227
|
+
return truncatedString;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
catch (error) {
|
|
1231
|
+
log.debug(`Error while truncating field, nothing was truncated here: ${error}`);
|
|
1232
|
+
}
|
|
1233
|
+
return field;
|
|
1234
|
+
}
|
|
1235
|
+
exports.truncateString = truncateString;
|
|
1236
|
+
function getSizeOfJsonObjectInBytes(jsonData) {
|
|
1237
|
+
try {
|
|
1238
|
+
const buffer = Buffer.from(JSON.stringify(jsonData));
|
|
1239
|
+
return buffer.length;
|
|
1240
|
+
}
|
|
1241
|
+
catch (error) {
|
|
1242
|
+
log.debug(`Something went wrong while calculating size of JSON object: ${error}`);
|
|
1243
|
+
}
|
|
1244
|
+
return -1;
|
|
1245
|
+
}
|
|
1246
|
+
exports.getSizeOfJsonObjectInBytes = getSizeOfJsonObjectInBytes;
|
|
1247
|
+
function checkAndTruncateVCSInfo(gitMetaData) {
|
|
1248
|
+
const gitMetaDataSizeInBytes = getSizeOfJsonObjectInBytes(gitMetaData);
|
|
1249
|
+
if (gitMetaDataSizeInBytes && gitMetaDataSizeInBytes > constants_1.MAX_GIT_META_DATA_SIZE_IN_BYTES) {
|
|
1250
|
+
const truncateSize = gitMetaDataSizeInBytes - constants_1.MAX_GIT_META_DATA_SIZE_IN_BYTES;
|
|
1251
|
+
const truncatedCommitMessage = truncateString(gitMetaData.commit_message, truncateSize);
|
|
1252
|
+
gitMetaData.commit_message = truncatedCommitMessage;
|
|
1253
|
+
log.info(`The commit has been truncated. Size of commit after truncation is ${getSizeOfJsonObjectInBytes(gitMetaData) / 1024} KB`);
|
|
1254
|
+
}
|
|
1255
|
+
return gitMetaData;
|
|
1256
|
+
}
|
|
1257
|
+
exports.checkAndTruncateVCSInfo = checkAndTruncateVCSInfo;
|
|
1258
|
+
const hasBrowserName = (cap) => {
|
|
1259
|
+
if (!cap || !cap.capabilities) {
|
|
1260
|
+
return false;
|
|
1261
|
+
}
|
|
1262
|
+
const browserStackCapabilities = cap.capabilities;
|
|
1263
|
+
return browserStackCapabilities.browserName !== undefined;
|
|
1264
|
+
};
|
|
1265
|
+
exports.hasBrowserName = hasBrowserName;
|
|
1266
|
+
const isValidCapsForHealing = (caps) => {
|
|
1267
|
+
// Get all capability values
|
|
1268
|
+
const capValues = Object.values(caps);
|
|
1269
|
+
// Check if there are any capabilities and if at least one has a browser name
|
|
1270
|
+
return capValues.length > 0 && capValues.some(exports.hasBrowserName);
|
|
1271
|
+
};
|
|
1272
|
+
exports.isValidCapsForHealing = isValidCapsForHealing;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browserstack-service",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.38.1",
|
|
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",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"url": "https://github.com/webdriverio/webdriverio/issues"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
+
"@browserstack/ai-sdk-node": "1.5.9",
|
|
26
27
|
"@percy/appium-app": "^2.0.1",
|
|
27
28
|
"@percy/selenium-webdriver": "^2.0.2",
|
|
28
29
|
"@types/gitconfiglocal": "^2.0.1",
|
|
@@ -47,5 +48,5 @@
|
|
|
47
48
|
"access": "public"
|
|
48
49
|
},
|
|
49
50
|
"types": "./build/index.d.ts",
|
|
50
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "c4de09f154e6f4f7550743f1e4acc8063d052942"
|
|
51
52
|
}
|