@wdio/browserstack-service 7.16.14 → 7.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/build/constants.d.ts +0 -2
- package/build/constants.d.ts.map +0 -1
- package/build/constants.js +0 -13
- package/build/index.d.ts +0 -13
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -22
- package/build/launcher.d.ts +0 -17
- package/build/launcher.d.ts.map +0 -1
- package/build/launcher.js +0 -124
- package/build/service.d.ts +0 -40
- package/build/service.d.ts.map +0 -1
- package/build/service.js +0 -196
- package/build/types.d.ts +0 -37
- package/build/types.d.ts.map +0 -1
- package/build/types.js +0 -2
- package/build/util.d.ts +0 -21
- package/build/util.d.ts.map +0 -1
- package/build/util.js +0 -58
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browserstack-service",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.17.0",
|
|
4
4
|
"description": "WebdriverIO service for better Browserstack integration",
|
|
5
5
|
"author": "Adam Bjerstedt <abjerstedt@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@wdio/types": "7.16.14",
|
|
29
29
|
"browserstack-local": "^1.4.5",
|
|
30
30
|
"got": "^11.0.2",
|
|
31
|
-
"webdriverio": "7.
|
|
31
|
+
"webdriverio": "7.17.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@wdio/cli": "^7.0.0"
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"types": "./build/index.d.ts",
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "e18d2cde6ff979758830bdff4c3bc82ca9818b24"
|
|
41
41
|
}
|
package/build/constants.d.ts
DELETED
package/build/constants.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,qHAStB,CAAA"}
|
package/build/constants.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BROWSER_DESCRIPTION = void 0;
|
|
4
|
-
exports.BROWSER_DESCRIPTION = [
|
|
5
|
-
'device',
|
|
6
|
-
'os',
|
|
7
|
-
'osVersion',
|
|
8
|
-
'os_version',
|
|
9
|
-
'browserName',
|
|
10
|
-
'browser',
|
|
11
|
-
'browserVersion',
|
|
12
|
-
'browser_version'
|
|
13
|
-
];
|
package/build/index.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import BrowserstackLauncher from './launcher';
|
|
2
|
-
import BrowserstackService from './service';
|
|
3
|
-
import type { BrowserstackConfig } from './types';
|
|
4
|
-
export default BrowserstackService;
|
|
5
|
-
export declare const launcher: typeof BrowserstackLauncher;
|
|
6
|
-
export * from './types';
|
|
7
|
-
declare global {
|
|
8
|
-
namespace WebdriverIO {
|
|
9
|
-
interface ServiceOption extends BrowserstackConfig {
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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,eAAe,mBAAmB,CAAA;AAClC,eAAO,MAAM,QAAQ,6BAAuB,CAAA;AAC5C,cAAc,SAAS,CAAA;AAEvB,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,aAAc,SAAQ,kBAAkB;SAAG;KACxD;CACJ"}
|
package/build/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* istanbul ignore file */
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k;
|
|
5
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
6
|
-
}) : (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
o[k2] = m[k];
|
|
9
|
-
}));
|
|
10
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
11
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
12
|
-
};
|
|
13
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.launcher = void 0;
|
|
18
|
-
const launcher_1 = __importDefault(require("./launcher"));
|
|
19
|
-
const service_1 = __importDefault(require("./service"));
|
|
20
|
-
exports.default = service_1.default;
|
|
21
|
-
exports.launcher = launcher_1.default;
|
|
22
|
-
__exportStar(require("./types"), exports);
|
package/build/launcher.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as BrowserstackLocalLauncher from 'browserstack-local';
|
|
2
|
-
import type { Capabilities, Services, Options } from '@wdio/types';
|
|
3
|
-
import { BrowserstackConfig } from './types';
|
|
4
|
-
declare type BrowserstackLocal = BrowserstackLocalLauncher.Local & {
|
|
5
|
-
pid?: number;
|
|
6
|
-
stop(callback: (err?: any) => void): void;
|
|
7
|
-
};
|
|
8
|
-
export default class BrowserstackLauncherService implements Services.ServiceInstance {
|
|
9
|
-
private _options;
|
|
10
|
-
private _config;
|
|
11
|
-
browserstackLocal?: BrowserstackLocal;
|
|
12
|
-
constructor(_options: BrowserstackConfig, capabilities: Capabilities.RemoteCapability, _config: Options.Testrunner);
|
|
13
|
-
onPrepare(config?: Options.Testrunner, capabilities?: Capabilities.RemoteCapabilities): void | Promise<unknown>;
|
|
14
|
-
onComplete(): true | Promise<unknown> | undefined;
|
|
15
|
-
}
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=launcher.d.ts.map
|
package/build/launcher.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAI5C,aAAK,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;IAI5E,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,OAAO;IALnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;gBAGzB,QAAQ,EAAE,kBAAkB,EACpC,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IAGvC,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IA+DtF,UAAU;CAkCb"}
|
package/build/launcher.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
-
};
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
const util_1 = require("util");
|
|
26
|
-
const perf_hooks_1 = require("perf_hooks");
|
|
27
|
-
const BrowserstackLocalLauncher = __importStar(require("browserstack-local"));
|
|
28
|
-
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
29
|
-
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
30
|
-
class BrowserstackLauncherService {
|
|
31
|
-
constructor(_options, capabilities, _config) {
|
|
32
|
-
this._options = _options;
|
|
33
|
-
this._config = _config;
|
|
34
|
-
}
|
|
35
|
-
onPrepare(config, capabilities) {
|
|
36
|
-
if (!this._options.browserstackLocal) {
|
|
37
|
-
return log.info('browserstackLocal is not enabled - skipping...');
|
|
38
|
-
}
|
|
39
|
-
const opts = {
|
|
40
|
-
key: this._config.key,
|
|
41
|
-
forcelocal: true,
|
|
42
|
-
onlyAutomate: true,
|
|
43
|
-
...this._options.opts
|
|
44
|
-
};
|
|
45
|
-
this.browserstackLocal = new BrowserstackLocalLauncher.Local();
|
|
46
|
-
if (Array.isArray(capabilities)) {
|
|
47
|
-
capabilities.forEach((capability) => {
|
|
48
|
-
if (!capability['bstack:options']) {
|
|
49
|
-
capability['bstack:options'] = {};
|
|
50
|
-
}
|
|
51
|
-
capability['bstack:options'].local = true;
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
else if (typeof capabilities === 'object') {
|
|
55
|
-
Object.entries(capabilities).forEach(([, caps]) => {
|
|
56
|
-
if (!caps.capabilities['bstack:options']) {
|
|
57
|
-
caps.capabilities['bstack:options'] = {};
|
|
58
|
-
}
|
|
59
|
-
caps.capabilities['bstack:options'].local = true;
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
throw TypeError('Capabilities should be an object or Array!');
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* measure TestingBot tunnel boot time
|
|
67
|
-
*/
|
|
68
|
-
const obs = new perf_hooks_1.PerformanceObserver((list) => {
|
|
69
|
-
const entry = list.getEntries()[0];
|
|
70
|
-
log.info(`Browserstack Local successfully started after ${entry.duration}ms`);
|
|
71
|
-
});
|
|
72
|
-
obs.observe({ entryTypes: ['measure'] });
|
|
73
|
-
let timer;
|
|
74
|
-
perf_hooks_1.performance.mark('tbTunnelStart');
|
|
75
|
-
return Promise.race([
|
|
76
|
-
(0, util_1.promisify)(this.browserstackLocal.start.bind(this.browserstackLocal))(opts),
|
|
77
|
-
new Promise((resolve, reject) => {
|
|
78
|
-
/* istanbul ignore next */
|
|
79
|
-
timer = setTimeout(function () {
|
|
80
|
-
reject('Browserstack Local failed to start within 60 seconds!');
|
|
81
|
-
}, 60000);
|
|
82
|
-
})
|
|
83
|
-
]).then(function (result) {
|
|
84
|
-
clearTimeout(timer);
|
|
85
|
-
perf_hooks_1.performance.mark('tbTunnelEnd');
|
|
86
|
-
perf_hooks_1.performance.measure('bootTime', 'tbTunnelStart', 'tbTunnelEnd');
|
|
87
|
-
return Promise.resolve(result);
|
|
88
|
-
}, function (err) {
|
|
89
|
-
clearTimeout(timer);
|
|
90
|
-
return Promise.reject(err);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
onComplete() {
|
|
94
|
-
if (!this.browserstackLocal || !this.browserstackLocal.isRunning()) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (this._options.forcedStop) {
|
|
98
|
-
return process.kill(this.browserstackLocal.pid);
|
|
99
|
-
}
|
|
100
|
-
let timer;
|
|
101
|
-
return Promise.race([
|
|
102
|
-
new Promise((resolve, reject) => {
|
|
103
|
-
var _a;
|
|
104
|
-
(_a = this.browserstackLocal) === null || _a === void 0 ? void 0 : _a.stop((err) => {
|
|
105
|
-
if (err) {
|
|
106
|
-
return reject(err);
|
|
107
|
-
}
|
|
108
|
-
resolve();
|
|
109
|
-
});
|
|
110
|
-
}),
|
|
111
|
-
new Promise((resolve, reject) => {
|
|
112
|
-
/* istanbul ignore next */
|
|
113
|
-
timer = setTimeout(() => reject(new Error('Browserstack Local failed to stop within 60 seconds!')), 60000);
|
|
114
|
-
})
|
|
115
|
-
]).then(function (result) {
|
|
116
|
-
clearTimeout(timer);
|
|
117
|
-
return Promise.resolve(result);
|
|
118
|
-
}, function (err) {
|
|
119
|
-
clearTimeout(timer);
|
|
120
|
-
return Promise.reject(err);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
exports.default = BrowserstackLauncherService;
|
package/build/service.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { Services, Capabilities, Options, Frameworks } from '@wdio/types';
|
|
2
|
-
import type { Browser, MultiRemoteBrowser } from 'webdriverio';
|
|
3
|
-
import { BrowserstackConfig, MultiRemoteAction } from './types';
|
|
4
|
-
export default class BrowserstackService implements Services.ServiceInstance {
|
|
5
|
-
private _options;
|
|
6
|
-
private _caps;
|
|
7
|
-
private _config;
|
|
8
|
-
private _sessionBaseUrl;
|
|
9
|
-
private _failReasons;
|
|
10
|
-
private _scenariosThatRan;
|
|
11
|
-
private _failureStatuses;
|
|
12
|
-
private _browser?;
|
|
13
|
-
private _fullTitle?;
|
|
14
|
-
constructor(_options: BrowserstackConfig, _caps: Capabilities.RemoteCapability, _config: Options.Testrunner);
|
|
15
|
-
_updateCaps(fn: (caps: Capabilities.Capabilities | Capabilities.DesiredCapabilities) => void): void;
|
|
16
|
-
/**
|
|
17
|
-
* if no user and key is specified even though a browserstack service was
|
|
18
|
-
* provided set user and key with values so that the session request
|
|
19
|
-
* will fail
|
|
20
|
-
*/
|
|
21
|
-
beforeSession(config: Options.Testrunner): void;
|
|
22
|
-
before(caps: Capabilities.RemoteCapability, specs: string[], browser: Browser<'async'> | MultiRemoteBrowser<'async'>): Promise<void>;
|
|
23
|
-
beforeSuite(suite: Frameworks.Suite): void;
|
|
24
|
-
beforeFeature(uri: unknown, feature: {
|
|
25
|
-
name: string;
|
|
26
|
-
}): Promise<any>;
|
|
27
|
-
afterTest(test: Frameworks.Test, context: never, results: Frameworks.TestResult): void;
|
|
28
|
-
after(result: number): Promise<any>;
|
|
29
|
-
/**
|
|
30
|
-
* For CucumberJS
|
|
31
|
-
*/
|
|
32
|
-
afterScenario(world: Frameworks.World): void;
|
|
33
|
-
onReload(oldSessionId: string, newSessionId: string): Promise<void>;
|
|
34
|
-
_isAppAutomate(): boolean;
|
|
35
|
-
_updateJob(requestBody: any): Promise<any>;
|
|
36
|
-
_multiRemoteAction(action: MultiRemoteAction): Promise<any>;
|
|
37
|
-
_update(sessionId: string, requestBody: any): import("got").CancelableRequest<import("got").Response<string>>;
|
|
38
|
-
_printSessionURL(): Promise<void>;
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=service.d.ts.map
|
package/build/service.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,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;AAG9D,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAmB,MAAM,SAAS,CAAA;AAIhF,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,QAAQ,CAAC,eAAe;IASpE,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IAVnB,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,UAAU,CAAC,CAAQ;gBAGf,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,YAAY,CAAC,gBAAgB,EACpC,OAAO,EAAE,OAAO,CAAC,UAAU;IAUvC,WAAW,CAAE,EAAE,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,GAAG,YAAY,CAAC,mBAAmB,KAAK,IAAI;IAU7F;;;;OAIG;IACH,aAAa,CAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IAYzC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;IAcpH,WAAW,CAAE,KAAK,EAAE,UAAU,CAAC,KAAK;IAIpC,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IAKrD,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,UAAU;IAqB/E,KAAK,CAAE,MAAM,EAAE,MAAM;IAgBrB;;OAEG;IACH,aAAa,CAAE,KAAK,EAAE,UAAU,CAAC,KAAK;IAmBhC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IA2BzD,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;IAUrC,gBAAgB;CAsBzB"}
|
package/build/service.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
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 logger_1 = __importDefault(require("@wdio/logger"));
|
|
7
|
-
const got_1 = __importDefault(require("got"));
|
|
8
|
-
const util_1 = require("./util");
|
|
9
|
-
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
10
|
-
class BrowserstackService {
|
|
11
|
-
constructor(_options, _caps, _config) {
|
|
12
|
-
this._options = _options;
|
|
13
|
-
this._caps = _caps;
|
|
14
|
-
this._config = _config;
|
|
15
|
-
this._sessionBaseUrl = 'https://api.browserstack.com/automate/sessions';
|
|
16
|
-
this._failReasons = [];
|
|
17
|
-
this._scenariosThatRan = [];
|
|
18
|
-
this._failureStatuses = ['failed', 'ambiguous', 'undefined', 'unknown'];
|
|
19
|
-
// Cucumber specific
|
|
20
|
-
const strict = Boolean(this._config.cucumberOpts && this._config.cucumberOpts.strict);
|
|
21
|
-
// See https://github.com/cucumber/cucumber-js/blob/master/src/runtime/index.ts#L136
|
|
22
|
-
if (strict) {
|
|
23
|
-
this._failureStatuses.push('pending');
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
_updateCaps(fn) {
|
|
27
|
-
const multiRemoteCap = this._caps;
|
|
28
|
-
if (multiRemoteCap.capabilities) {
|
|
29
|
-
return Object.entries(multiRemoteCap).forEach(([, caps]) => fn(caps.capabilities));
|
|
30
|
-
}
|
|
31
|
-
return fn(this._caps);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* if no user and key is specified even though a browserstack service was
|
|
35
|
-
* provided set user and key with values so that the session request
|
|
36
|
-
* will fail
|
|
37
|
-
*/
|
|
38
|
-
beforeSession(config) {
|
|
39
|
-
if (!config.user) {
|
|
40
|
-
config.user = 'NotSetUser';
|
|
41
|
-
}
|
|
42
|
-
if (!config.key) {
|
|
43
|
-
config.key = 'NotSetKey';
|
|
44
|
-
}
|
|
45
|
-
this._config.user = config.user;
|
|
46
|
-
this._config.key = config.key;
|
|
47
|
-
}
|
|
48
|
-
before(caps, specs, browser) {
|
|
49
|
-
this._browser = browser;
|
|
50
|
-
// Ensure capabilities are not null in case of multiremote
|
|
51
|
-
if (this._isAppAutomate()) {
|
|
52
|
-
this._sessionBaseUrl = 'https://api-cloud.browserstack.com/app-automate/sessions';
|
|
53
|
-
}
|
|
54
|
-
this._scenariosThatRan = [];
|
|
55
|
-
return this._printSessionURL();
|
|
56
|
-
}
|
|
57
|
-
beforeSuite(suite) {
|
|
58
|
-
this._fullTitle = suite.title;
|
|
59
|
-
}
|
|
60
|
-
beforeFeature(uri, feature) {
|
|
61
|
-
this._fullTitle = feature.name;
|
|
62
|
-
return this._updateJob({ name: this._fullTitle });
|
|
63
|
-
}
|
|
64
|
-
afterTest(test, context, results) {
|
|
65
|
-
const { error, passed } = results;
|
|
66
|
-
// Jasmine
|
|
67
|
-
if (test.fullName) {
|
|
68
|
-
const testSuiteName = test.fullName.slice(0, test.fullName.indexOf(test.description || '') - 1);
|
|
69
|
-
if (this._fullTitle === 'Jasmine__TopLevel__Suite') {
|
|
70
|
-
this._fullTitle = testSuiteName;
|
|
71
|
-
}
|
|
72
|
-
else if (this._fullTitle) {
|
|
73
|
-
this._fullTitle = (0, util_1.getParentSuiteName)(this._fullTitle, testSuiteName);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
// Mocha
|
|
78
|
-
this._fullTitle = `${test.parent} - ${test.title}`;
|
|
79
|
-
}
|
|
80
|
-
if (!passed) {
|
|
81
|
-
this._failReasons.push((error && error.message) || 'Unknown Error');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
after(result) {
|
|
85
|
-
// For Cucumber: Checks scenarios that ran (i.e. not skipped) on the session
|
|
86
|
-
// Only 1 Scenario ran and option enabled => Redefine session name to Scenario's name
|
|
87
|
-
if (this._options.preferScenarioName && this._scenariosThatRan.length === 1) {
|
|
88
|
-
this._fullTitle = this._scenariosThatRan.pop();
|
|
89
|
-
}
|
|
90
|
-
const hasReasons = Boolean(this._failReasons.filter(Boolean).length);
|
|
91
|
-
return this._updateJob({
|
|
92
|
-
status: result === 0 ? 'passed' : 'failed',
|
|
93
|
-
name: this._fullTitle,
|
|
94
|
-
reason: hasReasons ? this._failReasons.join('\n') : undefined
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* For CucumberJS
|
|
99
|
-
*/
|
|
100
|
-
afterScenario(world) {
|
|
101
|
-
var _a;
|
|
102
|
-
const status = (_a = world.result) === null || _a === void 0 ? void 0 : _a.status.toLowerCase();
|
|
103
|
-
if (status === 'skipped') {
|
|
104
|
-
this._scenariosThatRan.push(world.pickle.name || 'unknown pickle name');
|
|
105
|
-
}
|
|
106
|
-
if (status && this._failureStatuses.includes(status)) {
|
|
107
|
-
const exception = ((world.result && world.result.message) ||
|
|
108
|
-
(status === 'pending'
|
|
109
|
-
? `Some steps/hooks are pending for scenario "${world.pickle.name}"`
|
|
110
|
-
: 'Unknown Error'));
|
|
111
|
-
this._failReasons.push(exception);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
async onReload(oldSessionId, newSessionId) {
|
|
115
|
-
if (!this._browser) {
|
|
116
|
-
return Promise.resolve();
|
|
117
|
-
}
|
|
118
|
-
const hasReasons = Boolean(this._failReasons.filter(Boolean).length);
|
|
119
|
-
let status = hasReasons ? 'failed' : 'passed';
|
|
120
|
-
if (!this._browser.isMultiremote) {
|
|
121
|
-
log.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${status}`);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
const browserName = this._browser.instances.filter((browserName) => this._browser && this._browser[browserName].sessionId === newSessionId)[0];
|
|
125
|
-
log.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${status}`);
|
|
126
|
-
}
|
|
127
|
-
await this._update(oldSessionId, {
|
|
128
|
-
name: this._fullTitle,
|
|
129
|
-
status,
|
|
130
|
-
reason: hasReasons ? this._failReasons.join('\n') : undefined
|
|
131
|
-
});
|
|
132
|
-
this._scenariosThatRan = [];
|
|
133
|
-
delete this._fullTitle;
|
|
134
|
-
this._failReasons = [];
|
|
135
|
-
await this._printSessionURL();
|
|
136
|
-
}
|
|
137
|
-
_isAppAutomate() {
|
|
138
|
-
var _a, _b, _c;
|
|
139
|
-
const browserDesiredCapabilities = ((_b = (_a = this._browser) === null || _a === void 0 ? void 0 : _a.capabilities) !== null && _b !== void 0 ? _b : {});
|
|
140
|
-
const desiredCapabilities = ((_c = this._caps) !== null && _c !== void 0 ? _c : {});
|
|
141
|
-
return !!browserDesiredCapabilities['appium:app'] || !!desiredCapabilities['appium:app'] || !!browserDesiredCapabilities.app || !!desiredCapabilities.app;
|
|
142
|
-
}
|
|
143
|
-
_updateJob(requestBody) {
|
|
144
|
-
return this._multiRemoteAction((sessionId, browserName) => {
|
|
145
|
-
log.info(browserName
|
|
146
|
-
? `Update multiremote job for browser "${browserName}" and sessionId ${sessionId}`
|
|
147
|
-
: `Update job with sessionId ${sessionId}`);
|
|
148
|
-
return this._update(sessionId, requestBody);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
_multiRemoteAction(action) {
|
|
152
|
-
const { _browser } = this;
|
|
153
|
-
if (!_browser) {
|
|
154
|
-
return Promise.resolve();
|
|
155
|
-
}
|
|
156
|
-
if (!_browser.isMultiremote) {
|
|
157
|
-
return action(_browser.sessionId);
|
|
158
|
-
}
|
|
159
|
-
return Promise.all(_browser.instances
|
|
160
|
-
.filter(browserName => {
|
|
161
|
-
const cap = (0, util_1.getBrowserCapabilities)(_browser, this._caps, browserName);
|
|
162
|
-
return (0, util_1.isBrowserstackCapability)(cap);
|
|
163
|
-
})
|
|
164
|
-
.map((browserName) => (action(_browser[browserName].sessionId, browserName))));
|
|
165
|
-
}
|
|
166
|
-
_update(sessionId, requestBody) {
|
|
167
|
-
const sessionUrl = `${this._sessionBaseUrl}/${sessionId}.json`;
|
|
168
|
-
log.debug(`Updating Browserstack session at ${sessionUrl} with request body: `, requestBody);
|
|
169
|
-
return got_1.default.put(sessionUrl, {
|
|
170
|
-
json: requestBody,
|
|
171
|
-
username: this._config.user,
|
|
172
|
-
password: this._config.key
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
async _printSessionURL() {
|
|
176
|
-
if (!this._browser) {
|
|
177
|
-
return Promise.resolve();
|
|
178
|
-
}
|
|
179
|
-
await this._multiRemoteAction(async (sessionId, browserName) => {
|
|
180
|
-
const sessionUrl = `${this._sessionBaseUrl}/${sessionId}.json`;
|
|
181
|
-
log.debug(`Requesting Browserstack session URL at ${sessionUrl}`);
|
|
182
|
-
const response = await (0, got_1.default)(sessionUrl, {
|
|
183
|
-
username: this._config.user,
|
|
184
|
-
password: this._config.key,
|
|
185
|
-
responseType: 'json'
|
|
186
|
-
});
|
|
187
|
-
if (!this._browser) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
const capabilities = (0, util_1.getBrowserCapabilities)(this._browser, this._caps, browserName);
|
|
191
|
-
const browserString = (0, util_1.getBrowserDescription)(capabilities);
|
|
192
|
-
log.info(`${browserString} session: ${response.body.automation_session.browser_url}`);
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
exports.default = BrowserstackService;
|
package/build/types.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export interface SessionResponse {
|
|
2
|
-
automation_session: {
|
|
3
|
-
browser_url: string;
|
|
4
|
-
};
|
|
5
|
-
}
|
|
6
|
-
export declare type MultiRemoteAction = (sessionId: string, browserName?: string) => Promise<any>;
|
|
7
|
-
export interface BrowserstackConfig {
|
|
8
|
-
/**
|
|
9
|
-
* Set this to true to enable routing connections from Browserstack cloud through your computer.
|
|
10
|
-
* You will also need to set `browserstack.local` to true in browser capabilities.
|
|
11
|
-
*/
|
|
12
|
-
browserstackLocal?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Cucumber only. Set this to true to enable updating the session name to the Scenario name if only
|
|
15
|
-
* a single Scenario was ran. Useful when running in parallel
|
|
16
|
-
* with [wdio-cucumber-parallel-execution](https://github.com/SimitTomar/wdio-cucumber-parallel-execution).
|
|
17
|
-
*/
|
|
18
|
-
preferScenarioName?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Set this to true to kill the browserstack process on complete, without waiting for the
|
|
21
|
-
* browserstack stop callback to be called. This is experimental and should not be used by all.
|
|
22
|
-
*/
|
|
23
|
-
forcedStop?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Specified optional will be passed down to BrowserstackLocal. For more details check out the
|
|
26
|
-
* [`browserstack-local`](https://www.npmjs.com/package/browserstack-local#arguments) docs.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```js
|
|
30
|
-
* {
|
|
31
|
-
* localIdentifier: 'some-identifier'
|
|
32
|
-
* }
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
opts?: Partial<import('browserstack-local').Options>;
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=types.d.ts.map
|
package/build/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAE5B,kBAAkB,EAAE;QAEhB,WAAW,EAAE,MAAM,CAAA;KACtB,CAAA;CACJ;AAED,oBAAY,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAE1F,MAAM,WAAW,kBAAkB;IAC/B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAAA;CACvD"}
|
package/build/types.js
DELETED
package/build/util.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { Browser, MultiRemoteBrowser } from 'webdriverio';
|
|
2
|
-
import type { Capabilities } from '@wdio/types';
|
|
3
|
-
/**
|
|
4
|
-
* get browser description for Browserstack service
|
|
5
|
-
* @param cap browser capablities
|
|
6
|
-
*/
|
|
7
|
-
export declare function getBrowserDescription(cap: Capabilities.DesiredCapabilities): string;
|
|
8
|
-
/**
|
|
9
|
-
* get correct browser capabilities object in both multiremote and normal setups
|
|
10
|
-
* @param browser browser object
|
|
11
|
-
* @param caps browser capbilities object. In case of multiremote, the object itself should have a property named 'capabilities'
|
|
12
|
-
* @param browserName browser name in case of multiremote
|
|
13
|
-
*/
|
|
14
|
-
export declare function getBrowserCapabilities(browser: Browser<'async'> | MultiRemoteBrowser<'async'>, caps?: Capabilities.RemoteCapability, browserName?: string): Capabilities.Capabilities;
|
|
15
|
-
/**
|
|
16
|
-
* check for browserstack W3C capabilities. Does not support legacy capabilities
|
|
17
|
-
* @param cap browser capabilities
|
|
18
|
-
*/
|
|
19
|
-
export declare function isBrowserstackCapability(cap?: Capabilities.Capabilities): boolean;
|
|
20
|
-
export declare function getParentSuiteName(fullTitle: string, testSuiteTitle: string): string;
|
|
21
|
-
//# sourceMappingURL=util.d.ts.map
|
package/build/util.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI/C;;;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,WAEvE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAUpF"}
|
package/build/util.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getParentSuiteName = exports.isBrowserstackCapability = exports.getBrowserCapabilities = exports.getBrowserDescription = void 0;
|
|
4
|
-
const constants_1 = require("./constants");
|
|
5
|
-
/**
|
|
6
|
-
* get browser description for Browserstack service
|
|
7
|
-
* @param cap browser capablities
|
|
8
|
-
*/
|
|
9
|
-
function getBrowserDescription(cap) {
|
|
10
|
-
cap = cap || {};
|
|
11
|
-
if (cap['bstack:options']) {
|
|
12
|
-
cap = { ...cap, ...cap['bstack:options'] };
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* These keys describe the browser the test was run on
|
|
16
|
-
*/
|
|
17
|
-
return constants_1.BROWSER_DESCRIPTION
|
|
18
|
-
.map((k) => cap[k])
|
|
19
|
-
.filter(Boolean)
|
|
20
|
-
.join(' ');
|
|
21
|
-
}
|
|
22
|
-
exports.getBrowserDescription = getBrowserDescription;
|
|
23
|
-
/**
|
|
24
|
-
* get correct browser capabilities object in both multiremote and normal setups
|
|
25
|
-
* @param browser browser object
|
|
26
|
-
* @param caps browser capbilities object. In case of multiremote, the object itself should have a property named 'capabilities'
|
|
27
|
-
* @param browserName browser name in case of multiremote
|
|
28
|
-
*/
|
|
29
|
-
function getBrowserCapabilities(browser, caps, browserName) {
|
|
30
|
-
if (!browser.isMultiremote) {
|
|
31
|
-
return { ...browser.capabilities, ...caps };
|
|
32
|
-
}
|
|
33
|
-
const multiCaps = caps;
|
|
34
|
-
const globalCap = browserName && browser[browserName] ? browser[browserName].capabilities : {};
|
|
35
|
-
const cap = browserName && multiCaps[browserName] ? multiCaps[browserName].capabilities : {};
|
|
36
|
-
return { ...globalCap, ...cap };
|
|
37
|
-
}
|
|
38
|
-
exports.getBrowserCapabilities = getBrowserCapabilities;
|
|
39
|
-
/**
|
|
40
|
-
* check for browserstack W3C capabilities. Does not support legacy capabilities
|
|
41
|
-
* @param cap browser capabilities
|
|
42
|
-
*/
|
|
43
|
-
function isBrowserstackCapability(cap) {
|
|
44
|
-
return Boolean(cap && cap['bstack:options']);
|
|
45
|
-
}
|
|
46
|
-
exports.isBrowserstackCapability = isBrowserstackCapability;
|
|
47
|
-
function getParentSuiteName(fullTitle, testSuiteTitle) {
|
|
48
|
-
const fullTitleWords = fullTitle.split(' ');
|
|
49
|
-
const testSuiteTitleWords = testSuiteTitle.split(' ');
|
|
50
|
-
const shortestLength = Math.min(fullTitleWords.length, testSuiteTitleWords.length);
|
|
51
|
-
let c = 0;
|
|
52
|
-
let parentSuiteName = '';
|
|
53
|
-
while (c < shortestLength && fullTitleWords[c] === testSuiteTitleWords[c]) {
|
|
54
|
-
parentSuiteName += fullTitleWords[c++] + ' ';
|
|
55
|
-
}
|
|
56
|
-
return parentSuiteName.trim();
|
|
57
|
-
}
|
|
58
|
-
exports.getParentSuiteName = getParentSuiteName;
|