@testim/testim-cli 3.253.0 → 3.255.0
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/OverrideTestDataBuilder.js +1 -1
- package/agent/routers/cliJsCode/index.js +4 -4
- package/agent/routers/cliJsCode/router.js +46 -42
- package/agent/routers/cliJsCode/service.js +18 -13
- package/agent/routers/codim/router.js +14 -17
- package/agent/routers/codim/router.test.js +19 -21
- package/agent/routers/codim/service.js +16 -16
- package/agent/routers/general/index.js +4 -8
- package/agent/routers/hybrid/registerRoutes.js +18 -18
- package/agent/routers/index.js +7 -7
- package/agent/routers/playground/router.js +11 -10
- package/agent/routers/playground/service.js +22 -23
- package/agent/routers/standalone-browser/registerRoutes.js +10 -10
- package/cdpTestRunner.js +4 -3
- package/chromiumInstaller.js +4 -5
- package/cli/onExit.js +2 -2
- package/cli.js +11 -10
- package/cliAgentMode.js +8 -8
- package/codim/codim-cli.js +20 -17
- package/codim/hybrid-utils.js +1 -1
- package/codim/measure-perf.js +9 -6
- package/codim/template.js/tests/examples/01-simple-text-validation.test.js +6 -6
- package/codim/template.js/tests/examples/02-using-locators.test.js +13 -15
- package/codim/template.js/tests/examples/03-using-hooks.test.js +17 -19
- package/codim/template.js/tests/examples/04-skip-and-only.test.js +16 -17
- package/codim/template.js/tests/examples/05-multiple-windows.test.js +16 -17
- package/codim/template.js/webpack.config.js +1 -1
- package/codim/template.ts/webpack.config.js +3 -3
- package/commons/AbortError.js +4 -4
- package/commons/detectDebugger.js +4 -2
- package/commons/featureFlags.js +8 -0
- package/commons/httpRequest.js +5 -1
- package/commons/httpRequestCounters.js +21 -10
- package/commons/lazyRequire.js +14 -12
- package/commons/logger.js +4 -4
- package/commons/performance-logger.js +14 -8
- package/commons/preloadTests.js +2 -2
- package/commons/prepareRunner.js +4 -2
- package/commons/prepareRunnerAndTestimStartUtils.js +40 -42
- package/commons/runnerFileCache.js +1 -1
- package/commons/socket/baseSocketServiceSocketIO.js +32 -34
- package/commons/socket/realDataService.js +6 -5
- package/commons/socket/realDataServiceSocketIO.js +4 -4
- package/commons/socket/remoteStepService.js +4 -3
- package/commons/socket/remoteStepServiceSocketIO.js +11 -12
- package/commons/socket/socketService.js +50 -52
- package/commons/socket/testResultServiceSocketIO.js +11 -11
- package/commons/testimDesiredCapabilitiesBuilder.js +3 -2
- package/commons/testimNgrok.js +2 -2
- package/commons/testimNgrok.test.js +1 -1
- package/commons/testimServicesApi.js +27 -20
- package/commons/testimTunnel.test.js +2 -1
- package/commons/xhr2.js +97 -100
- package/coverage/SummaryToObjectReport.js +0 -1
- package/coverage/jsCoverage.js +12 -10
- package/errors.js +5 -0
- package/fixLocalBuild.js +2 -0
- package/inputFileUtils.js +11 -9
- package/npm-shrinkwrap.json +2286 -1284
- package/package.json +9 -8
- package/player/appiumTestPlayer.js +1 -1
- package/player/chromeLauncherTestPlayer.js +0 -1
- package/player/services/tabService.js +15 -1
- package/player/services/tabServiceMock.js +166 -0
- package/player/stepActions/locateStepAction.js +2 -0
- package/player/stepActions/navigationStepAction.js +11 -10
- package/player/stepActions/sleepStepAction.js +4 -5
- package/player/stepActions/textStepAction.js +4 -11
- package/player/utils/imageCaptureUtils.js +81 -120
- package/player/utils/windowUtils.js +4 -3
- package/player/webdriver.js +26 -23
- package/processHandler.js +3 -3
- package/processHandler.test.js +1 -1
- package/reports/consoleReporter.js +3 -2
- package/reports/junitReporter.js +7 -9
- package/reports/reporter.js +34 -39
- package/runOptions.d.ts +260 -0
- package/runOptions.js +59 -44
- package/runner.js +14 -0
- package/runners/ParallelWorkerManager.js +9 -10
- package/runners/TestPlanRunner.js +142 -78
- package/runners/buildCodeTests.js +38 -37
- package/runners/runnerUtils.js +3 -3
- package/services/gridService.js +36 -40
- package/services/lambdatestService.js +3 -5
- package/stepPlayers/cliJsStepPlayback.js +22 -17
- package/testRunHandler.js +8 -0
- package/testRunStatus.js +9 -6
- package/utils/argsUtils.js +86 -0
- package/utils/argsUtils.test.js +32 -0
- package/utils/fsUtils.js +154 -0
- package/{utils.js → utils/index.js} +19 -262
- package/utils/promiseUtils.js +89 -0
- package/utils/stringUtils.js +98 -0
- package/utils/stringUtils.test.js +22 -0
- package/utils/timeUtils.js +25 -0
- package/utils/utils.test.js +27 -0
- package/workers/BaseWorker.js +16 -14
- package/workers/WorkerAppium.js +1 -1
- package/workers/WorkerExtension.js +6 -7
- package/workers/WorkerExtensionSingleBrowser.js +4 -4
- package/workers/WorkerSelenium.js +5 -2
- package/utils.test.js +0 -68
|
@@ -96,7 +96,7 @@ function memoize(fn, fnName, duration = THREE_HOURS, parameters = undefined) {
|
|
|
96
96
|
}
|
|
97
97
|
logger.debug('cache miss:', { fnName });
|
|
98
98
|
if (!cacheMissAllowed) {
|
|
99
|
-
throw new Error(`
|
|
99
|
+
throw new Error(`Attempted to rebuild cache for ${originalFnName}. cache miss is not allowed with current run configuration`);
|
|
100
100
|
}
|
|
101
101
|
const value = await fn();
|
|
102
102
|
if (value) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const Promise = require('bluebird');
|
|
4
4
|
const pRetry = require('p-retry');
|
|
@@ -10,22 +10,21 @@ const MAX_RECONNECT_ATTEMPT_BEFORE_SWITCH = 10;
|
|
|
10
10
|
const EMIT_PROMISE_TIMEOUT = 5000;
|
|
11
11
|
const POLLING_TRANSPORT_TIMEOUT_MS = 10 * 1000;
|
|
12
12
|
|
|
13
|
-
const logger = require('../logger').getLogger(
|
|
13
|
+
const logger = require('../logger').getLogger('base socket service');
|
|
14
14
|
|
|
15
15
|
class BaseSocketServiceSocketIO {
|
|
16
|
-
|
|
17
16
|
constructor() {
|
|
18
17
|
this.attempts = 0;
|
|
19
18
|
this.rooms = {};
|
|
20
|
-
this.
|
|
19
|
+
this.emitPromiseQueue = undefined;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
joinToMultipleResults() {
|
|
24
23
|
const testResultIds = Object.keys(this.rooms);
|
|
25
|
-
logger.info(
|
|
26
|
-
testResultIds.
|
|
24
|
+
logger.info('re-join all existing rooms', { testResultIds });
|
|
25
|
+
testResultIds.forEach(resultId => {
|
|
27
26
|
const testId = this.rooms[resultId];
|
|
28
|
-
this.emitJoinRoom
|
|
27
|
+
this.emitJoinRoom?.(resultId, testId);
|
|
29
28
|
});
|
|
30
29
|
}
|
|
31
30
|
|
|
@@ -43,20 +42,22 @@ class BaseSocketServiceSocketIO {
|
|
|
43
42
|
try {
|
|
44
43
|
transport = this._socket.io.engine.transport.name;
|
|
45
44
|
} catch (e) {
|
|
45
|
+
/* empty */
|
|
46
46
|
}
|
|
47
|
-
logger.error(`Error in SocketService websocket _${method}_ socket ${this._socket.id}
|
|
47
|
+
logger.error(`Error in SocketService websocket _${method}_ socket ${this._socket.id} ` +
|
|
48
|
+
`is ${this.url} over ${transport}. Reconnect attempts ${this.attempts}. Error is: ${err?.message}`);
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
this._socket.on('reconnect_attempt', (attempt) => {
|
|
51
|
-
socketError('reconnect_attempt', {message: 'reconnect attempt', attempt});
|
|
52
|
+
socketError('reconnect_attempt', { message: 'reconnect attempt', attempt });
|
|
52
53
|
this.attempts++;
|
|
53
54
|
if (this.attempts === MAX_RECONNECT_ATTEMPT_BEFORE_SWITCH && !this.isAllowedWS) {
|
|
54
55
|
this._socket.io.opts.transports = ['polling'];
|
|
55
56
|
this._socket.io.opts.upgrade = false;
|
|
56
57
|
}
|
|
57
58
|
if (this.attempts >= MAX_SOCKET_RECONNECT_ATTEMPT) {
|
|
58
|
-
throw new Error(
|
|
59
|
-
|
|
59
|
+
throw new Error('Can\'t connect to Testim Servers.\n' +
|
|
60
|
+
`Action required: Please allow opening a websockets connection to ${config.SERVICES_HOST} in your firewall/proxy`);
|
|
60
61
|
}
|
|
61
62
|
});
|
|
62
63
|
|
|
@@ -81,14 +82,14 @@ class BaseSocketServiceSocketIO {
|
|
|
81
82
|
});
|
|
82
83
|
|
|
83
84
|
this._socket.on('reconnect', () => {
|
|
84
|
-
logger.info(
|
|
85
|
+
logger.info('reconnect to socket and re-join to rooms');
|
|
85
86
|
this.joinToMultipleResults();
|
|
86
87
|
});
|
|
87
88
|
|
|
88
89
|
this._socket.on('connect', () => {
|
|
89
90
|
this.attempts = 0;
|
|
90
|
-
if(this.isAllowedWS === undefined) {
|
|
91
|
-
this.isAllowedWS = this._socket.io.engine.transport && this._socket.io.engine.transport.name ===
|
|
91
|
+
if (this.isAllowedWS === undefined) {
|
|
92
|
+
this.isAllowedWS = this._socket.io.engine.transport && this._socket.io.engine.transport.name === 'websocket';
|
|
92
93
|
}
|
|
93
94
|
if (this.onConnect) {
|
|
94
95
|
this.onConnect();
|
|
@@ -98,7 +99,7 @@ class BaseSocketServiceSocketIO {
|
|
|
98
99
|
|
|
99
100
|
initNewSocket(projectId, ns) {
|
|
100
101
|
const opts = {
|
|
101
|
-
query: {
|
|
102
|
+
query: { projectId },
|
|
102
103
|
requestTimeout: POLLING_TRANSPORT_TIMEOUT_MS,
|
|
103
104
|
transports: ['websocket'],
|
|
104
105
|
upgrade: false,
|
|
@@ -125,7 +126,7 @@ class BaseSocketServiceSocketIO {
|
|
|
125
126
|
|
|
126
127
|
init(projectId, ns) {
|
|
127
128
|
const opts = {
|
|
128
|
-
query: {
|
|
129
|
+
query: { projectId },
|
|
129
130
|
requestTimeout: POLLING_TRANSPORT_TIMEOUT_MS,
|
|
130
131
|
transports: ['websocket'],
|
|
131
132
|
upgrade: false,
|
|
@@ -136,7 +137,7 @@ class BaseSocketServiceSocketIO {
|
|
|
136
137
|
opts.ca = global.caFileContent;
|
|
137
138
|
}
|
|
138
139
|
|
|
139
|
-
if(global.proxyUri) {
|
|
140
|
+
if (global.proxyUri) {
|
|
140
141
|
opts.agent = new global.ProxyAgent(global.proxyUri);
|
|
141
142
|
}
|
|
142
143
|
|
|
@@ -146,23 +147,20 @@ class BaseSocketServiceSocketIO {
|
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
emitPromise(eventName, eventData) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const emitAndWait = () => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
});
|
|
162
|
-
}).timeout(EMIT_PROMISE_TIMEOUT);
|
|
163
|
-
};
|
|
150
|
+
const errorneousEvents = {};
|
|
151
|
+
|
|
152
|
+
const emitAndWait = () => new Promise((resolve, reject) => {
|
|
153
|
+
this._socket.emit(eventName, eventData, data => {
|
|
154
|
+
if (data?.success) {
|
|
155
|
+
return resolve();
|
|
156
|
+
}
|
|
157
|
+
errorneousEvents[eventName] = eventData;
|
|
158
|
+
|
|
159
|
+
return reject(new Error('bad ack'));
|
|
160
|
+
});
|
|
161
|
+
}).timeout(EMIT_PROMISE_TIMEOUT);
|
|
164
162
|
|
|
165
|
-
this.
|
|
163
|
+
this.emitPromiseQueue = (this.emitPromiseQueue || Promise.resolve())
|
|
166
164
|
.then(() => pRetry(emitAndWait, { retries: 200, minTimeout: 3000 }))
|
|
167
165
|
.finally(() => {
|
|
168
166
|
if (Object.keys(errorneousEvents).length > 0) {
|
|
@@ -170,7 +168,7 @@ class BaseSocketServiceSocketIO {
|
|
|
170
168
|
}
|
|
171
169
|
});
|
|
172
170
|
|
|
173
|
-
return this.
|
|
171
|
+
return this.emitPromiseQueue;
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const RealDataServiceSocketIO = require('./realDataServiceSocketIO');
|
|
4
4
|
const socketService = require('./socketService');
|
|
5
5
|
|
|
6
|
-
const {socketEventTypes} = require('../constants');
|
|
6
|
+
const { socketEventTypes } = require('../constants');
|
|
7
7
|
const featureFlags = require('../featureFlags');
|
|
8
8
|
|
|
9
|
-
const {TEST_RESULT_CREATED, TEST_RESULT_UPDATED} = socketEventTypes;
|
|
9
|
+
const { TEST_RESULT_CREATED, TEST_RESULT_UPDATED } = socketEventTypes;
|
|
10
10
|
|
|
11
11
|
class RealDataService {
|
|
12
12
|
constructor() {
|
|
@@ -25,12 +25,13 @@ class RealDataService {
|
|
|
25
25
|
|
|
26
26
|
joinToTestResultsByRunId(runId, projectId) {
|
|
27
27
|
if (featureFlags.flags.useNewWSCLI.isEnabled()) {
|
|
28
|
-
return socketService.addFilter(runId, {runId}, [
|
|
28
|
+
return socketService.addFilter(runId, { runId }, [
|
|
29
29
|
TEST_RESULT_UPDATED,
|
|
30
|
-
TEST_RESULT_CREATED
|
|
30
|
+
TEST_RESULT_CREATED,
|
|
31
31
|
], true);
|
|
32
32
|
}
|
|
33
33
|
this.realDataServiceSocketIO.joinToTestResultsByRunId(runId, projectId);
|
|
34
|
+
return undefined;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
stopListenToTestResultsByRunId(runId) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const BaseSocketService = require('./baseSocketServiceSocketIO');
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ class RealDataServiceSocketIO extends BaseSocketService {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
emitJoinRoom(runId, projectId) {
|
|
11
|
-
this._socket.emit(
|
|
11
|
+
this._socket.emit('testResult:listen', { query: `projectId=${projectId}&runId=${runId}` });
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
joinToTestResultsByRunId(runId, projectId) {
|
|
@@ -18,7 +18,7 @@ class RealDataServiceSocketIO extends BaseSocketService {
|
|
|
18
18
|
|
|
19
19
|
stopListenToTestResultsByRunId(runId) {
|
|
20
20
|
this.leaveRoom(runId);
|
|
21
|
-
this._socket.emit(
|
|
21
|
+
this._socket.emit('testResult:listen:stop', {});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
listenToTestResultsByRunId(cb) {
|
|
@@ -26,7 +26,7 @@ class RealDataServiceSocketIO extends BaseSocketService {
|
|
|
26
26
|
cb(data.data);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
this._socket.on(
|
|
29
|
+
this._socket.on('testResult:changes', onDone.bind(this));
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
let remoteStepServiceSocketIO; // required lazily since it takes 150ms to load
|
|
2
2
|
const socketService = require('./socketService');
|
|
3
3
|
|
|
4
|
-
const {socketEventTypes} = require('../constants');
|
|
5
|
-
|
|
4
|
+
const { socketEventTypes } = require('../constants');
|
|
5
|
+
|
|
6
|
+
const { REMOTE_STEP_SAVED } = socketEventTypes;
|
|
6
7
|
const featureFlags = require('../featureFlags');
|
|
7
8
|
const Promise = require('bluebird');
|
|
8
9
|
|
|
@@ -17,7 +18,7 @@ class RemoteStepService {
|
|
|
17
18
|
|
|
18
19
|
joinToRemoteStep(resultId) {
|
|
19
20
|
if (featureFlags.flags.useNewWSCLI.isEnabled()) {
|
|
20
|
-
return socketService.addFilter(`${resultId}:remoteStep`, {resultId}, [REMOTE_STEP_SAVED]);
|
|
21
|
+
return socketService.addFilter(`${resultId}:remoteStep`, { resultId }, [REMOTE_STEP_SAVED]);
|
|
21
22
|
}
|
|
22
23
|
return remoteStepServiceSocketIO.joinToRemoteStep(resultId);
|
|
23
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const Promise = require('bluebird');
|
|
4
4
|
const BaseSocketService = require('./baseSocketServiceSocketIO');
|
|
@@ -10,15 +10,15 @@ class RemoteStepServiceSocketIO extends BaseSocketService {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
emitJoinRoom(resultId) {
|
|
13
|
-
return this.emitPromise(
|
|
13
|
+
return this.emitPromise('remoteStep:join', { resultId });
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
emitLeaveRoom(resultId) {
|
|
17
|
-
return this.emitPromise(
|
|
17
|
+
return this.emitPromise('remoteStep:leave', { resultId });
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
joinToRemoteStep(resultId) {
|
|
21
|
-
if(this.rooms[resultId]) {
|
|
21
|
+
if (this.rooms[resultId]) {
|
|
22
22
|
return Promise.resolve();
|
|
23
23
|
}
|
|
24
24
|
this.joinRoom(resultId);
|
|
@@ -26,17 +26,16 @@ class RemoteStepServiceSocketIO extends BaseSocketService {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
saveRemoteStep(resultId, stepId, remoteStep) {
|
|
29
|
-
return this.emitPromise(
|
|
29
|
+
return this.emitPromise('remoteStep:save', {
|
|
30
30
|
resultId,
|
|
31
31
|
stepId,
|
|
32
|
-
remoteStep
|
|
32
|
+
remoteStep,
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
listenToRemoteStep(resultId, onRemoteStep) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this._socket.off("remoteStep:saved", this.listerers[resultId]);
|
|
37
|
+
if (this.listerers[resultId]) {
|
|
38
|
+
this._socket.off('remoteStep:saved', this.listerers[resultId]);
|
|
40
39
|
delete this.listerers[resultId];
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -45,16 +44,16 @@ class RemoteStepServiceSocketIO extends BaseSocketService {
|
|
|
45
44
|
onRemoteStep(data.remoteStep);
|
|
46
45
|
}
|
|
47
46
|
};
|
|
48
|
-
this._socket.on(
|
|
47
|
+
this._socket.on('remoteStep:saved', this.listerers[resultId]);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
unlistenToRemoteStep(resultId) {
|
|
52
|
-
if(!this.listerers[resultId]) {
|
|
51
|
+
if (!this.listerers[resultId]) {
|
|
53
52
|
return Promise.resolve();
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
this.leaveRoom(resultId);
|
|
57
|
-
this._socket.off(
|
|
56
|
+
this._socket.off('remoteStep:saved', this.listerers[resultId]);
|
|
58
57
|
delete this.listerers[resultId];
|
|
59
58
|
return this.emitLeaveRoom(resultId);
|
|
60
59
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const WebSocket = require('ws');
|
|
4
|
-
const {WEBSOCKET_HOST} = require('../config');
|
|
4
|
+
const { WEBSOCKET_HOST } = require('../config');
|
|
5
5
|
const utils = require('../../utils');
|
|
6
|
-
const logger = require('../logger').getLogger(
|
|
7
|
-
const {EventEmitter} = require('events');
|
|
6
|
+
const logger = require('../logger').getLogger('socket-ng-service');
|
|
7
|
+
const { EventEmitter } = require('events');
|
|
8
8
|
const _ = require('lodash');
|
|
9
9
|
const Promise = require('bluebird');
|
|
10
10
|
const testimCustomToken = require('../testimCustomToken');
|
|
@@ -21,16 +21,16 @@ class SocketService extends EventEmitter {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
onReconnect(projectId) {
|
|
24
|
-
logger.info(
|
|
24
|
+
logger.info('test result websocket re-connect');
|
|
25
25
|
setTimeout(() => this.connect(projectId), WAIT_BETWEEN_RECONNECT_MS);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
formatUrl(url) {
|
|
29
|
-
if(_.startsWith(url,
|
|
29
|
+
if (_.startsWith(url, 'http://')) {
|
|
30
30
|
return _.replace(url, 'http://', 'ws://');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if(_.startsWith(url,
|
|
33
|
+
if (_.startsWith(url, 'https://')) {
|
|
34
34
|
return _.replace(url, 'https://', 'wss://');
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -41,50 +41,48 @@ class SocketService extends EventEmitter {
|
|
|
41
41
|
try {
|
|
42
42
|
return JSON.parse(event);
|
|
43
43
|
} catch (err) {
|
|
44
|
-
logger.error(
|
|
44
|
+
logger.error('failed to parse or trigger event', { err });
|
|
45
45
|
}
|
|
46
|
+
return undefined;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
49
|
connect(projectId) {
|
|
50
50
|
const wsBaseUrl = this.formatUrl(WEBSOCKET_HOST);
|
|
51
51
|
return testimCustomToken.getCustomTokenV3()
|
|
52
|
-
.then(token => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
.then(token => new Promise((resolve) => {
|
|
53
|
+
const options = {};
|
|
54
|
+
if (global.proxyUri) {
|
|
55
|
+
options.agent = new global.ProxyAgent(global.proxyUri);
|
|
56
|
+
}
|
|
57
|
+
this.ws = new WebSocket(`${wsBaseUrl}?projectId=${projectId}&clientId=${this.clientId}&token=${token}`, options);
|
|
58
|
+
|
|
59
|
+
this.ws.on('open', () => {
|
|
60
|
+
logger.info('websocket opened');
|
|
61
|
+
this.reSendAllExistingFilters();
|
|
62
|
+
if (this.onConnect) {
|
|
63
|
+
this.onConnect();
|
|
64
|
+
}
|
|
65
|
+
return resolve();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.ws.on('close', (event) => {
|
|
69
|
+
logger.info('websocket closed', { event });
|
|
70
|
+
if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
|
|
71
|
+
this.onReconnect(projectId, token, wsBaseUrl);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
this.ws.on('error', (event) => {
|
|
76
|
+
logger.info('websocket error', { event });
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
this.ws.on('message', (event) => {
|
|
80
|
+
const evObject = this.parseEvent(event);
|
|
81
|
+
if (evObject?.type) {
|
|
82
|
+
this.emit(evObject.type, evObject.data);
|
|
57
83
|
}
|
|
58
|
-
this.ws = new WebSocket(`${wsBaseUrl}?projectId=${projectId}&clientId=${this.clientId}&token=${token}`, options);
|
|
59
|
-
|
|
60
|
-
this.ws.on("open", () => {
|
|
61
|
-
logger.info(`websocket opened`);
|
|
62
|
-
this.reSendAllExistingFilters();
|
|
63
|
-
if (this.onConnect) {
|
|
64
|
-
this.onConnect();
|
|
65
|
-
}
|
|
66
|
-
return resolve();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
this.ws.on("close", (event) => {
|
|
70
|
-
logger.info(`websocket closed`, {event});
|
|
71
|
-
if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
|
|
72
|
-
this.onReconnect(projectId, token, wsBaseUrl);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
this.ws.on("error", (event) => {
|
|
77
|
-
logger.info(`websocket error`, {event});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
this.ws.on("message", (event) => {
|
|
81
|
-
const evObject = this.parseEvent(event);
|
|
82
|
-
if (evObject && evObject.type) {
|
|
83
|
-
this.emit(evObject.type, evObject.data);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
84
|
});
|
|
87
|
-
});
|
|
85
|
+
}));
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
// this is private because our sockets are supposed to be read-only to
|
|
@@ -99,7 +97,7 @@ class SocketService extends EventEmitter {
|
|
|
99
97
|
try {
|
|
100
98
|
this.ws.send(JSON.stringify(msg));
|
|
101
99
|
} catch (err) {
|
|
102
|
-
logger.error('failed to stringify message for sending', {err});
|
|
100
|
+
logger.error('failed to stringify message for sending', { err });
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
|
|
@@ -125,25 +123,25 @@ class SocketService extends EventEmitter {
|
|
|
125
123
|
const eventNameArray = Array.isArray(eventName) ? eventName : [eventName];
|
|
126
124
|
eventNameArray.forEach(name => {
|
|
127
125
|
this.listeners[`${key}:${name}`] = this.listeners[`${key}:${name}`] || [];
|
|
128
|
-
const
|
|
129
|
-
this.listeners[`${key}:${name}`].push(
|
|
130
|
-
this.on(name,
|
|
126
|
+
const _listener = fireIfSameMatchEventMatcher.bind(this);
|
|
127
|
+
this.listeners[`${key}:${name}`].push(_listener);
|
|
128
|
+
this.on(name, _listener);
|
|
131
129
|
});
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
reSendAllExistingFilters() {
|
|
135
133
|
Object.keys(this.filterMap).forEach(key => {
|
|
136
134
|
const filter = this.filterMap[key];
|
|
137
|
-
this.sendMessage({type:
|
|
135
|
+
this.sendMessage({ type: 'add-filter', filter });
|
|
138
136
|
});
|
|
139
137
|
}
|
|
140
138
|
|
|
141
139
|
addFilter(key, query, type, returnFullDocument = false) {
|
|
142
140
|
return new Promise(resolve => {
|
|
143
141
|
const filterId = utils.guid();
|
|
144
|
-
const filter = {query, id: filterId, type, fullDocument: returnFullDocument};
|
|
145
|
-
this.listenOnce(
|
|
146
|
-
this.sendMessage({type:
|
|
142
|
+
const filter = { query, id: filterId, type, fullDocument: returnFullDocument };
|
|
143
|
+
this.listenOnce('add-filter:done', data => data.id === filterId, resolve);
|
|
144
|
+
this.sendMessage({ type: 'add-filter', filter });
|
|
147
145
|
this.filterMap[key] = filter;
|
|
148
146
|
});
|
|
149
147
|
}
|
|
@@ -170,7 +168,7 @@ class SocketService extends EventEmitter {
|
|
|
170
168
|
const typeArray = Array.isArray(type) ? type : [type];
|
|
171
169
|
this.removeListeners(key, typeArray);
|
|
172
170
|
delete this.filterMap[key];
|
|
173
|
-
this.sendMessage({type:
|
|
171
|
+
this.sendMessage({ type: 'remove-filter', filter });
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const Promise = require('bluebird');
|
|
4
4
|
const BaseSocketService = require('./baseSocketServiceSocketIO');
|
|
@@ -10,8 +10,8 @@ class TestResultServiceSocketIO extends BaseSocketService {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
listenToTestResult(resultId, testId, onTestResultStatus) {
|
|
13
|
-
if(this.listerers[resultId]) {
|
|
14
|
-
this._socket.off(
|
|
13
|
+
if (this.listerers[resultId]) {
|
|
14
|
+
this._socket.off('testResult:updated', this.listerers[resultId]);
|
|
15
15
|
delete this.listerers[resultId];
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -21,18 +21,18 @@ class TestResultServiceSocketIO extends BaseSocketService {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
this._socket.on(
|
|
24
|
+
this._socket.on('testResult:updated', this.listerers[resultId]);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
emitJoinRoom(resultId, testId) {
|
|
28
|
-
return this.emitPromise(
|
|
28
|
+
return this.emitPromise('testResult:join', {
|
|
29
29
|
resultId,
|
|
30
|
-
testId
|
|
30
|
+
testId,
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
joinToTestResult(resultId, testId) {
|
|
35
|
-
if(this.rooms[resultId]) {
|
|
35
|
+
if (this.rooms[resultId]) {
|
|
36
36
|
return Promise.resolve();
|
|
37
37
|
}
|
|
38
38
|
this.joinRoom(resultId, testId);
|
|
@@ -40,19 +40,19 @@ class TestResultServiceSocketIO extends BaseSocketService {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
emitLeaveRoom(resultId, testId) {
|
|
43
|
-
return this.emitPromise(
|
|
43
|
+
return this.emitPromise('testResult:leave', {
|
|
44
44
|
resultId,
|
|
45
|
-
testId
|
|
45
|
+
testId,
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
leaveTestResult(resultId, testId) {
|
|
50
|
-
if(!this.listerers[resultId]) {
|
|
50
|
+
if (!this.listerers[resultId]) {
|
|
51
51
|
return Promise.resolve();
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
this.leaveRoom(resultId);
|
|
55
|
-
this._socket.off(
|
|
55
|
+
this._socket.off('testResult:updated', this.listerers[resultId]);
|
|
56
56
|
delete this.listerers[resultId];
|
|
57
57
|
return this.emitLeaveRoom(resultId, testId);
|
|
58
58
|
}
|
|
@@ -628,9 +628,10 @@ function buildAppiumOptions({ projectType, gridInfo, testRunConfig, nativeApp })
|
|
|
628
628
|
break;
|
|
629
629
|
case 'android':
|
|
630
630
|
appCaps = {
|
|
631
|
-
|
|
632
|
-
appActivity: nativeApp.activity,
|
|
631
|
+
platformName: 'Android',
|
|
633
632
|
'appium:automationName': 'UiAutomator2',
|
|
633
|
+
'appium:appPackage': nativeApp.packageName,
|
|
634
|
+
'appium:appActivity': nativeApp.activity,
|
|
634
635
|
};
|
|
635
636
|
break;
|
|
636
637
|
default:
|
package/commons/testimNgrok.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { ArgError } = require('../errors
|
|
4
|
-
const utils = require('../utils
|
|
3
|
+
const { ArgError } = require('../errors');
|
|
4
|
+
const utils = require('../utils');
|
|
5
5
|
const lazyRequire = require('./lazyRequire');
|
|
6
6
|
const logger = require('./logger').getLogger('testimNgrok');
|
|
7
7
|
|