@amazon/vinyl-browserstack 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @amazon/vinyl-browserstack
2
+
3
+ Runs an **in-browser Jasmine** suite across BrowserStack real browsers over
4
+ **Selenium/WebDriver** (`hub-cloud.browserstack.com/wd/hub`).
5
+
6
+ ## How it works
7
+
8
+ The consuming package builds a browser test page (its Jasmine bootstrap + specs)
9
+ and serves it. This runner:
10
+
11
+ 1. Starts a local Express server (serving the test page) plus a **reporter REST
12
+ API** the in-browser suite posts progress and logs to.
13
+ 2. Starts the **BrowserStack Local** tunnel.
14
+ 3. Builds a real **WebDriver** session per browser — parallelized to the
15
+ account's available session budget — and navigates each to the test URL with
16
+ a `?reportApi=` query param.
17
+ 4. Keeps each session alive with a periodic no-op WebDriver command (the specs
18
+ run in-browser with no driver interaction, so the session's idle timer must
19
+ be reset explicitly — REST status polling does not reset it), and enforces a
20
+ local max-duration cap since WebDriver has no server-side worker timeout.
21
+ 5. Aggregates per-spec pass/fail, writes `bStackLogs/<sessionId>.log` per
22
+ session, and stamps each session pass/fail via the Automate REST API.
23
+
24
+ This is the WebDriver successor to the legacy `/5/worker` (JS Testing) transport
25
+ in `@amazon/vinyl-build-utils`. It reuses that package's framework-agnostic
26
+ primitives (reporter API, Express server, Local tunnel, Automate client,
27
+ credentials, logging) and swaps only the transport.
28
+
29
+ Unlike the legacy transport, WebDriver sessions populate the BrowserStack
30
+ dashboard **Console Logs** tab (Chrome only; `bStackLogs/` remains the complete
31
+ cross-browser log source).
32
+
33
+ ## Usage
34
+
35
+ ```ts
36
+ import { runSeleniumBrowserStackAndExit } from '@amazon/vinyl-browserstack'
37
+ import { vinylDefaultBrowserStackOptions } from '@amazon/vinyl-build-utils'
38
+
39
+ runSeleniumBrowserStackAndExit({
40
+ ...vinylDefaultBrowserStackOptions,
41
+ workerCommon: { project: 'MyProject' },
42
+ })
43
+ ```
44
+
45
+ Credentials come from `options.credentials` or the `BROWSERSTACK_USERNAME` /
46
+ `BROWSERSTACK_ACCESS_KEY` environment variables (a `.env` file is honored).
@@ -0,0 +1,148 @@
1
+ import { type BrowserStackAutomateClient, type BrowserStackCredentials, type BrowserStackWorkerOptions, type LogEntry, type SessionDetails, type WorkerOptions } from '@amazon/vinyl-build-utils';
2
+ /**
3
+ * The default BrowserStack WebDriver hub.
4
+ */
5
+ export declare const DEFAULT_HUB_URL = "https://hub-cloud.browserstack.com/wd/hub";
6
+ /**
7
+ * Local state for a single WebDriver session.
8
+ */
9
+ export interface WebDriverWorkerState {
10
+ /**
11
+ * A local identifier, used to map reporter API calls back to this session.
12
+ */
13
+ readonly localId: string;
14
+ /**
15
+ * The browser configuration provided during construction. Replaced with the
16
+ * fallback browser combination if the worker exhausts its capture retries
17
+ * without reporting any progress (see {@link WorkerOptions.fallbackBrowser}).
18
+ */
19
+ workerOptions: WorkerOptions;
20
+ /**
21
+ * If non-null, indicates a fatal error.
22
+ */
23
+ error: Error | null;
24
+ /**
25
+ * The session details, as retrieved from the BrowserStack Automate API.
26
+ */
27
+ session: SessionDetails | null;
28
+ /**
29
+ * True once {@link WebDriverWorker.start} has been called. Does not become
30
+ * false after termination.
31
+ */
32
+ started: boolean;
33
+ /**
34
+ * True while the WebDriver session is active.
35
+ */
36
+ active: boolean;
37
+ /**
38
+ * The BrowserStack session hash (the WebDriver session id). Set once the
39
+ * session is established. There is no separate numeric worker id in the
40
+ * WebDriver transport.
41
+ */
42
+ sessionId: string | null;
43
+ /**
44
+ * The total number of specs, as reported by the in-browser reporter.
45
+ * Null until received.
46
+ */
47
+ totalSpecs: number | null;
48
+ /**
49
+ * The number of specs completed, as reported by the in-browser reporter.
50
+ */
51
+ totalCompleted: number;
52
+ /**
53
+ * The number of capture retry attempts remaining. A retry happens on a
54
+ * capture timeout (no progress), not on a test failure.
55
+ */
56
+ attemptsRemaining: number;
57
+ }
58
+ export type ReadonlyWebDriverWorkerState = Readonly<WebDriverWorkerState>;
59
+ export interface WebDriverWorkerDeps {
60
+ /**
61
+ * The BrowserStack Automate REST client, used for session status polling
62
+ * and pass/fail stamping (endpoints that apply to WebDriver sessions).
63
+ */
64
+ readonly client: BrowserStackAutomateClient;
65
+ /**
66
+ * Credentials, placed in the session capabilities.
67
+ */
68
+ readonly credentials: BrowserStackCredentials;
69
+ /**
70
+ * The WebDriver hub URL. Defaults to {@link DEFAULT_HUB_URL}.
71
+ */
72
+ readonly hubUrl?: string;
73
+ }
74
+ /**
75
+ * Drives a single BrowserStack session over Selenium/WebDriver: it builds a
76
+ * real session, navigates it to the in-browser test URL, keeps it alive while
77
+ * the specs run, and quits it when done. The in-browser Jasmine suite reports
78
+ * progress/pass-fail out of band via the reporter REST API, exactly as with the
79
+ * legacy worker transport.
80
+ */
81
+ export declare class WebDriverWorker {
82
+ private readonly deps;
83
+ /**
84
+ * Set to observe state updates.
85
+ */
86
+ onUpdate: () => void;
87
+ private readonly _state;
88
+ private tasks;
89
+ private driver;
90
+ private pollIntervalId;
91
+ private captureTimeoutId;
92
+ private maxDurationTimeoutId;
93
+ private options;
94
+ /**
95
+ * The worker url with an appended reportApi query param.
96
+ */
97
+ private readonly url;
98
+ constructor(deps: WebDriverWorkerDeps, workerOptions: WorkerOptions, options?: BrowserStackWorkerOptions);
99
+ /**
100
+ * True once the session status indicates completion or an error occurred.
101
+ * The reporter's `done` stamps the passed/failed status via the Automate API.
102
+ */
103
+ get completed(): boolean;
104
+ get state(): ReadonlyWebDriverWorkerState;
105
+ get name(): string | undefined;
106
+ get passed(): boolean;
107
+ set totalCompleted(value: number);
108
+ set totalSpecs(value: number);
109
+ done(passed: boolean, reason: string): Promise<void>;
110
+ private refreshSession;
111
+ /**
112
+ * Sends a no-op WebDriver command to reset the session idle timer. A
113
+ * WebDriver session is killed by `idleTimeout` if no commands are sent, but
114
+ * the specs run in-browser with zero driver interaction. REST status polling
115
+ * does NOT reset the idle timer, so this keep-alive is required.
116
+ */
117
+ private keepAlive;
118
+ appendLogs(logs: readonly LogEntry[]): void;
119
+ /**
120
+ * Builds the WebDriver session and navigates it to the test URL.
121
+ */
122
+ start(): Promise<void>;
123
+ /**
124
+ * Quits the WebDriver session. The session may be created again.
125
+ */
126
+ terminate(): Promise<void>;
127
+ private clearTimers;
128
+ /**
129
+ * Terminates the session, then starts a fresh one.
130
+ */
131
+ restart(): Promise<void>;
132
+ /**
133
+ * Invoked when the capture timeout is reached; retries (or falls back) if no
134
+ * test progress has been received yet.
135
+ */
136
+ private captureTimeoutHandler;
137
+ /**
138
+ * If a fallback browser is configured, swaps to it (keeping the rest of the
139
+ * worker options), resets the retry budget, and restarts. Returns true if a
140
+ * fallback was available.
141
+ */
142
+ private tryFallbackBrowser;
143
+ /**
144
+ * Sets the worker to a failed state and terminates.
145
+ */
146
+ private setError;
147
+ }
148
+ //# sourceMappingURL=WebDriverWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebDriverWorker.d.ts","sourceRoot":"","sources":["../src/WebDriverWorker.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,QAAQ,EAEb,KAAK,cAAc,EAEnB,KAAK,aAAa,EACrB,MAAM,2BAA2B,CAAA;AAQlC;;GAEG;AACH,eAAO,MAAM,eAAe,8CAA8C,CAAA;AAE1E;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAExB;;;;OAIG;IACH,aAAa,EAAE,aAAa,CAAA;IAE5B;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAEnB;;OAEG;IACH,OAAO,EAAE,cAAc,GAAG,IAAI,CAAA;IAE9B;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAA;IAEhB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAA;IAEf;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAExB;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAEzB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IAEtB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAA;AAEzE,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAA;IAE3C;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,uBAAuB,CAAA;IAE7C;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAoBpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAnBzB;;OAEG;IACI,QAAQ,EAAE,MAAM,IAAI,CAAW;IAEtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,OAAO,CAAqC;IAEpD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;gBAGP,IAAI,EAAE,mBAAmB,EAC1C,aAAa,EAAE,aAAa,EAC5B,OAAO,CAAC,EAAE,yBAAyB;IAoCvC;;;OAGG;IACH,IAAI,SAAS,IAAI,OAAO,CASvB;IAED,IAAI,KAAK,IAAI,4BAA4B,CAExC;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,EAE/B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAyBtC,cAAc;IAkB5B;;;;;OAKG;YACW,SAAS;IAQvB,UAAU,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE;IAgBpC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4D5B;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB1B,OAAO,CAAC,WAAW;IAenB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAkB5B;IAED;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAiC1B;;OAEG;IACH,OAAO,CAAC,QAAQ;CAyBnB"}
@@ -0,0 +1,332 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { logger, TaskQueue, } from '@amazon/vinyl-build-utils';
6
+ import { Builder } from 'selenium-webdriver';
7
+ import { buildCapabilities } from './capabilities';
8
+ import path from 'node:path';
9
+ import fs from 'node:fs';
10
+ import crypto from 'node:crypto';
11
+ /**
12
+ * The default BrowserStack WebDriver hub.
13
+ */
14
+ export const DEFAULT_HUB_URL = 'https://hub-cloud.browserstack.com/wd/hub';
15
+ /**
16
+ * Drives a single BrowserStack session over Selenium/WebDriver: it builds a
17
+ * real session, navigates it to the in-browser test URL, keeps it alive while
18
+ * the specs run, and quits it when done. The in-browser Jasmine suite reports
19
+ * progress/pass-fail out of band via the reporter REST API, exactly as with the
20
+ * legacy worker transport.
21
+ */
22
+ export class WebDriverWorker {
23
+ deps;
24
+ /**
25
+ * Set to observe state updates.
26
+ */
27
+ onUpdate = () => { };
28
+ _state;
29
+ tasks = new TaskQueue();
30
+ driver = null;
31
+ pollIntervalId = null;
32
+ captureTimeoutId = null;
33
+ maxDurationTimeoutId = null;
34
+ options;
35
+ /**
36
+ * The worker url with an appended reportApi query param.
37
+ */
38
+ url;
39
+ constructor(deps, workerOptions, options) {
40
+ this.deps = deps;
41
+ this.tasks.onError = (error) => this.setError(error);
42
+ this.options = {
43
+ retries: 2,
44
+ captureTimeout: 45,
45
+ pollInterval: 5,
46
+ logsDir: './bStackLogs',
47
+ queryParams: null,
48
+ ...options,
49
+ };
50
+ this._state = {
51
+ localId: crypto.randomUUID(),
52
+ workerOptions,
53
+ error: null,
54
+ session: null,
55
+ started: false,
56
+ active: false,
57
+ sessionId: null,
58
+ totalSpecs: null,
59
+ totalCompleted: 0,
60
+ attemptsRemaining: this.options.retries,
61
+ };
62
+ const finalUrl = new URL(workerOptions.url);
63
+ finalUrl.searchParams.set('reportApi', `/report/${this._state.localId}`);
64
+ if (options?.queryParams) {
65
+ for (const [name, value] of Object.entries(options.queryParams)) {
66
+ finalUrl.searchParams.set(name, value);
67
+ }
68
+ }
69
+ this.url = finalUrl.toString();
70
+ if (this.options.logsDir)
71
+ fs.mkdirSync(this.options.logsDir, { recursive: true });
72
+ }
73
+ /**
74
+ * True once the session status indicates completion or an error occurred.
75
+ * The reporter's `done` stamps the passed/failed status via the Automate API.
76
+ */
77
+ get completed() {
78
+ const state = this._state;
79
+ const status = state.session?.status;
80
+ return (state.error != null ||
81
+ (state.started &&
82
+ status != null &&
83
+ ['timeout', 'passed', 'failed'].includes(status)));
84
+ }
85
+ get state() {
86
+ return this._state;
87
+ }
88
+ get name() {
89
+ return this._state.workerOptions.name;
90
+ }
91
+ get passed() {
92
+ return this._state.session?.status === 'passed';
93
+ }
94
+ set totalCompleted(value) {
95
+ this._state.totalCompleted = value;
96
+ }
97
+ set totalSpecs(value) {
98
+ this._state.totalSpecs = value;
99
+ }
100
+ done(passed, reason) {
101
+ const name = this.name;
102
+ if (passed)
103
+ logger.info(`✅ ${name} passed`);
104
+ else
105
+ logger.info(`❌ ${name} failed\n${reason}\n`);
106
+ const client = this.deps.client;
107
+ return this.tasks
108
+ .enqueue(async () => {
109
+ const { sessionId } = this._state;
110
+ if (!sessionId) {
111
+ logger.debug('done aborting - sessionId is missing');
112
+ return;
113
+ }
114
+ logger.debug('done, passed:', passed);
115
+ this._state.session = await client.updateSession(sessionId, {
116
+ status: passed ? 'passed' : 'failed',
117
+ reason,
118
+ });
119
+ this.onUpdate();
120
+ })
121
+ .finally(() => {
122
+ this.terminate().catch(() => { });
123
+ });
124
+ }
125
+ async refreshSession() {
126
+ const state = this._state;
127
+ if (!state.sessionId)
128
+ return;
129
+ const previousStatus = state.session?.status;
130
+ state.session = await this.deps.client.getSession(state.sessionId);
131
+ if (state.session.status === 'timeout' &&
132
+ previousStatus !== 'timeout') {
133
+ const secs = state.workerOptions.timeout;
134
+ logger.error(`⏱️ ${this.name} timed out${secs ? ` after ${secs}s` : ''} — ` +
135
+ `session ended before tests completed; counts as a failure`);
136
+ }
137
+ this.onUpdate();
138
+ }
139
+ /**
140
+ * Sends a no-op WebDriver command to reset the session idle timer. A
141
+ * WebDriver session is killed by `idleTimeout` if no commands are sent, but
142
+ * the specs run in-browser with zero driver interaction. REST status polling
143
+ * does NOT reset the idle timer, so this keep-alive is required.
144
+ */
145
+ async keepAlive() {
146
+ try {
147
+ await this.driver?.getTitle();
148
+ }
149
+ catch (error) {
150
+ logger.debug(`keep-alive failed for '${this.name}':`, error);
151
+ }
152
+ }
153
+ appendLogs(logs) {
154
+ if (this.options.logsDir == null || logs.length === 0)
155
+ return;
156
+ const logFilePath = path.join(this.options.logsDir, `${this._state.sessionId}.log`);
157
+ fs.appendFile(logFilePath, logs.map((entry) => entry.join(' ')).join('\n') + '\n', (error) => {
158
+ if (error)
159
+ logger.error('Could not write to console log file:', error);
160
+ });
161
+ }
162
+ /**
163
+ * Builds the WebDriver session and navigates it to the test URL.
164
+ */
165
+ async start() {
166
+ logger.debug(`Starting session '${this.name}'...`);
167
+ const state = this._state;
168
+ state.started = true;
169
+ await this.tasks
170
+ .enqueue(async () => {
171
+ if (state.active)
172
+ return;
173
+ state.active = true;
174
+ this.onUpdate();
175
+ this.pollIntervalId = setInterval(() => {
176
+ void this.keepAlive();
177
+ void this.refreshSession();
178
+ }, this.options.pollInterval * 1000);
179
+ this.captureTimeoutId = setTimeout(this.captureTimeoutHandler, this.options.captureTimeout * 1000);
180
+ // WebDriver has no server-side total-worker timeout (unlike the
181
+ // legacy /5/worker `timeout`), so enforce it locally as a
182
+ // max-duration safety net for runaway sessions.
183
+ const timeout = state.workerOptions.timeout;
184
+ if (timeout) {
185
+ this.maxDurationTimeoutId = setTimeout(() => {
186
+ this.setError(new Error(`Session '${this.name}' exceeded max duration of ${timeout}s.`));
187
+ }, timeout * 1000);
188
+ }
189
+ // fallbackBrowser is a local concern, not a capability.
190
+ const { fallbackBrowser: _fallbackBrowser, ...workerOptions } = state.workerOptions;
191
+ const capabilities = buildCapabilities({ ...workerOptions, url: this.url }, this.deps.credentials);
192
+ const driver = await new Builder()
193
+ .usingServer(this.deps.hubUrl ?? DEFAULT_HUB_URL)
194
+ .withCapabilities(capabilities)
195
+ .build();
196
+ this.driver = driver;
197
+ state.sessionId = (await driver.getSession()).getId();
198
+ logger.info(`Session created for '${this.name}': ${state.sessionId}`);
199
+ await driver.get(this.url);
200
+ await this.refreshSession();
201
+ this.onUpdate();
202
+ })
203
+ .catch((error) => {
204
+ logger.error(`Session start failed '${this.name}'`, error);
205
+ state.started = false;
206
+ this.clearTimers();
207
+ this.onUpdate();
208
+ });
209
+ }
210
+ /**
211
+ * Quits the WebDriver session. The session may be created again.
212
+ */
213
+ terminate() {
214
+ logger.debug(`Terminate session '${this.name}'`);
215
+ return this.tasks.enqueue(async () => {
216
+ const state = this._state;
217
+ if (!state.active)
218
+ return;
219
+ state.active = false;
220
+ this.clearTimers();
221
+ const driver = this.driver;
222
+ if (driver) {
223
+ this.driver = null;
224
+ try {
225
+ await driver.quit();
226
+ logger.debug(`Quit session '${this.name}'`);
227
+ }
228
+ catch (error) {
229
+ // The session may already be gone (e.g. BrowserStack ended
230
+ // it); a failed quit is not fatal.
231
+ logger.warn('Could not quit WebDriver session:', error);
232
+ }
233
+ }
234
+ logger.debug(`Terminated session '${this.name}'...`);
235
+ this.onUpdate();
236
+ });
237
+ }
238
+ clearTimers() {
239
+ if (this.pollIntervalId) {
240
+ clearInterval(this.pollIntervalId);
241
+ this.pollIntervalId = null;
242
+ }
243
+ if (this.captureTimeoutId) {
244
+ clearTimeout(this.captureTimeoutId);
245
+ this.captureTimeoutId = null;
246
+ }
247
+ if (this.maxDurationTimeoutId) {
248
+ clearTimeout(this.maxDurationTimeoutId);
249
+ this.maxDurationTimeoutId = null;
250
+ }
251
+ }
252
+ /**
253
+ * Terminates the session, then starts a fresh one.
254
+ */
255
+ async restart() {
256
+ await this.terminate().catch(() => { });
257
+ this._state.sessionId = null;
258
+ this._state.session = null;
259
+ await this.start();
260
+ }
261
+ /**
262
+ * Invoked when the capture timeout is reached; retries (or falls back) if no
263
+ * test progress has been received yet.
264
+ */
265
+ captureTimeoutHandler = () => {
266
+ const state = this._state;
267
+ if (state.totalSpecs != null)
268
+ return;
269
+ if (state.attemptsRemaining > 0) {
270
+ state.attemptsRemaining--;
271
+ logger.warn(`No test results received for ${this.name}, retrying. Attempts remaining: ${state.attemptsRemaining}`);
272
+ this.restart().catch((error) => this.setError(error));
273
+ }
274
+ else if (!this.tryFallbackBrowser()) {
275
+ this.setError(new Error(`Did not capture test progress after ${this.options.retries + 1} attempts for '${this.name}'.`));
276
+ }
277
+ };
278
+ /**
279
+ * If a fallback browser is configured, swaps to it (keeping the rest of the
280
+ * worker options), resets the retry budget, and restarts. Returns true if a
281
+ * fallback was available.
282
+ */
283
+ tryFallbackBrowser() {
284
+ const state = this._state;
285
+ const { fallbackBrowser } = state.workerOptions;
286
+ if (!fallbackBrowser)
287
+ return false;
288
+ const target = [
289
+ fallbackBrowser.device,
290
+ fallbackBrowser.os,
291
+ fallbackBrowser.os_version,
292
+ fallbackBrowser.browser,
293
+ fallbackBrowser.browser_version,
294
+ ]
295
+ .filter(Boolean)
296
+ .join(' ');
297
+ logger.warn(`Did not capture test progress for '${this.name}'; falling back to '${target}'.`);
298
+ const { fallbackBrowser: _fallbackBrowser, browser: _browser, browser_version: _browserVersion, device: _device, ...rest } = state.workerOptions;
299
+ state.workerOptions = {
300
+ ...rest,
301
+ ...fallbackBrowser,
302
+ name: `${target} [fallback]`,
303
+ };
304
+ state.attemptsRemaining = this.options.retries;
305
+ this.restart().catch((error) => this.setError(error));
306
+ return true;
307
+ }
308
+ /**
309
+ * Sets the worker to a failed state and terminates.
310
+ */
311
+ setError(error) {
312
+ const state = this._state;
313
+ if (state.error)
314
+ return;
315
+ state.error = error;
316
+ logger.error(error == null
317
+ ? 'An internal error has occurred.'
318
+ : (error.message ?? String(error)));
319
+ this.tasks
320
+ .enqueue(async () => {
321
+ if (state.sessionId) {
322
+ state.session = await this.deps.client.updateSession(state.sessionId, {
323
+ status: 'failed',
324
+ reason: error?.message ?? 'Internal error',
325
+ });
326
+ this.onUpdate();
327
+ }
328
+ })
329
+ .catch(() => { });
330
+ this.terminate().catch(() => { });
331
+ }
332
+ }
@@ -0,0 +1,62 @@
1
+ import { type BrowserStackAutomateClient, type BrowserStackCredentials, type BrowserStackWorkerControllerOptions, type DoneRequest, type ProgressRequest, type ReportingListener, type StartedRequest, type WorkerOptions } from '@amazon/vinyl-build-utils';
2
+ import { type ReadonlyWebDriverWorkerState } from './WebDriverWorker';
3
+ export interface WebDriverWorkerControllerDeps {
4
+ /**
5
+ * The BrowserStack Automate REST client.
6
+ */
7
+ readonly client: BrowserStackAutomateClient;
8
+ /**
9
+ * Credentials, forwarded to each worker's session capabilities.
10
+ */
11
+ readonly credentials: BrowserStackCredentials;
12
+ /**
13
+ * The WebDriver hub URL. Defaults per {@link WebDriverWorker}.
14
+ */
15
+ readonly hubUrl?: string;
16
+ }
17
+ export interface WebDriverWorkerControllerState {
18
+ readonly workers: readonly ReadonlyWebDriverWorkerState[];
19
+ pending: number;
20
+ running: number;
21
+ passed: number;
22
+ failed: number;
23
+ percentComplete: number;
24
+ remaining: number;
25
+ readonly total: number;
26
+ }
27
+ export type ReadonlyWebDriverWorkerControllerState = Readonly<WebDriverWorkerControllerState>;
28
+ /**
29
+ * Schedules and parallelizes {@link WebDriverWorker}s up to the account's
30
+ * available parallel-session budget, and fans the reporter REST callbacks out
31
+ * to the matching worker. Transport-agnostic scheduling logic mirrors the
32
+ * legacy controller; only the worker type differs.
33
+ */
34
+ export declare class WebDriverWorkerController implements ReportingListener {
35
+ private readonly deps;
36
+ private readonly options?;
37
+ onUpdate: () => void;
38
+ private readonly _state;
39
+ private readonly workers;
40
+ private readonly localIdToWorkerMap;
41
+ private sessionPollIntervalId;
42
+ private startSessionsInFlight;
43
+ private startSessionsRequested;
44
+ constructor(deps: WebDriverWorkerControllerDeps, browsers: readonly WorkerOptions[], options?: BrowserStackWorkerControllerOptions | undefined);
45
+ get state(): ReadonlyWebDriverWorkerControllerState;
46
+ shouldHandleRequest(id: string): boolean;
47
+ onStarted(request: StartedRequest): void;
48
+ onProgress(request: ProgressRequest): void;
49
+ onDone(request: DoneRequest): void;
50
+ private refreshState;
51
+ private updateHandler;
52
+ /**
53
+ * Starts pending workers up to the available parallel-session budget.
54
+ * Reentrancy-safe: coalesces overlapping invocations into a single follow-up.
55
+ */
56
+ private startSessions;
57
+ private clearOpenSessionPollTimeout;
58
+ get allPassed(): boolean;
59
+ start(): void;
60
+ terminate(): Promise<void>;
61
+ }
62
+ //# sourceMappingURL=WebDriverWorkerController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebDriverWorkerController.d.ts","sourceRoot":"","sources":["../src/WebDriverWorkerController.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,mCAAmC,EACxC,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EACrB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACH,KAAK,4BAA4B,EAEpC,MAAM,mBAAmB,CAAA;AAE1B,MAAM,WAAW,6BAA6B;IAC1C;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAA;IAE3C;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,uBAAuB,CAAA;IAE7C;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,4BAA4B,EAAE,CAAA;IACzD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,MAAM,sCAAsC,GAC9C,QAAQ,CAAC,8BAA8B,CAAC,CAAA;AAI5C;;;;;GAKG;AACH,qBAAa,yBAA0B,YAAW,iBAAiB;IAW3D,OAAO,CAAC,QAAQ,CAAC,IAAI;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAZtB,QAAQ,EAAE,MAAM,IAAI,CAAW;IAEtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8B;IACjE,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,qBAAqB,CAA6B;IAC1D,OAAO,CAAC,sBAAsB,CAAQ;gBAGjB,IAAI,EAAE,6BAA6B,EACpD,QAAQ,EAAE,SAAS,aAAa,EAAE,EACjB,OAAO,CAAC,EAAE,mCAAmC,YAAA;IAuBlE,IAAI,KAAK,IAAI,sCAAsC,CAElD;IAED,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAM1C,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAQlC,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,aAAa,CAMpB;IAED;;;OAGG;IACH,OAAO,CAAC,aAAa;IA2DrB,OAAO,CAAC,2BAA2B;IAOnC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,KAAK,IAAI,IAAI;IAKP,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAanC"}
@@ -0,0 +1,165 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { logger, } from '@amazon/vinyl-build-utils';
6
+ import { WebDriverWorker, } from './WebDriverWorker';
7
+ /**
8
+ * Schedules and parallelizes {@link WebDriverWorker}s up to the account's
9
+ * available parallel-session budget, and fans the reporter REST callbacks out
10
+ * to the matching worker. Transport-agnostic scheduling logic mirrors the
11
+ * legacy controller; only the worker type differs.
12
+ */
13
+ export class WebDriverWorkerController {
14
+ deps;
15
+ options;
16
+ onUpdate = () => { };
17
+ _state;
18
+ workers;
19
+ localIdToWorkerMap;
20
+ sessionPollIntervalId = null;
21
+ startSessionsInFlight = null;
22
+ startSessionsRequested = false;
23
+ constructor(deps, browsers, options) {
24
+ this.deps = deps;
25
+ this.options = options;
26
+ this.workers = browsers.map((browser) => new WebDriverWorker(deps, browser, options?.worker));
27
+ this._state = {
28
+ workers: this.workers.map((worker) => worker.state),
29
+ pending: this.workers.length,
30
+ remaining: this.workers.length,
31
+ running: 0,
32
+ failed: 0,
33
+ passed: 0,
34
+ percentComplete: 0,
35
+ total: this.workers.length,
36
+ };
37
+ this.localIdToWorkerMap = new Map(this.workers.map((worker) => [worker.state.localId, worker]));
38
+ for (const worker of this.workers) {
39
+ worker.onUpdate = this.updateHandler;
40
+ }
41
+ }
42
+ get state() {
43
+ return this._state;
44
+ }
45
+ shouldHandleRequest(id) {
46
+ return this.localIdToWorkerMap.has(id);
47
+ }
48
+ onStarted(request) {
49
+ this.localIdToWorkerMap.get(request.id).totalSpecs = request.totalSpecs;
50
+ }
51
+ onProgress(request) {
52
+ const worker = this.localIdToWorkerMap.get(request.id);
53
+ worker.totalCompleted = request.totalCompleted;
54
+ worker.appendLogs(request.logs);
55
+ }
56
+ onDone(request) {
57
+ const worker = this.localIdToWorkerMap.get(request.id);
58
+ void worker.done(request.overallStatus === 'passed', request.reason ?? '');
59
+ }
60
+ refreshState() {
61
+ const state = this._state;
62
+ let running = 0;
63
+ let pending = 0;
64
+ let failed = 0;
65
+ let passed = 0;
66
+ let percentSum = 0;
67
+ for (const worker of this.workers) {
68
+ if (worker.completed) {
69
+ if (worker.passed)
70
+ passed++;
71
+ else
72
+ failed++;
73
+ percentSum++;
74
+ }
75
+ else {
76
+ if (worker.state.started)
77
+ running++;
78
+ else
79
+ pending++;
80
+ percentSum +=
81
+ worker.state.totalCompleted / (worker.state.totalSpecs || 1);
82
+ }
83
+ }
84
+ state.running = running;
85
+ state.pending = pending;
86
+ state.failed = failed;
87
+ state.passed = passed;
88
+ state.remaining = running + pending;
89
+ state.percentComplete = percentSum / (state.total || 1);
90
+ }
91
+ updateHandler = () => {
92
+ const state = this._state;
93
+ const previousRunning = state.running;
94
+ this.refreshState();
95
+ if (previousRunning !== state.running)
96
+ this.startSessions();
97
+ this.onUpdate();
98
+ };
99
+ /**
100
+ * Starts pending workers up to the available parallel-session budget.
101
+ * Reentrancy-safe: coalesces overlapping invocations into a single follow-up.
102
+ */
103
+ startSessions() {
104
+ if (this.startSessionsInFlight) {
105
+ this.startSessionsRequested = true;
106
+ return;
107
+ }
108
+ const run = (async () => {
109
+ const state = this._state;
110
+ if (state.pending === 0)
111
+ return;
112
+ const planDetails = await this.deps.client.getPlan();
113
+ const remainingOpenSessions = Math.min(this.options?.maxSessions ?? Number.MAX_SAFE_INTEGER, planDetails.parallel_sessions_max_allowed) -
114
+ Math.max(state.running, planDetails.parallel_sessions_running);
115
+ logger.debug('Plan parallel sessions:', `${planDetails.parallel_sessions_running} running, ${planDetails.parallel_sessions_max_allowed} allowed`);
116
+ const workersToStart = this.workers
117
+ .filter((worker) => !worker.state.started)
118
+ .slice(0, remainingOpenSessions);
119
+ if (workersToStart.length) {
120
+ logger.debug(`Starting ${workersToStart.length} sessions...`);
121
+ await Promise.all(workersToStart.map((worker) => worker.start().catch(() => { })));
122
+ }
123
+ this.refreshState();
124
+ if (this._state.pending > 0) {
125
+ logger.debug('No open sessions, checking again in 15s.');
126
+ this.clearOpenSessionPollTimeout();
127
+ this.sessionPollIntervalId = setTimeout(() => this.startSessions(), 15000);
128
+ }
129
+ })()
130
+ .catch((error) => {
131
+ logger.warn('startSessions failed', error);
132
+ this.clearOpenSessionPollTimeout();
133
+ this.sessionPollIntervalId = setTimeout(() => this.startSessions(), 15000);
134
+ })
135
+ .finally(() => {
136
+ this.startSessionsInFlight = null;
137
+ if (this.startSessionsRequested) {
138
+ this.startSessionsRequested = false;
139
+ this.clearOpenSessionPollTimeout();
140
+ this.startSessions();
141
+ }
142
+ });
143
+ this.startSessionsInFlight = run;
144
+ }
145
+ clearOpenSessionPollTimeout() {
146
+ if (this.sessionPollIntervalId != null) {
147
+ clearTimeout(this.sessionPollIntervalId);
148
+ this.sessionPollIntervalId = null;
149
+ }
150
+ }
151
+ get allPassed() {
152
+ return this.workers.every((worker) => worker.passed);
153
+ }
154
+ start() {
155
+ logger.debug('WebDriverWorkerController start');
156
+ this.startSessions();
157
+ }
158
+ async terminate() {
159
+ logger.debug('Terminating workers');
160
+ this.clearOpenSessionPollTimeout();
161
+ await Promise.all(this.workers.map((worker) => worker.terminate().catch(() => {
162
+ logger.warn(`Could not terminate worker: '${worker.state.workerOptions.name}'`);
163
+ }))).finally(() => logger.debug('terminate done'));
164
+ }
165
+ }
@@ -0,0 +1,41 @@
1
+ import type { BrowserStackCredentials, WorkerOptions } from '@amazon/vinyl-build-utils';
2
+ /**
3
+ * BrowserStack-specific WebDriver capabilities, nested under `bstack:options`
4
+ * per the W3C protocol.
5
+ * @see https://www.browserstack.com/docs/automate/capabilities
6
+ */
7
+ export interface BStackOptions {
8
+ os?: string;
9
+ osVersion?: string;
10
+ deviceName?: string;
11
+ realMobile?: boolean;
12
+ sessionName?: string;
13
+ buildName?: string;
14
+ projectName?: string;
15
+ resolution?: string;
16
+ video?: boolean;
17
+ networkLogs?: boolean;
18
+ consoleLogs?: 'disable' | 'errors' | 'warnings' | 'info' | 'verbose';
19
+ local?: boolean;
20
+ userName?: string;
21
+ accessKey?: string;
22
+ seleniumVersion?: string;
23
+ }
24
+ /**
25
+ * W3C WebDriver capabilities for a BrowserStack session.
26
+ */
27
+ export interface WebDriverCapabilities {
28
+ browserName: string;
29
+ browserVersion?: string;
30
+ 'bstack:options': BStackOptions;
31
+ }
32
+ /**
33
+ * Builds W3C WebDriver capabilities from framework-agnostic {@link WorkerOptions}.
34
+ *
35
+ * Credentials are placed in `bstack:options` (not the hub URL) so they never
36
+ * leak into logged request URLs. `local: true` routes the session through the
37
+ * BrowserStack Local tunnel. `consoleLogs: 'verbose'` populates the dashboard
38
+ * Console Logs tab (Chrome only; harmless elsewhere).
39
+ */
40
+ export declare function buildCapabilities(workerOptions: WorkerOptions, credentials: BrowserStackCredentials): WebDriverCapabilities;
41
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACR,uBAAuB,EACvB,aAAa,EAChB,MAAM,2BAA2B,CAAA;AAElC;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAA;IACpE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,aAAa,CAAA;CAClC;AAUD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,uBAAuB,GACrC,qBAAqB,CA2CvB"}
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Infers the WebDriver `browserName` for a mobile device from its OS: Android
7
+ * devices run Chrome, iOS devices run Safari.
8
+ */
9
+ function mobileBrowserName(os) {
10
+ return os.toLowerCase() === 'ios' ? 'safari' : 'chrome';
11
+ }
12
+ /**
13
+ * Builds W3C WebDriver capabilities from framework-agnostic {@link WorkerOptions}.
14
+ *
15
+ * Credentials are placed in `bstack:options` (not the hub URL) so they never
16
+ * leak into logged request URLs. `local: true` routes the session through the
17
+ * BrowserStack Local tunnel. `consoleLogs: 'verbose'` populates the dashboard
18
+ * Console Logs tab (Chrome only; harmless elsewhere).
19
+ */
20
+ export function buildCapabilities(workerOptions, credentials) {
21
+ const isMobile = workerOptions.device != null;
22
+ const bstackOptions = {
23
+ osVersion: workerOptions.os_version,
24
+ video: workerOptions.video ?? true,
25
+ networkLogs: workerOptions.networkLogs ?? false,
26
+ consoleLogs: 'verbose',
27
+ local: true,
28
+ userName: credentials.username,
29
+ accessKey: credentials.key,
30
+ // Only set when defined — `exactOptionalPropertyTypes` forbids
31
+ // assigning `undefined` to an optional property.
32
+ ...(workerOptions.name != null && { sessionName: workerOptions.name }),
33
+ ...(workerOptions.build != null && { buildName: workerOptions.build }),
34
+ ...(workerOptions.project != null && {
35
+ projectName: workerOptions.project,
36
+ }),
37
+ };
38
+ if (isMobile) {
39
+ bstackOptions.deviceName = workerOptions.device;
40
+ bstackOptions.realMobile = true;
41
+ }
42
+ else {
43
+ bstackOptions.os = workerOptions.os;
44
+ // `resolution` is a desktop-only capability.
45
+ if (workerOptions.resolution)
46
+ bstackOptions.resolution = workerOptions.resolution;
47
+ }
48
+ const browserName = isMobile
49
+ ? mobileBrowserName(workerOptions.os)
50
+ : workerOptions.browser;
51
+ const capabilities = {
52
+ browserName,
53
+ 'bstack:options': bstackOptions,
54
+ };
55
+ // browserVersion applies to desktop browsers only.
56
+ if (!isMobile && workerOptions.browser_version)
57
+ capabilities.browserVersion = workerOptions.browser_version;
58
+ return capabilities;
59
+ }
@@ -0,0 +1,5 @@
1
+ export * from './capabilities';
2
+ export * from './WebDriverWorker';
3
+ export * from './WebDriverWorkerController';
4
+ export * from './runSeleniumBrowserStack';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ export * from './capabilities';
6
+ export * from './WebDriverWorker';
7
+ export * from './WebDriverWorkerController';
8
+ export * from './runSeleniumBrowserStack';
@@ -0,0 +1,30 @@
1
+ import { type BrowserStackOptions } from '@amazon/vinyl-build-utils';
2
+ /**
3
+ * When the BrowserStack run has completed, provides the final results.
4
+ */
5
+ export interface BrowserStackResults {
6
+ readonly passed: boolean;
7
+ }
8
+ /**
9
+ * Runs an in-browser Jasmine suite across BrowserStack real browsers over
10
+ * Selenium/WebDriver.
11
+ *
12
+ * This will:
13
+ * - Start a local server, including the reporter REST API the in-browser suite
14
+ * posts progress/logs to.
15
+ * - Start the BrowserStack Local tunnel.
16
+ * - Build a real WebDriver session per browser (parallelized to the account's
17
+ * available session budget) and navigate each to the test URL.
18
+ *
19
+ * The transport is WebDriver (`hub-cloud.browserstack.com/wd/hub`); the
20
+ * in-browser reporter contract (per-spec pass/fail, `bStackLogs/<sessionId>.log`)
21
+ * is unchanged.
22
+ *
23
+ * @return the aggregate test results.
24
+ */
25
+ export declare function runSeleniumBrowserStack(options: BrowserStackOptions): Promise<BrowserStackResults>;
26
+ /**
27
+ * Calls {@link runSeleniumBrowserStack}, exiting the process when settled.
28
+ */
29
+ export declare function runSeleniumBrowserStackAndExit(options: BrowserStackOptions): void;
30
+ //# sourceMappingURL=runSeleniumBrowserStack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runSeleniumBrowserStack.d.ts","sourceRoot":"","sources":["../src/runSeleniumBrowserStack.ts"],"names":[],"mappings":"AAMA,OAAO,EAGH,KAAK,mBAAmB,EAW3B,MAAM,2BAA2B,CAAA;AAKlC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAC3B;AAiBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,uBAAuB,CACzC,OAAO,EAAE,mBAAmB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAwG9B;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC1C,OAAO,EAAE,mBAAmB,GAC7B,IAAI,CAaN"}
@@ -0,0 +1,145 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import express from 'express';
6
+ import { ansi, BrowserStackAutomateClient, configureExpress, configureReportingApi, getEnvBrowserStackCredentials, logger, LogLevel, progressBar, startBrowserStackLocal, startExpressServer, } from '@amazon/vinyl-build-utils';
7
+ import { WebDriverWorkerController } from './WebDriverWorkerController';
8
+ import crypto from 'node:crypto';
9
+ /**
10
+ * Creates a session name for the given browser options.
11
+ */
12
+ function generateNameForBrowser(browser) {
13
+ return [
14
+ browser.device,
15
+ browser.os,
16
+ browser.os_version,
17
+ browser.browser,
18
+ browser.browser_version,
19
+ ]
20
+ .filter((str) => str)
21
+ .join(' ');
22
+ }
23
+ /**
24
+ * Runs an in-browser Jasmine suite across BrowserStack real browsers over
25
+ * Selenium/WebDriver.
26
+ *
27
+ * This will:
28
+ * - Start a local server, including the reporter REST API the in-browser suite
29
+ * posts progress/logs to.
30
+ * - Start the BrowserStack Local tunnel.
31
+ * - Build a real WebDriver session per browser (parallelized to the account's
32
+ * available session budget) and navigate each to the test URL.
33
+ *
34
+ * The transport is WebDriver (`hub-cloud.browserstack.com/wd/hub`); the
35
+ * in-browser reporter contract (per-spec pass/fail, `bStackLogs/<sessionId>.log`)
36
+ * is unchanged.
37
+ *
38
+ * @return the aggregate test results.
39
+ */
40
+ export async function runSeleniumBrowserStack(options) {
41
+ if (!options.browsers.length)
42
+ throw new Error('options.browsers is required');
43
+ let done;
44
+ const donePromise = new Promise((r) => (done = r));
45
+ const bsCredentials = (await options.credentials) ?? getEnvBrowserStackCredentials();
46
+ if (!bsCredentials.username || !bsCredentials.key)
47
+ throw new Error('Missing BrowserStack credentials. May be provided via options.credentials, or the environmental ' +
48
+ 'variables BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY. ' +
49
+ 'Environmental variables may be set via a .env file.');
50
+ const useSticky = options.stickyProgress ?? process.stdout.isTTY;
51
+ logger.level = options.logLevel ?? LogLevel.INFO;
52
+ const localOptions = {
53
+ key: bsCredentials.key,
54
+ logFile: './bStackLogs/local.log',
55
+ ...options.local,
56
+ };
57
+ const shutdownLocalTunnel = await startBrowserStackLocal(localOptions);
58
+ const app = express();
59
+ configureExpress(app, options.server);
60
+ const serverHandle = await startExpressServer({ app }, options.server);
61
+ const client = new BrowserStackAutomateClient(bsCredentials);
62
+ const build = `build-${crypto.randomUUID()}`;
63
+ const workerOptions = options.browsers.map((browser) => {
64
+ const name = browser.name ?? generateNameForBrowser(browser);
65
+ let url = browser.url ??
66
+ options.workerCommon?.url ??
67
+ serverHandle.https?.url ??
68
+ serverHandle.http.url;
69
+ // Safari and iOS do not route `localhost` through the BrowserStack Local
70
+ // tunnel; they must reach the test server via `bs-local.com`.
71
+ if (browser.browser === 'safari' || browser.os === 'ios') {
72
+ url = url.replace('//localhost', '//bs-local.com');
73
+ }
74
+ return { build, name, ...options.workerCommon, ...browser, url };
75
+ });
76
+ const workerController = new WebDriverWorkerController({ client, credentials: bsCredentials }, workerOptions, options);
77
+ configureReportingApi(app, workerController);
78
+ const state = workerController.state;
79
+ function createProgressMessage() {
80
+ let failedStr = `failed: ${state.failed}`;
81
+ if (state.failed > 0)
82
+ failedStr = ansi.red + failedStr + ansi.resetColor;
83
+ return (`${ansi.green}passed: ${state.passed}${ansi.resetColor}, ${failedStr}, running: ${state.running}, pending: ${state.pending}\n` +
84
+ progressBar(state.percentComplete));
85
+ }
86
+ let previousDecile = 0;
87
+ workerController.onUpdate = () => {
88
+ if (disposed)
89
+ return;
90
+ const progressStr = createProgressMessage();
91
+ if (useSticky)
92
+ logger.sticky(progressStr);
93
+ else {
94
+ const decile = Math.trunc(state.percentComplete * 10);
95
+ if (decile !== previousDecile) {
96
+ logger.info(progressStr);
97
+ previousDecile = decile;
98
+ }
99
+ }
100
+ if (options.stopOnFirstFailure && state.failed)
101
+ void shutdown();
102
+ if (!state.remaining)
103
+ void shutdown();
104
+ };
105
+ const sigIntHandler = () => {
106
+ logger.info('SIGINT signal received.');
107
+ void shutdown().then(() => process.exit(1));
108
+ };
109
+ process.once('SIGINT', sigIntHandler);
110
+ let disposed = false;
111
+ async function shutdown() {
112
+ if (disposed)
113
+ return;
114
+ disposed = true;
115
+ logger.clearSticky();
116
+ logger.info(createProgressMessage());
117
+ logger.debug('Shutting down');
118
+ process.removeListener('SIGINT', sigIntHandler);
119
+ await workerController.terminate();
120
+ await serverHandle.close();
121
+ await shutdownLocalTunnel();
122
+ const passed = workerController.allPassed;
123
+ if (passed)
124
+ logger.info('✅ All tests passed');
125
+ done({ passed });
126
+ }
127
+ workerController.start();
128
+ return await donePromise;
129
+ }
130
+ /**
131
+ * Calls {@link runSeleniumBrowserStack}, exiting the process when settled.
132
+ */
133
+ export function runSeleniumBrowserStackAndExit(options) {
134
+ runSeleniumBrowserStack(options)
135
+ .then((result) => {
136
+ if (!result.passed)
137
+ process.exit(1);
138
+ })
139
+ .catch((error) => {
140
+ console.error(ansi.red +
141
+ String('message' in error ? error.message : error) +
142
+ ansi.resetColor);
143
+ process.exit(1);
144
+ });
145
+ }
@@ -0,0 +1 @@
1
+ {"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/typescript/lib/lib.es2023.d.ts","../../../node_modules/typescript/lib/lib.es2024.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2024.collection.d.ts","../../../node_modules/typescript/lib/lib.es2024.object.d.ts","../../../node_modules/typescript/lib/lib.es2024.promise.d.ts","../../../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2024.string.d.ts","../../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../../node_modules/typescript/lib/lib.esnext.float16.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/@babel/types/lib/index.d.ts","../../../node_modules/@types/babel__generator/index.d.ts","../../../node_modules/@babel/parser/typings/babel-parser.d.ts","../../../node_modules/@types/babel__template/index.d.ts","../../../node_modules/@types/babel__traverse/index.d.ts","../../../node_modules/@types/babel__core/index.d.ts","../../vinyl-build-utils/dist/babel/compattransform.d.ts","../../../node_modules/browserstack-local/index.d.ts","../../../node_modules/@types/node/compatibility/iterators.d.ts","../../../node_modules/@types/node/globals.typedarray.d.ts","../../../node_modules/@types/node/buffer.buffer.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../node_modules/@types/node/web-globals/crypto.d.ts","../../../node_modules/@types/node/web-globals/domexception.d.ts","../../../node_modules/@types/node/web-globals/events.d.ts","../../../node_modules/buffer/index.d.ts","../../../node_modules/undici-types/utility.d.ts","../../../node_modules/undici-types/header.d.ts","../../../node_modules/undici-types/readable.d.ts","../../../node_modules/undici-types/fetch.d.ts","../../../node_modules/undici-types/formdata.d.ts","../../../node_modules/undici-types/connector.d.ts","../../../node_modules/undici-types/client-stats.d.ts","../../../node_modules/undici-types/client.d.ts","../../../node_modules/undici-types/errors.d.ts","../../../node_modules/undici-types/dispatcher.d.ts","../../../node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/undici-types/global-origin.d.ts","../../../node_modules/undici-types/pool-stats.d.ts","../../../node_modules/undici-types/pool.d.ts","../../../node_modules/undici-types/handlers.d.ts","../../../node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/undici-types/h2c-client.d.ts","../../../node_modules/undici-types/agent.d.ts","../../../node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/undici-types/mock-call-history.d.ts","../../../node_modules/undici-types/mock-agent.d.ts","../../../node_modules/undici-types/mock-client.d.ts","../../../node_modules/undici-types/mock-pool.d.ts","../../../node_modules/undici-types/snapshot-agent.d.ts","../../../node_modules/undici-types/mock-errors.d.ts","../../../node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/undici-types/retry-handler.d.ts","../../../node_modules/undici-types/retry-agent.d.ts","../../../node_modules/undici-types/api.d.ts","../../../node_modules/undici-types/cache-interceptor.d.ts","../../../node_modules/undici-types/interceptors.d.ts","../../../node_modules/undici-types/util.d.ts","../../../node_modules/undici-types/cookies.d.ts","../../../node_modules/undici-types/patch.d.ts","../../../node_modules/undici-types/websocket.d.ts","../../../node_modules/undici-types/eventsource.d.ts","../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/undici-types/content-type.d.ts","../../../node_modules/undici-types/cache.d.ts","../../../node_modules/undici-types/index.d.ts","../../../node_modules/@types/node/web-globals/fetch.d.ts","../../../node_modules/@types/node/web-globals/navigator.d.ts","../../../node_modules/@types/node/web-globals/storage.d.ts","../../../node_modules/@types/node/web-globals/streams.d.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/inspector.generated.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/sea.d.ts","../../../node_modules/@types/node/sqlite.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/index.d.ts","../../../node_modules/@types/send/index.d.ts","../../../node_modules/@types/qs/index.d.ts","../../../node_modules/@types/range-parser/index.d.ts","../../../node_modules/@types/express-serve-static-core/index.d.ts","../../../node_modules/@types/http-errors/index.d.ts","../../../node_modules/@types/serve-static/index.d.ts","../../../node_modules/@types/connect/index.d.ts","../../../node_modules/@types/body-parser/index.d.ts","../../../node_modules/@types/express/index.d.ts","../../../node_modules/@types/http-proxy/index.d.ts","../../../node_modules/http-proxy-middleware/dist/types.d.ts","../../../node_modules/http-proxy-middleware/dist/factory.d.ts","../../../node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts","../../../node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts","../../../node_modules/http-proxy-middleware/dist/handlers/public.d.ts","../../../node_modules/http-proxy-middleware/dist/handlers/index.d.ts","../../../node_modules/http-proxy-middleware/dist/plugins/default/debug-proxy-errors-plugin.d.ts","../../../node_modules/http-proxy-middleware/dist/plugins/default/error-response-plugin.d.ts","../../../node_modules/http-proxy-middleware/dist/plugins/default/logger-plugin.d.ts","../../../node_modules/http-proxy-middleware/dist/plugins/default/proxy-events.d.ts","../../../node_modules/http-proxy-middleware/dist/plugins/default/index.d.ts","../../../node_modules/http-proxy-middleware/dist/legacy/types.d.ts","../../../node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.d.ts","../../../node_modules/http-proxy-middleware/dist/legacy/public.d.ts","../../../node_modules/http-proxy-middleware/dist/legacy/index.d.ts","../../../node_modules/http-proxy-middleware/dist/index.d.ts","../../vinyl-build-utils/dist/express/startexpressserver.d.ts","../../vinyl-build-utils/dist/express/serve.d.ts","../../vinyl-build-utils/dist/util/logger.d.ts","../../vinyl-build-utils/dist/browserstack/browserstackrestapi.d.ts","../../vinyl-build-utils/dist/browserstack/browserstackconfig.d.ts","../../vinyl-build-utils/dist/browserstack/browserstacklocal.d.ts","../../vinyl-build-utils/dist/browserstack/configurereporterapi.d.ts","../../vinyl-build-utils/dist/esbuild/analyzeexports.d.ts","../../../node_modules/esbuild/lib/main.d.ts","../../vinyl-build-utils/dist/esbuild/buildall.d.ts","../../vinyl-build-utils/dist/esbuild/compattransformplugin.d.ts","../../vinyl-build-utils/dist/esbuild/optionalentrypoints.d.ts","../../vinyl-build-utils/dist/esbuild/pureexportsplugin.d.ts","../../../node_modules/typescript/lib/typescript.d.ts","../../vinyl-build-utils/dist/typescript/tsc.d.ts","../../vinyl-build-utils/dist/typescript/buildtypedeclarations.d.ts","../../vinyl-build-utils/dist/esbuild/typedeclarationsplugin.d.ts","../../vinyl-build-utils/dist/typescript/parsetsconfig.d.ts","../../vinyl-build-utils/dist/typescript/replacepathaliases.d.ts","../../vinyl-build-utils/dist/typescript/resolveprojectreferences.d.ts","../../vinyl-build-utils/dist/util/console.d.ts","../../vinyl-build-utils/dist/util/copyfiles.d.ts","../../vinyl-build-utils/dist/util/extractargs.d.ts","../../vinyl-build-utils/dist/util/getrootprojectdir.d.ts","../../vinyl-build-utils/dist/util/prompt.d.ts","../../vinyl-build-utils/dist/util/sleep.d.ts","../../vinyl-build-utils/dist/util/string.d.ts","../../vinyl-build-utils/dist/util/taskqueue.d.ts","../../vinyl-build-utils/dist/util/writeindexfile.d.ts","../../vinyl-build-utils/dist/vinyl/buildvinylpackage.d.ts","../../vinyl-build-utils/dist/vinyl/vinyldefaultbrowserstackoptions.d.ts","../../vinyl-build-utils/dist/vinyl/vinyldefaulttscoptions.d.ts","../../vinyl-build-utils/dist/vinyl/vinylsupportedbrowsers.d.ts","../../vinyl-build-utils/dist/index.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/filterby.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/remotevalue.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/scripttypes.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/logentries.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/loginspector.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/browsingcontexttypes.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/cliprectangle.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/capturescreenshotparameters.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/createcontextparameters.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/protocolvalue.d.ts","../../../node_modules/@types/selenium-webdriver/bidi/browsingcontext.d.ts","../../../node_modules/@types/selenium-webdriver/http.d.ts","../../../node_modules/@types/selenium-webdriver/remote.d.ts","../../../node_modules/@types/selenium-webdriver/chrome.d.ts","../../../node_modules/@types/selenium-webdriver/edge.d.ts","../../../node_modules/@types/selenium-webdriver/lib/symbols.d.ts","../../../node_modules/@types/selenium-webdriver/firefox.d.ts","../../../node_modules/@types/selenium-webdriver/ie.d.ts","../../../node_modules/@types/selenium-webdriver/lib/by.d.ts","../../../node_modules/@types/selenium-webdriver/lib/capabilities.d.ts","../../../node_modules/@types/selenium-webdriver/lib/command.d.ts","../../../node_modules/@types/selenium-webdriver/lib/input.d.ts","../../../node_modules/@types/selenium-webdriver/lib/logging.d.ts","../../../node_modules/@types/selenium-webdriver/lib/until.d.ts","../../../node_modules/@types/ws/index.d.mts","../../../node_modules/@types/selenium-webdriver/bidi/index.d.ts","../../../node_modules/@types/selenium-webdriver/devtools/networkinterceptor.d.ts","../../../node_modules/@types/selenium-webdriver/lib/webdriver.d.ts","../../../node_modules/@types/selenium-webdriver/safari.d.ts","../../../node_modules/@types/selenium-webdriver/chromium.d.ts","../../../node_modules/@types/selenium-webdriver/lib/promise.d.ts","../../../node_modules/@types/selenium-webdriver/index.d.ts","../src/capabilities.ts","../src/webdriverworker.ts","../src/webdriverworkercontroller.ts","../src/runseleniumbrowserstack.ts","../src/index.ts"],"fileIdsList":[[74,84,139,156,157],[84,139,156,157],[74,75,76,77,78,84,139,156,157],[74,76,84,139,156,157],[84,139,153,156,157,189,196],[84,139,153,156,157,189],[84,139,150,153,156,157,189,190,191,192],[84,139,156,157,193,195,197],[84,139,150,153,155,156,157,159,171,182,189],[84,136,137,139,156,157],[84,138,139,156,157],[139,156,157],[84,139,144,156,157,174],[84,139,140,145,150,156,157,159,171,182],[84,139,140,141,150,156,157,159],[84,139,142,156,157,183],[84,139,143,144,151,156,157,160],[84,139,144,156,157,171,179],[84,139,145,147,150,156,157,159],[84,138,139,146,156,157],[84,139,147,148,156,157],[84,139,149,150,156,157],[84,138,139,150,156,157],[84,139,150,151,152,156,157,171,182],[84,139,150,151,152,156,157,166,171,174],[84,131,139,147,150,153,156,157,159,171,182],[84,139,150,151,153,154,156,157,159,171,179,182],[84,139,153,155,156,157,171,179,182],[82,83,84,85,86,87,88,89,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188],[84,139,150,156,157],[84,139,156,157,158,182],[84,139,147,150,156,157,159,171],[84,139,156,157,160],[84,139,156,157,161],[84,138,139,156,157,162],[84,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188],[84,139,156,157,164],[84,139,156,157,165],[84,139,150,156,157,166,167],[84,139,156,157,166,168,183,185],[84,139,151,156,157],[84,139,150,156,157,171,172,174],[84,139,156,157,173,174],[84,139,156,157,171,172],[84,139,156,157,174],[84,139,156,157,175],[84,136,139,156,157,171,176,182],[84,139,150,156,157,177,178],[84,139,156,157,177,178],[84,139,144,156,157,159,171,179],[84,139,156,157,180],[84,139,156,157,159,181],[84,139,153,156,157,165,182],[84,139,144,156,157,183],[84,139,156,157,171,184],[84,139,156,157,158,185],[84,139,156,157,186],[84,139,144,156,157],[84,131,139,156,157],[84,139,156,157,187],[84,131,139,150,152,156,157,162,171,174,182,184,185,187],[84,139,156,157,171,188],[84,139,156,157,255,257,258,259,281],[84,139,156,157,256],[84,139,150,156,157,189],[84,139,156,157,252],[84,139,156,157,250,253],[84,139,156,157,251],[84,139,156,157,261,262,281],[84,139,156,157,262,281],[84,139,156,157,261,262,265,281],[84,139,156,157,281],[84,139,156,157,254,260,261,263,264,266,267,268,269,271,272,273,277,278,279,280],[84,139,156,157,265,281],[84,139,156,157,270,281],[84,139,156,157,270,271,274,275,276,281],[84,139,151,156,157,171,189],[84,139,153,156,157,189,194],[84,139,150,153,155,156,157,159,171,179,182,188,189],[84,139,153,156,157,200],[84,139,153,156,157],[84,139,156,157,204],[84,139,156,157,202,203],[84,139,156,157,200,201,205,210,214],[84,139,153,156,157,200,211],[84,139,156,157,213],[84,139,156,157,211,212],[84,139,156,157,200],[84,139,156,157,206,207,208,209],[84,139,153,156,157,159,199],[84,97,100,103,104,139,156,157,182],[84,100,139,156,157,171,182],[84,100,104,139,156,157,182],[84,139,156,157,171],[84,94,139,156,157],[84,98,139,156,157],[84,96,97,100,139,156,157,182],[84,139,156,157,159,179],[84,139,156,157,189],[84,94,139,156,157,189],[84,96,100,139,156,157,159,182],[84,91,92,93,95,99,139,150,156,157,171,182],[84,100,108,116,139,156,157],[84,92,98,139,156,157],[84,100,125,126,139,156,157],[84,92,95,100,139,156,157,174,182,189],[84,100,139,156,157],[84,96,100,139,156,157,182],[84,91,139,156,157],[84,94,95,96,98,99,100,101,102,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,126,127,128,129,130,139,156,157],[84,100,118,121,139,147,156,157],[84,100,108,109,110,139,156,157],[84,98,100,109,111,139,156,157],[84,99,139,156,157],[84,92,94,100,139,156,157],[84,100,104,109,111,139,156,157],[84,104,139,156,157],[84,98,100,103,139,156,157,182],[84,92,96,100,108,139,156,157],[84,100,118,139,156,157],[84,111,139,156,157],[84,94,100,125,139,156,157,174,187,189],[84,139,156,157,249],[84,139,156,157,282,283,284,285],[81,84,139,144,156,157,198,249,284],[84,139,144,151,156,157,161,249,281,282],[84,139,156,157,249,283],[79,84,139,156,157],[81,84,139,156,157,217,218,219],[81,84,139,156,157],[84,139,156,157,198],[84,139,156,157,224],[84,139,156,157,224,231],[84,139,156,157,198,215,216],[84,139,156,157,179,198],[80,84,139,156,157,216,217,218,219,220,221,222,223,225,226,227,228,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248],[84,139,156,157,230],[84,139,156,157,229],[84,139,156,157,233],[84,139,156,157,217,224],[84,139,156,157,231],[84,139,156,157,220]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"556ccd493ec36c7d7cb130d51be66e147b91cc1415be383d71da0f1e49f742a9","impliedFormat":1},{"version":"b6d03c9cfe2cf0ba4c673c209fcd7c46c815b2619fd2aad59fc4229aaef2ed43","impliedFormat":1},{"version":"95aba78013d782537cc5e23868e736bec5d377b918990e28ed56110e3ae8b958","impliedFormat":1},{"version":"670a76db379b27c8ff42f1ba927828a22862e2ab0b0908e38b671f0e912cc5ed","impliedFormat":1},{"version":"13b77ab19ef7aadd86a1e54f2f08ea23a6d74e102909e3c00d31f231ed040f62","impliedFormat":1},{"version":"069bebfee29864e3955378107e243508b163e77ab10de6a5ee03ae06939f0bb9","impliedFormat":1},"4ac27de8e092863e77dd783e0e1221fd6037786a8729292526fb042cc4bbe7f5",{"version":"e83e467ebe549ca06658e4299b7024ee01ba52edf8faf5c70ed830a98a8ea3f3","impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"378281aa35786c27d5811af7e6bcaa492eebd0c7013d48137c35bbc69a2b9751","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"1b2dd1cbeb0cc6ae20795958ba5950395ebb2849b7c8326853dd15530c77ab0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"387a023d363f755eb63450a66c28b14cdd7bc30a104565e2dbf0a8988bb4a56c","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","impliedFormat":1},{"version":"487b694c3de27ddf4ad107d4007ad304d29effccf9800c8ae23c2093638d906a","impliedFormat":1},{"version":"3a80bc85f38526ca3b08007ee80712e7bb0601df178b23fbf0bf87036fce40ce","impliedFormat":1},{"version":"ccf4552357ce3c159ef75f0f0114e80401702228f1898bdc9402214c9499e8c0","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"2931540c47ee0ff8a62860e61782eb17b155615db61e36986e54645ec67f67c2","impliedFormat":1},{"version":"ccab02f3920fc75c01174c47fcf67882a11daf16baf9e81701d0a94636e94556","impliedFormat":1},{"version":"f6faf5f74e4c4cc309a6c6a6c4da02dbb840be5d3e92905a23dcd7b2b0bd1986","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"33e981bf6376e939f99bd7f89abec757c64897d33c005036b9a10d9587d80187","impliedFormat":1},{"version":"7fd1b31fd35876b0aa650811c25ec2c97a3c6387e5473eb18004bed86cdd76b6","impliedFormat":1},{"version":"b41767d372275c154c7ea6c9d5449d9a741b8ce080f640155cc88ba1763e35b3","impliedFormat":1},{"version":"3bacf516d686d08682751a3bd2519ea3b8041a164bfb4f1d35728993e70a2426","impliedFormat":1},{"version":"7fb266686238369442bd1719bc0d7edd0199da4fb8540354e1ff7f16669b4323","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"5b03a034c72146b61573aab280f295b015b9168470f2df05f6080a2122f9b4df","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"249b9cab7f5d628b71308c7d9bb0a808b50b091e640ba3ed6e2d0516f4a8d91d","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"54c3e2371e3d016469ad959697fd257e5621e16296fa67082c2575d0bf8eced0","impliedFormat":1},{"version":"beb8233b2c220cfa0feea31fbe9218d89fa02faa81ef744be8dce5acb89bb1fd","impliedFormat":1},{"version":"c183b931b68ad184bc8e8372bf663f3d33304772fb482f29fb91b3c391031f3e","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"48cc3ec153b50985fb95153258a710782b25975b10dd4ac8a4f3920632d10790","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"e1528ca65ac90f6fa0e4a247eb656b4263c470bb22d9033e466463e13395e599","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"866078923a56d026e39243b4392e282c1c63159723996fa89243140e1388a98d","impliedFormat":1},{"version":"f724236417941ea77ec8d38c6b7021f5fb7f8521c7f8c1538e87661f2c6a0774","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ea15fd99b2e34cb25fe8346c955000bb70c8b423ae4377a972ef46bfb37f595","impliedFormat":1},{"version":"7cf69dd5502c41644c9e5106210b5da7144800670cbe861f66726fa209e231c4","impliedFormat":1},{"version":"72c1f5e0a28e473026074817561d1bc9647909cf253c8d56c41d1df8d95b85f7","impliedFormat":1},{"version":"f9b4137a0d285bd77dba2e6e895530112264310ae47e07bf311feae428fb8b61","affectsGlobalScope":true,"impliedFormat":1},{"version":"c06b2652ffeb89afd0f1c52c165ced77032f9cd09bc481153fbd6b5504c69494","impliedFormat":1},{"version":"51aecd2df90a3cffea1eb4696b33b2d78594ea2aa2138e6b9471ec4841c6c2ee","impliedFormat":1},{"version":"9d8f9e63e29a3396285620908e7f14d874d066caea747dc4b2c378f0599166b4","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"612422d5ba6b4a5c4537f423e9199645468ad80a689801da63ab7edb43f7b835","impliedFormat":1},{"version":"db9ada976f9e52e13f7ae8b9a320f4b67b87685938c5879187d8864b2fbe97f3","impliedFormat":1},{"version":"9f39e70a354d0fba29ac3cdf6eca00b7f9e96f64b2b2780c432e8ea27f133743","impliedFormat":1},{"version":"0dace96cc0f7bc6d0ee2044921bdf19fe42d16284dbcc8ae200800d1c9579335","impliedFormat":1},{"version":"a2e2bbde231b65c53c764c12313897ffdfb6c49183dd31823ee2405f2f7b5378","impliedFormat":1},{"version":"ad1cc0ed328f3f708771272021be61ab146b32ecf2b78f3224959ff1e2cd2a5c","impliedFormat":1},{"version":"c64e1888baaa3253ca4405b455e4bf44f76357868a1bd0a52998ade9a092ad78","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc8c6f5322961b56d9906601b20798725df60baeab45ec014fba9f795d5596fd","impliedFormat":1},{"version":"0904660ae854e6d41f6ff25356db1d654436c6305b0f0aa89d1532df0253486e","impliedFormat":1},{"version":"060d305fe4494d8cb2b99d620928d369d1ee55c1645f5e729a2aca07d0f108cb","impliedFormat":1},{"version":"a016b2a26863dd6acb1f18c4ff37363c2b51e27ca7b3374dc6342aff1ddead2d","impliedFormat":1},{"version":"0c50296ee73dae94efc3f0da4936b1146ca6ce2217acfabb44c19c9a33fa30e5","impliedFormat":1},{"version":"bbf42f98a5819f4f06e18c8b669a994afe9a17fe520ae3454a195e6eabf7700d","impliedFormat":1},{"version":"0e5974dfff7a97181c7c376545f126b20acf2f1341db7d3fccea4977bf3ce19c","impliedFormat":1},{"version":"c7f977ea78a1b060a30554c1c4ec0e2269c6e305a349ca2ada14931ac27ecc0b","affectsGlobalScope":true,"impliedFormat":1},{"version":"3806cdd6b48ba01a9198134e62a384ec217a98f316d4baef74dd46d62c947a63","impliedFormat":1},{"version":"ff65b8a8bd380c6d129becc35de02f7c29ad7ce03300331ca91311fb4044d1a9","impliedFormat":1},{"version":"04bf1aa481d1adfb16d93d76e44ce71c51c8ef68039d849926551199489637f6","impliedFormat":1},{"version":"2c9adcc85574b002c9a6311ff2141055769e0071856ec979d92ff989042b1f1b","affectsGlobalScope":true,"impliedFormat":1},{"version":"b8bf3fe89ec8baa335f6370b9fa36308e1bc7a72e2eb2dad1e94f31e27fa28b5","affectsGlobalScope":true,"impliedFormat":1},{"version":"a58a15da4c5ba3df60c910a043281256fa52d36a0fcdef9b9100c646282e88dd","impliedFormat":1},{"version":"b36beffbf8acdc3ebc58c8bb4b75574b31a2169869c70fc03f82895b93950a12","impliedFormat":1},{"version":"de263f0089aefbfd73c89562fb7254a7468b1f33b61839aafc3f035d60766cb4","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"8c81fd4a110490c43d7c578e8c6f69b3af01717189196899a6a44f93daa57a3a","impliedFormat":1},{"version":"5fb39858b2459864b139950a09adae4f38dad87c25bf572ce414f10e4bd7baab","impliedFormat":1},{"version":"35390d6fa94bdb432c5d0bcb6547bdd11406c2692a6b90b9e47be2105ea19bd6","impliedFormat":1},{"version":"3910dab597c40e173bf0e0d419d3ce9682c54ebf6ae84849f9b829b1451a17ec","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"486c074a5c0f2254345c0d1c9540380f5463999e42d7e1a159305ea823d3c4b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"c119835edf36415081dfd9ed15fc0cd37aaa28d232be029ad073f15f3d88c323","impliedFormat":1},{"version":"8e7c3bed5f19ade8f911677ddc83052e2283e25b0a8654cd89db9079d4b323c7","impliedFormat":1},{"version":"9705cd157ffbb91c5cab48bdd2de5a437a372e63f870f8a8472e72ff634d47c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"ae86f30d5d10e4f75ce8dcb6e1bd3a12ecec3d071a21e8f462c5c85c678efb41","impliedFormat":1},{"version":"ccf3afaeebbeee4ca9092101e99fd6abd681116b6e5ec23e381bbb1e1f32262c","impliedFormat":1},{"version":"e03460fe72b259f6d25ad029f085e4bedc3f90477da4401d8fbc1efa9793230e","impliedFormat":1},{"version":"4286a3a6619514fca656089aee160bb6f2e77f4dd53dc5a96b26a0b4fc778055","impliedFormat":1},{"version":"ab7818a9d57a9297b90e456fc68b77f84d74395a9210a3cfa9d87db33aff8b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb08062718a5470cd864c1fae0eb5b3a3adc5bcd05dcf87608d6f60b65eca3f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"3a815b7d1aebc0646b91548eab2fc19dada09ff255d04c71ced00bbd3058c8eb","impliedFormat":1},{"version":"255d948f87f24ffd57bcb2fdf95792fd418a2e1f712a98cf2cce88744d75085c","impliedFormat":1},{"version":"0d5b085f36e6dc55bc6332ecb9c733be3a534958c238fb8d8d18d4a2b6f2a15a","impliedFormat":1},{"version":"836b36913830645ac3b28fe33731aac3fdb3524ee8adbb4cdab9a5c189f41943","affectsGlobalScope":true,"impliedFormat":1},{"version":"bfd3b3c21a56104693183942e221c1896ee23bcb8f8d91ab0b941f7b32985411","impliedFormat":1},{"version":"d7e9ab1b0996639047c61c1e62f85c620e4382206b3abb430d9a21fb7bc23c77","impliedFormat":1},{"version":"d34aa8df2d0b18fb56b1d772ff9b3c7aea7256cf0d692f969be6e1d27b74d660","impliedFormat":1},{"version":"93a3b8e57c68e348fc4054b245bd7cf4893225f56c991028844b693c2fa8c03c","impliedFormat":1},{"version":"2f5747b1508ccf83fad0c251ba1e5da2f5a30b78b09ffa1cfaf633045160afed","impliedFormat":1},{"version":"6823ccc7b5b77bbf898d878dbcad18aa45e0fa96bdd0abd0de98d514845d9ed9","affectsGlobalScope":true,"impliedFormat":1},{"version":"b71c603a539078a5e3a039b20f2b0a0d1708967530cf97dec8850a9ca45baa2b","impliedFormat":1},{"version":"168d88e14e0d81fe170e0dadd38ae9d217476c11435ea640ddb9b7382bdb6c1f","impliedFormat":1},{"version":"104c67f0da1bdf0d94865419247e20eded83ce7f9911a1aa75fc675c077ca66e","impliedFormat":1},{"version":"cc0d0b339f31ce0ab3b7a5b714d8e578ce698f1e13d7f8c60bfb766baeb1d35c","impliedFormat":1},{"version":"8e04cf0688e0d921111659c2b55851957017148fa7b977b02727477d155b3c47","impliedFormat":1},{"version":"26b7d0cd4b41ab557ef9e3bfeec42dcf24252843633e3d29f38d2c0b13aaa528","impliedFormat":1},{"version":"47bd5449f6c874f45d737a54e6aa4d9f723fa97067f46a05d8f7d7b69c5e8ebe","impliedFormat":1},{"version":"7d60217ec2719e0f373e50c0a397f401233ea42a569f8232a2ec17c77769f99a","impliedFormat":1},{"version":"39d59b812869b4f3bee27a44a4f37d7f5bf96c8dabd71a2dbd03c769b36e22c7","impliedFormat":1},{"version":"ddafa5a34d6dc63a55afbc273ff884e64025a4127b68c54016b91cf8d73fa656","impliedFormat":1},{"version":"901becb8779e1089442378fda5623e607ee4588762a32e7692436f1ea81cf848","impliedFormat":1},{"version":"8286d84d2567b713fd6a1fdfbb1a0abc8cfa668ee1e0e83d7dd4ade5761f2750","impliedFormat":1},{"version":"e4a52c589745f7bca3346962af0b62270302f9e60b116037483b3dea345d5f9d","impliedFormat":1},{"version":"38f50c96cd804ec61e75c742cd8165651f31076307a2492e6afd595f574975e6","impliedFormat":1},{"version":"c0513cfcf00f4fc7a7fe41b4c66b8cd56e280f37233c2ed8b89c9ae6f5fc3a7f","impliedFormat":1},{"version":"85e65d83a8e65bc6ff28b67b8b4a4565b6754be8e74a48080fc83f00be07a16f","impliedFormat":1},{"version":"9678e67085896b6fdfdaf3be547822a5f86ca030284b653a08235df00914d70d","impliedFormat":1},{"version":"8c806b7b1e03a9de990cced43abb3541304ce46b31073d326879d5f243cec1f4","impliedFormat":1},{"version":"a76355c652099c5ecfae4f038b23235b50ab00bbfda8d9685014b0c53e38210a","impliedFormat":1},{"version":"41c851891f277afd9bf0b3af06fb3d35c11b32cb0120e85ae5b7e6dbbda037de","impliedFormat":1},{"version":"8286d84d2567b713fd6a1fdfbb1a0abc8cfa668ee1e0e83d7dd4ade5761f2750","impliedFormat":1},{"version":"a710a056936098886b0b5eb6734034589d15dbd7fa29329dc936f3f4e7bce93b","impliedFormat":1},"1676e8dbe08ff284a0f75938d97e6a4da2dc39fcecb03b18276f598bd30ce58a","9669ae16bbbb071a7720ddfa9a27fb17da2c8114505e309d446ea34d8406c918","4ae7784b4e00b43c1c66f700748a3ca59a23f2ca5794ae204ba8cb4f6ddbda1c","0352d7ffabfeceb77a18b7bd7419cada59eee667ef2a1d4258c50c82a0f8138b","460c8a20b1d42ef2b6b433fc86a14916d31b94f170b483414a5b204fc8cb2dd2","1c2547abfdde0923c93d564601ba55a7de6aacdb172eaecd73e990e1c5e0d862","9a910c69bbe500390412706a8dc369832bef51d8b869483dcbc7bdf301465f2b","e280f80a5c28f3cf46d992920189be89bf31743bf38160e9fe50fca859dc78b7",{"version":"161c8e0690c46021506e32fda85956d785b70f309ae97011fd27374c065cac9b","affectsGlobalScope":true,"impliedFormat":1},"5138d0a331b474840a2aa8e1cad03446851e8545868ca303afec8b21d4239abd","caa69bfb6afa0055855768c8da388ca05bd720a8dd6c98442c7403c14cbd7852","b31238cf420fa129974ae9ca9884f59471dd7c406f2dfd0375b668cf0612ef1a","f87e597de6a4ffb71dd3e5876521ce41fa7e97fdd0121ca00a7928757ec156fc",{"version":"e134052a6b1ded61693b4037f615dc72f14e2881e79c1ddbff6c514c8a516b05","impliedFormat":1},"4a60ec1824049d71b400dd64537a32bcceca9a6abc4765774b96a3d5420a0dc5","e825c2088ed3da685196d340f3892364f545d6560c38cc80f203edebd6603e9b","e5090b9aef9ebd8998217d6a31fc3539b1d110916520e55985942fef00d44020","c35f6831d1bc77fc87541fe8036a5902d76a22d0bbb47d2d6dec0e1045b15872","3034a050a425edfd70b60feb643f839b5da4212943c52034db6417f3358e7b78","a574acd60e681a10957b00f85a8dfeda9ee4bdf1c7c0b7a2536da66363445d34","2d54add319e6484f93ff621e871c332d9e0912ddcebbc1e821910916317a74c6","1f7eee5d9fa88d0277f1c352cd50a810d5e2d7e2056ef0353fcabba90ec782cd","d43468180c2eeb03e3d166a9c7ea263be91b46421fff92a48c63bb31f98ff3ed","d61a755219ba1293fd90c8b78f4f9993173767572dbe738177802454d729da1f","4e6be930eb663c841e95e4668362b536b17c71c4ce34814bd63594e627ac7c01","b84cfff8a3846ab492435cf340c953a0d21d7a12aa4310b6289afe75adb7dec3","cce04a28a25886d5e02c6691aefc840cad682dfd0ed9c965b3b86277b400462f","a6a0ac02b9be82beba788dd3685f97baa13eb28919c7beffd4000dea9f3561fd","e9be992849b419a503eac4d58799d7d3539ba64423b9ec28ed84cf940f596633","c4ebe96ec8dbbcbbe2d872e18c32b75a83139c8b2fb62635de76fcf9ebc659b5","6e7c7d739ff13d1159386b5f55f0e3b5dcf8f751faeab98682bc6807bde5c38e","90e2f8aa0f21c24c059ef654db2080f3f989ef10a4a54cb465386958e87f3c01","c4e94d055a424c0e465b09b354d0149477927c398906d19a71fb8a1ab0c97ccc","e9c107b44c0182b2a023924108751cbd0ad1cb466f155996ee93be626ad704c2",{"version":"37aaeb31561ca66a4264fa5a3a965b417793d66308b0452aa38cf0b0b9acf404","impliedFormat":1},{"version":"880e16c716211a52c099f35a54760a50f0963a4a99fe47fffacd80b8c76cfa55","impliedFormat":1},{"version":"c394b124f1dc199fdb4334db392908a3101593ed35ccb32cdf7a88dd08191b01","impliedFormat":1},{"version":"84efa072f3137628fb1b36348630e54f2558551fabd44e6797e437669e5be7de","impliedFormat":1},{"version":"42edae270fb55922752561301d8f4ed6f6238888415596a68e0d57e648ef4e78","impliedFormat":1},{"version":"e5cfe3bccf8885ecb7f06609f08ce005eac9f9db92b96981da880cc2a955d3af","impliedFormat":1},{"version":"bd97fa393719c616f9c99a73848c06a82e41774badce3915c427bde4d2bcd8a7","impliedFormat":1},{"version":"5e2e4472ad4ef7e3e33924d7f249de1a9f04d483c4eb77c2a039d151b5f6cada","impliedFormat":1},{"version":"d1726670bab0f583c8476433382e57d3acbce6ca9565cd485843314be2406d98","impliedFormat":1},{"version":"e4fab1a9e6a94557e59fff48d56d5fe94dd96bb92f8e6b31f45affd92fa40432","impliedFormat":1},{"version":"ba0f0e98feb906008e247531dc84ee68ce90fdef655e06a0c3c9ae2c0796a993","impliedFormat":1},{"version":"031306386855ceeb4f4c875dd4f625ef40724cd322bb67cacbd8fbce0285e2ab","impliedFormat":1},{"version":"cf6a174888a6c2a0b8c330645226f5282f1c371694a7a1937004ebd5694e2822","impliedFormat":1},{"version":"e085ea128f0119276ca5ce2ec6e2f47a05c330a75b2e716623888269a5fdcb5b","impliedFormat":1},{"version":"caa6c6a57261f968d545f23458b60d6a464673452b92af66b0c2745252bb7be1","impliedFormat":1},{"version":"3fa21de354079911eec4d38d95252c606ff31980e435a4abef88958564bb5621","impliedFormat":1},{"version":"95e590ff188fca6a972449ed73899b93285692f0fed890a08fefe89786fc1527","impliedFormat":1},{"version":"8a9fd98412afb1ff9d56e0b0a6b341d17adc0629830e534f8661434a862cde64","impliedFormat":1},{"version":"274331ed7fac5c85be5a325ed1f2bb88b846efc6e67ff1488de005a97c9c582f","impliedFormat":1},{"version":"c09cc5fb4c91696aab69654caef6331920199be4970ccea0e007336458cda97f","impliedFormat":1},{"version":"4b49f2ae6c20a3f6221b79ebf3f3f3b89d7e64257d4f9ad56b345c6a2607e635","impliedFormat":1},{"version":"a537be85e045f432f8ddb0a0d152635301a5a6022560305d53ee833064d79a0c","impliedFormat":1},{"version":"1489add5d9512bd619ce820bbdc0ce5c45625e6257e68bd994b5ef1d7f9c3343","impliedFormat":1},{"version":"d966ecf371d8ca9cfbd839b9a60fec0e9c4288870ea99b5936b1ccf644029ca2","impliedFormat":1},{"version":"316f1486e15cbf7896425f0a16dfe12d447dd57cfb3244b8b119c77df870858f","impliedFormat":99},{"version":"624c6c996b36eaa03ae6ba2a2a71976445ac6b49d35c3aab55617751e48165e5","impliedFormat":1},{"version":"d59f81a60bc6f5351ca3d8d9f0cf1d580b2c109537581fc648317418ff2d28eb","impliedFormat":1},{"version":"5a8e78257763161fb85fff3374d95c06f1ea004416fc7b71d76725dadb834534","impliedFormat":1},{"version":"704a9d2ddd3034598c8703b948617ce724b11e3123513126dc5b5de871c46dc3","impliedFormat":1},{"version":"c2f45eaa5c9d816ca5205ba349d8daebfc2e5022b0cf98b117e2ed5663a38480","impliedFormat":1},{"version":"f2c8c6fbbad111c5e0551b2af8eccb40fb8b98972582f491efe97b0286e64853","impliedFormat":1},{"version":"0592c6bcb292c0bf1646e18b371082c5a897845bf701c69d532a3bac9c83a587","impliedFormat":1},{"version":"89d14ee1607b01e178605aca8bf7644e50ccf2ba0df8134b624f491c68f32bf5","signature":"7c9f10b2b58b2cfec669150ca8c0b117b4b11f4ec96af412d0e5ab76ce7c38cb"},{"version":"e57000889962c7814e1383a71ae5f0c38ce69502312a1249880efd503113edb6","signature":"29b1f327bb1c11add65c101437ccd5d53e8ae23d9cc69c4c8c090f06360026e1"},{"version":"cb3277a3eadaa7ff4a4e8d45fda5c7e05d74c08e3a92d5d449ca80e38216f8f8","signature":"2ae67ff426bc525b2ccc2621d6a43bbb81c0e8c48306601ff3f7abe90b4a7ba9"},{"version":"dc31e832b03a1815094d5bfde9fe5a82eaef9b8681060f09acd8ed20bcb758c9","signature":"c75d17b45ffdbc39e9c673772e17b662df059d1356d2257e84b8a8f7d3a6b861"},{"version":"db5dbe14bb3cd58e20b037b7a7660ad1c16c35b572e4eea9f30712c43d25e88c","signature":"eb376149bdf6db6318faec365aba73d7750044df00492ac8ad3b7bdff2fd807c"}],"root":[[282,286]],"options":{"alwaysStrict":true,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"jsx":1,"module":99,"noImplicitAny":true,"noImplicitThis":true,"outDir":"./","skipLibCheck":true,"strict":true,"strictBindCallApply":true,"strictFunctionTypes":true,"strictNullChecks":true,"strictPropertyInitialization":true,"target":99,"useUnknownInCatchVariables":true},"referencedMap":[[76,1],[74,2],[79,3],[75,1],[77,4],[78,1],[197,5],[196,6],[193,7],[198,8],[194,2],[199,9],[136,10],[137,10],[138,11],[84,12],[139,13],[140,14],[141,15],[82,2],[142,16],[143,17],[144,18],[145,19],[146,20],[147,21],[148,21],[149,22],[150,23],[151,24],[152,25],[85,2],[83,2],[153,26],[154,27],[155,28],[189,29],[156,30],[157,2],[158,31],[159,32],[160,33],[161,34],[162,35],[163,36],[164,37],[165,38],[166,39],[167,39],[168,40],[169,2],[170,41],[171,42],[173,43],[172,44],[174,45],[175,46],[176,47],[177,48],[178,49],[179,50],[180,51],[181,52],[182,53],[183,54],[184,55],[185,56],[186,57],[86,2],[87,58],[88,2],[89,2],[132,59],[133,60],[134,2],[135,45],[187,61],[188,62],[191,2],[192,2],[260,63],[255,2],[257,64],[256,2],[258,2],[250,2],[275,65],[253,66],[254,67],[259,2],[251,2],[252,68],[263,69],[279,69],[276,2],[264,70],[266,71],[261,72],[267,70],[281,73],[268,72],[269,74],[270,2],[271,75],[272,2],[280,72],[265,2],[273,72],[277,76],[262,72],[278,70],[190,77],[195,78],[274,79],[81,2],[90,2],[224,2],[201,80],[203,81],[205,82],[204,83],[202,81],[215,84],[212,85],[214,86],[213,87],[211,80],[206,88],[207,88],[210,89],[208,88],[209,88],[200,90],[72,2],[73,2],[12,2],[13,2],[15,2],[14,2],[2,2],[16,2],[17,2],[18,2],[19,2],[20,2],[21,2],[22,2],[23,2],[3,2],[24,2],[25,2],[4,2],[26,2],[30,2],[27,2],[28,2],[29,2],[31,2],[32,2],[33,2],[5,2],[34,2],[35,2],[36,2],[37,2],[6,2],[41,2],[38,2],[39,2],[40,2],[42,2],[7,2],[43,2],[48,2],[49,2],[44,2],[45,2],[46,2],[47,2],[8,2],[53,2],[50,2],[51,2],[52,2],[54,2],[9,2],[55,2],[56,2],[57,2],[59,2],[58,2],[60,2],[61,2],[10,2],[62,2],[63,2],[64,2],[11,2],[65,2],[66,2],[67,2],[68,2],[69,2],[1,2],[70,2],[71,2],[229,2],[108,91],[120,92],[106,93],[121,94],[130,95],[97,96],[98,97],[96,98],[129,99],[124,100],[128,101],[100,102],[117,103],[99,104],[127,105],[94,106],[95,100],[101,107],[102,2],[107,108],[105,107],[92,109],[131,110],[122,111],[111,112],[110,107],[112,113],[115,114],[109,115],[113,116],[125,99],[103,117],[104,118],[116,119],[93,94],[119,120],[118,107],[114,121],[123,2],[91,2],[126,122],[282,123],[286,124],[285,125],[283,126],[284,127],[80,128],[220,129],[221,130],[219,2],[222,131],[223,2],[225,132],[226,132],[227,2],[228,132],[232,133],[217,134],[216,135],[249,136],[231,137],[233,138],[234,2],[235,139],[230,138],[236,2],[237,2],[238,2],[239,2],[218,2],[240,2],[241,2],[242,2],[243,2],[244,2],[245,140],[246,123],[247,141],[248,142]],"latestChangedDtsFile":"./index.d.ts","version":"5.9.3"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@amazon/vinyl-browserstack",
3
+ "version": "3.0.1",
4
+ "description": "Runs an in-browser Jasmine suite across BrowserStack real browsers over Selenium/WebDriver.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/amazonmusic/vinyl.git"
8
+ },
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "development": "./src/index.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -p ./src/tsconfig.json",
24
+ "build:release": "tsc -p ./src/tsconfig.json",
25
+ "build:watch": "tsc -p ./src/tsconfig.json -w",
26
+ "clean": "rimraf --glob dist \"**/*.tsbuildinfo\"",
27
+ "lint": "npm run oxlint:check && npm run prettier:check",
28
+ "lint:write": "npm run oxlint:write && npm run prettier:write",
29
+ "prettier:check": "prettier . --ignore-path ../../.prettierignore --cache --check",
30
+ "prettier:write": "prettier . --ignore-path ../../.prettierignore --cache --write",
31
+ "release": "npm run lint && npm run build:release",
32
+ "test": "echo \"No tests\"",
33
+ "test:coverage": "echo \"No tests\"",
34
+ "oxlint:check": "oxlint --type-aware --deny-warnings",
35
+ "oxlint:write": "oxlint --type-aware --fix"
36
+ },
37
+ "author": "",
38
+ "license": "Apache-2.0",
39
+ "devDependencies": {
40
+ "@types/express": "^5.0.1",
41
+ "@types/selenium-webdriver": "^4.1.28"
42
+ },
43
+ "dependencies": {
44
+ "@amazon/vinyl-build-utils": "^3.0.1",
45
+ "express": "^5.1.0",
46
+ "selenium-webdriver": "^4.28.1"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ }
51
+ }