@testim/testim-cli 3.190.0 → 3.194.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/codim/codim-npm-package/index.ts +1 -0
- package/commons/featureFlags.js +1 -0
- package/commons/testimDesiredCapabilitiesBuilder.js +0 -1
- package/commons/testimServicesApi.js +2 -2
- package/npm-shrinkwrap.json +183 -77
- package/package.json +3 -2
- package/player/chromeLauncherTestPlayer.js +5 -2
- package/player/seleniumTestPlayer.js +10 -16
- package/player/stepActions/apiStepAction.js +1 -0
- package/player/stepActions/salesforceAutoLoginStepAction.js +37 -0
- package/player/stepActions/stepAction.js +7 -10
- package/player/stepActions/stepActionRegistrar.js +61 -58
- package/runOptions.js +30 -0
- package/runner.js +10 -1
- package/runners/strategies/BaseStrategy.js +32 -21
- package/runners/strategies/LocalStrategy.js +8 -4
- package/testRunHandler.js +1 -1
- package/testRunStatus.js +22 -18
package/commons/featureFlags.js
CHANGED
|
@@ -53,6 +53,7 @@ class FeatureFlagsService {
|
|
|
53
53
|
safariSelectOptionDispatchEventOnSelectElement: new Rox.Flag(true),
|
|
54
54
|
experimentalPreCodeCompilation: new Rox.Flag(false),
|
|
55
55
|
useSameBrowserForMultiTests: new LabFeatureFlag('labs'),
|
|
56
|
+
highSpeedMode: new LabFeatureFlag(),
|
|
56
57
|
usePortedHtml5DragDrop: new Rox.Flag(),
|
|
57
58
|
};
|
|
58
59
|
Rox.register('default', this.flags);
|
|
@@ -193,7 +193,6 @@ function _buildChromiumOptions(opts, browserOptions, testRunConfig, customExtens
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
if (isDFGrid(gridInfo) && browserName === 'MicrosoftEdge') {
|
|
196
|
-
delete chromiumOptions.prefs['profile.content_settings.exceptions.clipboard']; // for some reason this breaks
|
|
197
196
|
opts.desiredCapabilities['ms:edgeChromium'] = true;
|
|
198
197
|
}
|
|
199
198
|
|
|
@@ -100,7 +100,7 @@ function saveTestPlanResult(projectId, testPlanId, result) {
|
|
|
100
100
|
return utils.runWithRetries(() => postAuth({ url: '/testPlan/result', body: { projectId, testPlanId, result } }));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
function updateTestStatus(status, executionId, testId, resultId, startTime, endTime, success, failureReason, config, projectId, remoteRunId, testRetryKey) {
|
|
103
|
+
function updateTestStatus(status, executionId, testId, resultId, startTime, endTime, success, failureReason, config, projectId, remoteRunId, testRetryKey, apiRetries = DEFAULT_REQUEST_RETRY) {
|
|
104
104
|
return utils.runWithRetries(() => putAuth('/result/run/test', {
|
|
105
105
|
runId: executionId,
|
|
106
106
|
testId,
|
|
@@ -115,7 +115,7 @@ function updateTestStatus(status, executionId, testId, resultId, startTime, endT
|
|
|
115
115
|
runnerVersion,
|
|
116
116
|
remoteRunId,
|
|
117
117
|
testRetryKey,
|
|
118
|
-
}),
|
|
118
|
+
}), apiRetries);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
function updateExecutionTests(executionId, runnerStatuses, status, reason, success, startTime, endTime, projectId) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1273,11 +1273,6 @@
|
|
|
1273
1273
|
"integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
|
|
1274
1274
|
"dev": true
|
|
1275
1275
|
},
|
|
1276
|
-
"async-limiter": {
|
|
1277
|
-
"version": "1.0.1",
|
|
1278
|
-
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
|
1279
|
-
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
|
1280
|
-
},
|
|
1281
1276
|
"async-settle": {
|
|
1282
1277
|
"version": "1.0.0",
|
|
1283
1278
|
"resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
|
|
@@ -1316,9 +1311,9 @@
|
|
|
1316
1311
|
}
|
|
1317
1312
|
},
|
|
1318
1313
|
"axios-retry": {
|
|
1319
|
-
"version": "3.2.
|
|
1320
|
-
"resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.2.
|
|
1321
|
-
"integrity": "sha512-
|
|
1314
|
+
"version": "3.2.3",
|
|
1315
|
+
"resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.2.3.tgz",
|
|
1316
|
+
"integrity": "sha512-JfxUUN6PDyinrDVP/NbCKxmwvwJfMfQ0DLs95o/OEd+mw5+hrBXNGfx1Wq2gskd7ODWc4kcd9CjStCpDv3Us4g==",
|
|
1322
1317
|
"requires": {
|
|
1323
1318
|
"@babel/runtime": "^7.15.4",
|
|
1324
1319
|
"is-retry-allowed": "^2.2.0"
|
|
@@ -1566,15 +1561,15 @@
|
|
|
1566
1561
|
"dev": true
|
|
1567
1562
|
},
|
|
1568
1563
|
"browserslist": {
|
|
1569
|
-
"version": "4.17.
|
|
1570
|
-
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.
|
|
1571
|
-
"integrity": "sha512-
|
|
1564
|
+
"version": "4.17.5",
|
|
1565
|
+
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.5.tgz",
|
|
1566
|
+
"integrity": "sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==",
|
|
1572
1567
|
"dev": true,
|
|
1573
1568
|
"requires": {
|
|
1574
|
-
"caniuse-lite": "^1.0.
|
|
1575
|
-
"electron-to-chromium": "^1.3.
|
|
1569
|
+
"caniuse-lite": "^1.0.30001271",
|
|
1570
|
+
"electron-to-chromium": "^1.3.878",
|
|
1576
1571
|
"escalade": "^3.1.1",
|
|
1577
|
-
"node-releases": "^2.0.
|
|
1572
|
+
"node-releases": "^2.0.1",
|
|
1578
1573
|
"picocolors": "^1.0.0"
|
|
1579
1574
|
}
|
|
1580
1575
|
},
|
|
@@ -1727,9 +1722,9 @@
|
|
|
1727
1722
|
"dev": true
|
|
1728
1723
|
},
|
|
1729
1724
|
"caniuse-lite": {
|
|
1730
|
-
"version": "1.0.
|
|
1731
|
-
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.
|
|
1732
|
-
"integrity": "sha512-
|
|
1725
|
+
"version": "1.0.30001271",
|
|
1726
|
+
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001271.tgz",
|
|
1727
|
+
"integrity": "sha512-BBruZFWmt3HFdVPS8kceTBIguKxu4f99n5JNp06OlPD/luoAMIaIK5ieV5YjnBLH3Nysai9sxj9rpJj4ZisXOA==",
|
|
1733
1728
|
"dev": true
|
|
1734
1729
|
},
|
|
1735
1730
|
"caseless": {
|
|
@@ -1917,9 +1912,9 @@
|
|
|
1917
1912
|
},
|
|
1918
1913
|
"dependencies": {
|
|
1919
1914
|
"@types/node": {
|
|
1920
|
-
"version": "16.11.
|
|
1921
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.
|
|
1922
|
-
"integrity": "sha512-
|
|
1915
|
+
"version": "16.11.6",
|
|
1916
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
|
|
1917
|
+
"integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w=="
|
|
1923
1918
|
},
|
|
1924
1919
|
"mkdirp": {
|
|
1925
1920
|
"version": "0.5.5",
|
|
@@ -2511,6 +2506,11 @@
|
|
|
2511
2506
|
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
|
2512
2507
|
"dev": true
|
|
2513
2508
|
},
|
|
2509
|
+
"decimal.js": {
|
|
2510
|
+
"version": "10.3.1",
|
|
2511
|
+
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
|
|
2512
|
+
"integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ=="
|
|
2513
|
+
},
|
|
2514
2514
|
"decode-uri-component": {
|
|
2515
2515
|
"version": "0.2.0",
|
|
2516
2516
|
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
|
@@ -2853,9 +2853,9 @@
|
|
|
2853
2853
|
"integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ=="
|
|
2854
2854
|
},
|
|
2855
2855
|
"electron-to-chromium": {
|
|
2856
|
-
"version": "1.3.
|
|
2857
|
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.
|
|
2858
|
-
"integrity": "sha512-
|
|
2856
|
+
"version": "1.3.879",
|
|
2857
|
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.879.tgz",
|
|
2858
|
+
"integrity": "sha512-zJo+D9GwbJvM31IdFmwcGvychhk4KKbKYo2GWlsn+C/dxz2NwmbhGJjWwTfFSF2+eFH7VvfA8MCZ8SOqTrlnpw==",
|
|
2859
2859
|
"dev": true
|
|
2860
2860
|
},
|
|
2861
2861
|
"emoji-regex": {
|
|
@@ -4854,6 +4854,11 @@
|
|
|
4854
4854
|
"isobject": "^3.0.1"
|
|
4855
4855
|
}
|
|
4856
4856
|
},
|
|
4857
|
+
"is-potential-custom-element-name": {
|
|
4858
|
+
"version": "1.0.1",
|
|
4859
|
+
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
|
|
4860
|
+
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
|
|
4861
|
+
},
|
|
4857
4862
|
"is-regex": {
|
|
4858
4863
|
"version": "1.1.4",
|
|
4859
4864
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
|
|
@@ -5208,72 +5213,173 @@
|
|
|
5208
5213
|
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
|
|
5209
5214
|
},
|
|
5210
5215
|
"jsdom": {
|
|
5211
|
-
"version": "
|
|
5212
|
-
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-
|
|
5213
|
-
"integrity": "sha512
|
|
5214
|
-
"requires": {
|
|
5215
|
-
"abab": "^2.0.
|
|
5216
|
-
"acorn": "^
|
|
5217
|
-
"acorn-globals": "^
|
|
5218
|
-
"
|
|
5219
|
-
"
|
|
5220
|
-
"
|
|
5221
|
-
"
|
|
5222
|
-
"domexception": "^
|
|
5223
|
-
"escodegen": "^
|
|
5224
|
-
"
|
|
5225
|
-
"
|
|
5226
|
-
"
|
|
5227
|
-
"
|
|
5228
|
-
"
|
|
5229
|
-
"
|
|
5230
|
-
"
|
|
5231
|
-
"
|
|
5232
|
-
"
|
|
5233
|
-
"
|
|
5234
|
-
"w3c-
|
|
5235
|
-
"
|
|
5216
|
+
"version": "16.7.0",
|
|
5217
|
+
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
|
|
5218
|
+
"integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
|
|
5219
|
+
"requires": {
|
|
5220
|
+
"abab": "^2.0.5",
|
|
5221
|
+
"acorn": "^8.2.4",
|
|
5222
|
+
"acorn-globals": "^6.0.0",
|
|
5223
|
+
"cssom": "^0.4.4",
|
|
5224
|
+
"cssstyle": "^2.3.0",
|
|
5225
|
+
"data-urls": "^2.0.0",
|
|
5226
|
+
"decimal.js": "^10.2.1",
|
|
5227
|
+
"domexception": "^2.0.1",
|
|
5228
|
+
"escodegen": "^2.0.0",
|
|
5229
|
+
"form-data": "^3.0.0",
|
|
5230
|
+
"html-encoding-sniffer": "^2.0.1",
|
|
5231
|
+
"http-proxy-agent": "^4.0.1",
|
|
5232
|
+
"https-proxy-agent": "^5.0.0",
|
|
5233
|
+
"is-potential-custom-element-name": "^1.0.1",
|
|
5234
|
+
"nwsapi": "^2.2.0",
|
|
5235
|
+
"parse5": "6.0.1",
|
|
5236
|
+
"saxes": "^5.0.1",
|
|
5237
|
+
"symbol-tree": "^3.2.4",
|
|
5238
|
+
"tough-cookie": "^4.0.0",
|
|
5239
|
+
"w3c-hr-time": "^1.0.2",
|
|
5240
|
+
"w3c-xmlserializer": "^2.0.0",
|
|
5241
|
+
"webidl-conversions": "^6.1.0",
|
|
5236
5242
|
"whatwg-encoding": "^1.0.5",
|
|
5237
5243
|
"whatwg-mimetype": "^2.3.0",
|
|
5238
|
-
"whatwg-url": "^
|
|
5239
|
-
"ws": "^
|
|
5244
|
+
"whatwg-url": "^8.5.0",
|
|
5245
|
+
"ws": "^7.4.6",
|
|
5240
5246
|
"xml-name-validator": "^3.0.0"
|
|
5241
5247
|
},
|
|
5242
5248
|
"dependencies": {
|
|
5243
5249
|
"acorn": {
|
|
5244
|
-
"version": "
|
|
5245
|
-
"resolved": "https://registry.npmjs.org/acorn/-/acorn-
|
|
5246
|
-
"integrity": "sha512-
|
|
5250
|
+
"version": "8.5.0",
|
|
5251
|
+
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz",
|
|
5252
|
+
"integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q=="
|
|
5247
5253
|
},
|
|
5248
|
-
"
|
|
5249
|
-
"version": "0.
|
|
5250
|
-
"resolved": "https://registry.npmjs.org/
|
|
5251
|
-
"integrity": "sha512-
|
|
5254
|
+
"acorn-globals": {
|
|
5255
|
+
"version": "6.0.0",
|
|
5256
|
+
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
|
|
5257
|
+
"integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
|
|
5258
|
+
"requires": {
|
|
5259
|
+
"acorn": "^7.1.1",
|
|
5260
|
+
"acorn-walk": "^7.1.1"
|
|
5261
|
+
},
|
|
5262
|
+
"dependencies": {
|
|
5263
|
+
"acorn": {
|
|
5264
|
+
"version": "7.4.1",
|
|
5265
|
+
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
|
5266
|
+
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
|
|
5267
|
+
}
|
|
5268
|
+
}
|
|
5252
5269
|
},
|
|
5253
|
-
"
|
|
5254
|
-
"version": "
|
|
5255
|
-
"resolved": "https://registry.npmjs.org/
|
|
5256
|
-
"integrity": "sha512-
|
|
5270
|
+
"acorn-walk": {
|
|
5271
|
+
"version": "7.2.0",
|
|
5272
|
+
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
|
|
5273
|
+
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA=="
|
|
5274
|
+
},
|
|
5275
|
+
"data-urls": {
|
|
5276
|
+
"version": "2.0.0",
|
|
5277
|
+
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
|
|
5278
|
+
"integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
|
|
5257
5279
|
"requires": {
|
|
5258
|
-
"
|
|
5280
|
+
"abab": "^2.0.3",
|
|
5281
|
+
"whatwg-mimetype": "^2.3.0",
|
|
5282
|
+
"whatwg-url": "^8.0.0"
|
|
5283
|
+
}
|
|
5284
|
+
},
|
|
5285
|
+
"domexception": {
|
|
5286
|
+
"version": "2.0.1",
|
|
5287
|
+
"resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
|
|
5288
|
+
"integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
|
|
5289
|
+
"requires": {
|
|
5290
|
+
"webidl-conversions": "^5.0.0"
|
|
5291
|
+
},
|
|
5292
|
+
"dependencies": {
|
|
5293
|
+
"webidl-conversions": {
|
|
5294
|
+
"version": "5.0.0",
|
|
5295
|
+
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
|
|
5296
|
+
"integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA=="
|
|
5297
|
+
}
|
|
5298
|
+
}
|
|
5299
|
+
},
|
|
5300
|
+
"escodegen": {
|
|
5301
|
+
"version": "2.0.0",
|
|
5302
|
+
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
|
|
5303
|
+
"integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
|
|
5304
|
+
"requires": {
|
|
5305
|
+
"esprima": "^4.0.1",
|
|
5306
|
+
"estraverse": "^5.2.0",
|
|
5307
|
+
"esutils": "^2.0.2",
|
|
5308
|
+
"optionator": "^0.8.1",
|
|
5309
|
+
"source-map": "~0.6.1"
|
|
5310
|
+
}
|
|
5311
|
+
},
|
|
5312
|
+
"estraverse": {
|
|
5313
|
+
"version": "5.3.0",
|
|
5314
|
+
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
|
5315
|
+
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
|
|
5316
|
+
},
|
|
5317
|
+
"html-encoding-sniffer": {
|
|
5318
|
+
"version": "2.0.1",
|
|
5319
|
+
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
|
|
5320
|
+
"integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
|
|
5321
|
+
"requires": {
|
|
5322
|
+
"whatwg-encoding": "^1.0.5"
|
|
5323
|
+
}
|
|
5324
|
+
},
|
|
5325
|
+
"parse5": {
|
|
5326
|
+
"version": "6.0.1",
|
|
5327
|
+
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
|
|
5328
|
+
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
|
|
5329
|
+
},
|
|
5330
|
+
"saxes": {
|
|
5331
|
+
"version": "5.0.1",
|
|
5332
|
+
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
|
|
5333
|
+
"integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
|
|
5334
|
+
"requires": {
|
|
5335
|
+
"xmlchars": "^2.2.0"
|
|
5259
5336
|
}
|
|
5260
5337
|
},
|
|
5261
5338
|
"tough-cookie": {
|
|
5262
|
-
"version": "
|
|
5263
|
-
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-
|
|
5264
|
-
"integrity": "sha512-
|
|
5339
|
+
"version": "4.0.0",
|
|
5340
|
+
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
|
|
5341
|
+
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
|
|
5342
|
+
"requires": {
|
|
5343
|
+
"psl": "^1.1.33",
|
|
5344
|
+
"punycode": "^2.1.1",
|
|
5345
|
+
"universalify": "^0.1.2"
|
|
5346
|
+
}
|
|
5347
|
+
},
|
|
5348
|
+
"tr46": {
|
|
5349
|
+
"version": "2.1.0",
|
|
5350
|
+
"resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
|
|
5351
|
+
"integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
|
|
5265
5352
|
"requires": {
|
|
5266
|
-
"psl": "^1.1.28",
|
|
5267
5353
|
"punycode": "^2.1.1"
|
|
5268
5354
|
}
|
|
5269
5355
|
},
|
|
5270
|
-
"
|
|
5271
|
-
"version": "
|
|
5272
|
-
"resolved": "https://registry.npmjs.org/
|
|
5273
|
-
"integrity": "sha512-
|
|
5356
|
+
"w3c-xmlserializer": {
|
|
5357
|
+
"version": "2.0.0",
|
|
5358
|
+
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
|
|
5359
|
+
"integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
|
|
5360
|
+
"requires": {
|
|
5361
|
+
"xml-name-validator": "^3.0.0"
|
|
5362
|
+
}
|
|
5363
|
+
},
|
|
5364
|
+
"webidl-conversions": {
|
|
5365
|
+
"version": "6.1.0",
|
|
5366
|
+
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
|
5367
|
+
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
|
|
5368
|
+
},
|
|
5369
|
+
"whatwg-url": {
|
|
5370
|
+
"version": "8.7.0",
|
|
5371
|
+
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
|
|
5372
|
+
"integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
|
|
5274
5373
|
"requires": {
|
|
5275
|
-
"
|
|
5374
|
+
"lodash": "^4.7.0",
|
|
5375
|
+
"tr46": "^2.1.0",
|
|
5376
|
+
"webidl-conversions": "^6.1.0"
|
|
5276
5377
|
}
|
|
5378
|
+
},
|
|
5379
|
+
"ws": {
|
|
5380
|
+
"version": "7.5.5",
|
|
5381
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
|
|
5382
|
+
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w=="
|
|
5277
5383
|
}
|
|
5278
5384
|
}
|
|
5279
5385
|
},
|
|
@@ -5415,9 +5521,9 @@
|
|
|
5415
5521
|
}
|
|
5416
5522
|
},
|
|
5417
5523
|
"lazystream": {
|
|
5418
|
-
"version": "1.0.
|
|
5419
|
-
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.
|
|
5420
|
-
"integrity": "
|
|
5524
|
+
"version": "1.0.1",
|
|
5525
|
+
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
|
|
5526
|
+
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
|
|
5421
5527
|
"requires": {
|
|
5422
5528
|
"readable-stream": "^2.0.5"
|
|
5423
5529
|
}
|
|
@@ -6420,9 +6526,9 @@
|
|
|
6420
6526
|
}
|
|
6421
6527
|
},
|
|
6422
6528
|
"node-releases": {
|
|
6423
|
-
"version": "2.0.
|
|
6424
|
-
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.
|
|
6425
|
-
"integrity": "sha512-
|
|
6529
|
+
"version": "2.0.1",
|
|
6530
|
+
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
|
|
6531
|
+
"integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==",
|
|
6426
6532
|
"dev": true
|
|
6427
6533
|
},
|
|
6428
6534
|
"nopt": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testim/testim-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.194.0",
|
|
4
4
|
"description": "Command line interface for running Testing on your CI",
|
|
5
5
|
"author": "Oren Rubin",
|
|
6
6
|
"contributors": [{
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"istanbul-lib-report": "3.0.0",
|
|
79
79
|
"istanbul-reports": "3.0.2",
|
|
80
80
|
"jimp": "0.2.28",
|
|
81
|
-
"jsdom": "
|
|
81
|
+
"jsdom": "16.7.0",
|
|
82
82
|
"jsonwebtoken": "8.5.1",
|
|
83
83
|
"lodash": "4.17.20",
|
|
84
84
|
"memory-fs": "0.5.0",
|
|
@@ -118,6 +118,7 @@
|
|
|
118
118
|
"test": "IS_UNIT_TEST=1 ./node_modules/mocha/bin/_mocha --timeout 2000 --reporter spec --exit --recursive \"./src/**/*.test.js\" --exclude ./src/codim/template.js/tests/examples/**/*.test.js",
|
|
119
119
|
"test:watch": "IS_UNIT_TEST=1 ./node_modules/mocha/bin/_mocha --timeout 2000 --exit --recursive \"./src/**/*.test.js\" --exclude ./src/codim/template.js/tests/examples/**/*.test.js --watch",
|
|
120
120
|
"test:cov": "nyc --reporter=lcov --reporter=text yarn test",
|
|
121
|
+
"upload-bundle-s3": "scripts/upload.js",
|
|
121
122
|
"prepare-version": "rm -rf ./deploy && mkdir -p deploy && gulp prepare-version-on-prem",
|
|
122
123
|
"make-onprem-deps": "cp ../../yarn.lock deploy && cd deploy && yarn install --production && bundle-deps",
|
|
123
124
|
"pack-onprem": "yarn prepare-version && yarn make-onprem-deps && cd deploy && npm pack && zip -r testim-cli.zip testim-cli-*.tgz",
|
|
@@ -4,9 +4,10 @@ const launcher = require('chrome-launcher');
|
|
|
4
4
|
const desiredCapabilitiesBuilder = require('../commons/testimDesiredCapabilitiesBuilder');
|
|
5
5
|
const utils = require('../utils');
|
|
6
6
|
const httpRequest = require('../commons/httpRequest');
|
|
7
|
+
const { registerExitHook } = require('../processHandler');
|
|
7
8
|
const CDPTestRunner = require('../cdpTestRunner');
|
|
8
9
|
|
|
9
|
-
class
|
|
10
|
+
class LauncherDriver {
|
|
10
11
|
constructor(sessionId) {
|
|
11
12
|
this.sessionId = sessionId;
|
|
12
13
|
this.cdpTestRunner = new CDPTestRunner();
|
|
@@ -24,6 +25,8 @@ class LancherDriver {
|
|
|
24
25
|
this._isAlive = true;
|
|
25
26
|
const browserEndpoint = await httpRequest.get(`http://localhost:${this.chrome.port}/json/version`);
|
|
26
27
|
await this.cdpTestRunner.initSession(browserEndpoint.webSocketDebuggerUrl);
|
|
28
|
+
|
|
29
|
+
registerExitHook(() => this.chrome.kill());
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
isAlive() {
|
|
@@ -49,7 +52,7 @@ class LancherDriver {
|
|
|
49
52
|
class ChromeLauncherTestPlayer {
|
|
50
53
|
constructor(id) {
|
|
51
54
|
this.sessionId = utils.guid();
|
|
52
|
-
this.driver = new
|
|
55
|
+
this.driver = new LauncherDriver(this.sessionId);
|
|
53
56
|
this.id = id;
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const TabService = require('./services/tabService');
|
|
4
4
|
const PortSelector = require('./services/portSelector');
|
|
@@ -24,9 +24,6 @@ const WebDriver = require('./webdriver');
|
|
|
24
24
|
const CryptoJS = require('crypto-js');
|
|
25
25
|
const StepActionUtils = require('./utils/stepActionUtils');
|
|
26
26
|
|
|
27
|
-
// Set JSDOM SVGElement on Global to support text validation on SVG
|
|
28
|
-
global.SVGElement = require("jsdom/lib/jsdom/living/generated/SVGSVGElement").interface;
|
|
29
|
-
|
|
30
27
|
class SeleniumTestPlayer {
|
|
31
28
|
constructor(id, userParamsData, shouldMonitorPerformance, automationMode = 'code', driver = new WebDriver(), testRetryCount, previousTestResultId) {
|
|
32
29
|
this.driver = driver;
|
|
@@ -34,7 +31,7 @@ class SeleniumTestPlayer {
|
|
|
34
31
|
|
|
35
32
|
const stepActionUtils = new StepActionUtils(this.driver);
|
|
36
33
|
this.stepActionFactory = new StepActionFactory(stepActionUtils);
|
|
37
|
-
require('./stepActions/stepActionRegistrar')(this.driver, this.stepActionFactory,
|
|
34
|
+
require('./stepActions/stepActionRegistrar')(this.driver, this.stepActionFactory, 'selenium');
|
|
38
35
|
|
|
39
36
|
if (assetService.setMd5) {
|
|
40
37
|
// delete after https://github.com/testimio/clickim/pull/3430 release to the store
|
|
@@ -74,9 +71,9 @@ class SeleniumTestPlayer {
|
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
onStepCompleted(result, testId, resultId, step) {
|
|
77
|
-
if(step && step.isTabOpener) {
|
|
74
|
+
if (step && step.isTabOpener) {
|
|
78
75
|
this.tabService.addNewPopup(this.id, step.id)
|
|
79
|
-
.catch(() => {});
|
|
76
|
+
.catch(() => { });
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
79
|
|
|
@@ -84,10 +81,8 @@ class SeleniumTestPlayer {
|
|
|
84
81
|
const END_DRIVER_TIMEOUT = 1000 * 60 * 2;
|
|
85
82
|
return this.driver.end()
|
|
86
83
|
.timeout(END_DRIVER_TIMEOUT)
|
|
87
|
-
.catch(Promise.TimeoutError, () =>
|
|
88
|
-
|
|
89
|
-
})
|
|
90
|
-
.catch(() => {})
|
|
84
|
+
.catch(Promise.TimeoutError, () => this.driver.forceEnd())
|
|
85
|
+
.catch(() => { })
|
|
91
86
|
.then(() => {
|
|
92
87
|
this.sessionPlayer.playbackManager.off(commonConstants.playback.RESULT, this.onStepCompleted);
|
|
93
88
|
this.sessionPlayer = null;
|
|
@@ -101,10 +96,10 @@ class SeleniumTestPlayer {
|
|
|
101
96
|
this.tabService.clearAllTabs(this.id);
|
|
102
97
|
}
|
|
103
98
|
|
|
104
|
-
addTab(openerStepId, options = { loadInfo: true}) {
|
|
99
|
+
addTab(openerStepId, options = { loadInfo: true }) {
|
|
105
100
|
return this.driver.getTabIds()
|
|
106
101
|
.tap(ids => this.tabService.addNewTab(this.id, ids[ids.length - 1], openerStepId, options))
|
|
107
|
-
.then(ids => this.sessionPlayer.addPlaybackFrameHandler(ids[ids.length - 1], undefined, {emptyPage: true}))
|
|
102
|
+
.then(ids => this.sessionPlayer.addPlaybackFrameHandler(ids[ids.length - 1], undefined, { emptyPage: true }));
|
|
108
103
|
}
|
|
109
104
|
|
|
110
105
|
async addAllTabs(openerStepId, options = { loadInfo: true, checkForMainTab: true, takeScreenshots: true }, blackList = []) {
|
|
@@ -112,14 +107,14 @@ class SeleniumTestPlayer {
|
|
|
112
107
|
// the ids are reversed so we search first in the last tab opened - otherwise it starts looking from the testim editor and not the AUT
|
|
113
108
|
|
|
114
109
|
const PROHIBITED_URLS = ['app.testim.io'].concat(blackList);
|
|
115
|
-
for(const id of ids.reverse()) {
|
|
110
|
+
for (const id of ids.reverse()) {
|
|
116
111
|
await this.tabService.addNewTab(this.id, id, openerStepId, { ...options, forceSwitch: true });
|
|
117
112
|
const tabInfo = this.tabService.getTabInfo(this.id, id);
|
|
118
113
|
if (PROHIBITED_URLS.some(bad => tabInfo.url.includes(bad))) {
|
|
119
114
|
await this.tabService.removeTabInfo(this.id, id);
|
|
120
115
|
continue;
|
|
121
116
|
}
|
|
122
|
-
await this.sessionPlayer.addPlaybackFrameHandler(id, undefined, {emptyPage: true });
|
|
117
|
+
await this.sessionPlayer.addPlaybackFrameHandler(id, undefined, { emptyPage: true });
|
|
123
118
|
}
|
|
124
119
|
if (this.tabService.tabCount(this.id) === 1) {
|
|
125
120
|
// if we only have one tab because we removed the editor tab - we have to switchTab to one of the other tabs, otherwise
|
|
@@ -130,7 +125,6 @@ class SeleniumTestPlayer {
|
|
|
130
125
|
}
|
|
131
126
|
// deal with checkForMainTab failing due to the page refreshing or JavaScript not responding or a similar issue
|
|
132
127
|
this.tabService.fixMissingMainTab(this.id);
|
|
133
|
-
|
|
134
128
|
}
|
|
135
129
|
|
|
136
130
|
getSessionId() {
|
|
@@ -36,6 +36,7 @@ class ApiStepAction extends StepAction {
|
|
|
36
36
|
headers: context.apiHeaders,
|
|
37
37
|
body: context.apiBody,
|
|
38
38
|
timeout: context.data.maxTotalStepTime,
|
|
39
|
+
omitCookies: step.omitCookies,
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
return (step.sendViaWebApp ? this.runApiInAut(step, context) : this.runApiInBg(eventData))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const NavigationStepAction = require('./navigationStepAction');
|
|
2
|
+
const Promise = require('bluebird');
|
|
3
|
+
|
|
4
|
+
class SalesforceAutoLoginStepAction extends NavigationStepAction {
|
|
5
|
+
async performAction() {
|
|
6
|
+
let salesforceUrl = this.context.data.testimNavigationStepDestination || this.context.data.url;
|
|
7
|
+
try {
|
|
8
|
+
salesforceUrl = await this.updateBaseUrl(salesforceUrl);
|
|
9
|
+
await this.driver.url(salesforceUrl);
|
|
10
|
+
await Promise.delay(300); // wait a little for the page to load (fixes screenshots and clicking on elements in username verification screen)
|
|
11
|
+
let newUrl = await this.driver.getUrl();
|
|
12
|
+
// Verify username screen
|
|
13
|
+
const isUsernameVerificationNeeded = newUrl.includes(this.step.USERNAME_VERIFICATION_PATH_ID);
|
|
14
|
+
if (isUsernameVerificationNeeded) {
|
|
15
|
+
await this.driver.executeCodeAsync(`
|
|
16
|
+
function ${this.step.handleUsernameVerificationAUTFunc.toString()}
|
|
17
|
+
handleUsernameVerificationAUTFunc();
|
|
18
|
+
var done = arguments[1];
|
|
19
|
+
done();
|
|
20
|
+
`);
|
|
21
|
+
await Promise.delay(500);
|
|
22
|
+
newUrl = await this.driver.getUrl(); // If we managed to continue correctly we want to get the new redirected url
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
newUrl,
|
|
27
|
+
};
|
|
28
|
+
} catch (err) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
reason: err.message,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = SalesforceAutoLoginStepAction;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const { commonConstants } = require('../../commons/getSessionPlayerRequire');
|
|
4
4
|
const Promise = require('bluebird');
|
|
5
5
|
|
|
6
6
|
class StepAction {
|
|
7
|
-
|
|
8
7
|
constructor(step, context, frameHandler, exportsGlobal = {}, stepActionUtils, locateElementPlayer, exportsTest = {}) {
|
|
9
8
|
this.step = step;
|
|
10
9
|
this.context = context;
|
|
@@ -21,21 +20,19 @@ class StepAction {
|
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
performAction() {
|
|
24
|
-
throw new Error(
|
|
23
|
+
throw new Error('not implemented');
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
getTarget() {
|
|
28
|
-
const targetId = this.step.targetId ||
|
|
27
|
+
const targetId = this.step.targetId || 'targetId';
|
|
29
28
|
return this.context.data[targetId];
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
execute(stepActionFactory, step) {
|
|
33
32
|
return Promise.resolve(this.performAction(stepActionFactory, step))
|
|
34
|
-
.then(res => {
|
|
35
|
-
return Promise.resolve(Object.assign({}, {success: true}, res));
|
|
36
|
-
})
|
|
33
|
+
.then(res => Promise.resolve(Object.assign({}, { success: true }, res)))
|
|
37
34
|
.catch(err => {
|
|
38
|
-
const errorMsg = (err || {}).message || err && err.seleniumStack && err.seleniumStack.message;
|
|
35
|
+
const errorMsg = (err || {}).message || (err && err.seleniumStack && err.seleniumStack.message);
|
|
39
36
|
const displayMsg = (err || {}).displayMessage;
|
|
40
37
|
return Promise.resolve({
|
|
41
38
|
success: false,
|
|
@@ -43,11 +40,11 @@ class StepAction {
|
|
|
43
40
|
exception: err,
|
|
44
41
|
errorType: commonConstants.stepResult.ACTION_EXCEPTION,
|
|
45
42
|
resultInfo: {
|
|
46
|
-
exception:
|
|
43
|
+
exception: `selenium exception: ${errorMsg}`,
|
|
47
44
|
// clickim -> playbackStepResultHandler.js -> FAILURE_REASON_MAPPING -> ACTION_EXCEPTION
|
|
48
45
|
// expects resultInfo.error or resultInfo.reason
|
|
49
46
|
error: displayMsg || errorMsg,
|
|
50
|
-
}
|
|
47
|
+
},
|
|
51
48
|
});
|
|
52
49
|
});
|
|
53
50
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const LocateStepAction = require('./locateStepAction');
|
|
4
4
|
const ScrollStepAction = require('./scrollStepAction');
|
|
@@ -21,6 +21,7 @@ const RefreshStepAction = require('./RefreshStepAction');
|
|
|
21
21
|
const ApiStepAction = require('./apiStepAction');
|
|
22
22
|
const ExtractTextStepAction = require('./extractTextStepAction');
|
|
23
23
|
const TdkHybridStepAction = require('./tdkHybridStepAction');
|
|
24
|
+
const SalesforceAutoLoginStepAction = require('./salesforceAutoLoginStepAction');
|
|
24
25
|
|
|
25
26
|
const CliJsStepAction = require('./cliJsStepAction');
|
|
26
27
|
const CliConditionStepAction = require('./cliConditionStepAction');
|
|
@@ -48,69 +49,71 @@ function register(stepActionByType, stepActionFactory) {
|
|
|
48
49
|
|
|
49
50
|
module.exports = function (driver, stepActionFactory, runMode) {
|
|
50
51
|
const STEP_ACTION_MAPPING = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
52
|
+
locate: LocateStepAction,
|
|
53
|
+
scroll: ScrollStepAction,
|
|
54
|
+
mouse: MouseStepAction,
|
|
55
|
+
submit: SubmitStepAction,
|
|
56
|
+
text: TextStepAction,
|
|
57
|
+
'special-key': SpecialKeyStepAction,
|
|
58
|
+
'user-code': JsCodeStepAction,
|
|
59
|
+
'validation-code-step': JsCodeStepAction,
|
|
60
|
+
'wait-for-code-step': JsCodeStepAction,
|
|
61
|
+
'action-code-step': JsCodeStepAction,
|
|
62
|
+
'condition-step': JsConditionStepAction,
|
|
63
|
+
'skip-code-step': JsConditionStepAction,
|
|
64
|
+
'element-code-step': JsConditionStepAction,
|
|
65
|
+
'evaluate-expression': EvaluateExpressionStepAction,
|
|
66
|
+
'text-validation': TextValidationStepAction,
|
|
67
|
+
'wait-for-text-validation': TextValidationStepAction,
|
|
68
|
+
'select-option': SelectOptionStepAction,
|
|
69
|
+
'drop-file': DropFileStepAction,
|
|
70
|
+
'input-file': InputFileStepAction,
|
|
71
|
+
hover: HoverStepAction,
|
|
72
|
+
navigation: NavigationStepAction,
|
|
73
|
+
wheel: WheelStepAction,
|
|
74
|
+
sleep: SleepStepAction,
|
|
75
|
+
refresh: RefreshStepAction,
|
|
76
|
+
'api-validation': ApiStepAction,
|
|
77
|
+
'api-action': ApiStepAction,
|
|
78
|
+
'api-code-step': JsCodeStepAction,
|
|
79
|
+
'extract-text': ExtractTextStepAction,
|
|
80
|
+
|
|
81
|
+
'cli-validation-download-file': ExtensionOnlyStepAction,
|
|
82
|
+
'cli-wait-for-download-file': ExtensionOnlyStepAction,
|
|
83
|
+
'network-validation-step': ExtensionOnlyStepAction,
|
|
84
|
+
|
|
85
|
+
'cli-validation-code-step': CliJsStepAction,
|
|
86
|
+
'cli-wait-for-code-step': CliJsStepAction,
|
|
87
|
+
'cli-action-code-step': CliJsStepAction,
|
|
88
|
+
'cli-api-code-step': CliJsStepAction,
|
|
89
|
+
|
|
90
|
+
'cli-condition-step': CliConditionStepAction,
|
|
91
|
+
'node-package': NodePackageStepAction,
|
|
92
|
+
|
|
93
|
+
'email-code-step': JsCodeStepAction,
|
|
94
|
+
'cli-email-code-step': CliJsStepAction,
|
|
95
|
+
'tdk-hybrid': TdkHybridStepAction,
|
|
96
|
+
|
|
97
|
+
'salesforce-autologin': SalesforceAutoLoginStepAction,
|
|
95
98
|
};
|
|
96
99
|
|
|
97
100
|
const ANDROID_STEP_ACTION_MAPPING = {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
locate: AndroidLocateStepAction,
|
|
102
|
+
'android-tap': MobileTapStepAction,
|
|
103
|
+
'android-long-click': AndroidLongClickStepAction,
|
|
101
104
|
'android-device-key': MobileGlobalActionStepAction,
|
|
102
105
|
'android-key-board-special-keys': AndroidSpecialKeyStepAction,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
text: MobileTextChangeStepAction,
|
|
107
|
+
'android-swipe': AndroidSwipeStepAction,
|
|
108
|
+
'android-scroll': AndroidScrollStepAction,
|
|
106
109
|
};
|
|
107
110
|
|
|
108
111
|
const IOS_STEP_ACTION_MAPPING = {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
locate: IosLocateStepAction,
|
|
113
|
+
'ios-tap': MobileTapStepAction,
|
|
114
|
+
'ios-device-key': MobileGlobalActionStepAction,
|
|
115
|
+
text: MobileTextChangeStepAction,
|
|
116
|
+
'ios-scroll': IosScrollStepAction,
|
|
114
117
|
};
|
|
115
118
|
|
|
116
119
|
register(STEP_ACTION_MAPPING, stepActionFactory);
|
|
@@ -119,7 +122,7 @@ module.exports = function (driver, stepActionFactory, runMode) {
|
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
// override android actions
|
|
122
|
-
if (runMode ===
|
|
125
|
+
if (runMode === 'android') {
|
|
123
126
|
register(ANDROID_STEP_ACTION_MAPPING, stepActionFactory);
|
|
124
127
|
if (stepActionFactory.registerLocateStepActionUtils) {
|
|
125
128
|
stepActionFactory.registerLocateStepActionUtils(AndroidLocateStepAction.getUtils(driver));
|
|
@@ -127,7 +130,7 @@ module.exports = function (driver, stepActionFactory, runMode) {
|
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
// override ios actions
|
|
130
|
-
if (runMode ===
|
|
133
|
+
if (runMode === 'ios') {
|
|
131
134
|
register(IOS_STEP_ACTION_MAPPING, stepActionFactory);
|
|
132
135
|
if (stepActionFactory.registerLocateStepActionUtils) {
|
|
133
136
|
stepActionFactory.registerLocateStepActionUtils(IosLocateStepAction.getUtils(driver));
|
package/runOptions.js
CHANGED
|
@@ -348,6 +348,7 @@ program
|
|
|
348
348
|
.option('--aws-access-key-id [accessKeyId]', 'accessKeyId', '')
|
|
349
349
|
.option('--aws-secret-access-key [secretAccessKey]', 'secretAccessKey', '')
|
|
350
350
|
|
|
351
|
+
.option('--high-speed', 'run in high speed mode')
|
|
351
352
|
.option('--lightweight-mode [settings]', 'run lightweight mode')
|
|
352
353
|
.option('--create-prefeched-data [location]', 'prefech data into local cache file')
|
|
353
354
|
.option('--use-prefeched-data [location]', 'use prefeched data from local cache file, and force using only cached data')
|
|
@@ -1020,6 +1021,7 @@ module.exports = {
|
|
|
1020
1021
|
const DEFAULTS = {
|
|
1021
1022
|
general: true,
|
|
1022
1023
|
disableLabs: true,
|
|
1024
|
+
disableFeatureFlags: true,
|
|
1023
1025
|
disableAssets: true,
|
|
1024
1026
|
disablePixelValidation: true,
|
|
1025
1027
|
disableResults: true,
|
|
@@ -1029,10 +1031,13 @@ module.exports = {
|
|
|
1029
1031
|
disableVisibilityCheck: false,
|
|
1030
1032
|
disableLocators: false,
|
|
1031
1033
|
bypassSetup: false,
|
|
1034
|
+
disableAutoImprove: true,
|
|
1032
1035
|
disableQuotaBlocking: true,
|
|
1033
1036
|
onlyTestIdsNoSuite: true,
|
|
1034
1037
|
uploadAssetsAndResultsOnFailure: true,
|
|
1035
1038
|
preloadTests: true,
|
|
1039
|
+
disableProjectDefaults: true,
|
|
1040
|
+
type: 'lightweight',
|
|
1036
1041
|
};
|
|
1037
1042
|
|
|
1038
1043
|
const lightweightModeOptions = typeof program.lightweightMode === 'string' ? JSON.parse(program.lightweightMode) : {};
|
|
@@ -1040,8 +1045,33 @@ module.exports = {
|
|
|
1040
1045
|
} catch (err) {
|
|
1041
1046
|
return Promise.reject(new ArgError(`failed to parse lightweightMode settings error: ${err.message}`));
|
|
1042
1047
|
}
|
|
1048
|
+
} else if (program.highSpeed && program.mode === CLI_MODE.EXTENSION) {
|
|
1049
|
+
program.lightweightMode = {
|
|
1050
|
+
general: true,
|
|
1051
|
+
disableLabs: false,
|
|
1052
|
+
disableFeatureFlags: false,
|
|
1053
|
+
disableAssets: true,
|
|
1054
|
+
disablePixelValidation: false,
|
|
1055
|
+
disableResults: true,
|
|
1056
|
+
disableStepDelay: true,
|
|
1057
|
+
disableRemoteStep: false,
|
|
1058
|
+
assumePreloadedSharedSteps: false,
|
|
1059
|
+
disableVisibilityCheck: false,
|
|
1060
|
+
disableLocators: false,
|
|
1061
|
+
bypassSetup: false,
|
|
1062
|
+
disableQuotaBlocking: false,
|
|
1063
|
+
disableAutoImprove: false,
|
|
1064
|
+
onlyTestIdsNoSuite: false,
|
|
1065
|
+
uploadAssetsAndResultsOnFailure: true,
|
|
1066
|
+
preloadTests: false,
|
|
1067
|
+
disableProjectDefaults: false,
|
|
1068
|
+
type: 'highSpeed',
|
|
1069
|
+
};
|
|
1043
1070
|
}
|
|
1044
1071
|
|
|
1072
|
+
if (typeof program.baseUrl === 'boolean') {
|
|
1073
|
+
return Promise.reject(new ArgError('base url cannot be used as a flag, and must contain a string value'));
|
|
1074
|
+
}
|
|
1045
1075
|
|
|
1046
1076
|
return ({
|
|
1047
1077
|
testId: [].concat(program.testId),
|
package/runner.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/* eslint-disable no-console */
|
|
4
|
-
const { CLI_MODE
|
|
4
|
+
const { CLI_MODE } = require('./commons/constants');
|
|
5
5
|
const Promise = require('bluebird');
|
|
6
6
|
const _ = require('lodash');
|
|
7
7
|
const { EDITOR_URL } = require('./commons/config');
|
|
@@ -308,6 +308,15 @@ async function init(options) {
|
|
|
308
308
|
if (!(options.lightweightMode && options.lightweightMode.disableLabs)) {
|
|
309
309
|
await labFeaturesService.loadLabFeatures(projectById.id, companyByProjectId.activePlan);
|
|
310
310
|
}
|
|
311
|
+
|
|
312
|
+
if (options.lightweightMode && options.lightweightMode.type === 'highSpeed' && (!labFeaturesService.isFeatureAvailableForProject('highSpeedMode') || options.company.planType === 'free')) {
|
|
313
|
+
delete options.lightweightMode;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (options.lightweightMode && options.lightweightMode.type === 'highSpeed') {
|
|
317
|
+
console.log('High-speed mode will ignore step delays. Test artifacts like screenshots and logs will only be saved for failed runs. For more information see our docs: https://help.testim.io/docs/high-speed-mode');
|
|
318
|
+
}
|
|
319
|
+
|
|
311
320
|
gridService.keepAlive.start(project);
|
|
312
321
|
analyticsIdentify(project);
|
|
313
322
|
await setMockNetworkRules(options);
|
|
@@ -23,11 +23,18 @@ const calcSource = (source, user) => {
|
|
|
23
23
|
return source;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
function setLightweightAnalytics(properties, lightweightMode) {
|
|
27
|
+
if (lightweightMode && lightweightMode.type) {
|
|
28
|
+
properties[`${lightweightMode.type}Mode`] = true;
|
|
29
|
+
}
|
|
30
|
+
return properties;
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
class BaseStrategy {
|
|
27
34
|
analyticsTestStart({
|
|
28
35
|
executionId, projectId, testId, resultId, companyId, companyName, projectName, companyPlanType, sessionType, source, user, lightweightMode,
|
|
29
36
|
}) {
|
|
30
|
-
|
|
37
|
+
const properties = setLightweightAnalytics({
|
|
31
38
|
executionId,
|
|
32
39
|
projectId,
|
|
33
40
|
testId,
|
|
@@ -37,34 +44,38 @@ class BaseStrategy {
|
|
|
37
44
|
projectName,
|
|
38
45
|
companyPlanType,
|
|
39
46
|
sessionType,
|
|
40
|
-
lightweightMode,
|
|
41
47
|
source: calcSource(source, user),
|
|
42
|
-
});
|
|
48
|
+
}, lightweightMode);
|
|
49
|
+
analytics.trackWithCIUser('test-run-ci', properties);
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
analyticsTestEnd({
|
|
46
53
|
executionId, projectId, testId, resultId, result, companyId, companyName, projectName, companyPlanType, sessionType, source, user, lightweightMode,
|
|
54
|
+
logger,
|
|
47
55
|
}) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
try {
|
|
57
|
+
const properties = setLightweightAnalytics({
|
|
58
|
+
executionId,
|
|
59
|
+
projectId,
|
|
60
|
+
testId,
|
|
61
|
+
resultId,
|
|
62
|
+
companyId,
|
|
63
|
+
companyName,
|
|
64
|
+
projectName,
|
|
65
|
+
companyPlanType,
|
|
66
|
+
sessionType,
|
|
67
|
+
mockNetworkEnabled: result.wasMockNetworkActivated,
|
|
68
|
+
source: calcSource(source, user),
|
|
69
|
+
}, lightweightMode);
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
if (result.success) {
|
|
72
|
+
analytics.trackWithCIUser('test-run-ci-success', properties);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
analytics.trackWithCIUser('test-run-ci-fail', Object.assign({}, properties, { failureReason: result.failureReason }));
|
|
76
|
+
} catch (err) {
|
|
77
|
+
logger.error('failed to update test end analytics', { err });
|
|
66
78
|
}
|
|
67
|
-
analytics.trackWithCIUser('test-run-ci-fail', Object.assign({}, properties, { failureReason: result.failureReason }));
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
runTests(testList, testStatus, executionId, options, branchToUse, authData, workerCount, stopOnError) {
|
|
@@ -74,7 +74,7 @@ class LocalStrategy extends BaseStrategy {
|
|
|
74
74
|
const user = options.user;
|
|
75
75
|
const companyPlanType = options.company && options.company.planType;
|
|
76
76
|
const projectName = options.projectData && options.projectData.name;
|
|
77
|
-
const lightweightMode =
|
|
77
|
+
const lightweightMode = options.lightweightMode;
|
|
78
78
|
const sessionType = utils.getSessionType(options);
|
|
79
79
|
|
|
80
80
|
const onTestStarted = (wid, testId, resultId, isRerun, testRetryKey) => {
|
|
@@ -95,12 +95,15 @@ class LocalStrategy extends BaseStrategy {
|
|
|
95
95
|
});
|
|
96
96
|
return testStatus.testStartAndReport(wid, executionId, resultId, isRerun, testRetryKey);
|
|
97
97
|
};
|
|
98
|
-
const onTestCompleted = (wid, testId, testResult, sessionId, isRerun) => testStatus.testEndAndReport(wid, testResult, executionId, sessionId, isRerun).
|
|
99
|
-
|
|
98
|
+
const onTestCompleted = (wid, testId, testResult, sessionId, isRerun) => testStatus.testEndAndReport(wid, testResult, executionId, sessionId, isRerun).catch(err => {
|
|
99
|
+
logger.error('testEndAndReport threw an error', { err });
|
|
100
|
+
}).then(() => {
|
|
101
|
+
const isLocalRun = Boolean(options.useLocalChromeDriver || options.useChromeLauncher);
|
|
102
|
+
if (lightweightMode && lightweightMode.disableResults && isLocalRun) {
|
|
100
103
|
return undefined;
|
|
101
104
|
}
|
|
102
105
|
const update = {};
|
|
103
|
-
if (
|
|
106
|
+
if (lightweightMode && lightweightMode.onlyTestIdsNoSuite) {
|
|
104
107
|
update.show = true;
|
|
105
108
|
}
|
|
106
109
|
if (testResult.seleniumStats) {
|
|
@@ -160,6 +163,7 @@ class LocalStrategy extends BaseStrategy {
|
|
|
160
163
|
source,
|
|
161
164
|
user,
|
|
162
165
|
lightweightMode,
|
|
166
|
+
logger,
|
|
163
167
|
});
|
|
164
168
|
if (stopOnError && !testResult.success) {
|
|
165
169
|
reject(new StopRunOnError());
|
package/testRunHandler.js
CHANGED
|
@@ -518,7 +518,7 @@ TestRun.prototype.onRetry = async function () {
|
|
|
518
518
|
this._originalTestResultId = this._originalTestResultId || this._previousTestResultId;
|
|
519
519
|
this._testResultId = utils.guid();
|
|
520
520
|
|
|
521
|
-
if (this._options.lightweightMode && this._options.lightweightMode.
|
|
521
|
+
if (this._options.lightweightMode && this._options.lightweightMode.onlyTestIdsNoSuite) {
|
|
522
522
|
return;
|
|
523
523
|
}
|
|
524
524
|
|
package/testRunStatus.js
CHANGED
|
@@ -47,6 +47,7 @@ const RunStatus = function (testInfoList, options, testPlanId, branchToUse) {
|
|
|
47
47
|
this.executionStartedPromise = Promise.resolve();
|
|
48
48
|
|
|
49
49
|
const browserNames = utils.getUniqBrowsers(options, testInfoList);
|
|
50
|
+
const runnerMode = options.lightweightMode ? options.lightweightMode.type : options.mode;
|
|
50
51
|
this.execConfig = {
|
|
51
52
|
parallel: TESTIM_CONCURRENT_WORKER_COUNT || options.parallel || 1,
|
|
52
53
|
browser: browserNames,
|
|
@@ -74,7 +75,7 @@ const RunStatus = function (testInfoList, options, testPlanId, branchToUse) {
|
|
|
74
75
|
tunnel: options.tunnel,
|
|
75
76
|
tunnelPort: options.tunnelPort,
|
|
76
77
|
tunnelHostHeader: options.tunnelHostHeader,
|
|
77
|
-
runnerMode
|
|
78
|
+
runnerMode,
|
|
78
79
|
gridId: options.gridId || options.gridData.gridId,
|
|
79
80
|
gridName: options.grid || options.gridData.name,
|
|
80
81
|
gridType: options.gridData.type,
|
|
@@ -152,7 +153,7 @@ RunStatus.prototype.testStart = function (wid, executionId, resultId, isRerun) {
|
|
|
152
153
|
|
|
153
154
|
RunStatus.prototype.updateTestStatusRunning = function (test, executionId, testRetryKey) {
|
|
154
155
|
const { project: projectId, remoteRunId, projectData } = this.options;
|
|
155
|
-
if (this.options.lightweightMode && this.options.lightweightMode.
|
|
156
|
+
if (this.options.lightweightMode && this.options.lightweightMode.onlyTestIdsNoSuite) {
|
|
156
157
|
return this.executionStartedPromise;
|
|
157
158
|
}
|
|
158
159
|
|
|
@@ -184,9 +185,6 @@ RunStatus.prototype.testStartReport = function (test, executionId, testRetryKey)
|
|
|
184
185
|
.then(params => {
|
|
185
186
|
this.options.runParams[test.resultId] = test.config.testData = Object.assign({}, test.config.testData, this.exportsGlobal, this.fileUserParamsData, this.beforeSuiteParams, params);
|
|
186
187
|
test.startTime = Date.now();
|
|
187
|
-
if (this.options.lightweightMode && this.options.lightweightMode.disableResults) {
|
|
188
|
-
return undefined;
|
|
189
|
-
}
|
|
190
188
|
return this.updateTestStatusRunning(test, executionId, testRetryKey);
|
|
191
189
|
}).catch(err => {
|
|
192
190
|
logger.error('Failed to start test', { err });
|
|
@@ -279,19 +277,25 @@ RunStatus.prototype.testEnd = function (wid, result, executionId, sessionId, isR
|
|
|
279
277
|
return test;
|
|
280
278
|
};
|
|
281
279
|
|
|
282
|
-
RunStatus.prototype.testEndReport = function (test, executionId, result) {
|
|
280
|
+
RunStatus.prototype.testEndReport = async function (test, executionId, result) {
|
|
283
281
|
const globalParameters = result.exportsGlobal;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
282
|
+
try {
|
|
283
|
+
try {
|
|
284
|
+
await runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }));
|
|
285
|
+
} catch (err) {
|
|
286
|
+
logger.error('HOOK threw an error', { test: test.testId, err });
|
|
287
|
+
// eslint-disable-next-line no-console
|
|
288
|
+
console.error('HOOK threw an error', err); // show the customer that his hook failed.
|
|
289
|
+
}
|
|
290
|
+
if (this.options.lightweightMode && this.options.lightweightMode.onlyTestIdsNoSuite) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return await servicesApi.updateTestStatus('FINISHED', executionId, test.testId, test.resultId, test.startTime, result.endTime, test.success, test.failureReason, null, this.options.project, this.options.remoteRunId, undefined, 5);
|
|
295
|
+
} catch (err) {
|
|
296
|
+
logger.error('Failed to update test finished', { err });
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
295
299
|
};
|
|
296
300
|
|
|
297
301
|
RunStatus.prototype.testEndAndReport = function (wid, result, executionId, sessionId, isRerun) {
|
|
@@ -446,7 +450,7 @@ RunStatus.prototype.executionEnd = function (executionId) {
|
|
|
446
450
|
.then((coverageSummary) => {
|
|
447
451
|
resultExtraData.coverageSummary = coverageSummary;
|
|
448
452
|
|
|
449
|
-
if (this.options.lightweightMode && this.options.lightweightMode.
|
|
453
|
+
if (this.options.lightweightMode && this.options.lightweightMode.onlyTestIdsNoSuite) {
|
|
450
454
|
return undefined;
|
|
451
455
|
}
|
|
452
456
|
return servicesApi.reportExecutionFinished(
|