@testim/testim-cli 3.197.0 → 3.198.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.
@@ -9,7 +9,7 @@ const Promise = require('bluebird');
9
9
  const fse = require('fs-extra');
10
10
  const logger = require('./logger').getLogger('cli-service');
11
11
  const { requireWithFallback } = require('./requireWithFallback');
12
- const os = require('os');
12
+ const fs = require('fs');
13
13
 
14
14
  async function getLatestPackageVersion(packageName) {
15
15
  const result = await exec(`npm view ${packageName} version`);
@@ -40,6 +40,16 @@ function getLocallyInstalledPackageVersion(rootPath, packageName) {
40
40
  return require(path.join(rootPath, `./node_modules/${packageName}/package.json`)).version;
41
41
  }
42
42
 
43
+ // this is not exactly correct, but it's good enough.
44
+ async function fileExists(path) {
45
+ try {
46
+ await fs.promises.access(path);
47
+ return true;
48
+ } catch (err) {
49
+ return false;
50
+ }
51
+ }
52
+
43
53
  async function installPackageLocally(rootPath, packageName, execOptions) {
44
54
  function getPathWithMissingPermissions(error) {
45
55
  const pathRegex = /EACCES[^']+'(.+)'/;
@@ -50,26 +60,48 @@ async function installPackageLocally(rootPath, packageName, execOptions) {
50
60
  return regexResult[1];
51
61
  }
52
62
 
53
- return exec(`npm i ${packageName} --no-save --no-package-lock --no-prune --prefer-offline --no-audit --progress=false`, { ...execOptions, cwd: rootPath }).catch(err => {
54
- const pathWithMissingPermissions = getPathWithMissingPermissions(err);
55
- if (pathWithMissingPermissions) {
56
- logger.info('Failed to install package due to insufficient write access', {
57
- ...additionalLogDetails(),
58
- package: packageName,
59
- path: pathWithMissingPermissions,
60
- });
61
- // eslint-disable-next-line no-console
62
- console.error(`
63
+ // this is here because our shrinkwrap blocks our lazy deps for some reason
64
+ const oldShrinkwrap = path.join(rootPath, 'npm-shrinkwrap.json');
65
+ const newShrinkwrap = path.join(rootPath, 'npm-shrinkwrap-dummy.json');
66
+ let renamed = false;
67
+ try {
68
+ try {
69
+ if (await fileExists(oldShrinkwrap)) {
70
+ await fs.promises.rename(oldShrinkwrap, newShrinkwrap);
71
+ renamed = true;
72
+ }
73
+ } catch (err) {
74
+ // ignore error
75
+ }
76
+ return await exec(`npm i ${packageName} --no-save --no-package-lock --no-prune --prefer-offline --no-audit --progress=false`, { ...execOptions, cwd: rootPath }).catch(err => {
77
+ const pathWithMissingPermissions = getPathWithMissingPermissions(err);
78
+ if (pathWithMissingPermissions) {
79
+ logger.info('Failed to install package due to insufficient write access', {
80
+ ...additionalLogDetails(),
81
+ package: packageName,
82
+ path: pathWithMissingPermissions,
83
+ });
84
+ // eslint-disable-next-line no-console
85
+ console.error(`
63
86
 
64
87
  Testim failed installing the package ${packageName} due to insufficient permissions.
65
88
  This is probably due to an installation of @testim/testim-cli with sudo, and running it without sudo.
66
89
  Testim had missing write access to ${pathWithMissingPermissions}
67
90
 
68
91
  `);
69
- throw new NpmPermissionsError(pathWithMissingPermissions);
92
+ throw new NpmPermissionsError(pathWithMissingPermissions);
93
+ }
94
+ throw err;
95
+ });
96
+ } finally {
97
+ if (renamed) {
98
+ try {
99
+ await fs.promises.rename(newShrinkwrap, oldShrinkwrap);
100
+ } catch (err) {
101
+ // ignore error
102
+ }
70
103
  }
71
- throw err;
72
- });
104
+ }
73
105
  }
74
106
 
75
107
  const localNpmLocation = path.resolve(require.resolve('npm'), '../../bin/npm-cli.js');
@@ -5,8 +5,8 @@ const { sinon, expect } = require('../../test/utils/testUtils');
5
5
  const os = require('os');
6
6
  const { NpmPermissionsError } = require('../errors');
7
7
  const path = require('path');
8
+
8
9
  const fs = require('fs');
9
- const { getCliLocation } = require('../utils');
10
10
 
11
11
  describe('npmWrapper', () => {
12
12
  describe('installPackageLocally', () => {
@@ -22,17 +22,22 @@ describe('npmWrapper', () => {
22
22
 
23
23
  let fakeChildProcess;
24
24
  let fakeLogger;
25
-
25
+ let fakeFS;
26
26
  let originalConsole;
27
27
  beforeEach(() => {
28
28
  fakeChildProcess = { exec: sinon.stub() };
29
29
  fakeLogger = { warn: sinon.stub(), info: sinon.stub() };
30
-
30
+ fakeFS = {
31
+ promises: {
32
+ access: sinon.stub().rejects(new Error()),
33
+ },
34
+ };
31
35
  originalConsole = global.console;
32
36
  global.console = { log: sinon.stub(), error: sinon.stub() };
33
37
 
34
38
  npmWrapper = proxyquire('./npmWrapper', {
35
39
  child_process: fakeChildProcess,
40
+ fs: fakeFS,
36
41
  './logger': { getLogger: () => fakeLogger },
37
42
  });
38
43
  });
@@ -65,7 +70,7 @@ describe('npmWrapper', () => {
65
70
 
66
71
  stubExecRejection(execErr);
67
72
 
68
- expect(npmWrapper.installPackageLocally('/some/dir', 'some-package')).to.be.rejectedWith(execErr);
73
+ await expect(npmWrapper.installPackageLocally('/some/dir', 'some-package')).to.be.rejectedWith(execErr);
69
74
  });
70
75
 
71
76
  it('should throw an error if an error which isnt related to permissions occurred', async () => {
@@ -73,7 +78,7 @@ describe('npmWrapper', () => {
73
78
 
74
79
  stubExecRejection(execErr);
75
80
 
76
- expect(npmWrapper.installPackageLocally('/some/dir', 'some-package')).to.be.rejectedWith(execErr);
81
+ await expect(npmWrapper.installPackageLocally('/some/dir', 'some-package')).to.be.rejectedWith(execErr);
77
82
  });
78
83
 
79
84
  it('should throw an error if stderr includes "EACCES", but the path was not specified', async () => {
@@ -81,7 +86,7 @@ describe('npmWrapper', () => {
81
86
 
82
87
  stubExecRejection(execErr);
83
88
 
84
- expect(npmWrapper.installPackageLocally('/some/dir', 'some-package')).to.be.rejectedWith(execErr);
89
+ await expect(npmWrapper.installPackageLocally('/some/dir', 'some-package')).to.be.rejectedWith(execErr);
85
90
  });
86
91
 
87
92
  [
@@ -194,5 +199,176 @@ Testim had missing write access to ${expectedPath}
194
199
  expect(fs.existsSync(unexpectedDir), 'expected the package not to be installed - this could be a problem with the test itself, and not the tested class').to.be.false;
195
200
  }).timeout(20000);
196
201
  });
202
+
203
+ describe('shirnkwrap handling', () => {
204
+ let fakeChildProcess;
205
+ let fakeLogger;
206
+ let originalConsole;
207
+ const shrinkwrapPath = '/some/dir/npm-shrinkwrap.json';
208
+ const shrinkwrapDummyPath = '/some/dir/npm-shrinkwrap-dummy.json';
209
+ beforeEach(() => {
210
+ fakeChildProcess = { exec: sinon.stub() };
211
+ fakeLogger = { warn: sinon.stub(), info: sinon.stub() };
212
+ originalConsole = global.console;
213
+ global.console = { log: sinon.stub(), error: sinon.stub() };
214
+ });
215
+
216
+ afterEach(() => {
217
+ global.console = originalConsole;
218
+ });
219
+
220
+ it('does not call rename if access fails', async () => {
221
+ const fakeFS = {
222
+ promises: {
223
+ access: sinon.stub(),
224
+ rename: sinon.stub(),
225
+ },
226
+ };
227
+ fakeFS.promises.access.rejects();
228
+ const npmWrapper = proxyquire('./npmWrapper', {
229
+ child_process: fakeChildProcess,
230
+ fs: fakeFS,
231
+ './logger': { getLogger: () => fakeLogger },
232
+ });
233
+
234
+ fakeChildProcess.exec.yields(undefined, []); //resolve without errors
235
+ const cwd = '/some/dir';
236
+ const pkg = 'some-package';
237
+ await npmWrapper.installPackageLocally(cwd, pkg);
238
+ sinon.assert.calledOnce(fakeFS.promises.access);
239
+ sinon.assert.notCalled(fakeFS.promises.rename);
240
+ expect(fakeFS.promises.access.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
241
+ });
242
+
243
+ it('calls rename once if rename fails on the first time', async () => {
244
+ const fakeFS = {
245
+ promises: {
246
+ access: sinon.stub().resolves(),
247
+ rename: sinon.stub().rejects(),
248
+ },
249
+ };
250
+
251
+ const npmWrapper = proxyquire('./npmWrapper', {
252
+ child_process: fakeChildProcess,
253
+ fs: fakeFS,
254
+ './logger': { getLogger: () => fakeLogger },
255
+ });
256
+
257
+ fakeChildProcess.exec.yields(undefined, []); //resolve without errors
258
+ const cwd = '/some/dir';
259
+ const pkg = 'some-package';
260
+ await npmWrapper.installPackageLocally(cwd, pkg);
261
+ sinon.assert.calledOnce(fakeFS.promises.access);
262
+ sinon.assert.calledOnce(fakeFS.promises.rename);
263
+ });
264
+
265
+ it('calls rename twice if first is success', async () => {
266
+ const fakeFS = {
267
+ promises: {
268
+ access: sinon.stub().resolves(),
269
+ rename: sinon.stub().resolves(),
270
+ },
271
+ };
272
+ const npmWrapper = proxyquire('./npmWrapper', {
273
+ child_process: fakeChildProcess,
274
+ fs: fakeFS,
275
+ './logger': { getLogger: () => fakeLogger },
276
+ });
277
+
278
+ fakeChildProcess.exec.yields(undefined, []); //resolve without errors
279
+ const cwd = '/some/dir';
280
+ const pkg = 'some-package';
281
+
282
+ await npmWrapper.installPackageLocally(cwd, pkg);
283
+ sinon.assert.calledOnce(fakeFS.promises.access);
284
+ sinon.assert.calledTwice(fakeFS.promises.rename);
285
+ expect(fakeFS.promises.access.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
286
+ expect(fakeFS.promises.rename.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
287
+ expect(fakeFS.promises.rename.getCall(0).args[1]).to.be.equal(shrinkwrapDummyPath);
288
+ expect(fakeFS.promises.rename.getCall(1).args[0]).to.be.equal(shrinkwrapDummyPath);
289
+ expect(fakeFS.promises.rename.getCall(1).args[1]).to.be.equal(shrinkwrapPath);
290
+ });
291
+
292
+ it('doesn\'t throw if first rename fails', async () => {
293
+ const fakeFS = {
294
+ promises: {
295
+ access: sinon.stub().resolves(true),
296
+ rename: sinon.stub().rejects(),
297
+ },
298
+ };
299
+ const npmWrapper = proxyquire('./npmWrapper', {
300
+ child_process: fakeChildProcess,
301
+ fs: fakeFS,
302
+ './logger': { getLogger: () => fakeLogger },
303
+ });
304
+
305
+ fakeChildProcess.exec.yields(undefined, []); //resolve without errors
306
+ const cwd = '/some/dir';
307
+ const pkg = 'some-package';
308
+ await npmWrapper.installPackageLocally(cwd, pkg);
309
+ sinon.assert.calledOnce(fakeFS.promises.access);
310
+ sinon.assert.calledOnce(fakeFS.promises.rename);
311
+ expect(fakeFS.promises.access.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
312
+ expect(fakeFS.promises.rename.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
313
+ expect(fakeFS.promises.rename.getCall(0).args[1]).to.be.equal(shrinkwrapDummyPath);
314
+ });
315
+
316
+ it('doesn\'t throw is second rename fails', async () => {
317
+ const fakeFS = {
318
+ promises: {
319
+ access: sinon.stub().resolves(),
320
+ rename: sinon.stub().onFirstCall().resolves().onSecondCall()
321
+ .rejects(),
322
+ },
323
+ };
324
+
325
+ const npmWrapper = proxyquire('./npmWrapper', {
326
+ child_process: fakeChildProcess,
327
+ fs: fakeFS,
328
+ './logger': { getLogger: () => fakeLogger },
329
+ });
330
+
331
+ fakeChildProcess.exec.yields(undefined, []); //resolve without errors
332
+ const cwd = '/some/dir';
333
+ const pkg = 'some-package';
334
+ await npmWrapper.installPackageLocally(cwd, pkg);
335
+ sinon.assert.calledOnce(fakeFS.promises.access);
336
+ sinon.assert.calledTwice(fakeFS.promises.rename);
337
+ expect(fakeFS.promises.access.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
338
+ expect(fakeFS.promises.rename.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
339
+ expect(fakeFS.promises.rename.getCall(0).args[1]).to.be.equal(shrinkwrapDummyPath);
340
+ expect(fakeFS.promises.rename.getCall(1).args[0]).to.be.equal(shrinkwrapDummyPath);
341
+ expect(fakeFS.promises.rename.getCall(1).args[1]).to.be.equal(shrinkwrapPath);
342
+ });
343
+
344
+ it('calls rename even if exec fails', async () => {
345
+ const fakeFS = {
346
+ promises: {
347
+ access: sinon.stub().resolves(),
348
+ rename: sinon.stub().onFirstCall().resolves().onSecondCall()
349
+ .rejects(),
350
+ },
351
+ };
352
+
353
+ fakeChildProcess.exec.throws();
354
+
355
+ const npmWrapper = proxyquire('./npmWrapper', {
356
+ child_process: fakeChildProcess,
357
+ fs: fakeFS,
358
+ './logger': { getLogger: () => fakeLogger },
359
+ });
360
+
361
+ const cwd = '/some/dir';
362
+ const pkg = 'some-package';
363
+ await expect(npmWrapper.installPackageLocally(cwd, pkg)).to.be.rejected;
364
+ sinon.assert.calledOnce(fakeFS.promises.access);
365
+ sinon.assert.calledTwice(fakeFS.promises.rename);
366
+ expect(fakeFS.promises.access.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
367
+ expect(fakeFS.promises.rename.getCall(0).args[0]).to.be.equal(shrinkwrapPath);
368
+ expect(fakeFS.promises.rename.getCall(0).args[1]).to.be.equal(shrinkwrapDummyPath);
369
+ expect(fakeFS.promises.rename.getCall(1).args[0]).to.be.equal(shrinkwrapDummyPath);
370
+ expect(fakeFS.promises.rename.getCall(1).args[1]).to.be.equal(shrinkwrapPath);
371
+ });
372
+ });
197
373
  });
198
374
  });
@@ -1514,9 +1514,9 @@
1514
1514
  "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
1515
1515
  },
1516
1516
  "asn1": {
1517
- "version": "0.2.4",
1518
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
1519
- "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
1517
+ "version": "0.2.6",
1518
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
1519
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
1520
1520
  "requires": {
1521
1521
  "safer-buffer": "~2.1.0"
1522
1522
  }
@@ -1873,13 +1873,13 @@
1873
1873
  "dev": true
1874
1874
  },
1875
1875
  "browserslist": {
1876
- "version": "4.17.5",
1877
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.5.tgz",
1878
- "integrity": "sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==",
1876
+ "version": "4.17.6",
1877
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz",
1878
+ "integrity": "sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==",
1879
1879
  "dev": true,
1880
1880
  "requires": {
1881
- "caniuse-lite": "^1.0.30001271",
1882
- "electron-to-chromium": "^1.3.878",
1881
+ "caniuse-lite": "^1.0.30001274",
1882
+ "electron-to-chromium": "^1.3.886",
1883
1883
  "escalade": "^3.1.1",
1884
1884
  "node-releases": "^2.0.1",
1885
1885
  "picocolors": "^1.0.0"
@@ -2033,9 +2033,9 @@
2033
2033
  "dev": true
2034
2034
  },
2035
2035
  "caniuse-lite": {
2036
- "version": "1.0.30001274",
2037
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001274.tgz",
2038
- "integrity": "sha512-+Nkvv0fHyhISkiMIjnyjmf5YJcQ1IQHZN6U9TLUMroWR38FNwpsC51Gb68yueafX1V6ifOisInSgP9WJFS13ew==",
2036
+ "version": "1.0.30001278",
2037
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz",
2038
+ "integrity": "sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==",
2039
2039
  "dev": true
2040
2040
  },
2041
2041
  "caseless": {
@@ -3172,9 +3172,9 @@
3172
3172
  "integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ=="
3173
3173
  },
3174
3174
  "electron-to-chromium": {
3175
- "version": "1.3.886",
3176
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.886.tgz",
3177
- "integrity": "sha512-+vYdeBosI63VkCtNWnEVFjgNd/IZwvnsWkKyPtWAvrhA+XfByKoBJcbsMgudVU/bUcGAF9Xp3aXn96voWlc3oQ==",
3175
+ "version": "1.3.890",
3176
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.890.tgz",
3177
+ "integrity": "sha512-VWlVXSkv0cA/OOehrEyqjUTHwV8YXCPTfPvbtoeU2aHR21vI4Ejh5aC4AxUwOmbLbBgb6Gd3URZahoCxtBqCYQ==",
3178
3178
  "dev": true
3179
3179
  },
3180
3180
  "emoji-regex": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.197.0",
3
+ "version": "3.198.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -0,0 +1,9 @@
1
+ const CliJsStepAction = require('./cliJsStepAction');
2
+
3
+ class SalesforceApexActionStepAction extends CliJsStepAction {
4
+ getSkipStatus() {
5
+ return false;
6
+ }
7
+ }
8
+
9
+ module.exports = SalesforceApexActionStepAction;
@@ -19,7 +19,7 @@ class SalesforceAutoLoginStepAction extends NavigationStepAction {
19
19
  var done = arguments[1];
20
20
  done();
21
21
  `, timeout);
22
- await Promise.delay(1500);
22
+ await Promise.delay(5000);
23
23
  newUrl = await this.driver.getUrl(); // If we managed to continue correctly we want to get the new redirected url
24
24
  }
25
25
  await Promise.delay(700);
@@ -21,9 +21,11 @@ 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');
25
24
  const PixelValidationStepAction = require('./pixelValidationStepAction');
26
25
 
26
+ const SalesforceAutoLoginStepAction = require('./salesforceAutoLoginStepAction');
27
+ const SalesforceApexActionStepAction = require('./salesforceApexActionStepAction');
28
+
27
29
  const CliJsStepAction = require('./cliJsStepAction');
28
30
  const CliConditionStepAction = require('./cliConditionStepAction');
29
31
  const NodePackageStepAction = require('./nodePackageStepAction');
@@ -85,6 +87,7 @@ module.exports = function (driver, stepActionFactory, runMode) {
85
87
  'tdk-hybrid': TdkHybridStepAction,
86
88
 
87
89
  'salesforce-autologin': SalesforceAutoLoginStepAction,
90
+ 'salesforce-apex-action': SalesforceApexActionStepAction,
88
91
  };
89
92
 
90
93
  register(STEP_ACTION_MAPPING, stepActionFactory);
package/testRunHandler.js CHANGED
@@ -7,6 +7,7 @@ const testimServicesApi = require('./commons/testimServicesApi');
7
7
  const { timeoutMessages, CLI_MODE } = require('./commons/constants');
8
8
  const logger = require('./commons/logger').getLogger('test-run-handler');
9
9
  const perf = require('./commons/performance-logger');
10
+ const { URL } = require('url');
10
11
  const Promise = require('bluebird');
11
12
  const _ = require('lodash');
12
13
  const remoteStepPlayback = require('./stepPlayers/remoteStepPlayback');
@@ -316,6 +317,19 @@ TestRun.prototype.isRetryKeyMismatch = function (testResult) {
316
317
  return testResult.testRetryKey && (testResult.testRetryKey !== this.getRetryKey());
317
318
  };
318
319
 
320
+ TestRun.prototype.validateRunConfig = function () {
321
+ const baseUrl = this.getBaseUrl();
322
+ const { browserValue } = this.getRunConfig();
323
+
324
+ if (baseUrl) {
325
+ const { username, password } = new URL(baseUrl);
326
+
327
+ if (browserValue === 'safari' && (username || password)) {
328
+ throw new Error('Basic authentication in URL is not supported in Safari');
329
+ }
330
+ }
331
+ };
332
+
319
333
  TestRun.prototype.onStarted = function (startTimeout) {
320
334
  return new Promise(resolve => {
321
335
  // We can't leave the test result as it may remove other listeners as well
@@ -467,7 +481,7 @@ TestRun.prototype.onCompleted = function () {
467
481
  waitForTestEnd();
468
482
  }
469
483
  } catch (err) {
470
- logger.error('failed to check is complete', {err});
484
+ logger.error('failed to check is complete', { err });
471
485
  waitForTestEnd();
472
486
  }
473
487
  }, 3000);
package/testRunStatus.js CHANGED
@@ -23,11 +23,11 @@ const gitRepoUrl = process.env.GIT_URL || process.env.CIRCLE_REPOSITORY_URL;
23
23
  const runnerVersion = utils.getRunnerVersion();
24
24
 
25
25
 
26
- function runHook(fn, object) {
26
+ function runHook(fn, ...args) {
27
27
  if (!fn || typeof fn !== 'function') {
28
28
  return Promise.resolve();
29
29
  }
30
- return Promise.try(() => fn(object) || {}).catch(err => {
30
+ return Promise.try(() => fn(...args) || {}).catch(err => {
31
31
  logger.warn('failed to run hook', { err });
32
32
  throw new ArgError(`failed to run hook promise ${err.message}`);
33
33
  });
@@ -181,7 +181,7 @@ RunStatus.prototype.testStartReport = function (test, executionId, testRetryKey)
181
181
  if (utils.isQuarantineAndNotRemoteRun(test, this.options)) {
182
182
  return Promise.resolve();
183
183
  }
184
- return runHook(this.options.beforeTest, Object.assign({}, test, { exportsGlobal: this.exportsGlobal }))
184
+ return runHook(this.options.beforeTest, Object.assign({}, test, { exportsGlobal: this.exportsGlobal }), this.options.userData.loginData.token)
185
185
  .then(params => {
186
186
  this.options.runParams[test.resultId] = test.config.testData = Object.assign({}, test.config.testData, this.exportsGlobal, this.fileUserParamsData, this.beforeSuiteParams, params);
187
187
  test.startTime = Date.now();
@@ -278,7 +278,7 @@ RunStatus.prototype.testEndReport = async function (test, executionId, result, t
278
278
  const globalParameters = result.exportsGlobal;
279
279
  try {
280
280
  try {
281
- await runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }));
281
+ await runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }), this.options.userData.loginData.token);
282
282
  } catch (err) {
283
283
  logger.error('HOOK threw an error', { test: test.testId, err });
284
284
  // eslint-disable-next-line no-console
@@ -387,6 +387,7 @@ class BaseWorker {
387
387
  !disableRemoteStep && remoteStepService.joinToRemoteStep(this.testResultId),
388
388
  !disableResults && testResultService.joinToTestResult(this.testResultId, this.testId),
389
389
  ])
390
+ .then(() => testRunHandler.validateRunConfig())
390
391
  .then(() => this.runTest(testRunHandler, this.customExtensionLocalLocation, shouldRerun))
391
392
  .then(testResult => onRunComplete(testResult, testRunHandler))
392
393
  .then(result => {