diff --git a/doc/api/inspector.md b/doc/api/inspector.md index 7b1adcc47b32a0..8ab827bd1f9145 100644 --- a/doc/api/inspector.md +++ b/doc/api/inspector.md @@ -28,6 +28,17 @@ started. If wait is `true`, will block until a client has connected to the inspect port and flow control has been passed to the debugger client. +### inspector.console + +An object to send messages to the remote inspector console. + +```js +require('inspector').console.log('a message'); +``` + +The inspector console does not have API parity with Node.js +console. + ### inspector.close() Deactivate the inspector. Blocks until there are no active connections. diff --git a/lib/inspector.js b/lib/inspector.js index f4ec71fd6c2105..f4e365b774be79 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -11,6 +11,7 @@ const { } = require('internal/errors').codes; const util = require('util'); const { Connection, open, url } = process.binding('inspector'); +const { originalConsole } = require('internal/process/per_thread'); if (!Connection || !require('internal/worker').isMainThread) throw new ERR_INSPECTOR_NOT_AVAILABLE(); @@ -103,5 +104,6 @@ module.exports = { open: (port, host, wait) => open(port, host, !!wait), close: process._debugEnd, url: url, + console: originalConsole, Session }; diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 5904e5dd0ad564..e433c67aa42c8b 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -120,6 +120,8 @@ const browserGlobals = !process._noBrowserGlobals; if (browserGlobals) { + // we are setting this here to foward it to the inspector later + perThreadSetup.originalConsole = global.console; setupGlobalTimeouts(); setupGlobalConsole(); setupGlobalURL(); diff --git a/test/common/inspector-helper.js b/test/common/inspector-helper.js index e590349f9c2b71..13726049798f0e 100644 --- a/test/common/inspector-helper.js +++ b/test/common/inspector-helper.js @@ -7,6 +7,7 @@ const fixtures = require('../common/fixtures'); const { spawn } = require('child_process'); const { parse: parseURL } = require('url'); const { getURLFromFilePath } = require('internal/url'); +const { EventEmitter } = require('events'); const _MAINSCRIPT = fixtures.path('loop.js'); const DEBUG = false; @@ -311,10 +312,12 @@ class InspectorSession { } } -class NodeInstance { +class NodeInstance extends EventEmitter { constructor(inspectorFlags = ['--inspect-brk=0'], scriptContents = '', scriptFile = _MAINSCRIPT) { + super(); + this._scriptPath = scriptFile; this._script = scriptFile ? null : scriptContents; this._portCallback = null; @@ -326,7 +329,10 @@ class NodeInstance { this._unprocessedStderrLines = []; this._process.stdout.on('data', makeBufferingDataCallback( - (line) => console.log('[out]', line))); + (line) => { + this.emit('stdout', line); + console.log('[out]', line); + })); this._process.stderr.on('data', makeBufferingDataCallback( (message) => this.onStderrLine(message))); diff --git a/test/sequential/test-inspector-console.js b/test/sequential/test-inspector-console.js new file mode 100644 index 00000000000000..6a06c798881654 --- /dev/null +++ b/test/sequential/test-inspector-console.js @@ -0,0 +1,39 @@ +// Flags: --expose-internals +'use strict'; + +const common = require('../common'); +common.skipIfInspectorDisabled(); + +const { NodeInstance } = require('../common/inspector-helper.js'); +const assert = require('assert'); + +async function runTest() { + const script = 'require(\'inspector\').console.log(\'hello world\');'; + const child = new NodeInstance('--inspect-brk=0', script, ''); + + let out = ''; + child.on('stdout', (line) => out += line); + + const session = await child.connectInspectorSession(); + + const commands = [ + { 'method': 'Runtime.enable' }, + { 'method': 'Runtime.runIfWaitingForDebugger' } + ]; + + session.send(commands); + + const msg = await session.waitForNotification('Runtime.consoleAPICalled'); + + assert.strictEqual(msg.params.type, 'log'); + assert.deepStrictEqual(msg.params.args, [{ + type: 'string', + value: 'hello world' + }]); + assert.strictEqual(out, ''); + + session.disconnect(); +} + +common.crashOnUnhandledRejection(); +runTest();