@testingbot/cli 1.0.7 → 1.0.9
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 +29 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +79 -46
- 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 +7 -0
- package/dist/models/espresso_options.d.ts.map +1 -1
- package/dist/models/espresso_options.js +18 -0
- package/dist/models/maestro_options.d.ts +20 -2
- package/dist/models/maestro_options.d.ts.map +1 -1
- package/dist/models/maestro_options.js +38 -1
- package/dist/models/xcuitest_options.d.ts +7 -0
- package/dist/models/xcuitest_options.d.ts.map +1 -1
- package/dist/models/xcuitest_options.js +18 -0
- 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 +31 -0
- package/dist/providers/maestro.d.ts.map +1 -1
- package/dist/providers/maestro.js +399 -149
- 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,9 @@ class MaestroOptions {
|
|
|
30
34
|
_ignoreChecksumCheck;
|
|
31
35
|
_shardSplit;
|
|
32
36
|
_debug;
|
|
37
|
+
_configFile;
|
|
38
|
+
_groups;
|
|
39
|
+
_googlePlayStore;
|
|
33
40
|
// Metadata
|
|
34
41
|
_metadata;
|
|
35
42
|
constructor(app, flows, device, options) {
|
|
@@ -48,6 +55,12 @@ class MaestroOptions {
|
|
|
48
55
|
this._geoCountryCode = options?.geoCountryCode;
|
|
49
56
|
this._env = options?.env;
|
|
50
57
|
this._maestroVersion = options?.maestroVersion;
|
|
58
|
+
this._tunnel = options?.tunnel ?? false;
|
|
59
|
+
this._tunnelIdentifier =
|
|
60
|
+
options?.tunnelIdentifier ??
|
|
61
|
+
(this._tunnel
|
|
62
|
+
? `maestro-testing-${(0, node_crypto_1.randomUUID)().slice(0, 8)}`
|
|
63
|
+
: undefined);
|
|
51
64
|
this._quiet = options?.quiet ?? false;
|
|
52
65
|
this._async = options?.async ?? false;
|
|
53
66
|
this._dryRun = options?.dryRun ?? false;
|
|
@@ -61,6 +74,9 @@ class MaestroOptions {
|
|
|
61
74
|
this._ignoreChecksumCheck = options?.ignoreChecksumCheck ?? false;
|
|
62
75
|
this._shardSplit = options?.shardSplit;
|
|
63
76
|
this._debug = options?.debug ?? false;
|
|
77
|
+
this._configFile = options?.configFile;
|
|
78
|
+
this._groups = options?.groups;
|
|
79
|
+
this._googlePlayStore = options?.googlePlayStore ?? false;
|
|
64
80
|
this._metadata = options?.metadata;
|
|
65
81
|
}
|
|
66
82
|
get app() {
|
|
@@ -108,6 +124,12 @@ class MaestroOptions {
|
|
|
108
124
|
get maestroVersion() {
|
|
109
125
|
return this._maestroVersion;
|
|
110
126
|
}
|
|
127
|
+
get tunnel() {
|
|
128
|
+
return this._tunnel;
|
|
129
|
+
}
|
|
130
|
+
get tunnelIdentifier() {
|
|
131
|
+
return this._tunnelIdentifier;
|
|
132
|
+
}
|
|
111
133
|
get quiet() {
|
|
112
134
|
return this._quiet;
|
|
113
135
|
}
|
|
@@ -141,9 +163,18 @@ class MaestroOptions {
|
|
|
141
163
|
get debug() {
|
|
142
164
|
return this._debug;
|
|
143
165
|
}
|
|
166
|
+
get configFile() {
|
|
167
|
+
return this._configFile;
|
|
168
|
+
}
|
|
144
169
|
get metadata() {
|
|
145
170
|
return this._metadata;
|
|
146
171
|
}
|
|
172
|
+
get groups() {
|
|
173
|
+
return this._groups;
|
|
174
|
+
}
|
|
175
|
+
get googlePlayStore() {
|
|
176
|
+
return this._googlePlayStore;
|
|
177
|
+
}
|
|
147
178
|
getMaestroOptions() {
|
|
148
179
|
const opts = {};
|
|
149
180
|
if (this._includeTags && this._includeTags.length > 0) {
|
|
@@ -189,11 +220,17 @@ class MaestroOptions {
|
|
|
189
220
|
if (this._timeZone)
|
|
190
221
|
caps.timeZone = this._timeZone;
|
|
191
222
|
if (this._throttleNetwork)
|
|
192
|
-
caps.
|
|
223
|
+
caps.throttle_network = this._throttleNetwork;
|
|
193
224
|
if (this._geoCountryCode)
|
|
194
225
|
caps['testingbot.geoCountryCode'] = this._geoCountryCode;
|
|
226
|
+
if (this._tunnelIdentifier)
|
|
227
|
+
caps.tunnelIdentifier = this._tunnelIdentifier;
|
|
195
228
|
if (this._realDevice)
|
|
196
229
|
caps.realDevice = 'true';
|
|
230
|
+
if (this._groups && this._groups.length > 0)
|
|
231
|
+
caps.groups = this._groups;
|
|
232
|
+
if (this._googlePlayStore)
|
|
233
|
+
caps.googlePlayStore = true;
|
|
197
234
|
return caps;
|
|
198
235
|
}
|
|
199
236
|
}
|
|
@@ -23,6 +23,7 @@ export interface XCUITestCapabilities {
|
|
|
23
23
|
name?: string;
|
|
24
24
|
build?: string;
|
|
25
25
|
'testingbot.geoCountryCode'?: string;
|
|
26
|
+
tunnelIdentifier?: string;
|
|
26
27
|
}
|
|
27
28
|
export interface XCUITestRunOptions {
|
|
28
29
|
orientation?: Orientation;
|
|
@@ -47,6 +48,8 @@ export default class XCUITestOptions {
|
|
|
47
48
|
private _timeZone?;
|
|
48
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;
|
|
@@ -66,6 +69,8 @@ export default class XCUITestOptions {
|
|
|
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;
|
|
@@ -88,6 +93,8 @@ export default class XCUITestOptions {
|
|
|
88
93
|
get timeZone(): string | undefined;
|
|
89
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":"AAGA,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,WAAW,CAAC;AACnD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;AAC5C,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,KAAK,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IAEjC,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,gBAAgB,CAAC,EAAE,eAAe,GAAG,oBAAoB,CAAC;CAC3D;AAED,MAAM,CAAC,OAAO,OAAO,eAAe;IAClC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,MAAM,CAAC,CAAS;IAExB,OAAO,CAAC,YAAY,CAAC,CAAc;IAEnC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,SAAS,CAAC,CAAS;IAE3B,OAAO,CAAC,eAAe,CAAC,CAAS;IAEjC,OAAO,CAAC,gBAAgB,CAAC,CAAyC;IAElE,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,iBAAiB,CAAC,CAAS;IAEnC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAC,CAAe;IAC/B,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAElC,OAAO,CAAC,SAAS,CAAC,CAAc;gBAG9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,eAAe,GAAG,oBAAoB,CAAC;QACzD,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,WAAW,CAAC;KACxB;IAuCH,IAAW,GAAG,IAAI,MAAM,CAEvB;IAED,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED,IAAW,MAAM,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,IAAW,OAAO,IAAI,MAAM,GAAG,SAAS,CAEvC;IAED,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED,IAAW,IAAI,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAW,KAAK,IAAI,MAAM,GAAG,SAAS,CAErC;IAED,IAAW,WAAW,IAAI,WAAW,GAAG,SAAS,CAEhD;IAED,IAAW,QAAQ,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,IAAW,MAAM,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,IAAW,QAAQ,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,IAAW,cAAc,IAAI,MAAM,GAAG,SAAS,CAE9C;IAED,IAAW,eAAe,IACtB,eAAe,GACf,oBAAoB,GACpB,SAAS,CAEZ;IAED,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED,IAAW,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAEhD;IAED,IAAW,KAAK,IAAI,OAAO,CAE1B;IAED,IAAW,KAAK,IAAI,OAAO,CAE1B;IAED,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED,IAAW,MAAM,IAAI,YAAY,GAAG,SAAS,CAE5C;IAED,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAE/C;IAED,IAAW,QAAQ,IAAI,WAAW,GAAG,SAAS,CAE7C;IAEM,eAAe,IAAI,oBAAoB;IAmBvC,kBAAkB,IAAI,kBAAkB,GAAG,SAAS;CAc5D"}
|
|
@@ -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;
|
|
@@ -24,6 +25,9 @@ class XCUITestOptions {
|
|
|
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;
|
|
@@ -52,6 +56,12 @@ class XCUITestOptions {
|
|
|
52
56
|
this._timeZone = options?.timeZone;
|
|
53
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;
|
|
@@ -104,6 +114,12 @@ class XCUITestOptions {
|
|
|
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
|
}
|
|
@@ -141,6 +157,8 @@ class XCUITestOptions {
|
|
|
141
157
|
caps.build = this._build;
|
|
142
158
|
if (this._geoCountryCode)
|
|
143
159
|
caps['testingbot.geoCountryCode'] = this._geoCountryCode;
|
|
160
|
+
if (this._tunnelIdentifier)
|
|
161
|
+
caps.tunnelIdentifier = this._tunnelIdentifier;
|
|
144
162
|
return caps;
|
|
145
163
|
}
|
|
146
164
|
getXCUITestOptions() {
|
|
@@ -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"}
|