diff --git a/modules/util/JitsiMeetInMemoryLogStorage.js b/modules/util/JitsiMeetInMemoryLogStorage.js new file mode 100644 index 000000000..6e485f31a --- /dev/null +++ b/modules/util/JitsiMeetInMemoryLogStorage.js @@ -0,0 +1,50 @@ +/** + * Implements in memory logs storage, used for testing/debugging. + */ +export default class JitsiMeetInMemoryLogStorage { + + /** + * Creates new JitsiMeetInMemoryLogStorage + */ + constructor() { + /** + * Array of the log entries to keep. + * @type {array} + */ + this.logs = []; + } + + /** + * @returns {boolean} true when this storage is ready or + * false otherwise. + */ + isReady() { + return true; + } + + /** + * Called by the LogCollector to store a series of log lines into + * batch. + * @param {string|object[]} logEntries an array containing strings + * representing log lines or aggregated lines objects. + */ + storeLogs(logEntries) { + for (let i = 0, len = logEntries.length; i < len; i++) { + const logEntry = logEntries[i]; + + if (typeof logEntry === 'object') { + this.logs.push(logEntry.text); + } else { + // Regular message + this.logs.push(logEntry); + } + } + } + + /** + * @returns {array} the collected log entries. + */ + getLogs() { + return this.logs; + } +} diff --git a/react/features/base/logging/middleware.js b/react/features/base/logging/middleware.js index ef602ca73..c16bead1e 100644 --- a/react/features/base/logging/middleware.js +++ b/react/features/base/logging/middleware.js @@ -6,8 +6,12 @@ import { APP_WILL_MOUNT } from '../../app'; import JitsiMeetJS, { LIB_WILL_INIT } from '../lib-jitsi-meet'; import { MiddlewareRegistry } from '../redux'; +import JitsiMeetInMemoryLogStorage + from '../../../../modules/util/JitsiMeetInMemoryLogStorage'; import JitsiMeetLogStorage from '../../../../modules/util/JitsiMeetLogStorage'; +import { isTestModeEnabled } from '../testing'; + import { SET_LOGGING_CONFIG } from './actionTypes'; declare var APP: Object; @@ -67,10 +71,11 @@ function _appWillMount({ getState }, next, action) { * * @param {Object} loggingConfig - The configuration with which logging is to be * initialized. + * @param {boolean} isTestingEnabled - Is debug logging enabled. * @private * @returns {void} */ -function _initLogging(loggingConfig) { +function _initLogging(loggingConfig, isTestingEnabled) { // Create the LogCollector and register it as the global log transport. It // is done early to capture as much logs as possible. Captured logs will be // cached, before the JitsiMeetLogStorage gets ready (statistics module is @@ -81,6 +86,16 @@ function _initLogging(loggingConfig) { APP.logCollector = new Logger.LogCollector(new JitsiMeetLogStorage()); Logger.addGlobalTransport(APP.logCollector); JitsiMeetJS.addGlobalLogTransport(APP.logCollector); + + if (isTestingEnabled) { + APP.debugLogs = new JitsiMeetInMemoryLogStorage(); + const debugLogCollector = new Logger.LogCollector( + APP.debugLogs, { storeInterval: 1000 }); + + Logger.addGlobalTransport(debugLogCollector); + JitsiMeetJS.addGlobalLogTransport(debugLogCollector); + debugLogCollector.start(); + } } } @@ -121,6 +136,7 @@ function _libWillInit({ getState }, next, action) { function _setLoggingConfig({ getState }, next, action) { const result = next(action); const newValue = getState()['features/base/logging'].config; + const isTestingEnabled = isTestModeEnabled(getState()); // TODO Generally, we'll want to _setLogLevels and _initLogging only if the // logging config values actually change. @@ -131,7 +147,7 @@ function _setLoggingConfig({ getState }, next, action) { _setLogLevels(Logger, newValue); _setLogLevels(JitsiMeetJS, newValue); - _initLogging(newValue); + _initLogging(newValue, isTestingEnabled); return result; } diff --git a/react/features/base/testing/components/TestHint.web.js b/react/features/base/testing/components/TestHint.web.js new file mode 100644 index 000000000..e69de29bb