From 3e111b1dae8eec90c20fe7ed037c501a577a10b6 Mon Sep 17 00:00:00 2001 From: MaxymS Date: Tue, 26 Jul 2022 15:21:40 +0300 Subject: [PATCH] SUIT-16525 - log levels configuration was improved. Logic was adopted for js-api v3 version --- config/index.js | 2 +- index.d.ts | 8 +++++++ lib/api/webSockets.js | 10 ++++++-- lib/chains/locationChain.js | 15 ++++++++++-- lib/chains/openUrlChain.js | 15 ++++++++++-- lib/composers/thenComposer.js | 17 ++++++++++--- lib/utils/logger.js | 11 +++++++-- lib/utils/socketChainHelper.js | 17 ++++++------- lib/validation/jsonSchemas.js | 4 ++++ test/utils/socketChainHelper.test.js | 36 ++++++++++++++++------------ 10 files changed, 100 insertions(+), 35 deletions(-) diff --git a/config/index.js b/config/index.js index 6410bc44..c86b0985 100644 --- a/config/index.js +++ b/config/index.js @@ -19,7 +19,7 @@ const DEFAULT_TIMEOUT = 2000; const overridableFields = [ 'tokenId', 'tokenPassword', 'concurrency', 'preset', 'presets', 'deviceId', 'appConfigId', 'inspect', 'inspectBrk', 'logLevel', 'logDir', 'timestamp', 'configFile', 'disallowCrashReports', 'defaultTimeout', 'screenshotDir', - 'includeChangelist', + 'includeChangelist', 'testLines', 'testErrors', 'networkLogs', 'consoleLogs', // launcher common extra log options ]; const serverAddress = process.env[envVars.SUITEST_BE_SERVER] || 'the.suite.st'; diff --git a/index.d.ts b/index.d.ts index c1536114..637196ab 100644 --- a/index.d.ts +++ b/index.d.ts @@ -63,6 +63,10 @@ declare namespace suitest { setContinueOnFatalError(continueOnFatalError: ConfigureOptions['continueOnFatalError']): void; setDisallowCrashReports(disallowCrashReports: ConfigureOptions['disallowCrashReports']): void; setLogLevel(logLevel: ConfigureOptions['logLevel']): void; + setLogLevel(testLines: ConfigureOptions['testLines']): void; + setLogLevel(testErrors: ConfigureOptions['testErrors']): void; + setLogLevel(networkLogs: ConfigureOptions['networkLogs']): void; + setLogLevel(consoleLogs: ConfigureOptions['consoleLogs']): void; // subjects location(): LocationChain; @@ -277,6 +281,10 @@ declare namespace suitest { interface ConfigureOptions { logLevel: 'silent'|'normal'|'verbose'|'debug'|'silly'; + testLines: 'silent'|'normal'|'verbose'|'debug'|'silly'; + testErrors: 'silent'|'normal'|'verbose'|'debug'|'silly'; + networkLogs?: 'silent'|'normal'|'verbose'|'debug'|'silly'; + consoleLogs?: 'silent'|'normal'|'verbose'|'debug'|'silly'; disallowCrashReports: boolean; continueOnFatalError: boolean; defaultTimeout: number; diff --git a/lib/api/webSockets.js b/lib/api/webSockets.js index 9fd4aab2..e882495d 100644 --- a/lib/api/webSockets.js +++ b/lib/api/webSockets.js @@ -76,7 +76,10 @@ const webSocketsFactory = (self) => { const requestBody = logItem.request && logItem.request.requestBody; const responseBody = logItem.response && logItem.response.responseBody; - if (config.logLevel === logLevels.debug) { + if ( + (config.networkLogs && config.networkLogs === logLevels.debug) || + (!config.networkLogs && config.logLevel === logLevels.debug) + ) { return logger.debug( 'Incoming request log (details omitted)\n' + `ItemId: ${requestId}\n` + @@ -86,7 +89,10 @@ const webSocketsFactory = (self) => { (responseBody ? 'ResponseBody: [body]' : '') + '\n', ); - } else if (config.logLevel === logLevels.silly) { + } else if ( + (config.networkLogs && config.networkLogs === logLevels.silly) || + (!config.networkLogs && config.logLevel === logLevels.silly) + ) { return logger.silly( 'Incoming request log\n' + `ItemId: ${requestId}\n` + diff --git a/lib/chains/locationChain.js b/lib/chains/locationChain.js index 2de7e97b..9bf130a4 100644 --- a/lib/chains/locationChain.js +++ b/lib/chains/locationChain.js @@ -16,13 +16,18 @@ const { gettersComposer, makeToJSONComposer, } = require('../composers'); -const {getRequestType} = require('../utils/socketChainHelper'); +const { + getRequestType, + processServerResponse, +} = require('../utils/socketChainHelper'); const { applyTimeout, applyNegation, } = require('../utils/chainUtils'); const locationFactory = (classInstance) => { + const {logger} = classInstance; + const toJSON = data => { const type = getRequestType(data); const subject = {type: 'location'}; @@ -47,7 +52,13 @@ const locationFactory = (classInstance) => { // Build Composers const toStringComposer = makeToStringComposer(toJSON); - const thenComposer = makeThenComposer(toJSON); + const thenComposer = makeThenComposer(toJSON, processServerResponse( + logger, + { + logLevel: classInstance.getConfig().logLevel, + testLines: classInstance.getConfig().testLines, + testErrors: classInstance.getConfig().testErrors, + })); const toJSONComposer = makeToJSONComposer(toJSON); /** diff --git a/lib/chains/openUrlChain.js b/lib/chains/openUrlChain.js index b4a95d6b..5586bd50 100644 --- a/lib/chains/openUrlChain.js +++ b/lib/chains/openUrlChain.js @@ -10,10 +10,15 @@ const { makeToJSONComposer, } = require('../composers'); const {invalidInputMessage} = require('../texts'); -const {getRequestType} = require('../utils/socketChainHelper'); +const { + getRequestType, + processServerResponse, +} = require('../utils/socketChainHelper'); const {validate, validators} = require('../validation'); const openUrlFactory = (classInstance) => { + const {logger} = classInstance; + const toJSON = data => ({ type: getRequestType(data, false), request: { @@ -24,7 +29,13 @@ const openUrlFactory = (classInstance) => { // Build Composers const toStringComposer = makeToStringComposer(toJSON); - const thenComposer = makeThenComposer(toJSON); + const thenComposer = makeThenComposer(toJSON, processServerResponse( + logger, + { + logLevel: classInstance.getConfig().logLevel, + testLines: classInstance.getConfig().testLines, + testErrors: classInstance.getConfig().testErrors, + })); const toJSONComposer = makeToJSONComposer(toJSON); /** diff --git a/lib/composers/thenComposer.js b/lib/composers/thenComposer.js index ccbbcbf5..ccd760f6 100644 --- a/lib/composers/thenComposer.js +++ b/lib/composers/thenComposer.js @@ -39,7 +39,7 @@ const makeThenComposer = (getSocketMessage, callback, beforeSend) => makeMethodC if (beforeSend) { beforeSend(data); } else { - const translation = translateLine(dataToTranslate, config.logLevel); + const translation = translateLine(dataToTranslate, config.testLines || config.logLevel); if (translation) { logger.log(translation); @@ -49,11 +49,22 @@ const makeThenComposer = (getSocketMessage, callback, beforeSend) => makeMethodC .then(() => webSockets.send(socketMessage).then(result => { return callback ? callback(result, data, socketMessage) - : processServerResponse(logger, config.logLevel)(result, data, socketMessage, snippets); + : processServerResponse( + logger, + { + logLevel: config.logLevel, + testLines: config.testLines, + testErrors: config.testError, + })(result, data, socketMessage, snippets); }, error => { return callback ? callback(error, data, socketMessage) - : processServerResponse(logger, config.logLevel)(error, data, socketMessage, snippets); + : processServerResponse(logger, + { + logLevel: config.logLevel, + testLines: config.testLines, + testErrors: config.testErrors, + })(error, data, socketMessage, snippets); })) .catch(err => { if (err instanceof SuitestError && err.code === SuitestError.AUTH_NOT_ALLOWED) { diff --git a/lib/utils/logger.js b/lib/utils/logger.js index 1d45d380..291240ef 100644 --- a/lib/utils/logger.js +++ b/lib/utils/logger.js @@ -191,8 +191,12 @@ const createLogger = (config, pairedDeviceContext) => { const log = method => (...messages) => { // check if logging is allowed by logging level specified in config /* istanbul ignore if */ - if (!method.levels.includes(config.logLevel)) + if ( + !(config.networkLogs && method.levels.includes(config.networkLogs) && method.key === 'debug') && + !(!config.networkLogs && method.levels.includes(config.logLevel)) + ) { return; + } clearTimeout(delayedLog); @@ -321,7 +325,10 @@ const createLogger = (config, pairedDeviceContext) => { */ getAppOutput: (subtype, data) => { // No need to display anything - if (config.logLevel === logLevels.silent) { + if ( + (config.consoleLogs && config.consoleLogs === logLevels.silent) || + (!config.consoleLogs && config.logLevel === logLevels.silent) + ) { return; } diff --git a/lib/utils/socketChainHelper.js b/lib/utils/socketChainHelper.js index 27bb9455..7de35f1a 100644 --- a/lib/utils/socketChainHelper.js +++ b/lib/utils/socketChainHelper.js @@ -24,11 +24,17 @@ const assertionErrorTypes = ['queryFailed', 'appRunning', 'appNotRunning', 'quer const processServerResponse = (logger, verbosity) => function processServerResponseHandler(res, data, jsonMessage, snippets) { const isSnippet = data.type === 'runSnippet'; + const isSuccess = res.result === 'success' || res.result === 'warning'; + const isEval = res.contentType === 'eval'; + const isTestLine = res.contentType === 'testLine'; + const isQuery = res.contentType === 'query'; + const isTakeScreenshot = res.contentType === 'takeScreenshot'; + const isAborted = res.result === 'aborted'; const isAssertionError = isSnippet || assertionErrorTypes.includes(normalizeErrorType(res)); const responseForError = getResponseForError(res); const message = getErrorMessage({ response: res, - verbosity, + verbosity: verbosity ? verbosity.testErrors || verbosity.logLevel : undefined, jsonMessage, snippets, }); @@ -37,12 +43,6 @@ const processServerResponse = (logger, verbosity) => throw err; }; const infoMessage = prefix => getInfoErrorMessage(message, prefix, res, data.stack); - const isSuccess = res.result === 'success' || res.result === 'warning'; - const isEval = res.contentType === 'eval'; - const isTestLine = res.contentType === 'testLine'; - const isQuery = res.contentType === 'query'; - const isTakeScreenshot = res.contentType === 'takeScreenshot'; - const isAborted = res.result === 'aborted'; // warnings if (res.result === 'warning') { @@ -94,7 +94,8 @@ const processServerResponse = (logger, verbosity) => if (isSuccess) { if (isSnippet) { const snippet = getSnippetLogs({ - verbosity: mapLogLevelsToTranslationModule[verbosity], + // eslint-disable-next-line max-len + verbosity: mapLogLevelsToTranslationModule[verbosity ? verbosity.testLines || verbosity.logLevel : undefined], definitions: snippets, results: [], testId: jsonMessage.request.val, diff --git a/lib/validation/jsonSchemas.js b/lib/validation/jsonSchemas.js index 34cdff52..561ba387 100644 --- a/lib/validation/jsonSchemas.js +++ b/lib/validation/jsonSchemas.js @@ -370,6 +370,10 @@ schemas[validationKeys.CONFIGURE] = { 'logDir': {'type': 'string'}, 'defaultTimeout': {'type': 'number'}, 'logLevel': {'enum': ['silent', 'normal', 'verbose', 'debug', 'silly']}, + 'testLines': {'enum': ['silent', 'normal', 'verbose', 'debug', 'silly']}, + 'testErrors': {'enum': ['silent', 'normal', 'verbose', 'debug', 'silly']}, + 'networkLogs': {'enum': ['silent', 'normal', 'verbose', 'debug', 'silly']}, + 'consoleLogs': {'enum': ['silent', 'normal', 'verbose', 'debug', 'silly']}, 'orgId': {'type': 'string'}, 'repl': {'type': 'boolean'}, 'timestamp': {'type': 'string'}, diff --git a/test/utils/socketChainHelper.test.js b/test/utils/socketChainHelper.test.js index c031ea05..65e8fdc8 100644 --- a/test/utils/socketChainHelper.test.js +++ b/test/utils/socketChainHelper.test.js @@ -31,48 +31,54 @@ describe('socket chain helpers', () => { }, }; + const logVerbose = { + logLevel: 'verbose', + testLines: undefined, + testErrors: undefined, + }; + // query - assert.throws(() => processServerResponse(logger, 'verbose')({ + assert.throws(() => processServerResponse(logger, logVerbose)({ contentType: 'query', }, {stack: ''}, chain), SuitestError, 'query fail'); - assert.strictEqual(processServerResponse(logger, 'verbose')({ + assert.strictEqual(processServerResponse(logger, logVerbose)({ contentType: 'query', cookieExists: true, }, {stack: ''}, chain), true, 'query cookie exists'); - assert.strictEqual(processServerResponse(logger, 'verbose')({ + assert.strictEqual(processServerResponse(logger, logVerbose)({ contentType: 'query', elementExists: false, }, {stack: ''}, chain), undefined, 'query element not found'); // eval - assert.strictEqual(processServerResponse(logger, 'verbose')({ + assert.strictEqual(processServerResponse(logger, logVerbose)({ contentType: 'eval', result: 'success', errorType: 'error', }, {stack: ''}, chain), true, 'evals success'); - assert.strictEqual(processServerResponse(logger, 'verbose')({ + assert.strictEqual(processServerResponse(logger, logVerbose)({ contentType: 'eval', result: 'fail', errorType: 'queryFailed', }, {stack: ''}, chain), false, 'eval fail'); // test line - assert.strictEqual(processServerResponse(logger, 'verbose')({ + assert.strictEqual(processServerResponse(logger, logVerbose)({ contentType: 'testLine', result: 'success', }, {stack: ''}, chain), undefined, 'testLine success'); // all other - assert.throws(() => processServerResponse(logger, 'verbose')({ + assert.throws(() => processServerResponse(logger, logVerbose)({ result: 'fail', }, {stack: ''}, chain), Error, 'testLine fail'); - assert.throws(() => processServerResponse(logger, 'verbose')({ + assert.throws(() => processServerResponse(logger, logVerbose)({ result: 'error', }, {stack: ''}, chain), Error, 'testLine fail'); // execution error - assert.throws(() => processServerResponse(logger, 'verbose')({ + assert.throws(() => processServerResponse(logger, logVerbose)({ executionError: 'appNotRunning', }, {stack: ''}, chain), Error, 'execution error'); assert.throws( - () => processServerResponse(logger, 'verbose')({ + () => processServerResponse(logger, logVerbose)({ contentType: 'eval', result: 'fail', errorType: 'invalidInput', @@ -147,7 +153,7 @@ describe('socket chain helpers', () => { ); assert.throws( - () => processServerResponse(logger, 'verbose')( + () => processServerResponse(logger, logVerbose)( { result: 'fail', errorType: 'queryFailed', @@ -162,7 +168,7 @@ describe('socket chain helpers', () => { ); assert.throws( - () => processServerResponse(logger, 'verbose')( + () => processServerResponse(logger, logVerbose)( { result: 'fail', expression: [ @@ -240,7 +246,7 @@ describe('socket chain helpers', () => { ); assert.throws( - () => processServerResponse(logger, 'verbose')( + () => processServerResponse(logger, logVerbose)( { result: 'fail', expression: [ @@ -303,7 +309,7 @@ describe('socket chain helpers', () => { ); assert.throws( - () => processServerResponse(logger, 'verbose')( + () => processServerResponse(logger, logVerbose)( { result: 'fail', expression: [{ @@ -363,7 +369,7 @@ describe('socket chain helpers', () => { sinon.stub(logger, 'warn'); try { - assert.strictEqual(processServerResponse(logger, 'verbose')({ + assert.strictEqual(processServerResponse(logger, logVerbose)({ contentType: 'eval', result: 'warning', errorType: 'error',