@wdio/browserstack-service 7.25.4 → 7.27.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/README.md +52 -13
- package/build/constants.d.ts +2 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +5 -1
- package/build/launcher.d.ts +1 -1
- package/build/launcher.d.ts.map +1 -1
- package/build/service.d.ts +18 -10
- package/build/service.d.ts.map +1 -1
- package/build/service.js +79 -40
- package/build/types.d.ts +47 -15
- package/build/types.d.ts.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
WebdriverIO
|
|
1
|
+
WebdriverIO BrowserStack Service
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
|
-
> A WebdriverIO service that manages local tunnel and job metadata for
|
|
4
|
+
> A WebdriverIO service that manages local tunnel and job metadata for BrowserStack users.
|
|
5
5
|
|
|
6
6
|
## Installation
|
|
7
7
|
|
|
@@ -16,7 +16,7 @@ Instructions on how to install `WebdriverIO` can be found [here.](https://webdri
|
|
|
16
16
|
|
|
17
17
|
## Configuration
|
|
18
18
|
|
|
19
|
-
WebdriverIO has
|
|
19
|
+
WebdriverIO has BrowserStack support out of the box. You should set `user` and `key` in your `wdio.conf.js` file. This service plugin provides support for [BrowserStack](https://www.browserstack.com/automate/node#setting-local-tunnel) Tunnel](https://www.browserstack.com/automate/node#setting-local-tunnel). Set `browserstackLocal: true` also to activate this feature.
|
|
20
20
|
Reporting of session status on BrowserStack will respect `strict` setting of Cucumber options.
|
|
21
21
|
|
|
22
22
|
```js
|
|
@@ -39,19 +39,13 @@ exports.config
|
|
|
39
39
|
In order to authorize to the BrowserStack service your config needs to contain a [`user`](https://webdriver.io/docs/options#user) and [`key`](https://webdriver.io/docs/options#key) option.
|
|
40
40
|
|
|
41
41
|
### browserstackLocal
|
|
42
|
-
Set this to true to enable routing connections from
|
|
43
|
-
|
|
44
|
-
Type: `Boolean`<br />
|
|
45
|
-
Default: `false`
|
|
46
|
-
|
|
47
|
-
### preferScenarioName
|
|
48
|
-
Cucumber only. Set this to true to enable updating the session name to the Scenario name if only a single Scenario was ran. Useful when running in parallel with [wdio-cucumber-parallel-execution](https://github.com/SimitTomar/wdio-cucumber-parallel-execution).
|
|
42
|
+
Set this to true to enable routing connections from BrowserStack cloud through your computer.
|
|
49
43
|
|
|
50
44
|
Type: `Boolean`<br />
|
|
51
45
|
Default: `false`
|
|
52
46
|
|
|
53
47
|
### forcedStop
|
|
54
|
-
Set this to true to kill the
|
|
48
|
+
Set this to true to kill the BrowserStack Local process on complete, without waiting for the BrowserStack Local stop callback to be called. This is experimental and should not be used by all. Mostly necessary as a workaraound for [this issue](https://github.com/browserstack/browserstack-local-nodejs/issues/41).
|
|
55
49
|
|
|
56
50
|
Type: `Boolean`<br />
|
|
57
51
|
Default: `false`
|
|
@@ -141,8 +135,53 @@ services: [
|
|
|
141
135
|
]
|
|
142
136
|
```
|
|
143
137
|
|
|
138
|
+
### preferScenarioName
|
|
139
|
+
|
|
140
|
+
Cucumber only. Set the BrowserStack Automate session name to the Scenario name if only a single Scenario ran.
|
|
141
|
+
Useful when running in parallel with [wdio-cucumber-parallel-execution](https://github.com/SimitTomar/wdio-cucumber-parallel-execution).
|
|
142
|
+
|
|
143
|
+
Type: `Boolean`<br />
|
|
144
|
+
Default: `false`
|
|
145
|
+
|
|
146
|
+
### sessionNameFormat
|
|
147
|
+
|
|
148
|
+
Customize the BrowserStack Automate session name format.
|
|
149
|
+
|
|
150
|
+
Type: `Function`<br />
|
|
151
|
+
Default (Cucumber/Jasmine): `(config, capabilities, suiteTitle) => suiteTitle`<br />
|
|
152
|
+
Default (Mocha): `(config, capabilities, suiteTitle, testTitle) => suiteTitle + ' - ' + testTitle`
|
|
153
|
+
|
|
154
|
+
### sessionNameOmitTestTitle
|
|
155
|
+
|
|
156
|
+
Mocha only. Do not append the test title to the BrowserStack Automate session name.
|
|
157
|
+
|
|
158
|
+
Type: `Boolean`<br />
|
|
159
|
+
Default: `false`
|
|
160
|
+
|
|
161
|
+
### sessionNamePrependTopLevelSuiteTitle
|
|
162
|
+
|
|
163
|
+
Mocha only. Prepend the top level suite title to the BrowserStack Automate session name.
|
|
164
|
+
|
|
165
|
+
Type: `Boolean`<br />
|
|
166
|
+
Default: `false`
|
|
167
|
+
|
|
168
|
+
### setSessionName
|
|
169
|
+
|
|
170
|
+
Automatically set the BrowserStack Automate session name.
|
|
171
|
+
|
|
172
|
+
Type: `Boolean`<br />
|
|
173
|
+
Default: `true`
|
|
174
|
+
|
|
175
|
+
### setSessionStatus
|
|
176
|
+
|
|
177
|
+
Automatically set the BrowserStack Automate session status (passed/failed).
|
|
178
|
+
|
|
179
|
+
Type: `Boolean`<br />
|
|
180
|
+
Default: `true`
|
|
181
|
+
|
|
144
182
|
### opts
|
|
145
|
-
|
|
183
|
+
|
|
184
|
+
BrowserStack Local options.
|
|
146
185
|
|
|
147
186
|
Type: `Object`<br />
|
|
148
187
|
Default: `{}`
|
|
@@ -185,7 +224,7 @@ opts = { f: "/my/awesome/folder" };
|
|
|
185
224
|
|
|
186
225
|
#### Force Start
|
|
187
226
|
|
|
188
|
-
To kill other running
|
|
227
|
+
To kill other running BrowserStack Local instances -
|
|
189
228
|
|
|
190
229
|
```js
|
|
191
230
|
opts = { force: "true" };
|
package/build/constants.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { BrowserstackConfig } from './types';
|
|
1
2
|
export declare const BROWSER_DESCRIPTION: readonly ["device", "os", "osVersion", "os_version", "browserName", "browser", "browserVersion", "browser_version"];
|
|
2
3
|
export declare const VALID_APP_EXTENSION: string[];
|
|
4
|
+
export declare const DEFAULT_OPTIONS: Partial<BrowserstackConfig>;
|
|
3
5
|
//# 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,eAAO,MAAM,mBAAmB,qHAStB,CAAA;AAEV,eAAO,MAAM,mBAAmB,UAI/B,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,eAAO,MAAM,mBAAmB,qHAStB,CAAA;AAEV,eAAO,MAAM,mBAAmB,UAI/B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,kBAAkB,CAGvD,CAAA"}
|
package/build/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VALID_APP_EXTENSION = exports.BROWSER_DESCRIPTION = void 0;
|
|
3
|
+
exports.DEFAULT_OPTIONS = exports.VALID_APP_EXTENSION = exports.BROWSER_DESCRIPTION = void 0;
|
|
4
4
|
exports.BROWSER_DESCRIPTION = [
|
|
5
5
|
'device',
|
|
6
6
|
'os',
|
|
@@ -16,3 +16,7 @@ exports.VALID_APP_EXTENSION = [
|
|
|
16
16
|
'.aab',
|
|
17
17
|
'.ipa'
|
|
18
18
|
];
|
|
19
|
+
exports.DEFAULT_OPTIONS = {
|
|
20
|
+
setSessionName: true,
|
|
21
|
+
setSessionStatus: true
|
|
22
|
+
};
|
package/build/launcher.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as BrowserstackLocalLauncher from 'browserstack-local';
|
|
|
2
2
|
import type { Capabilities, Services, Options } from '@wdio/types';
|
|
3
3
|
import { App, AppConfig, AppUploadResponse } from './types';
|
|
4
4
|
import { BrowserstackConfig } from './types';
|
|
5
|
-
|
|
5
|
+
type BrowserstackLocal = BrowserstackLocalLauncher.Local & {
|
|
6
6
|
pid?: number;
|
|
7
7
|
stop(callback: (err?: any) => void): void;
|
|
8
8
|
};
|
package/build/launcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAI3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAK5C,
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAI3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAK5C,KAAK,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7C,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,2BAA4B,YAAW,QAAQ,CAAC,eAAe;IAI5E,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,OAAO;IALnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;gBAGzB,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACzD,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IAiCjC,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IA6E5F,UAAU;IAmCJ,UAAU,CAAC,GAAG,EAAC,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkBrD;;;OAGG;IACG,YAAY,CAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBhE,WAAW,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAC,MAAM;CA+C9F"}
|
package/build/service.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { Services, Capabilities, Options, Frameworks } from '@wdio/types';
|
|
|
2
2
|
import type { Browser, MultiRemoteBrowser } from 'webdriverio';
|
|
3
3
|
import { BrowserstackConfig, MultiRemoteAction } from './types';
|
|
4
4
|
export default class BrowserstackService implements Services.ServiceInstance {
|
|
5
|
-
private _options;
|
|
6
5
|
private _caps;
|
|
7
6
|
private _config;
|
|
8
7
|
private _sessionBaseUrl;
|
|
@@ -10,22 +9,30 @@ export default class BrowserstackService implements Services.ServiceInstance {
|
|
|
10
9
|
private _scenariosThatRan;
|
|
11
10
|
private _failureStatuses;
|
|
12
11
|
private _browser?;
|
|
12
|
+
private _suiteTitle?;
|
|
13
13
|
private _fullTitle?;
|
|
14
|
-
|
|
14
|
+
private _options;
|
|
15
|
+
constructor(options: BrowserstackConfig & Options.Testrunner, _caps: Capabilities.RemoteCapability, _config: Options.Testrunner);
|
|
15
16
|
_updateCaps(fn: (caps: Capabilities.Capabilities | Capabilities.DesiredCapabilities) => void): void;
|
|
17
|
+
beforeSession(config: Omit<Options.Testrunner, 'capabilities'>): void;
|
|
18
|
+
before(caps: Capabilities.RemoteCapability, specs: string[], browser: Browser<'async'> | MultiRemoteBrowser<'async'>): Promise<void>;
|
|
16
19
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
+
* Set the default job name at the suite level to make sure we account
|
|
21
|
+
* for the cases where there is a long running `before` function for a
|
|
22
|
+
* suite or one that can fail.
|
|
23
|
+
* Don't do this for Jasmine because `suite.title` is `Jasmine__TopLevel__Suite`
|
|
24
|
+
* and `suite.fullTitle` is `undefined`, so no alternative to use for the job name.
|
|
25
|
+
*/
|
|
26
|
+
beforeSuite(suite: Frameworks.Suite): Promise<void>;
|
|
27
|
+
beforeTest(test: Frameworks.Test): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* For CucumberJS
|
|
20
30
|
*/
|
|
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
31
|
beforeFeature(uri: unknown, feature: {
|
|
25
32
|
name: string;
|
|
26
|
-
}): Promise<
|
|
33
|
+
}): Promise<void>;
|
|
27
34
|
afterTest(test: Frameworks.Test, context: never, results: Frameworks.TestResult): void;
|
|
28
|
-
after(result: number): Promise<
|
|
35
|
+
after(result: number): Promise<void>;
|
|
29
36
|
/**
|
|
30
37
|
* For CucumberJS
|
|
31
38
|
*/
|
|
@@ -36,5 +43,6 @@ export default class BrowserstackService implements Services.ServiceInstance {
|
|
|
36
43
|
_multiRemoteAction(action: MultiRemoteAction): Promise<any>;
|
|
37
44
|
_update(sessionId: string, requestBody: any): import("got").CancelableRequest<import("got").Response<string>>;
|
|
38
45
|
_printSessionURL(): Promise<void>;
|
|
46
|
+
private _setSessionName;
|
|
39
47
|
}
|
|
40
48
|
//# sourceMappingURL=service.d.ts.map
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAKhF,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,QAAQ,CAAC,eAAe;IAYpE,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IAZnB,OAAO,CAAC,eAAe,CAAmD;IAC1E,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,gBAAgB,CAA4D;IACpF,OAAO,CAAC,QAAQ,CAAC,CAAgD;IACjE,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAyC;gBAGrD,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACxC,KAAK,EAAE,YAAY,CAAC,gBAAgB,EACpC,OAAO,EAAE,OAAO,CAAC,UAAU;IAavC,WAAW,CAAE,EAAE,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,GAAG,YAAY,CAAC,mBAAmB,KAAK,IAAI;IAU7F,aAAa,CAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC;IAe/D,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;IAepH;;;;;;OAMG;IACG,WAAW,CAAE,KAAK,EAAE,UAAU,CAAC,KAAK;IAQpC,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI;IAiBvC;;OAEG;IACH,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;IAOzE,KAAK,CAAE,MAAM,EAAE,MAAM;IAkB3B;;OAEG;IACH,aAAa,CAAE,KAAK,EAAE,UAAU,CAAC,KAAK;IAmBhC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IAgCzD,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;YAuBR,eAAe;CAyBhC"}
|
package/build/service.js
CHANGED
|
@@ -6,18 +6,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
7
7
|
const got_1 = __importDefault(require("got"));
|
|
8
8
|
const util_1 = require("./util");
|
|
9
|
+
const constants_1 = require("./constants");
|
|
9
10
|
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
10
11
|
class BrowserstackService {
|
|
11
|
-
constructor(
|
|
12
|
-
this._options = _options;
|
|
12
|
+
constructor(options, _caps, _config) {
|
|
13
13
|
this._caps = _caps;
|
|
14
14
|
this._config = _config;
|
|
15
15
|
this._sessionBaseUrl = 'https://api.browserstack.com/automate/sessions';
|
|
16
16
|
this._failReasons = [];
|
|
17
17
|
this._scenariosThatRan = [];
|
|
18
18
|
this._failureStatuses = ['failed', 'ambiguous', 'undefined', 'unknown'];
|
|
19
|
+
this._options = { ...constants_1.DEFAULT_OPTIONS, ...options };
|
|
19
20
|
// added to maintain backward compatibility with webdriverIO v5
|
|
20
|
-
this._config || (this._config = _options);
|
|
21
|
+
this._config || (this._config = this._options);
|
|
21
22
|
// Cucumber specific
|
|
22
23
|
const strict = Boolean(this._config.cucumberOpts && this._config.cucumberOpts.strict);
|
|
23
24
|
// See https://github.com/cucumber/cucumber-js/blob/master/src/runtime/index.ts#L136
|
|
@@ -32,12 +33,10 @@ class BrowserstackService {
|
|
|
32
33
|
}
|
|
33
34
|
return fn(this._caps);
|
|
34
35
|
}
|
|
35
|
-
/**
|
|
36
|
-
* if no user and key is specified even though a browserstack service was
|
|
37
|
-
* provided set user and key with values so that the session request
|
|
38
|
-
* will fail
|
|
39
|
-
*/
|
|
40
36
|
beforeSession(config) {
|
|
37
|
+
// if no user and key is specified even though a browserstack service was
|
|
38
|
+
// provided set user and key with values so that the session request
|
|
39
|
+
// will fail
|
|
41
40
|
if (!config.user) {
|
|
42
41
|
config.user = 'NotSetUser';
|
|
43
42
|
}
|
|
@@ -57,45 +56,62 @@ class BrowserstackService {
|
|
|
57
56
|
this._scenariosThatRan = [];
|
|
58
57
|
return this._printSessionURL();
|
|
59
58
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Set the default job name at the suite level to make sure we account
|
|
61
|
+
* for the cases where there is a long running `before` function for a
|
|
62
|
+
* suite or one that can fail.
|
|
63
|
+
* Don't do this for Jasmine because `suite.title` is `Jasmine__TopLevel__Suite`
|
|
64
|
+
* and `suite.fullTitle` is `undefined`, so no alternative to use for the job name.
|
|
65
|
+
*/
|
|
66
|
+
async beforeSuite(suite) {
|
|
67
|
+
this._suiteTitle = suite.title;
|
|
68
|
+
if (suite.title && suite.title !== 'Jasmine__TopLevel__Suite') {
|
|
69
|
+
await this._setSessionName(suite.title);
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// Jasmine
|
|
72
|
+
async beforeTest(test) {
|
|
73
|
+
let suiteTitle = this._suiteTitle;
|
|
70
74
|
if (test.fullName) {
|
|
75
|
+
// For Jasmine, `suite.title` is `Jasmine__TopLevel__Suite`.
|
|
76
|
+
// This tweak allows us to set the real suite name.
|
|
71
77
|
const testSuiteName = test.fullName.slice(0, test.fullName.indexOf(test.description || '') - 1);
|
|
72
|
-
if (this.
|
|
73
|
-
|
|
78
|
+
if (this._suiteTitle === 'Jasmine__TopLevel__Suite') {
|
|
79
|
+
suiteTitle = testSuiteName;
|
|
74
80
|
}
|
|
75
|
-
else if (this.
|
|
76
|
-
|
|
81
|
+
else if (this._suiteTitle) {
|
|
82
|
+
suiteTitle = (0, util_1.getParentSuiteName)(this._suiteTitle, testSuiteName);
|
|
77
83
|
}
|
|
78
84
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
await this._setSessionName(suiteTitle, test);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* For CucumberJS
|
|
89
|
+
*/
|
|
90
|
+
beforeFeature(uri, feature) {
|
|
91
|
+
this._suiteTitle = feature.name;
|
|
92
|
+
return this._setSessionName(feature.name);
|
|
93
|
+
}
|
|
94
|
+
afterTest(test, context, results) {
|
|
95
|
+
const { error, passed } = results;
|
|
83
96
|
if (!passed) {
|
|
84
97
|
this._failReasons.push((error && error.message) || 'Unknown Error');
|
|
85
98
|
}
|
|
86
99
|
}
|
|
87
|
-
after(result) {
|
|
100
|
+
async after(result) {
|
|
101
|
+
const { preferScenarioName, setSessionName, setSessionStatus } = this._options;
|
|
88
102
|
// For Cucumber: Checks scenarios that ran (i.e. not skipped) on the session
|
|
89
103
|
// Only 1 Scenario ran and option enabled => Redefine session name to Scenario's name
|
|
90
|
-
if (
|
|
104
|
+
if (preferScenarioName && this._scenariosThatRan.length === 1) {
|
|
91
105
|
this._fullTitle = this._scenariosThatRan.pop();
|
|
92
106
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
if (setSessionStatus) {
|
|
108
|
+
const hasReasons = this._failReasons.length > 0;
|
|
109
|
+
await this._updateJob({
|
|
110
|
+
status: result === 0 ? 'passed' : 'failed',
|
|
111
|
+
...(setSessionName ? { name: this._fullTitle } : {}),
|
|
112
|
+
...(hasReasons ? { reason: this._failReasons.join('\n') } : {})
|
|
113
|
+
});
|
|
114
|
+
}
|
|
99
115
|
}
|
|
100
116
|
/**
|
|
101
117
|
* For CucumberJS
|
|
@@ -118,8 +134,9 @@ class BrowserstackService {
|
|
|
118
134
|
if (!this._browser) {
|
|
119
135
|
return Promise.resolve();
|
|
120
136
|
}
|
|
121
|
-
const
|
|
122
|
-
|
|
137
|
+
const { setSessionName, setSessionStatus } = this._options;
|
|
138
|
+
const hasReasons = this._failReasons.length > 0;
|
|
139
|
+
const status = hasReasons ? 'failed' : 'passed';
|
|
123
140
|
if (!this._browser.isMultiremote) {
|
|
124
141
|
log.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${status}`);
|
|
125
142
|
}
|
|
@@ -127,12 +144,15 @@ class BrowserstackService {
|
|
|
127
144
|
const browserName = this._browser.instances.filter((browserName) => this._browser && this._browser[browserName].sessionId === newSessionId)[0];
|
|
128
145
|
log.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${status}`);
|
|
129
146
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
147
|
+
if (setSessionStatus) {
|
|
148
|
+
await this._update(oldSessionId, {
|
|
149
|
+
status,
|
|
150
|
+
...(setSessionName ? { name: this._fullTitle } : {}),
|
|
151
|
+
...(hasReasons ? { reason: this._failReasons.join('\n') } : {})
|
|
152
|
+
});
|
|
153
|
+
}
|
|
135
154
|
this._scenariosThatRan = [];
|
|
155
|
+
delete this._suiteTitle;
|
|
136
156
|
delete this._fullTitle;
|
|
137
157
|
this._failReasons = [];
|
|
138
158
|
await this._printSessionURL();
|
|
@@ -195,5 +215,24 @@ class BrowserstackService {
|
|
|
195
215
|
log.info(`${browserString} session: ${response.body.automation_session.browser_url}`);
|
|
196
216
|
});
|
|
197
217
|
}
|
|
218
|
+
async _setSessionName(suiteTitle, test) {
|
|
219
|
+
if (!this._options.setSessionName || !suiteTitle) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
let name = suiteTitle;
|
|
223
|
+
if (this._options.sessionNameFormat) {
|
|
224
|
+
name = this._options.sessionNameFormat(this._config, this._caps, suiteTitle, test === null || test === void 0 ? void 0 : test.title);
|
|
225
|
+
}
|
|
226
|
+
else if (test && !test.fullName) {
|
|
227
|
+
// Mocha
|
|
228
|
+
const pre = this._options.sessionNamePrependTopLevelSuiteTitle ? `${suiteTitle} - ` : '';
|
|
229
|
+
const post = !this._options.sessionNameOmitTestTitle ? ` - ${test.title}` : '';
|
|
230
|
+
name = `${pre}${test.parent}${post}`;
|
|
231
|
+
}
|
|
232
|
+
if (name !== this._fullTitle) {
|
|
233
|
+
this._fullTitle = name;
|
|
234
|
+
await this._updateJob({ name });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
198
237
|
}
|
|
199
238
|
exports.default = BrowserstackService;
|
package/build/types.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { Capabilities, Options } from '@wdio/types';
|
|
1
2
|
export interface SessionResponse {
|
|
2
3
|
automation_session: {
|
|
3
4
|
browser_url: string;
|
|
4
5
|
};
|
|
5
6
|
}
|
|
6
|
-
export
|
|
7
|
-
export
|
|
7
|
+
export type MultiRemoteAction = (sessionId: string, browserName?: string) => Promise<any>;
|
|
8
|
+
export type AppConfig = {
|
|
8
9
|
id?: string;
|
|
9
10
|
path?: string;
|
|
10
11
|
custom_id?: string;
|
|
@@ -20,30 +21,29 @@ export interface App {
|
|
|
20
21
|
customId?: string;
|
|
21
22
|
}
|
|
22
23
|
export interface BrowserstackConfig {
|
|
23
|
-
/**
|
|
24
|
-
* Set this to true to enable routing connections from Browserstack cloud through your computer.
|
|
25
|
-
* You will also need to set `browserstack.local` to true in browser capabilities.
|
|
26
|
-
*/
|
|
27
|
-
browserstackLocal?: boolean;
|
|
28
24
|
/**
|
|
29
25
|
* Set this with app file path present locally on your device or
|
|
30
|
-
* app hashed id returned after uploading app to
|
|
26
|
+
* app hashed id returned after uploading app to BrowserStack or
|
|
31
27
|
* custom_id, sharable_id of the uploaded app
|
|
28
|
+
* @default undefined
|
|
32
29
|
*/
|
|
33
30
|
app?: string | AppConfig;
|
|
34
31
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
32
|
+
* Enable routing connections from BrowserStack cloud through your computer.
|
|
33
|
+
* You will also need to set `browserstack.local` to true in browser capabilities.
|
|
34
|
+
* @default false
|
|
38
35
|
*/
|
|
39
|
-
|
|
36
|
+
browserstackLocal?: boolean;
|
|
40
37
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
38
|
+
* Kill the BrowserStack Local process on complete, without waiting for the
|
|
39
|
+
* BrowserStack Local stop callback to be called.
|
|
40
|
+
*
|
|
41
|
+
* __This is experimental and should not be used by all.__
|
|
42
|
+
* @default false
|
|
43
43
|
*/
|
|
44
44
|
forcedStop?: boolean;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* BrowserStack Local options. For more details check out the
|
|
47
47
|
* [`browserstack-local`](https://www.npmjs.com/package/browserstack-local#arguments) docs.
|
|
48
48
|
*
|
|
49
49
|
* @example
|
|
@@ -52,7 +52,39 @@ export interface BrowserstackConfig {
|
|
|
52
52
|
* localIdentifier: 'some-identifier'
|
|
53
53
|
* }
|
|
54
54
|
* ```
|
|
55
|
+
* @default {}
|
|
55
56
|
*/
|
|
56
57
|
opts?: Partial<import('browserstack-local').Options>;
|
|
58
|
+
/**
|
|
59
|
+
* Cucumber only. Set the BrowserStack Automate session name to the Scenario name if only a single Scenario ran.
|
|
60
|
+
* Useful when running in parallel with [wdio-cucumber-parallel-execution](https://github.com/SimitTomar/wdio-cucumber-parallel-execution).
|
|
61
|
+
* @default false
|
|
62
|
+
*/
|
|
63
|
+
preferScenarioName?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Customize the BrowserStack Automate session name format.
|
|
66
|
+
* @default undefined
|
|
67
|
+
*/
|
|
68
|
+
sessionNameFormat?: (config: Options.Testrunner, capabilities: Capabilities.RemoteCapability, suiteTitle: string, testTitle?: string) => string;
|
|
69
|
+
/**
|
|
70
|
+
* Mocha only. Do not append the test title to the BrowserStack Automate session name.
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
sessionNameOmitTestTitle?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Mocha only. Prepend the top level suite title to the BrowserStack Automate session name.
|
|
76
|
+
* @default false
|
|
77
|
+
*/
|
|
78
|
+
sessionNamePrependTopLevelSuiteTitle?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Automatically set the BrowserStack Automate session name.
|
|
81
|
+
* @default true
|
|
82
|
+
*/
|
|
83
|
+
setSessionName?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Automatically set the BrowserStack Automate session status (passed/failed).
|
|
86
|
+
* @default true
|
|
87
|
+
*/
|
|
88
|
+
setSessionStatus?: boolean;
|
|
57
89
|
}
|
|
58
90
|
//# sourceMappingURL=types.d.ts.map
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAExD,MAAM,WAAW,eAAe;IAE5B,kBAAkB,EAAE;QAEhB,WAAW,EAAE,MAAM,CAAA;KACtB,CAAA;CACJ;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;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,GAAG;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAAA;IACpD;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAChB,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,YAAY,EAAE,YAAY,CAAC,gBAAgB,EAC3C,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,KACjB,MAAM,CAAA;IACX;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;OAGG;IACH,oCAAoC,CAAC,EAAE,OAAO,CAAC;IAC/C;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browserstack-service",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.27.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",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@types/node": "^18.0.0",
|
|
27
|
-
"@wdio/logger": "7.
|
|
28
|
-
"@wdio/types": "7.
|
|
27
|
+
"@wdio/logger": "7.26.0",
|
|
28
|
+
"@wdio/types": "7.26.0",
|
|
29
29
|
"browserstack-local": "^1.4.5",
|
|
30
30
|
"form-data": "^4.0.0",
|
|
31
31
|
"got": "^11.0.2",
|
|
32
|
-
"webdriverio": "7.
|
|
32
|
+
"webdriverio": "7.27.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"types": "./build/index.d.ts",
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "8b7701a7e782c6475b1218bcb60423a4c175309a"
|
|
42
42
|
}
|