@testim/testim-cli 3.215.0 → 3.216.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/agent/routers/cliJsCode/service.js +46 -85
- package/agent/routers/codim/service.js +0 -2
- package/cliAgentMode.js +0 -1
- package/codim/template.js/package.json +2 -2
- package/codim/template.ts/package.json +2 -2
- package/commons/featureFlags.js +1 -1
- package/commons/npmWrapper.js +14 -7
- package/commons/npmWrapper.test.js +1 -1
- package/commons/testimDesiredCapabilitiesBuilder.js +21 -0
- package/npm-shrinkwrap.json +21848 -6389
- package/package.json +7 -8
- package/player/services/tabService.js +28 -28
- package/player/utils/imageCaptureUtils.js +10 -1
- package/player/utils/screenshotUtils.js +1 -1
- package/services/lambdatestService.js +1 -0
- package/agent/routers/cliJsCode/runNpmWorker.js +0 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testim/testim-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.216.0",
|
|
4
4
|
"description": "Command line interface for running Testing on your CI",
|
|
5
5
|
"author": "Oren Rubin",
|
|
6
6
|
"contributors": [{
|
|
@@ -17,20 +17,19 @@
|
|
|
17
17
|
"@types/node": "10.17.24",
|
|
18
18
|
"@types/selenium-webdriver": "4.0.9",
|
|
19
19
|
"bundle-deps": "1.0.0",
|
|
20
|
-
"chai": "4.
|
|
20
|
+
"chai": "4.3.4",
|
|
21
21
|
"chai-as-promised": "7.1.1",
|
|
22
22
|
"gulp": "4.0.2",
|
|
23
23
|
"gulp-cli": "2.3.0",
|
|
24
24
|
"gulp-json-editor": "2.5.4",
|
|
25
25
|
"gulp-preprocess": "3.0.3",
|
|
26
|
-
"husky": "4.3.8",
|
|
27
26
|
"merge-stream": "2.0.0",
|
|
28
27
|
"mocha": "7.2.0",
|
|
29
28
|
"nyc": "15.1.0",
|
|
30
29
|
"proxyquire": "2.1.3",
|
|
31
|
-
"request": "2.88.
|
|
30
|
+
"request": "2.88.0",
|
|
32
31
|
"sinon": "9.0.2",
|
|
33
|
-
"sinon-chai": "3.
|
|
32
|
+
"sinon-chai": "3.7.0",
|
|
34
33
|
"ts-node": "8.10.1",
|
|
35
34
|
"tsconfig-paths": "3.9.0",
|
|
36
35
|
"typescript": "3.9.3"
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
"archiver": "3.1.1",
|
|
60
59
|
"bluebird": "3.7.2",
|
|
61
60
|
"bluebird-retry": "0.11.0",
|
|
62
|
-
"body-parser": "1.19.
|
|
61
|
+
"body-parser": "1.19.1",
|
|
63
62
|
"chalk": "4.1.0",
|
|
64
63
|
"chrome-launcher": "0.13.4",
|
|
65
64
|
"combine-source-map": "0.8.0",
|
|
@@ -86,7 +85,7 @@
|
|
|
86
85
|
"mkdirp": "1.0.4",
|
|
87
86
|
"moment": "2.25.3",
|
|
88
87
|
"ms": "2.1.2",
|
|
89
|
-
"npm": "
|
|
88
|
+
"npm": "8.3.0",
|
|
90
89
|
"object-hash": "2.0.3",
|
|
91
90
|
"ora": "4.0.4",
|
|
92
91
|
"pako": "1.0.11",
|
|
@@ -97,7 +96,7 @@
|
|
|
97
96
|
"rox-node": "4.9.18",
|
|
98
97
|
"semver": "7.3.2",
|
|
99
98
|
"serialize-error": "7.0.1",
|
|
100
|
-
"socket.io-client": "
|
|
99
|
+
"socket.io-client": "4.4.1",
|
|
101
100
|
"superagent": "3.8.3",
|
|
102
101
|
"superagent-proxy": "3.0.0",
|
|
103
102
|
"test-exclude": "6.0.0",
|
|
@@ -72,9 +72,9 @@ class TabService {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
getAllTabInfoStrings(sessionId) {
|
|
75
|
-
|
|
75
|
+
const allIds = this.getAllTabIds(sessionId);
|
|
76
76
|
return allIds.map(tabId => {
|
|
77
|
-
|
|
77
|
+
const tabInfo = this.getTabInfo(sessionId, tabId);
|
|
78
78
|
return `tabId=${tabId}, url=${tabInfo.url}, order=${tabInfo.order}, isMain=${tabInfo.isMain}, openerStepId=${tabInfo.openerStepId}, isClosed=${tabInfo.isClosed}, currentUrl: ${tabInfo.currentUrl}, lastUpdatedUrl: ${tabInfo.lastUpdatedUrl}`;
|
|
79
79
|
});
|
|
80
80
|
}
|
|
@@ -116,7 +116,7 @@ class TabService {
|
|
|
116
116
|
buildTabInfo(sessionId, tabId, order, openerStepId, options = {}) {
|
|
117
117
|
return this.getTabDetails(tabId, sessionId, options)
|
|
118
118
|
.then(tab => {
|
|
119
|
-
|
|
119
|
+
const infoId = guid();
|
|
120
120
|
|
|
121
121
|
function isMainTab(tabService) {
|
|
122
122
|
if (options.checkForMainTab) {
|
|
@@ -147,7 +147,7 @@ class TabService {
|
|
|
147
147
|
addTab(sessionId, id, order, openerStepId, options = {}) {
|
|
148
148
|
return this.buildTabInfo(sessionId, id, order, openerStepId, options)
|
|
149
149
|
.then(infoId => {
|
|
150
|
-
|
|
150
|
+
const _windowUtils = new WindowUtils(id, this.driver);
|
|
151
151
|
this._utils[infoId] = {
|
|
152
152
|
attachDebugger: () => Promise.resolve(),
|
|
153
153
|
detachDebugger: () => Promise.resolve(),
|
|
@@ -191,15 +191,15 @@ class TabService {
|
|
|
191
191
|
return this.getMainTabUtils(sessionId);
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
195
|
+
const nonMainTabs = Object.keys(infos)
|
|
196
196
|
.map(tabId => infos[tabId])
|
|
197
197
|
.filter(info => !info.isMain);
|
|
198
198
|
if (nonMainTabs.length === 1) {
|
|
199
199
|
return this._utils[nonMainTabs[0].infoId];
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
|
|
202
|
+
const sameTabs = Object.keys(sessionId)
|
|
203
203
|
.map(key => sessionId[key])
|
|
204
204
|
.filter(info => this.isSameTab(sessionId, tabInfo, info));
|
|
205
205
|
if (sameTabs.length > 0) {
|
|
@@ -211,7 +211,7 @@ class TabService {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
exactUrlMatch(first, second, allUrls) {
|
|
214
|
-
|
|
214
|
+
const exactUrlMatch = allUrls
|
|
215
215
|
.filter(url => url === second.url);
|
|
216
216
|
|
|
217
217
|
if ((first.url === second.url || first.currentUrl === second.url || (first.currentUrl && (first.currentUrl === second.currentUrl))) && (exactUrlMatch.length === 1)) {
|
|
@@ -221,11 +221,11 @@ class TabService {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
singleExactMatchForParts(first, second, allUrls, combinePartsFunction) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
224
|
+
const firstUrlParts = UrlUtils.urlBreaker(first.url || first.currentUrl);
|
|
225
|
+
const secondUrlParts = UrlUtils.urlBreaker(second.url || second.currentUrl);
|
|
226
|
+
const firstPartsCombined = combinePartsFunction(firstUrlParts);
|
|
227
|
+
const secondPartsCombined = combinePartsFunction(secondUrlParts);
|
|
228
|
+
const allDomainAndPathMatches = allUrls.map(url => UrlUtils.urlBreaker(url))
|
|
229
229
|
.map(urlParts => combinePartsFunction(urlParts))
|
|
230
230
|
.filter(combinedParts => combinedParts === firstPartsCombined);
|
|
231
231
|
if ((firstPartsCombined === secondPartsCombined) && (allDomainAndPathMatches.length === 1)) {
|
|
@@ -251,20 +251,20 @@ class TabService {
|
|
|
251
251
|
return true;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
255
|
+
const alltopFrameUrls = Object.keys(infos)
|
|
256
256
|
.map(tabId => infos[tabId].url);
|
|
257
257
|
|
|
258
258
|
if (this.exactUrlMatch(first, second, alltopFrameUrls)) {
|
|
259
259
|
return true;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
-
|
|
262
|
+
const combineDomainAndPath = urlParts => (`${urlParts.domain}/${urlParts.path.join('/')}`);
|
|
263
263
|
if (this.singleExactMatchForParts(first, second, alltopFrameUrls, combineDomainAndPath)) {
|
|
264
264
|
return true;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
const combineDomainPathAndHash = urlParts => (`${urlParts.domain}/${urlParts.path.join('/')}#${urlParts.hash}`);
|
|
268
268
|
if (this.singleExactMatchForParts(first, second, alltopFrameUrls, combineDomainPathAndHash)) {
|
|
269
269
|
return true;
|
|
270
270
|
}
|
|
@@ -277,14 +277,14 @@ class TabService {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
getMainTabInfo(sessionId) {
|
|
280
|
-
|
|
280
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
281
281
|
return Object.keys(infos)
|
|
282
282
|
.map(id => infos[id])
|
|
283
283
|
.find(tabInfo => tabInfo.isMain);
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
getMainTabUtils(sessionId) {
|
|
287
|
-
|
|
287
|
+
const mainTabInfo = this.getMainTabInfo(sessionId);
|
|
288
288
|
if (!mainTabInfo) {
|
|
289
289
|
return {};
|
|
290
290
|
}
|
|
@@ -292,20 +292,20 @@ class TabService {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
removeTabInfo(sessionId, tabId) {
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
296
|
+
const info = infos[tabId];
|
|
297
297
|
delete this.sessionTabs[sessionId].tabInfos[tabId];
|
|
298
298
|
delete this._utils[info.infoId];
|
|
299
299
|
this.sessionTabs[sessionId].tabCount--;
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
getMainTabId(sessionId) {
|
|
303
|
-
|
|
303
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
304
304
|
return Object.keys(infos).find(id => infos[id].isMain);
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
isMainTabExists(sessionId) {
|
|
308
|
-
|
|
308
|
+
const mainTabId = this.getMainTabId(sessionId);
|
|
309
309
|
if (!mainTabId) {
|
|
310
310
|
return Promise.resolve(false);
|
|
311
311
|
}
|
|
@@ -313,7 +313,7 @@ class TabService {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
clearAllTabs(sessionId) {
|
|
316
|
-
|
|
316
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
317
317
|
|
|
318
318
|
this.sessionTabs[sessionId].tabCount = 0;
|
|
319
319
|
Object.keys(infos)
|
|
@@ -321,7 +321,7 @@ class TabService {
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
clearNonMainTabs(sessionId) {
|
|
324
|
-
|
|
324
|
+
const infos = this.getAllTabInfos(sessionId);
|
|
325
325
|
Object.keys(infos)
|
|
326
326
|
.filter(tabId => !infos[tabId].isMain)
|
|
327
327
|
.forEach(tabId => this.removeTabInfo(sessionId, tabId));
|
|
@@ -414,9 +414,9 @@ class TabService {
|
|
|
414
414
|
}
|
|
415
415
|
|
|
416
416
|
waitToPendingTabs(id, openerStepId) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
417
|
+
const retryInterval = 500;
|
|
418
|
+
let timeToWait = 3000;
|
|
419
|
+
const that = this;
|
|
420
420
|
|
|
421
421
|
if (!openerStepId) {
|
|
422
422
|
return Promise.resolve();
|
|
@@ -186,18 +186,27 @@ ImageCaptureUtils.prototype = {
|
|
|
186
186
|
},
|
|
187
187
|
|
|
188
188
|
takeAreaDataUrl(areas, format) {
|
|
189
|
+
// Future changes in clickim will pass parameters to this function as a single object
|
|
190
|
+
if (areas.areas) {
|
|
191
|
+
areas = areas.areas;
|
|
192
|
+
}
|
|
193
|
+
|
|
189
194
|
return this.screenshotUtils.takeScreenshot(format)
|
|
190
195
|
.then((imageInfo) => cropImageFromImageData(areas, imageInfo).then((result) => {
|
|
191
196
|
result.screenImage = imageInfo.image;
|
|
192
197
|
result.absoluteScreenHighlight = getElementAbsoluteRectangle(
|
|
193
198
|
areas.elementRect,
|
|
194
199
|
imageInfo.devicePixelRatio);
|
|
195
|
-
|
|
196
200
|
return Promise.resolve(result);
|
|
197
201
|
}));
|
|
198
202
|
},
|
|
199
203
|
|
|
200
204
|
takeArea(areas) {
|
|
205
|
+
// Future changes in clickim will pass parameters to this function as a single object
|
|
206
|
+
if (areas.areas) {
|
|
207
|
+
areas = areas.areas;
|
|
208
|
+
}
|
|
209
|
+
|
|
201
210
|
return this.screenshotUtils.takeScreenshot()
|
|
202
211
|
.then((imageInfo) => {
|
|
203
212
|
const result = {};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module.exports = function (input) {
|
|
2
|
-
const {transactionId, packages, command, localPackageInstallFolder, proxyUri} = input;
|
|
3
|
-
return installLocalPackages(transactionId, packages, command, localPackageInstallFolder, proxyUri);
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const npm = require("npm");
|
|
8
|
-
const {NpmPackageError} = require('../../../errors');
|
|
9
|
-
|
|
10
|
-
function installLocalPackages(transactionId, packages, command, localPackageInstallFolder, proxyUri) {
|
|
11
|
-
if (!packages || packages.length === 0) {
|
|
12
|
-
return Promise.resolve();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const installFolder = path.join(localPackageInstallFolder, `/${transactionId}`);
|
|
16
|
-
|
|
17
|
-
return new Promise((resolve, reject) => {
|
|
18
|
-
const npmLoadConfig = {
|
|
19
|
-
prefix: installFolder,
|
|
20
|
-
loglevel: 'silent',
|
|
21
|
-
};
|
|
22
|
-
if(proxyUri) {
|
|
23
|
-
npmLoadConfig.proxy = proxyUri;
|
|
24
|
-
npmLoadConfig["https-proxy"] = proxyUri;
|
|
25
|
-
}
|
|
26
|
-
npm.load(npmLoadConfig, (err) => {
|
|
27
|
-
if (err) {
|
|
28
|
-
return reject(err);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
npm.commands[command](packages, (installErr, data) => {
|
|
32
|
-
if (installErr) {
|
|
33
|
-
return reject(new NpmPackageError(installErr.message));
|
|
34
|
-
}
|
|
35
|
-
resolve(Object.assign({data, installFolder}));
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
}
|