@testingbot/cli 1.0.6 → 1.0.8
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 +25 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +79 -50
- package/dist/config/constants.d.ts +15 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +17 -0
- package/dist/index.js +2 -0
- package/dist/models/espresso_options.d.ts +11 -4
- package/dist/models/espresso_options.d.ts.map +1 -1
- package/dist/models/espresso_options.js +24 -7
- package/dist/models/maestro_options.d.ts +13 -3
- package/dist/models/maestro_options.d.ts.map +1 -1
- package/dist/models/maestro_options.js +25 -2
- package/dist/models/xcuitest_options.d.ts +11 -4
- package/dist/models/xcuitest_options.d.ts.map +1 -1
- package/dist/models/xcuitest_options.js +24 -7
- package/dist/providers/base_provider.d.ts +28 -2
- package/dist/providers/base_provider.d.ts.map +1 -1
- package/dist/providers/base_provider.js +70 -2
- package/dist/providers/espresso.d.ts +1 -0
- package/dist/providers/espresso.d.ts.map +1 -1
- package/dist/providers/espresso.js +82 -35
- package/dist/providers/maestro.d.ts +21 -0
- package/dist/providers/maestro.d.ts.map +1 -1
- package/dist/providers/maestro.js +320 -72
- package/dist/providers/xcuitest.d.ts +1 -0
- package/dist/providers/xcuitest.d.ts.map +1 -1
- package/dist/providers/xcuitest.js +79 -35
- package/dist/ui/banner.d.ts +3 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +82 -0
- package/dist/ui/spinner.d.ts +32 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +92 -0
- package/dist/ui/terminal-title.d.ts +8 -0
- package/dist/ui/terminal-title.d.ts.map +1 -0
- package/dist/ui/terminal-title.js +57 -0
- package/dist/upload.d.ts +4 -0
- package/dist/upload.d.ts.map +1 -1
- package/dist/upload.js +70 -12
- package/dist/utils/connectivity.js +5 -3
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +10 -0
- package/package.json +5 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_crypto_1 = require("node:crypto");
|
|
3
4
|
class MaestroOptions {
|
|
4
5
|
static isIpaFile(app) {
|
|
5
6
|
return app?.toLowerCase().endsWith('.ipa') ?? false;
|
|
@@ -19,6 +20,9 @@ class MaestroOptions {
|
|
|
19
20
|
_geoCountryCode;
|
|
20
21
|
_env;
|
|
21
22
|
_maestroVersion;
|
|
23
|
+
// Tunnel
|
|
24
|
+
_tunnel;
|
|
25
|
+
_tunnelIdentifier;
|
|
22
26
|
_quiet;
|
|
23
27
|
_async;
|
|
24
28
|
_dryRun;
|
|
@@ -30,6 +34,7 @@ class MaestroOptions {
|
|
|
30
34
|
_ignoreChecksumCheck;
|
|
31
35
|
_shardSplit;
|
|
32
36
|
_debug;
|
|
37
|
+
_configFile;
|
|
33
38
|
// Metadata
|
|
34
39
|
_metadata;
|
|
35
40
|
constructor(app, flows, device, options) {
|
|
@@ -48,6 +53,12 @@ class MaestroOptions {
|
|
|
48
53
|
this._geoCountryCode = options?.geoCountryCode;
|
|
49
54
|
this._env = options?.env;
|
|
50
55
|
this._maestroVersion = options?.maestroVersion;
|
|
56
|
+
this._tunnel = options?.tunnel ?? false;
|
|
57
|
+
this._tunnelIdentifier =
|
|
58
|
+
options?.tunnelIdentifier ??
|
|
59
|
+
(this._tunnel
|
|
60
|
+
? `maestro-testing-${(0, node_crypto_1.randomUUID)().slice(0, 8)}`
|
|
61
|
+
: undefined);
|
|
51
62
|
this._quiet = options?.quiet ?? false;
|
|
52
63
|
this._async = options?.async ?? false;
|
|
53
64
|
this._dryRun = options?.dryRun ?? false;
|
|
@@ -61,6 +72,7 @@ class MaestroOptions {
|
|
|
61
72
|
this._ignoreChecksumCheck = options?.ignoreChecksumCheck ?? false;
|
|
62
73
|
this._shardSplit = options?.shardSplit;
|
|
63
74
|
this._debug = options?.debug ?? false;
|
|
75
|
+
this._configFile = options?.configFile;
|
|
64
76
|
this._metadata = options?.metadata;
|
|
65
77
|
}
|
|
66
78
|
get app() {
|
|
@@ -108,6 +120,12 @@ class MaestroOptions {
|
|
|
108
120
|
get maestroVersion() {
|
|
109
121
|
return this._maestroVersion;
|
|
110
122
|
}
|
|
123
|
+
get tunnel() {
|
|
124
|
+
return this._tunnel;
|
|
125
|
+
}
|
|
126
|
+
get tunnelIdentifier() {
|
|
127
|
+
return this._tunnelIdentifier;
|
|
128
|
+
}
|
|
111
129
|
get quiet() {
|
|
112
130
|
return this._quiet;
|
|
113
131
|
}
|
|
@@ -141,6 +159,9 @@ class MaestroOptions {
|
|
|
141
159
|
get debug() {
|
|
142
160
|
return this._debug;
|
|
143
161
|
}
|
|
162
|
+
get configFile() {
|
|
163
|
+
return this._configFile;
|
|
164
|
+
}
|
|
144
165
|
get metadata() {
|
|
145
166
|
return this._metadata;
|
|
146
167
|
}
|
|
@@ -189,9 +210,11 @@ class MaestroOptions {
|
|
|
189
210
|
if (this._timeZone)
|
|
190
211
|
caps.timeZone = this._timeZone;
|
|
191
212
|
if (this._throttleNetwork)
|
|
192
|
-
caps.
|
|
213
|
+
caps.throttle_network = this._throttleNetwork;
|
|
193
214
|
if (this._geoCountryCode)
|
|
194
|
-
caps.geoCountryCode = this._geoCountryCode;
|
|
215
|
+
caps['testingbot.geoCountryCode'] = this._geoCountryCode;
|
|
216
|
+
if (this._tunnelIdentifier)
|
|
217
|
+
caps.tunnelIdentifier = this._tunnelIdentifier;
|
|
195
218
|
if (this._realDevice)
|
|
196
219
|
caps.realDevice = 'true';
|
|
197
220
|
return caps;
|
|
@@ -22,13 +22,14 @@ export interface XCUITestCapabilities {
|
|
|
22
22
|
phoneOnly?: boolean;
|
|
23
23
|
name?: string;
|
|
24
24
|
build?: string;
|
|
25
|
+
'testingbot.geoCountryCode'?: string;
|
|
26
|
+
tunnelIdentifier?: string;
|
|
25
27
|
}
|
|
26
28
|
export interface XCUITestRunOptions {
|
|
27
29
|
orientation?: Orientation;
|
|
28
30
|
language?: string;
|
|
29
31
|
locale?: string;
|
|
30
32
|
timeZone?: string;
|
|
31
|
-
geoLocation?: string;
|
|
32
33
|
throttle_network?: ThrottleNetwork | CustomNetworkProfile;
|
|
33
34
|
}
|
|
34
35
|
export default class XCUITestOptions {
|
|
@@ -45,8 +46,10 @@ export default class XCUITestOptions {
|
|
|
45
46
|
private _language?;
|
|
46
47
|
private _locale?;
|
|
47
48
|
private _timeZone?;
|
|
48
|
-
private
|
|
49
|
+
private _geoCountryCode?;
|
|
49
50
|
private _throttleNetwork?;
|
|
51
|
+
private _tunnel;
|
|
52
|
+
private _tunnelIdentifier?;
|
|
50
53
|
private _quiet;
|
|
51
54
|
private _async;
|
|
52
55
|
private _dryRun;
|
|
@@ -64,8 +67,10 @@ export default class XCUITestOptions {
|
|
|
64
67
|
language?: string;
|
|
65
68
|
locale?: string;
|
|
66
69
|
timeZone?: string;
|
|
67
|
-
|
|
70
|
+
geoCountryCode?: string;
|
|
68
71
|
throttleNetwork?: ThrottleNetwork | CustomNetworkProfile;
|
|
72
|
+
tunnel?: boolean;
|
|
73
|
+
tunnelIdentifier?: string;
|
|
69
74
|
quiet?: boolean;
|
|
70
75
|
async?: boolean;
|
|
71
76
|
dryRun?: boolean;
|
|
@@ -86,8 +91,10 @@ export default class XCUITestOptions {
|
|
|
86
91
|
get language(): string | undefined;
|
|
87
92
|
get locale(): string | undefined;
|
|
88
93
|
get timeZone(): string | undefined;
|
|
89
|
-
get
|
|
94
|
+
get geoCountryCode(): string | undefined;
|
|
90
95
|
get throttleNetwork(): ThrottleNetwork | CustomNetworkProfile | undefined;
|
|
96
|
+
get tunnel(): boolean;
|
|
97
|
+
get tunnelIdentifier(): string | undefined;
|
|
91
98
|
get quiet(): boolean;
|
|
92
99
|
get async(): boolean;
|
|
93
100
|
get dryRun(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcuitest_options.d.ts","sourceRoot":"","sources":["../../src/models/xcuitest_options.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"xcuitest_options.d.ts","sourceRoot":"","sources":["../../src/models/xcuitest_options.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
7
|
const testingbot_error_1 = __importDefault(require("./testingbot_error"));
|
|
7
8
|
class XCUITestOptions {
|
|
8
9
|
_app;
|
|
@@ -21,9 +22,12 @@ class XCUITestOptions {
|
|
|
21
22
|
_locale;
|
|
22
23
|
_timeZone;
|
|
23
24
|
// Geolocation
|
|
24
|
-
|
|
25
|
+
_geoCountryCode;
|
|
25
26
|
// Network throttling
|
|
26
27
|
_throttleNetwork;
|
|
28
|
+
// Tunnel
|
|
29
|
+
_tunnel;
|
|
30
|
+
_tunnelIdentifier;
|
|
27
31
|
// Execution mode
|
|
28
32
|
_quiet;
|
|
29
33
|
_async;
|
|
@@ -50,8 +54,14 @@ class XCUITestOptions {
|
|
|
50
54
|
this._language = options?.language;
|
|
51
55
|
this._locale = options?.locale;
|
|
52
56
|
this._timeZone = options?.timeZone;
|
|
53
|
-
this.
|
|
57
|
+
this._geoCountryCode = options?.geoCountryCode;
|
|
54
58
|
this._throttleNetwork = options?.throttleNetwork;
|
|
59
|
+
this._tunnel = options?.tunnel ?? false;
|
|
60
|
+
this._tunnelIdentifier =
|
|
61
|
+
options?.tunnelIdentifier ??
|
|
62
|
+
(this._tunnel
|
|
63
|
+
? `xcuitest-testing-${(0, node_crypto_1.randomUUID)().slice(0, 8)}`
|
|
64
|
+
: undefined);
|
|
55
65
|
this._quiet = options?.quiet ?? false;
|
|
56
66
|
this._async = options?.async ?? false;
|
|
57
67
|
this._dryRun = options?.dryRun ?? false;
|
|
@@ -98,12 +108,18 @@ class XCUITestOptions {
|
|
|
98
108
|
get timeZone() {
|
|
99
109
|
return this._timeZone;
|
|
100
110
|
}
|
|
101
|
-
get
|
|
102
|
-
return this.
|
|
111
|
+
get geoCountryCode() {
|
|
112
|
+
return this._geoCountryCode;
|
|
103
113
|
}
|
|
104
114
|
get throttleNetwork() {
|
|
105
115
|
return this._throttleNetwork;
|
|
106
116
|
}
|
|
117
|
+
get tunnel() {
|
|
118
|
+
return this._tunnel;
|
|
119
|
+
}
|
|
120
|
+
get tunnelIdentifier() {
|
|
121
|
+
return this._tunnelIdentifier;
|
|
122
|
+
}
|
|
107
123
|
get quiet() {
|
|
108
124
|
return this._quiet;
|
|
109
125
|
}
|
|
@@ -139,6 +155,10 @@ class XCUITestOptions {
|
|
|
139
155
|
caps.name = this._name;
|
|
140
156
|
if (this._build)
|
|
141
157
|
caps.build = this._build;
|
|
158
|
+
if (this._geoCountryCode)
|
|
159
|
+
caps['testingbot.geoCountryCode'] = this._geoCountryCode;
|
|
160
|
+
if (this._tunnelIdentifier)
|
|
161
|
+
caps.tunnelIdentifier = this._tunnelIdentifier;
|
|
142
162
|
return caps;
|
|
143
163
|
}
|
|
144
164
|
getXCUITestOptions() {
|
|
@@ -153,9 +173,6 @@ class XCUITestOptions {
|
|
|
153
173
|
opts.locale = this._locale;
|
|
154
174
|
if (this._timeZone)
|
|
155
175
|
opts.timeZone = this._timeZone;
|
|
156
|
-
// Geolocation
|
|
157
|
-
if (this._geoLocation)
|
|
158
|
-
opts.geoLocation = this._geoLocation;
|
|
159
176
|
// Network throttling
|
|
160
177
|
if (this._throttleNetwork)
|
|
161
178
|
opts.throttle_network = this._throttleNetwork;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Credentials from '../models/credentials';
|
|
2
2
|
import TestingBotError from '../models/testingbot_error';
|
|
3
3
|
import Upload from '../upload';
|
|
4
|
+
import Spinner from '../ui/spinner';
|
|
4
5
|
/**
|
|
5
6
|
* Common interface for run information shared by all providers
|
|
6
7
|
*/
|
|
@@ -22,21 +23,33 @@ export interface BaseProviderOptions {
|
|
|
22
23
|
quiet?: boolean;
|
|
23
24
|
reportOutputDir?: string;
|
|
24
25
|
dryRun?: boolean;
|
|
26
|
+
tunnel?: boolean;
|
|
27
|
+
tunnelIdentifier?: string;
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
30
|
* Abstract base class for test providers (Espresso, XCUITest, Maestro)
|
|
28
31
|
* Contains common functionality shared across all providers.
|
|
29
32
|
*/
|
|
30
33
|
export default abstract class BaseProvider<TOptions extends BaseProviderOptions> {
|
|
31
|
-
protected readonly
|
|
32
|
-
protected readonly
|
|
34
|
+
protected readonly MIN_POLL_INTERVAL_MS: number;
|
|
35
|
+
protected readonly MAX_POLL_INTERVAL_MS: number;
|
|
36
|
+
protected readonly POLL_BACKOFF_MULTIPLIER: number;
|
|
37
|
+
protected readonly MAX_POLL_DURATION_MS: number;
|
|
38
|
+
/**
|
|
39
|
+
* Returns the next polling interval based on whether the status payload
|
|
40
|
+
* changed since the last poll. Resets to the minimum on change; otherwise
|
|
41
|
+
* multiplies the current interval by the backoff factor up to the maximum.
|
|
42
|
+
*/
|
|
43
|
+
protected computeNextPollInterval(currentIntervalMs: number, changed: boolean): number;
|
|
33
44
|
protected credentials: Credentials;
|
|
34
45
|
protected options: TOptions;
|
|
35
46
|
protected upload: Upload;
|
|
47
|
+
protected spinner: Spinner;
|
|
36
48
|
protected appId: number | undefined;
|
|
37
49
|
protected activeRunIds: number[];
|
|
38
50
|
protected isShuttingDown: boolean;
|
|
39
51
|
protected signalHandler: (() => void) | null;
|
|
52
|
+
private tunnelInstance;
|
|
40
53
|
/**
|
|
41
54
|
* The base URL for the provider's API endpoint
|
|
42
55
|
*/
|
|
@@ -54,10 +67,23 @@ export default abstract class BaseProvider<TOptions extends BaseProviderOptions>
|
|
|
54
67
|
* Removes signal handlers
|
|
55
68
|
*/
|
|
56
69
|
protected removeSignalHandlers(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Override hook for subclasses to stop any extra animation loops (e.g.
|
|
72
|
+
* Maestro's flow-table timer) during shutdown. Default is a no-op.
|
|
73
|
+
*/
|
|
74
|
+
protected stopAnimations(): void;
|
|
57
75
|
/**
|
|
58
76
|
* Handles graceful shutdown when interrupt signal is received
|
|
59
77
|
*/
|
|
60
78
|
protected handleShutdown(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Starts a TestingBot tunnel if the --tunnel option is enabled.
|
|
81
|
+
*/
|
|
82
|
+
protected startTunnel(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Stops the TestingBot tunnel if one is running.
|
|
85
|
+
*/
|
|
86
|
+
protected stopTunnel(): Promise<void>;
|
|
61
87
|
/**
|
|
62
88
|
* Stops all active test runs
|
|
63
89
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base_provider.d.ts","sourceRoot":"","sources":["../../src/providers/base_provider.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAGhD,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAEzD,OAAO,MAAM,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"base_provider.d.ts","sourceRoot":"","sources":["../../src/providers/base_provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,22 +10,40 @@ const utils_1 = __importDefault(require("../utils"));
|
|
|
10
10
|
const upload_1 = __importDefault(require("../upload"));
|
|
11
11
|
const platform_1 = __importDefault(require("../utils/platform"));
|
|
12
12
|
const logger_1 = __importDefault(require("../logger"));
|
|
13
|
+
const spinner_1 = __importDefault(require("../ui/spinner"));
|
|
14
|
+
const testingbot_tunnel_launcher_1 = require("testingbot-tunnel-launcher");
|
|
13
15
|
const error_helpers_1 = require("../utils/error-helpers");
|
|
14
16
|
const connectivity_1 = require("../utils/connectivity");
|
|
17
|
+
const constants_1 = require("../config/constants");
|
|
15
18
|
/**
|
|
16
19
|
* Abstract base class for test providers (Espresso, XCUITest, Maestro)
|
|
17
20
|
* Contains common functionality shared across all providers.
|
|
18
21
|
*/
|
|
19
22
|
class BaseProvider {
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
MIN_POLL_INTERVAL_MS = constants_1.POLLING.MIN_INTERVAL_MS;
|
|
24
|
+
MAX_POLL_INTERVAL_MS = constants_1.POLLING.MAX_INTERVAL_MS;
|
|
25
|
+
POLL_BACKOFF_MULTIPLIER = constants_1.POLLING.BACKOFF_MULTIPLIER;
|
|
26
|
+
MAX_POLL_DURATION_MS = constants_1.POLLING.MAX_DURATION_MS;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the next polling interval based on whether the status payload
|
|
29
|
+
* changed since the last poll. Resets to the minimum on change; otherwise
|
|
30
|
+
* multiplies the current interval by the backoff factor up to the maximum.
|
|
31
|
+
*/
|
|
32
|
+
computeNextPollInterval(currentIntervalMs, changed) {
|
|
33
|
+
if (changed) {
|
|
34
|
+
return this.MIN_POLL_INTERVAL_MS;
|
|
35
|
+
}
|
|
36
|
+
return Math.min(Math.round(currentIntervalMs * this.POLL_BACKOFF_MULTIPLIER), this.MAX_POLL_INTERVAL_MS);
|
|
37
|
+
}
|
|
22
38
|
credentials;
|
|
23
39
|
options;
|
|
24
40
|
upload;
|
|
41
|
+
spinner = new spinner_1.default();
|
|
25
42
|
appId = undefined;
|
|
26
43
|
activeRunIds = [];
|
|
27
44
|
isShuttingDown = false;
|
|
28
45
|
signalHandler = null;
|
|
46
|
+
tunnelInstance = null;
|
|
29
47
|
constructor(credentials, options) {
|
|
30
48
|
this.credentials = credentials;
|
|
31
49
|
this.options = options;
|
|
@@ -78,6 +96,11 @@ class BaseProvider {
|
|
|
78
96
|
this.signalHandler = null;
|
|
79
97
|
}
|
|
80
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Override hook for subclasses to stop any extra animation loops (e.g.
|
|
101
|
+
* Maestro's flow-table timer) during shutdown. Default is a no-op.
|
|
102
|
+
*/
|
|
103
|
+
stopAnimations() { }
|
|
81
104
|
/**
|
|
82
105
|
* Handles graceful shutdown when interrupt signal is received
|
|
83
106
|
*/
|
|
@@ -87,9 +110,12 @@ class BaseProvider {
|
|
|
87
110
|
process.exit(1);
|
|
88
111
|
}
|
|
89
112
|
this.isShuttingDown = true;
|
|
113
|
+
this.spinner.stop();
|
|
114
|
+
this.stopAnimations();
|
|
90
115
|
this.clearLine();
|
|
91
116
|
logger_1.default.info('Received interrupt signal, stopping test runs...');
|
|
92
117
|
this.stopActiveRuns()
|
|
118
|
+
.then(() => this.stopTunnel())
|
|
93
119
|
.then(() => {
|
|
94
120
|
logger_1.default.info('All test runs have been stopped.');
|
|
95
121
|
process.exit(1);
|
|
@@ -99,6 +125,48 @@ class BaseProvider {
|
|
|
99
125
|
process.exit(1);
|
|
100
126
|
});
|
|
101
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Starts a TestingBot tunnel if the --tunnel option is enabled.
|
|
130
|
+
*/
|
|
131
|
+
async startTunnel() {
|
|
132
|
+
if (!this.options.tunnel)
|
|
133
|
+
return;
|
|
134
|
+
if (!this.options.quiet) {
|
|
135
|
+
logger_1.default.info('Starting TestingBot tunnel...');
|
|
136
|
+
}
|
|
137
|
+
const tunnelOptions = {
|
|
138
|
+
apiKey: this.credentials.userName,
|
|
139
|
+
apiSecret: this.credentials.accessKey,
|
|
140
|
+
};
|
|
141
|
+
if (this.options.tunnelIdentifier) {
|
|
142
|
+
tunnelOptions.tunnelIdentifier = this.options.tunnelIdentifier;
|
|
143
|
+
}
|
|
144
|
+
this.tunnelInstance = await (0, testingbot_tunnel_launcher_1.downloadAndRunAsync)(tunnelOptions);
|
|
145
|
+
if (!this.options.quiet) {
|
|
146
|
+
logger_1.default.info('TestingBot tunnel is running.');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Stops the TestingBot tunnel if one is running.
|
|
151
|
+
*/
|
|
152
|
+
async stopTunnel() {
|
|
153
|
+
if (!this.tunnelInstance)
|
|
154
|
+
return;
|
|
155
|
+
if (!this.options.quiet) {
|
|
156
|
+
logger_1.default.info('Stopping TestingBot tunnel...');
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
await (0, testingbot_tunnel_launcher_1.killAsync)();
|
|
160
|
+
this.tunnelInstance = null;
|
|
161
|
+
if (!this.options.quiet) {
|
|
162
|
+
logger_1.default.info('TestingBot tunnel stopped.');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
logger_1.default.error(`Failed to stop tunnel: ${error instanceof Error ? error.message : error}`);
|
|
167
|
+
this.tunnelInstance = null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
102
170
|
/**
|
|
103
171
|
* Stops all active test runs
|
|
104
172
|
*/
|
|
@@ -36,6 +36,7 @@ export default class Espresso extends BaseProvider<EspressoOptions> {
|
|
|
36
36
|
private socket;
|
|
37
37
|
private updateServer;
|
|
38
38
|
private updateKey;
|
|
39
|
+
private socketFallbackWarned;
|
|
39
40
|
constructor(credentials: Credentials, options: EspressoOptions);
|
|
40
41
|
private validate;
|
|
41
42
|
run(): Promise<EspressoResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"espresso.d.ts","sourceRoot":"","sources":["../../src/providers/espresso.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAEzD,OAAO,WAAW,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"espresso.d.ts","sourceRoot":"","sources":["../../src/providers/espresso.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAEzD,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAQhD,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAChD,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,eAAe,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,YAAY,CAAC,eAAe,CAAC;IACjE,SAAS,CAAC,QAAQ,CAAC,GAAG,yDACkC;IAExD,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,oBAAoB,CAAS;gBAElB,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe;YAIvD,QAAQ;IAuCT,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;YA6G7B,SAAS;YAcT,aAAa;YAab,QAAQ;YA0DR,SAAS;YA4BT,iBAAiB;IA+F/B,OAAO,CAAC,gBAAgB;IA0CxB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,aAAa;YAkBP,YAAY;IAwD1B,OAAO,CAAC,qBAAqB;IA6C7B,OAAO,CAAC,0BAA0B;IAOlC,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,mBAAmB;CAa5B"}
|