suitest-js-api 4.2.0 → 4.2.2

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.
@@ -8,7 +8,7 @@ const {apiUrl} = require('../../config');
8
8
  const SuitestError = require('../utils/SuitestError');
9
9
  const makeUrlFromArray = require('../utils/makeUrlFromArray');
10
10
  const {suitestServerError} = require('../texts');
11
- const {captureException} = require('../utils/sentry/Raven');
11
+ const {captureException} = require('../utils/sentry/Sentry');
12
12
 
13
13
  /**
14
14
  * Make http request
@@ -38,7 +38,7 @@ async function request(url, requestObject, onFail) {
38
38
  } catch (e) {
39
39
  // Caught low-level network error, i.e. not HTTP error
40
40
  // Report it to Sentry
41
- await captureException(e, {extra:{networkingError: true}});
41
+ await captureException(e, {extra: {networkingError: true}});
42
42
 
43
43
  throw e;
44
44
  }
@@ -6,7 +6,7 @@
6
6
  const WS = require('ws');
7
7
  const {v1: uuid} = require('uuid');
8
8
  const {path} = require('ramda');
9
- const Raven = require('raven');
9
+ const {captureException} = require('../utils/sentry/Sentry');
10
10
  const {fetch, setUserAgent} = require('../utils/fetch');
11
11
 
12
12
  const SuitestError = require('../utils/SuitestError');
@@ -89,6 +89,10 @@ const webSocketsFactory = (self) => {
89
89
  throw new SuitestError(texts.testingMinutesExceededMessage());
90
90
  }
91
91
 
92
+ if (content.type === 'releasingDevice') {
93
+ throw new SuitestError(texts.releasingDeviceMessage());
94
+ }
95
+
92
96
  if (content.type === 'executorStopped') {
93
97
  // Notify user about executor being stopped
94
98
  throw new SuitestError(texts.executorStopped());
@@ -276,7 +280,7 @@ const webSocketsFactory = (self) => {
276
280
  try {
277
281
  logger.log(translateNotStartedReason(res.reason));
278
282
  } catch (error) {
279
- Raven.captureException(error);
283
+ captureException(error);
280
284
  }
281
285
  }
282
286
  if (res.type === 'progress') {
@@ -10,7 +10,7 @@ const texts = require('../texts');
10
10
  const {stackTraceParser} = require('../utils/stackTraceParser');
11
11
  const suitest = require('../../index');
12
12
  const {logger} = suitest;
13
- const {captureMessage} = require('../utils/sentry/Raven');
13
+ const {captureMessage} = require('../utils/sentry/Sentry');
14
14
 
15
15
  let isReplActive = false;
16
16
  let replModeWasActivated = false;
@@ -5,7 +5,7 @@ const chainPromise = require('../utils/chainPromise');
5
5
  const {fetchTestDefinitions} = require('../utils/chainUtils');
6
6
  const {processServerResponse} = require('../utils/socketChainHelper');
7
7
  const {translateLine} = require('../utils/chainUtils');
8
- const {captureException} = require('../utils/sentry/Raven');
8
+ const {captureException} = require('../utils/sentry/Sentry');
9
9
  const {connectionNotEstablished} = require('../texts');
10
10
 
11
11
  // A map to find promise by chain data object
@@ -13,7 +13,7 @@ const {TEST_COMMAND, TOKEN} = require('../constants/modes');
13
13
  const sessionConstants = require('../constants/session');
14
14
  const {getDevicesDetails} = require('../utils/getDeviceInfo');
15
15
  const {closeSessionUnchained} = require('../commands/closeSession');
16
- const {captureException} = require('../utils/sentry/Raven');
16
+ const {captureException} = require('../utils/sentry/Sentry');
17
17
  const t = require('../texts');
18
18
  const {version} = require('../../package.json');
19
19
  const ipcServer = require('./ipc/server');
package/lib/texts.js CHANGED
@@ -164,6 +164,8 @@ ${leaves}`,
164
164
 
165
165
  testingMinutesExceededMessage: () => 'You reached the limit of testing minutes specified by your subscription plan. If you need more minutes, contact us at sales@suite.st or upgrade your subscription.',
166
166
 
167
+ releasingDeviceMessage: () => 'The device has been disconnected.',
168
+
167
169
  // ipc
168
170
  ipcFailedToCreateServer: template`Failed to create IPC server. Port ${0} is busy.`,
169
171
 
@@ -1,5 +1,5 @@
1
1
  const {stackTraceWrapper} = require('./stackTraceParser');
2
- const {captureException} = require('../utils/sentry/Raven');
2
+ const {captureException} = require('./sentry/Sentry');
3
3
 
4
4
  let currentPromise = Promise.resolve();
5
5
 
@@ -6,7 +6,7 @@ const timestamp = require('./timestamp');
6
6
  const {truncate} = require('./stringUtils');
7
7
  const {Transform} = require('stream');
8
8
  const semver = require('semver');
9
- const Raven = require('raven');
9
+ const {captureException} = require('./sentry/Sentry');
10
10
 
11
11
  /**
12
12
  * Define custom colors
@@ -257,7 +257,7 @@ const createLogger = (config, pairedDeviceContext) => {
257
257
  } else if (appLogger[lowercasedMethod]) {
258
258
  appLogger[lowercasedMethod](...args);
259
259
  } else {
260
- Raven.captureException(new Error(`Received log method "${method}" does not exists`));
260
+ captureException(new Error(`Received log method "${method}" does not exists`));
261
261
  appLogger.log(...args);
262
262
  }
263
263
  };
@@ -1,5 +1,5 @@
1
1
  const {mergeAll} = require('ramda');
2
- const {wrapThrow} = require('./sentry/Raven');
2
+ const {wrapThrow} = require('./sentry/Sentry');
3
3
 
4
4
  const makeChain = (instance, getComposers, data) => {
5
5
  const makeNewChain = wrapThrow(updatedData => {
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  const translate = require('../utils/translateResults');
9
- const Raven = require('raven');
9
+ const sentry = require('./sentry/Sentry');
10
10
 
11
11
  /**
12
12
  * Print progress description to stdout
@@ -21,7 +21,7 @@ function handleProgress(logger, res) {
21
21
  logger.log(` - ${msg}`);
22
22
  }
23
23
  } catch (error) {
24
- Raven.captureException(error);
24
+ sentry.captureException(error);
25
25
  }
26
26
  }
27
27
 
@@ -0,0 +1,120 @@
1
+ /* istanbul ignore file */
2
+
3
+ /**
4
+ * Configure sentry reporting
5
+ */
6
+
7
+ const Sentry = require('@sentry/node');
8
+ const isSuitestUncaughtError = require('./isSuitestUncaughtError');
9
+ const {version} = require('../../../package.json');
10
+
11
+ let isSetup = false;
12
+
13
+ const setUpSentry = (config, authContext) => {
14
+ if (!isSetup && !config.disallowCrashReports) {
15
+ Sentry.init({
16
+ dsn: config.sentryDsn,
17
+ release: version,
18
+ integrations(defaultIntegrations) {
19
+ // Keep behavior compatible with old Raven setup:
20
+ // - autoBreadcrumbs.console = false
21
+ // - autoBreadcrumbs.http = false
22
+ // - captureUnhandledRejections = false
23
+ return defaultIntegrations.filter(integration => {
24
+ return !['Console', 'Http', 'OnUnhandledRejection'].includes(integration.name);
25
+ });
26
+ },
27
+ beforeSend(data) {
28
+ // Populate error report with type of user session
29
+ data.user = {authType: authContext.context.toString()};
30
+
31
+ // send report if enabled in config and only uncaught suitest api errors
32
+ // and if message was sent
33
+ if (
34
+ !config.disallowCrashReports
35
+ && (
36
+ (data.extra && data.extra.networkingError)
37
+ || !data.exception
38
+ || (
39
+ data.exception
40
+ && data.exception.values
41
+ && data.exception.values[0]
42
+ && isSuitestUncaughtError(data.exception.values[0])
43
+ )
44
+ )
45
+ ) {
46
+ return data;
47
+ }
48
+
49
+ return null;
50
+ },
51
+ });
52
+ isSetup = true;
53
+ }
54
+ };
55
+
56
+ /**
57
+ * Best-effort delivery for telemetry events.
58
+ * We intentionally do not fail the main execution flow if Sentry is unavailable.
59
+ */
60
+ function flush() {
61
+ return Sentry.flush(2000)
62
+ .catch(() => undefined);
63
+ }
64
+
65
+ /**
66
+ * Explicitly capture provided exception
67
+ * @param {Error} error
68
+ * @param {Object} [extra]
69
+ * @returns {Promise<unknown>}
70
+ */
71
+ function captureException(error, extra) {
72
+ Sentry.captureException(error, extra);
73
+
74
+ // Keep async contract
75
+ return flush();
76
+ }
77
+
78
+ /**
79
+ * @description Send log message to sentry
80
+ * @param {string} message
81
+ * @param {object} kwargs
82
+ * @returns {Promise<unknown>}
83
+ */
84
+ function captureMessage(message, kwargs) {
85
+ Sentry.captureMessage(message, kwargs);
86
+
87
+ // Keep async contract
88
+ return flush();
89
+ }
90
+
91
+ /**
92
+ * Sentry's implementation of wrap does not trow an exception
93
+ * after it's reported. We need an error to be thrown to user.
94
+ * @param {Function} callback
95
+ * @returns {Function}
96
+ */
97
+ const wrapThrow = callback => (...args) => {
98
+ try {
99
+ return callback.apply(undefined, args);
100
+ } catch (e) {
101
+ /*
102
+ * Capturing Sentry exception is asynchronous.
103
+ * While this function has to be synchronous.
104
+ * If client's application does not catch this exception and node
105
+ * crashes - we'll not get the report.
106
+ * If client's application does catch an error an process it somehow
107
+ * (e.g. mocha), we'll receive an exception in Sentry
108
+ */
109
+ Sentry.captureException(e);
110
+
111
+ throw e;
112
+ }
113
+ };
114
+
115
+ module.exports = {
116
+ captureException,
117
+ captureMessage,
118
+ wrapThrow,
119
+ setUpSentry,
120
+ };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Investigate raven error data.
2
+ * Investigate sentry error data.
3
3
  * Error should not be reported if its not from suitest api code and not of defined SuitestError type
4
4
  */
5
5
 
@@ -8,13 +8,13 @@ const SuitestError = require('../SuitestError');
8
8
  const isSuitestMethod = require('../isSuitestMethod');
9
9
 
10
10
  /**
11
- * @param {*} ravenException
11
+ * @param {*} sentryError
12
12
  * @returns boolean
13
13
  */
14
- function isSuitestUncaughtError(ravenException) {
15
- return ravenException.type !== SuitestError.type // error is not SuitestError
16
- && ravenException.type !== ASSERTION_ERROR_TYPE // error is not node native AssertionError
17
- && ravenException.stacktrace.frames.some(fr => isSuitestMethod(fr.filename)); // but error occurred within suitest api code
14
+ function isSuitestUncaughtError(sentryError) {
15
+ return sentryError.type !== SuitestError.type // error is not SuitestError
16
+ && sentryError.type !== ASSERTION_ERROR_TYPE // error is not node native AssertionError
17
+ && sentryError.stacktrace.frames.some(fr => isSuitestMethod(fr.filename)); // but error occurred within suitest api code
18
18
  }
19
19
 
20
20
  module.exports = isSuitestUncaughtError;
@@ -1,7 +1,7 @@
1
1
  const {TOKEN} = require('../constants/modes');
2
2
  const chainPromise = require('./chainPromise');
3
3
  const {validate, validators} = require('../validation');
4
- const {captureException} = require('./sentry/Raven');
4
+ const {captureException} = require('./sentry/Sentry');
5
5
  const envVars = require('../constants/environment');
6
6
  const messageId = require('../constants/ipcMessageId');
7
7
  const ipcClient = require('../testLauncher/ipc/client');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suitest-js-api",
3
- "version": "4.2.0",
3
+ "version": "4.2.2",
4
4
  "main": "index.js",
5
5
  "repository": "github:SuitestAutomation/suitest-js-api",
6
6
  "author": "Suitest <hello@suite.st>",
@@ -98,10 +98,11 @@
98
98
  "typescript": "5.8.3"
99
99
  },
100
100
  "dependencies": {
101
+ "@sentry/node": "^7.120.3",
101
102
  "@suitest/smst-to-text": "^4.28.5",
102
103
  "@suitest/translate": "^4.31.0",
103
104
  "@types/node": "^14.0.10",
104
- "ajv": "^6.12.2",
105
+ "ajv": "^6.14.0",
105
106
  "ansi-regex": "^5.0.0",
106
107
  "chokidar": "^3.4.0",
107
108
  "colors": "^1.4.0",
@@ -116,7 +117,6 @@
116
117
  "package-json": "^7.0.0",
117
118
  "prettyjson": "^1.2.1",
118
119
  "ramda": "^0.27.0",
119
- "raven": "^2.6.2",
120
120
  "semver": "^7.3.2",
121
121
  "stack-trace": "^0.0.10",
122
122
  "uuid": "8.1.0",
package/suitest.js CHANGED
@@ -1,4 +1,4 @@
1
- require('./lib/utils/sentry/Raven');
1
+ require('./lib/utils/sentry/Sentry');
2
2
  const {clone} = require('ramda');
3
3
 
4
4
  // Commands
@@ -77,7 +77,7 @@ const ipcServer = require('./lib/testLauncher/ipc/server');
77
77
  const Context = require('./lib/utils/Context');
78
78
  const AuthContext = require('./lib/utils/AuthContext');
79
79
  const {configFactory} = require('./config');
80
- const {setUpRaven} = require('./lib/utils/sentry/Raven');
80
+ const {setUpSentry} = require('./lib/utils/sentry/Sentry');
81
81
  const {warnLauncherAndLibHasDiffVersions} = require('./lib/utils/packageMetadataHelper');
82
82
  const {createLogger} = require('./lib/utils/logger');
83
83
 
@@ -106,7 +106,7 @@ class SUITEST_API extends EventEmitter {
106
106
  this.logger = createLogger(this.configuration.config, this.pairedDeviceContext);
107
107
  this.unusedExpressionWatchers = unusedExpressionWatchersFactory(this);
108
108
  this.webSockets = webSocketsFactory(this);
109
- setUpRaven(this.configuration.config, this.authContext);
109
+ setUpSentry(this.configuration.config, this.authContext);
110
110
 
111
111
  this.openSession = (...args) => openSession(this, ...args);
112
112
  this.pairDevice = (...args) => pairDevice(this, ...args);
@@ -1,95 +0,0 @@
1
- /* istanbul ignore file */
2
-
3
- /**
4
- * Configure raven sentry reporting
5
- */
6
-
7
- const Raven = require('raven');
8
- const isSuitestUncaughtError = require('./isSuitestUncaughtError');
9
- const {version} = require('../../../package.json');
10
-
11
- let isSetup = false;
12
-
13
- const setUpRaven = (config, authContext) => {
14
- if (!isSetup && !config.disallowCrashReports) {
15
- Raven
16
- .config(config.sentryDsn, {
17
- release: version,
18
- dataCallback: data => {
19
- // Populate error report with type of user session
20
- data.user = {authType: authContext.context.toString()};
21
-
22
- return data;
23
- },
24
- autoBreadcrumbs: {
25
- 'console': false, // console logging
26
- 'http': false, // rest requests (during unit testing, nock disables some requests)
27
- },
28
- captureUnhandledRejections: false,
29
- shouldSendCallback(data) {
30
- // send report if enabled in config and only uncaught suitest api errors
31
- // and if message was sent
32
-
33
- return !config.disallowCrashReports && (
34
- data.extra.networkingError
35
- || !data.exception
36
- || isSuitestUncaughtError(data.exception[0])
37
- );
38
- },
39
- })
40
- .install(err => {
41
- isSetup = !!err;
42
- });
43
- }
44
- };
45
-
46
- /**
47
- * Explicitly capture provided exception
48
- * @param {Error} error
49
- * @param {Object} [extra]
50
- * @returns {Promise<*>}
51
- */
52
- function captureException(error, extra) {
53
- return new Promise(res => Raven.captureException(error, extra, res));
54
- }
55
-
56
- /**
57
- * @description Send log message to sentry
58
- * @param {string} message
59
- * @param {object} kwargs
60
- * @returns {Promise<unknown>}
61
- */
62
- function captureMessage(message, kwargs) {
63
- return new Promise(res => Raven.captureMessage(message, kwargs, res));
64
- }
65
-
66
- /**
67
- * Sentry's implementation of wrap does not trow an exception
68
- * after it's reported. We need an error to be thrown to user.
69
- * @param {Function} callback
70
- * @returns {Function}
71
- */
72
- const wrapThrow = callback => (...args) => {
73
- try {
74
- return callback.apply(undefined, args);
75
- } catch (e) {
76
- /*
77
- * Capturing Raven exception is asynchronous.
78
- * While this function has to be synchronous.
79
- * If client's application does not catch this exception and node
80
- * crashes - we'll not get the report.
81
- * If client's application does catch an error an process it somehow
82
- * (e.g. mocha), we'll receive an exception in Sentry
83
- */
84
- Raven.captureException(e);
85
-
86
- throw e;
87
- }
88
- };
89
-
90
- module.exports = {
91
- captureException,
92
- captureMessage,
93
- wrapThrow,
94
- setUpRaven,
95
- };
@@ -1,4 +0,0 @@
1
- const sinon = require('sinon');
2
- const raven = require('../sentry/Raven');
3
-
4
- sinon.stub(raven, 'captureException').resolves();