@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.
@@ -119,6 +119,7 @@ type ApiCallOptions = {
119
119
  headers?: Headers;
120
120
  body?: string;
121
121
  sendViaWebApp?: boolean;
122
+ omitCookies?: boolean;
122
123
  }
123
124
 
124
125
  export enum GeneratedValueTypes {
@@ -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
- }), DEFAULT_REQUEST_RETRY);
118
+ }), apiRetries);
119
119
  }
120
120
 
121
121
  function updateExecutionTests(executionId, runnerStatuses, status, reason, success, startTime, endTime, projectId) {
@@ -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.2",
1320
- "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.2.2.tgz",
1321
- "integrity": "sha512-dalsS+nk+dw3KIJ+sXzNCAPWhgqWkJhfHFeDXBKJXo0S/Uc1YVHf+d9Vhh9WgoAFgSU2JgLnQjSB99rRfg29Sg==",
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.4",
1570
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz",
1571
- "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==",
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.30001265",
1575
- "electron-to-chromium": "^1.3.867",
1569
+ "caniuse-lite": "^1.0.30001271",
1570
+ "electron-to-chromium": "^1.3.878",
1576
1571
  "escalade": "^3.1.1",
1577
- "node-releases": "^2.0.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.30001269",
1731
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz",
1732
- "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==",
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.1",
1921
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz",
1922
- "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA=="
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.871",
2857
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz",
2858
- "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==",
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": "14.0.0",
5212
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.0.0.tgz",
5213
- "integrity": "sha512-/VkyPmdtbwqpJSkwDx3YyJ3U1oawYNB/h5z8vTUZGAzjtu2OHTeFRfnJqyMHsJ5Cyes23trOmvUpM1GfHH1leA==",
5214
- "requires": {
5215
- "abab": "^2.0.0",
5216
- "acorn": "^6.0.4",
5217
- "acorn-globals": "^4.3.0",
5218
- "array-equal": "^1.0.0",
5219
- "cssom": "^0.3.4",
5220
- "cssstyle": "^1.1.1",
5221
- "data-urls": "^1.1.0",
5222
- "domexception": "^1.0.1",
5223
- "escodegen": "^1.11.0",
5224
- "html-encoding-sniffer": "^1.0.2",
5225
- "nwsapi": "^2.0.9",
5226
- "parse5": "5.1.0",
5227
- "pn": "^1.1.0",
5228
- "request": "^2.88.0",
5229
- "request-promise-native": "^1.0.5",
5230
- "saxes": "^3.1.5",
5231
- "symbol-tree": "^3.2.2",
5232
- "tough-cookie": "^2.5.0",
5233
- "w3c-hr-time": "^1.0.1",
5234
- "w3c-xmlserializer": "^1.0.1",
5235
- "webidl-conversions": "^4.0.2",
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": "^7.0.0",
5239
- "ws": "^6.1.2",
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": "6.4.2",
5245
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
5246
- "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="
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
- "cssom": {
5249
- "version": "0.3.8",
5250
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
5251
- "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
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
- "cssstyle": {
5254
- "version": "1.4.0",
5255
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
5256
- "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
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
- "cssom": "0.3.x"
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": "2.5.0",
5263
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
5264
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
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
- "ws": {
5271
- "version": "6.2.2",
5272
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
5273
- "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
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
- "async-limiter": "~1.0.0"
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.0",
5419
- "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
5420
- "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
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.0",
6424
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz",
6425
- "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==",
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.190.0",
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": "14.0.0",
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 LancherDriver {
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 LancherDriver(this.sessionId);
55
+ this.driver = new LauncherDriver(this.sessionId);
53
56
  this.id = id;
54
57
  }
55
58
 
@@ -1,4 +1,4 @@
1
- "use strict";
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, "selenium");
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
- return this.driver.forceEnd();
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
- "use strict";
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("not implemented");
23
+ throw new Error('not implemented');
25
24
  }
26
25
 
27
26
  getTarget() {
28
- const targetId = this.step.targetId || "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: "selenium exception: " + errorMsg,
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
- "use strict";
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
- "locate": LocateStepAction,
52
- "scroll": ScrollStepAction,
53
- "mouse": MouseStepAction,
54
- "submit": SubmitStepAction,
55
- "text": TextStepAction,
56
- "special-key": SpecialKeyStepAction,
57
- "user-code": JsCodeStepAction,
58
- "validation-code-step": JsCodeStepAction,
59
- "wait-for-code-step": JsCodeStepAction,
60
- "action-code-step": JsCodeStepAction,
61
- "condition-step": JsConditionStepAction,
62
- "skip-code-step": JsConditionStepAction,
63
- "element-code-step": JsConditionStepAction,
64
- "evaluate-expression": EvaluateExpressionStepAction,
65
- "text-validation": TextValidationStepAction,
66
- "wait-for-text-validation": TextValidationStepAction,
67
- "select-option": SelectOptionStepAction,
68
- "drop-file": DropFileStepAction,
69
- "input-file": InputFileStepAction,
70
- "hover": HoverStepAction,
71
- "navigation": NavigationStepAction,
72
- "wheel": WheelStepAction,
73
- "sleep": SleepStepAction,
74
- "refresh": RefreshStepAction,
75
- "api-validation": ApiStepAction,
76
- "api-action": ApiStepAction,
77
- "api-code-step": JsCodeStepAction,
78
- "extract-text": ExtractTextStepAction,
79
-
80
- "cli-validation-download-file": ExtensionOnlyStepAction,
81
- "cli-wait-for-download-file": ExtensionOnlyStepAction,
82
- "network-validation-step": ExtensionOnlyStepAction,
83
-
84
- "cli-validation-code-step": CliJsStepAction,
85
- "cli-wait-for-code-step": CliJsStepAction,
86
- "cli-action-code-step": CliJsStepAction,
87
- "cli-api-code-step": CliJsStepAction,
88
-
89
- "cli-condition-step": CliConditionStepAction,
90
- "node-package": NodePackageStepAction,
91
-
92
- "email-code-step": JsCodeStepAction,
93
- "cli-email-code-step": CliJsStepAction,
94
- "tdk-hybrid": TdkHybridStepAction,
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
- "locate": AndroidLocateStepAction,
99
- "android-tap": MobileTapStepAction,
100
- "android-long-click": AndroidLongClickStepAction,
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
- "text": MobileTextChangeStepAction,
104
- "android-swipe": AndroidSwipeStepAction,
105
- "android-scroll": AndroidScrollStepAction,
106
+ text: MobileTextChangeStepAction,
107
+ 'android-swipe': AndroidSwipeStepAction,
108
+ 'android-scroll': AndroidScrollStepAction,
106
109
  };
107
110
 
108
111
  const IOS_STEP_ACTION_MAPPING = {
109
- "locate": IosLocateStepAction,
110
- "ios-tap": MobileTapStepAction,
111
- "ios-device-key": MobileGlobalActionStepAction,
112
- "text": MobileTextChangeStepAction,
113
- "ios-scroll": IosScrollStepAction,
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 === "android") {
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 === "ios") {
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, gridTypes } = require('./commons/constants');
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
- analytics.trackWithCIUser('test-run-ci', {
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
- const properties = {
49
- executionId,
50
- projectId,
51
- testId,
52
- resultId,
53
- companyId,
54
- companyName,
55
- projectName,
56
- companyPlanType,
57
- sessionType,
58
- mockNetworkEnabled: result.wasMockNetworkActivated,
59
- lightweightMode,
60
- source: calcSource(source, user),
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
- if (result.success) {
64
- analytics.trackWithCIUser('test-run-ci-success', properties);
65
- return;
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 = Boolean(options.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).then(() => {
99
- if (options.lightweightMode && options.lightweightMode.disableResults) {
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 (options.lightweightMode && options.lightweightMode.onlyTestIdsNoSuite) {
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.disableResults) {
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: options.mode,
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.disableResults) {
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
- return runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }))
285
- .then(() => {
286
- if (this.options.lightweightMode && this.options.lightweightMode.disableResults) {
287
- return undefined;
288
- }
289
- return servicesApi.updateTestStatus('FINISHED', executionId, test.testId, test.resultId, test.startTime, result.endTime, test.success, test.failureReason, null, this.options.project, this.options.remoteRunId);
290
- })
291
- .catch(err => {
292
- logger.error('Failed to update test finished', { err });
293
- throw err;
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.disableResults && !this.options.lightweightMode.onlyTestIdsNoSuite) {
453
+ if (this.options.lightweightMode && this.options.lightweightMode.onlyTestIdsNoSuite) {
450
454
  return undefined;
451
455
  }
452
456
  return servicesApi.reportExecutionFinished(