@wdio/browserstack-service 8.0.0-alpha.577 → 8.0.0-alpha.593

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 CHANGED
@@ -1,7 +1,7 @@
1
- WebdriverIO Browserstack Service
1
+ WebdriverIO BrowserStack Service
2
2
  ==========
3
3
 
4
- > A WebdriverIO service that manages local tunnel and job metadata for Browserstack users.
4
+ > A WebdriverIO service that manages local tunnel and job metadata for BrowserStack users.
5
5
 
6
6
  ## Installation
7
7
 
@@ -17,7 +17,7 @@ Instructions on how to install `WebdriverIO` can be found [here.](https://webdri
17
17
 
18
18
  ## Configuration
19
19
 
20
- 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
+ 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.
21
21
  Reporting of session status on BrowserStack will respect `strict` setting of Cucumber options.
22
22
 
23
23
  ```js
@@ -40,19 +40,13 @@ export const config = {
40
40
  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.
41
41
 
42
42
  ### browserstackLocal
43
- Set this to true to enable routing connections from Browserstack cloud through your computer.
44
-
45
- Type: `Boolean`<br />
46
- Default: `false`
47
-
48
- ### preferScenarioName
49
- Cucumber only. Set this to true to enable updating the session name to the Scenario name if only a single Scenario was run. Useful when running in parallel with [wdio-cucumber-parallel-execution](https://github.com/SimitTomar/wdio-cucumber-parallel-execution).
43
+ Set this to true to enable routing connections from BrowserStack cloud through your computer.
50
44
 
51
45
  Type: `Boolean`<br />
52
46
  Default: `false`
53
47
 
54
48
  ### forcedStop
55
- Set this to true to kill the Browserstack process on complete, without waiting for the browserstack 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).
49
+ 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).
56
50
 
57
51
  Type: `Boolean`<br />
58
52
  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
- Specified optional will be passed down to BrowserstackLocal.
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 Browserstack Local instances -
227
+ To kill other running BrowserStack Local instances -
189
228
 
190
229
  ```js
191
230
  opts = { force: "true" };
@@ -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
@@ -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"}
@@ -13,3 +13,7 @@ export const VALID_APP_EXTENSION = [
13
13
  '.aab',
14
14
  '.ipa'
15
15
  ];
16
+ export const DEFAULT_OPTIONS = {
17
+ setSessionName: true,
18
+ setSessionStatus: true
19
+ };
@@ -2,7 +2,6 @@ import type { Services, Capabilities, Options, Frameworks } from '@wdio/types';
2
2
  import type { Browser, MultiRemoteBrowser } from 'webdriverio';
3
3
  import type { 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
- constructor(_options: BrowserstackConfig & Options.Testrunner, _caps: Capabilities.RemoteCapability, _config: Options.Testrunner);
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
- * 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
+ * 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<any>;
33
+ }): Promise<void>;
27
34
  afterTest(test: Frameworks.Test, context: never, results: Frameworks.TestResult): void;
28
- after(result: number): Promise<any>;
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
@@ -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,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAmB,MAAM,SAAS,CAAA;AAIrF,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,GAAG,OAAO,CAAC,UAAU,EACjD,KAAK,EAAE,YAAY,CAAC,gBAAgB,EACpC,OAAO,EAAE,OAAO,CAAC,UAAU;IAYvC,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;IAepH,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"}
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,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAmB,MAAM,SAAS,CAAA;AAKrF,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
@@ -1,9 +1,9 @@
1
1
  import logger from '@wdio/logger';
2
2
  import got from 'got';
3
3
  import { getBrowserDescription, getBrowserCapabilities, isBrowserstackCapability, getParentSuiteName } from './util.js';
4
+ import { DEFAULT_OPTIONS } from './constants.js';
4
5
  const log = logger('@wdio/browserstack-service');
5
6
  export default class BrowserstackService {
6
- _options;
7
7
  _caps;
8
8
  _config;
9
9
  _sessionBaseUrl = 'https://api.browserstack.com/automate/sessions';
@@ -11,13 +11,15 @@ export default class BrowserstackService {
11
11
  _scenariosThatRan = [];
12
12
  _failureStatuses = ['failed', 'ambiguous', 'undefined', 'unknown'];
13
13
  _browser;
14
+ _suiteTitle;
14
15
  _fullTitle;
15
- constructor(_options, _caps, _config) {
16
- this._options = _options;
16
+ _options;
17
+ constructor(options, _caps, _config) {
17
18
  this._caps = _caps;
18
19
  this._config = _config;
20
+ this._options = { ...DEFAULT_OPTIONS, ...options };
19
21
  // added to maintain backward compatibility with webdriverIO v5
20
- this._config || (this._config = _options);
22
+ this._config || (this._config = this._options);
21
23
  // Cucumber specific
22
24
  const strict = Boolean(this._config.cucumberOpts && this._config.cucumberOpts.strict);
23
25
  // See https://github.com/cucumber/cucumber-js/blob/master/src/runtime/index.ts#L136
@@ -32,12 +34,10 @@ export default class BrowserstackService {
32
34
  }
33
35
  return fn(this._caps);
34
36
  }
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
37
  beforeSession(config) {
38
+ // if no user and key is specified even though a browserstack service was
39
+ // provided set user and key with values so that the session request
40
+ // will fail
41
41
  if (!config.user) {
42
42
  config.user = 'NotSetUser';
43
43
  }
@@ -57,45 +57,62 @@ export default class BrowserstackService {
57
57
  this._scenariosThatRan = [];
58
58
  return this._printSessionURL();
59
59
  }
60
- beforeSuite(suite) {
61
- this._fullTitle = suite.title;
62
- }
63
- beforeFeature(uri, feature) {
64
- this._fullTitle = feature.name;
65
- return this._updateJob({ name: this._fullTitle });
60
+ /**
61
+ * Set the default job name at the suite level to make sure we account
62
+ * for the cases where there is a long running `before` function for a
63
+ * suite or one that can fail.
64
+ * Don't do this for Jasmine because `suite.title` is `Jasmine__TopLevel__Suite`
65
+ * and `suite.fullTitle` is `undefined`, so no alternative to use for the job name.
66
+ */
67
+ async beforeSuite(suite) {
68
+ this._suiteTitle = suite.title;
69
+ if (suite.title && suite.title !== 'Jasmine__TopLevel__Suite') {
70
+ await this._setSessionName(suite.title);
71
+ }
66
72
  }
67
- afterTest(test, context, results) {
68
- const { error, passed } = results;
69
- // Jasmine
73
+ async beforeTest(test) {
74
+ let suiteTitle = this._suiteTitle;
70
75
  if (test.fullName) {
76
+ // For Jasmine, `suite.title` is `Jasmine__TopLevel__Suite`.
77
+ // This tweak allows us to set the real suite name.
71
78
  const testSuiteName = test.fullName.slice(0, test.fullName.indexOf(test.description || '') - 1);
72
- if (this._fullTitle === 'Jasmine__TopLevel__Suite') {
73
- this._fullTitle = testSuiteName;
79
+ if (this._suiteTitle === 'Jasmine__TopLevel__Suite') {
80
+ suiteTitle = testSuiteName;
74
81
  }
75
- else if (this._fullTitle) {
76
- this._fullTitle = getParentSuiteName(this._fullTitle, testSuiteName);
82
+ else if (this._suiteTitle) {
83
+ suiteTitle = getParentSuiteName(this._suiteTitle, testSuiteName);
77
84
  }
78
85
  }
79
- else {
80
- // Mocha
81
- this._fullTitle = `${test.parent} - ${test.title}`;
82
- }
86
+ await this._setSessionName(suiteTitle, test);
87
+ }
88
+ /**
89
+ * For CucumberJS
90
+ */
91
+ beforeFeature(uri, feature) {
92
+ this._suiteTitle = feature.name;
93
+ return this._setSessionName(feature.name);
94
+ }
95
+ afterTest(test, context, results) {
96
+ const { error, passed } = results;
83
97
  if (!passed) {
84
98
  this._failReasons.push((error && error.message) || 'Unknown Error');
85
99
  }
86
100
  }
87
- after(result) {
101
+ async after(result) {
102
+ const { preferScenarioName, setSessionName, setSessionStatus } = this._options;
88
103
  // For Cucumber: Checks scenarios that ran (i.e. not skipped) on the session
89
104
  // Only 1 Scenario ran and option enabled => Redefine session name to Scenario's name
90
- if (this._options.preferScenarioName && this._scenariosThatRan.length === 1) {
105
+ if (preferScenarioName && this._scenariosThatRan.length === 1) {
91
106
  this._fullTitle = this._scenariosThatRan.pop();
92
107
  }
93
- const hasReasons = Boolean(this._failReasons.filter(Boolean).length);
94
- return this._updateJob({
95
- status: result === 0 ? 'passed' : 'failed',
96
- name: this._fullTitle,
97
- reason: hasReasons ? this._failReasons.join('\n') : undefined
98
- });
108
+ if (setSessionStatus) {
109
+ const hasReasons = this._failReasons.length > 0;
110
+ await this._updateJob({
111
+ status: result === 0 ? 'passed' : 'failed',
112
+ ...(setSessionName ? { name: this._fullTitle } : {}),
113
+ ...(hasReasons ? { reason: this._failReasons.join('\n') } : {})
114
+ });
115
+ }
99
116
  }
100
117
  /**
101
118
  * For CucumberJS
@@ -117,8 +134,9 @@ export default class BrowserstackService {
117
134
  if (!this._browser) {
118
135
  return Promise.resolve();
119
136
  }
120
- const hasReasons = Boolean(this._failReasons.filter(Boolean).length);
121
- let status = hasReasons ? 'failed' : 'passed';
137
+ const { setSessionName, setSessionStatus } = this._options;
138
+ const hasReasons = this._failReasons.length > 0;
139
+ const status = hasReasons ? 'failed' : 'passed';
122
140
  if (!this._browser.isMultiremote) {
123
141
  log.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${status}`);
124
142
  }
@@ -126,12 +144,15 @@ export default class BrowserstackService {
126
144
  const browserName = this._browser.instances.filter((browserName) => this._browser && this._browser[browserName].sessionId === newSessionId)[0];
127
145
  log.info(`Update (reloaded) multiremote job for browser "${browserName}" and sessionId ${oldSessionId}, ${status}`);
128
146
  }
129
- await this._update(oldSessionId, {
130
- name: this._fullTitle,
131
- status,
132
- reason: hasReasons ? this._failReasons.join('\n') : undefined
133
- });
147
+ if (setSessionStatus) {
148
+ await this._update(oldSessionId, {
149
+ status,
150
+ ...(setSessionName ? { name: this._fullTitle } : {}),
151
+ ...(hasReasons ? { reason: this._failReasons.join('\n') } : {})
152
+ });
153
+ }
134
154
  this._scenariosThatRan = [];
155
+ delete this._suiteTitle;
135
156
  delete this._fullTitle;
136
157
  this._failReasons = [];
137
158
  await this._printSessionURL();
@@ -193,4 +214,23 @@ export default class BrowserstackService {
193
214
  log.info(`${browserString} session: ${response.body.automation_session.browser_url}`);
194
215
  });
195
216
  }
217
+ async _setSessionName(suiteTitle, test) {
218
+ if (!this._options.setSessionName || !suiteTitle) {
219
+ return;
220
+ }
221
+ let name = suiteTitle;
222
+ if (this._options.sessionNameFormat) {
223
+ name = this._options.sessionNameFormat(this._config, this._caps, suiteTitle, test?.title);
224
+ }
225
+ else if (test && !test.fullName) {
226
+ // Mocha
227
+ const pre = this._options.sessionNamePrependTopLevelSuiteTitle ? `${suiteTitle} - ` : '';
228
+ const post = !this._options.sessionNameOmitTestTitle ? ` - ${test.title}` : '';
229
+ name = `${pre}${test.parent}${post}`;
230
+ }
231
+ if (name !== this._fullTitle) {
232
+ this._fullTitle = name;
233
+ await this._updateJob({ name });
234
+ }
235
+ }
196
236
  }
package/build/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { Capabilities, Options } from '@wdio/types';
1
2
  export interface SessionResponse {
2
3
  automation_session: {
3
4
  browser_url: 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 Browserstack or
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
- * Cucumber only. Set this to true to enable updating the session name to the Scenario name if only
36
- * a single Scenario was ran. Useful when running in parallel
37
- * with [wdio-cucumber-parallel-execution](https://github.com/SimitTomar/wdio-cucumber-parallel-execution).
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
- preferScenarioName?: boolean;
36
+ browserstackLocal?: boolean;
40
37
  /**
41
- * Set this to true to kill the browserstack process on complete, without waiting for the
42
- * browserstack stop callback to be called. This is experimental and should not be used by all.
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
- * Specified optional will be passed down to BrowserstackLocal. For more details check out the
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
@@ -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,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;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB;;;;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"}
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": "8.0.0-alpha.577+73cd77ef7",
3
+ "version": "8.0.0-alpha.593+1844805fe",
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,12 +28,12 @@
28
28
  "typeScriptVersion": "3.8.3",
29
29
  "dependencies": {
30
30
  "@types/node": "^18.0.0",
31
- "@wdio/logger": "8.0.0-alpha.577+73cd77ef7",
32
- "@wdio/types": "8.0.0-alpha.577+73cd77ef7",
31
+ "@wdio/logger": "8.0.0-alpha.593+1844805fe",
32
+ "@wdio/types": "8.0.0-alpha.593+1844805fe",
33
33
  "browserstack-local": "^1.5.1",
34
34
  "form-data": "^4.0.0",
35
35
  "got": "^12.1.0",
36
- "webdriverio": "8.0.0-alpha.577+73cd77ef7"
36
+ "webdriverio": "8.0.0-alpha.593+1844805fe"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0"
@@ -41,5 +41,5 @@
41
41
  "publishConfig": {
42
42
  "access": "public"
43
43
  },
44
- "gitHead": "73cd77ef7887819c56dc98932a0c34e8af10b64a"
44
+ "gitHead": "1844805fe3b4dd68bd2f0f4139a39adc2ab2718e"
45
45
  }