@wdio/browserstack-service 8.0.0-alpha.331 → 8.0.0-alpha.411

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
@@ -57,6 +57,92 @@ Set this to true to kill the browserstack process on complete, without waiting f
57
57
  Type: `Boolean`<br />
58
58
  Default: `false`
59
59
 
60
+ ### app
61
+
62
+ [Appium](https://appium.io/) set this with app file path available locally on your machine to use the app as [application under test](https://www.browserstack.com/docs/app-automate/appium/set-up-tests/specify-app) for Appium sessions.
63
+
64
+ Type: `String` or `JsonObject`<br />
65
+ Default: `undefined`
66
+
67
+ List of available app values:
68
+
69
+ #### path
70
+
71
+ Use local available app file path as application under test for appium.
72
+
73
+ ```js
74
+ services: [
75
+ ['browserstack', {
76
+ app: '/path/to/local/app.apk'
77
+ // OR
78
+ app: {
79
+ path: '/path/to/local/app.apk'
80
+ }
81
+ }]
82
+ ]
83
+ ```
84
+
85
+ Pass custom_id while app upload.
86
+
87
+ ```js
88
+ services: [
89
+ ['browserstack', {
90
+ app: {
91
+ path: '/path/to/local/app.apk',
92
+ custom_id: 'custom_id'
93
+ }
94
+ }]
95
+ ]
96
+ ```
97
+
98
+ #### id
99
+
100
+ Use app url returned after uploading app to BrowserStack.
101
+
102
+ ```js
103
+ services: [
104
+ ['browserstack', {
105
+ app: 'bs://<app-id>'
106
+ // OR
107
+ app: {
108
+ id: 'bs://<app-id>'
109
+ }
110
+ }]
111
+ ]
112
+ ```
113
+
114
+ #### custom_id
115
+
116
+ use custom_id of already uploaded apps
117
+
118
+ ```js
119
+ services: [
120
+ ['browserstack', {
121
+ app: 'custom_id'
122
+ // OR
123
+ app: {
124
+ custom_id: 'custom_id'
125
+ }
126
+ }]
127
+ ]
128
+ ```
129
+
130
+ #### shareable_id
131
+
132
+ use shareable_id of already uploaded apps
133
+
134
+ ```js
135
+ services: [
136
+ ['browserstack', {
137
+ app: 'username/custom_id'
138
+ // OR
139
+ app: {
140
+ shareable_id: 'username/custom_id'
141
+ }
142
+ }]
143
+ ]
144
+ ```
145
+
60
146
  ### opts
61
147
  Specified optional will be passed down to BrowserstackLocal.
62
148
 
@@ -1,2 +1,3 @@
1
1
  export declare const BROWSER_DESCRIPTION: readonly ["device", "os", "osVersion", "os_version", "browserName", "browser", "browserVersion", "browser_version"];
2
+ export declare const VALID_APP_EXTENSION: string[];
2
3
  //# 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"}
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"}
@@ -8,3 +8,8 @@ export const BROWSER_DESCRIPTION = [
8
8
  'browserVersion',
9
9
  'browser_version'
10
10
  ];
11
+ export const VALID_APP_EXTENSION = [
12
+ '.apk',
13
+ '.aab',
14
+ '.ipa'
15
+ ];
@@ -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 { BrowserstackConfig } from './types';
3
+ import type { BrowserstackConfig, App, AppConfig, AppUploadResponse } from './types';
4
4
  declare type BrowserstackLocal = BrowserstackLocalLauncher.Local & {
5
5
  pid?: number;
6
6
  stop(callback: (err?: any) => void): void;
@@ -10,8 +10,15 @@ export default class BrowserstackLauncherService implements Services.ServiceInst
10
10
  private _config;
11
11
  browserstackLocal?: BrowserstackLocal;
12
12
  constructor(_options: BrowserstackConfig & Options.Testrunner, capabilities: Capabilities.RemoteCapability, _config: Options.Testrunner);
13
- onPrepare(config?: Options.Testrunner, capabilities?: Capabilities.RemoteCapabilities): void | Promise<unknown>;
13
+ onPrepare(config?: Options.Testrunner, capabilities?: Capabilities.RemoteCapabilities): Promise<unknown>;
14
14
  onComplete(): true | Promise<unknown> | undefined;
15
+ _uploadApp(app: App): Promise<AppUploadResponse>;
16
+ /**
17
+ * @param {String | AppConfig} appConfig <string>: should be "app file path" or "app_url" or "custom_id" or "shareable_id".
18
+ * <object>: only "path" and "custom_id" should coexist as multiple properties.
19
+ */
20
+ _validateApp(appConfig: AppConfig | string): Promise<App>;
21
+ _updateCaps(capabilities?: Capabilities.RemoteCapabilities, capType?: string, value?: string): void;
15
22
  }
16
23
  export {};
17
24
  //# sourceMappingURL=launcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAOjD,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,GAAG,OAAO,CAAC,UAAU,EACzD,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IAiCvC,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IAyEtF,UAAU;CAkCb"}
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAQpF,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,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/launcher.js CHANGED
@@ -1,12 +1,21 @@
1
+ import got from 'got';
2
+ import FormData from 'form-data';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
1
5
  import { createRequire } from 'node:module';
2
6
  import { promisify } from 'node:util';
3
7
  import { performance, PerformanceObserver } from 'node:perf_hooks';
8
+ import { SevereServiceError } from 'webdriverio';
4
9
  import * as BrowserstackLocalLauncher from 'browserstack-local';
5
10
  import logger from '@wdio/logger';
11
+ import { VALID_APP_EXTENSION } from './constants.js';
6
12
  const require = createRequire(import.meta.url);
7
13
  const { version: bstackServiceVersion } = require('../package.json');
8
14
  const log = logger('@wdio/browserstack-service');
9
15
  export default class BrowserstackLauncherService {
16
+ _options;
17
+ _config;
18
+ browserstackLocal;
10
19
  constructor(_options, capabilities, _config) {
11
20
  this._options = _options;
12
21
  this._config = _config;
@@ -45,7 +54,40 @@ export default class BrowserstackLauncherService {
45
54
  });
46
55
  }
47
56
  }
48
- onPrepare(config, capabilities) {
57
+ async onPrepare(config, capabilities) {
58
+ /**
59
+ * Upload app to BrowserStack if valid file path to app is given.
60
+ * Update app value of capability directly if app_url, custom_id, shareable_id is given
61
+ */
62
+ if (!this._options.app) {
63
+ log.info('app is not defined in browserstack-service config, skipping ...');
64
+ }
65
+ else {
66
+ let app = {};
67
+ let appConfig = this._options.app;
68
+ try {
69
+ app = await this._validateApp(appConfig);
70
+ }
71
+ catch (error) {
72
+ throw new SevereServiceError(error);
73
+ }
74
+ if (VALID_APP_EXTENSION.includes(path.extname(app.app))) {
75
+ if (fs.existsSync(app.app)) {
76
+ let data;
77
+ data = await this._uploadApp(app);
78
+ log.info(`app upload completed: ${JSON.stringify(data)}`);
79
+ app.app = data.app_url;
80
+ }
81
+ else if (app.customId) {
82
+ app.app = app.customId;
83
+ }
84
+ else {
85
+ throw new SevereServiceError(`[Invalid app path] app path ${app.app} is not correct, Provide correct path to app under test`);
86
+ }
87
+ }
88
+ log.info(`Using app: ${app.app}`);
89
+ this._updateCaps(capabilities, 'app', app.app);
90
+ }
49
91
  if (!this._options.browserstackLocal) {
50
92
  return log.info('browserstackLocal is not enabled - skipping...');
51
93
  }
@@ -54,43 +96,9 @@ export default class BrowserstackLauncherService {
54
96
  ...this._options.opts
55
97
  };
56
98
  this.browserstackLocal = new BrowserstackLocalLauncher.Local();
57
- if (Array.isArray(capabilities)) {
58
- capabilities.forEach((capability) => {
59
- if (!capability['bstack:options']) {
60
- const extensionCaps = Object.keys(capability).filter((cap) => cap.includes(':'));
61
- if (extensionCaps.length) {
62
- capability['bstack:options'] = { local: true };
63
- }
64
- else {
65
- capability['browserstack.local'] = true;
66
- }
67
- }
68
- else {
69
- capability['bstack:options'].local = true;
70
- }
71
- });
72
- }
73
- else if (typeof capabilities === 'object') {
74
- Object.entries(capabilities).forEach(([, caps]) => {
75
- if (!caps.capabilities['bstack:options']) {
76
- const extensionCaps = Object.keys(caps.capabilities).filter((cap) => cap.includes(':'));
77
- if (extensionCaps.length) {
78
- caps.capabilities['bstack:options'] = { local: true };
79
- }
80
- else {
81
- caps.capabilities['browserstack.local'] = true;
82
- }
83
- }
84
- else {
85
- caps.capabilities['bstack:options'].local = true;
86
- }
87
- });
88
- }
89
- else {
90
- throw TypeError('Capabilities should be an object or Array!');
91
- }
99
+ this._updateCaps(capabilities, 'local');
92
100
  /**
93
- * measure TestingBot tunnel boot time
101
+ * measure BrowserStack tunnel boot time
94
102
  */
95
103
  const obs = new PerformanceObserver((list) => {
96
104
  const entry = list.getEntries()[0];
@@ -146,4 +154,105 @@ export default class BrowserstackLauncherService {
146
154
  return Promise.reject(err);
147
155
  });
148
156
  }
157
+ async _uploadApp(app) {
158
+ log.info(`uploading app ${app.app} ${app.customId ? `and custom_id: ${app.customId}` : ''} to browserstack`);
159
+ const form = new FormData();
160
+ if (app.app)
161
+ form.append('file', fs.createReadStream(app.app));
162
+ if (app.customId)
163
+ form.append('custom_id', app.customId);
164
+ const res = await got.post('https://api-cloud.browserstack.com/app-automate/upload', {
165
+ body: form,
166
+ username: this._config.user,
167
+ password: this._config.key
168
+ }).json().catch((err) => {
169
+ throw new SevereServiceError(`app upload failed ${err.message}`);
170
+ });
171
+ return res;
172
+ }
173
+ /**
174
+ * @param {String | AppConfig} appConfig <string>: should be "app file path" or "app_url" or "custom_id" or "shareable_id".
175
+ * <object>: only "path" and "custom_id" should coexist as multiple properties.
176
+ */
177
+ async _validateApp(appConfig) {
178
+ let app = {};
179
+ if (typeof appConfig === 'string') {
180
+ app.app = appConfig;
181
+ }
182
+ else if (typeof appConfig === 'object' && Object.keys(appConfig).length) {
183
+ if (Object.keys(appConfig).length > 2 || (Object.keys(appConfig).length === 2 && (!appConfig.path || !appConfig.custom_id))) {
184
+ throw new SevereServiceError(`keys ${Object.keys(appConfig)} can't co-exist as app values, use any one property from
185
+ {id<string>, path<string>, custom_id<string>, shareable_id<string>}, only "path" and "custom_id" can co-exist.`);
186
+ }
187
+ app.app = appConfig.id || appConfig.path || appConfig.custom_id || appConfig.shareable_id;
188
+ app.customId = appConfig.custom_id;
189
+ }
190
+ else {
191
+ throw new SevereServiceError('[Invalid format] app should be string or an object');
192
+ }
193
+ if (!app.app) {
194
+ throw new SevereServiceError(`[Invalid app property] supported properties are {id<string>, path<string>, custom_id<string>, shareable_id<string>}.
195
+ For more details please visit https://www.browserstack.com/docs/app-automate/appium/set-up-tests/specify-app ')`);
196
+ }
197
+ return app;
198
+ }
199
+ _updateCaps(capabilities, capType, value) {
200
+ if (Array.isArray(capabilities)) {
201
+ capabilities.forEach((capability) => {
202
+ if (!capability['bstack:options']) {
203
+ const extensionCaps = Object.keys(capability).filter((cap) => cap.includes(':'));
204
+ if (extensionCaps.length) {
205
+ if (capType === 'local') {
206
+ capability['bstack:options'] = { local: true };
207
+ }
208
+ else if (capType === 'app') {
209
+ capability['appium:app'] = value;
210
+ }
211
+ }
212
+ else if (capType === 'local') {
213
+ capability['browserstack.local'] = true;
214
+ }
215
+ else if (capType === 'app') {
216
+ capability['app'] = value;
217
+ }
218
+ }
219
+ else if (capType === 'local') {
220
+ capability['bstack:options'].local = true;
221
+ }
222
+ else if (capType === 'app') {
223
+ capability['appium:app'] = value;
224
+ }
225
+ });
226
+ }
227
+ else if (typeof capabilities === 'object') {
228
+ Object.entries(capabilities).forEach(([, caps]) => {
229
+ if (!caps.capabilities['bstack:options']) {
230
+ const extensionCaps = Object.keys(caps.capabilities).filter((cap) => cap.includes(':'));
231
+ if (extensionCaps.length) {
232
+ if (capType === 'local') {
233
+ caps.capabilities['bstack:options'] = { local: true };
234
+ }
235
+ else if (capType === 'app') {
236
+ caps.capabilities['appium:app'] = value;
237
+ }
238
+ }
239
+ else if (capType === 'local') {
240
+ caps.capabilities['browserstack.local'] = true;
241
+ }
242
+ else if (capType === 'app') {
243
+ caps.capabilities['app'] = value;
244
+ }
245
+ }
246
+ else if (capType === 'local') {
247
+ caps.capabilities['bstack:options'].local = true;
248
+ }
249
+ else if (capType === 'app') {
250
+ caps.capabilities['appium:app'] = value;
251
+ }
252
+ });
253
+ }
254
+ else {
255
+ throw new SevereServiceError('Capabilities should be an object or Array!');
256
+ }
257
+ }
149
258
  }
package/build/service.js CHANGED
@@ -3,14 +3,19 @@ import got from 'got';
3
3
  import { getBrowserDescription, getBrowserCapabilities, isBrowserstackCapability, getParentSuiteName } from './util.js';
4
4
  const log = logger('@wdio/browserstack-service');
5
5
  export default class BrowserstackService {
6
+ _options;
7
+ _caps;
8
+ _config;
9
+ _sessionBaseUrl = 'https://api.browserstack.com/automate/sessions';
10
+ _failReasons = [];
11
+ _scenariosThatRan = [];
12
+ _failureStatuses = ['failed', 'ambiguous', 'undefined', 'unknown'];
13
+ _browser;
14
+ _fullTitle;
6
15
  constructor(_options, _caps, _config) {
7
16
  this._options = _options;
8
17
  this._caps = _caps;
9
18
  this._config = _config;
10
- this._sessionBaseUrl = 'https://api.browserstack.com/automate/sessions';
11
- this._failReasons = [];
12
- this._scenariosThatRan = [];
13
- this._failureStatuses = ['failed', 'ambiguous', 'undefined', 'unknown'];
14
19
  // added to maintain backward compatibility with webdriverIO v5
15
20
  this._config || (this._config = _options);
16
21
  // Cucumber specific
package/build/types.d.ts CHANGED
@@ -4,12 +4,33 @@ export interface SessionResponse {
4
4
  };
5
5
  }
6
6
  export declare type MultiRemoteAction = (sessionId: string, browserName?: string) => Promise<any>;
7
+ export declare type AppConfig = {
8
+ id?: string;
9
+ path?: string;
10
+ custom_id?: string;
11
+ shareable_id?: string;
12
+ };
13
+ export interface AppUploadResponse {
14
+ app_url?: string;
15
+ custom_id?: string;
16
+ shareable_id?: string;
17
+ }
18
+ export interface App {
19
+ app?: string;
20
+ customId?: string;
21
+ }
7
22
  export interface BrowserstackConfig {
8
23
  /**
9
24
  * Set this to true to enable routing connections from Browserstack cloud through your computer.
10
25
  * You will also need to set `browserstack.local` to true in browser capabilities.
11
26
  */
12
27
  browserstackLocal?: boolean;
28
+ /**
29
+ * Set this with app file path present locally on your device or
30
+ * app hashed id returned after uploading app to Browserstack or
31
+ * custom_id, sharable_id of the uploaded app
32
+ */
33
+ app?: string | AppConfig;
13
34
  /**
14
35
  * Cucumber only. Set this to true to enable updating the session name to the Scenario name if only
15
36
  * a single Scenario was ran. Useful when running in parallel
@@ -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,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"}
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,oBAAY,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/browserstack-service",
3
- "version": "8.0.0-alpha.331+78ec9a352",
3
+ "version": "8.0.0-alpha.411+2d3189eaf",
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,11 +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.331+78ec9a352",
32
- "@wdio/types": "8.0.0-alpha.331+78ec9a352",
31
+ "@wdio/logger": "8.0.0-alpha.411+2d3189eaf",
32
+ "@wdio/types": "8.0.0-alpha.411+2d3189eaf",
33
33
  "browserstack-local": "^1.5.1",
34
+ "form-data": "^4.0.0",
34
35
  "got": "^12.1.0",
35
- "webdriverio": "8.0.0-alpha.331+78ec9a352"
36
+ "webdriverio": "8.0.0-alpha.411+2d3189eaf"
36
37
  },
37
38
  "peerDependencies": {
38
39
  "@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0"
@@ -40,5 +41,5 @@
40
41
  "publishConfig": {
41
42
  "access": "public"
42
43
  },
43
- "gitHead": "78ec9a35262f7d5ff4001cf777553f0a3c173d6d"
44
+ "gitHead": "2d3189eaf8779f61699c1377f44f9841ed8a72c7"
44
45
  }