Skip to content

Commit 2922028

Browse files
mcollinatargos
authored andcommitted
inspector: expose original console
Adds require('inspector').console, mapping it to the original global.console of V8. This enables applications to send messages to the inspector console programmatically. Fixes: #21651 PR-URL: #21659 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 0108ff6 commit 2922028

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

doc/api/inspector.md

+11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ started.
2828
If wait is `true`, will block until a client has connected to the inspect port
2929
and flow control has been passed to the debugger client.
3030

31+
### inspector.console
32+
33+
An object to send messages to the remote inspector console.
34+
35+
```js
36+
require('inspector').console.log('a message');
37+
```
38+
39+
The inspector console does not have API parity with Node.js
40+
console.
41+
3142
### inspector.close()
3243

3344
Deactivate the inspector. Blocks until there are no active connections.

lib/inspector.js

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const {
1111
} = require('internal/errors').codes;
1212
const util = require('util');
1313
const { Connection, open, url } = process.binding('inspector');
14+
const { originalConsole } = require('internal/process/per_thread');
1415

1516
if (!Connection || !require('internal/worker').isMainThread)
1617
throw new ERR_INSPECTOR_NOT_AVAILABLE();
@@ -103,5 +104,6 @@ module.exports = {
103104
open: (port, host, wait) => open(port, host, !!wait),
104105
close: process._debugEnd,
105106
url: url,
107+
console: originalConsole,
106108
Session
107109
};

lib/internal/bootstrap/node.js

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@
120120

121121
const browserGlobals = !process._noBrowserGlobals;
122122
if (browserGlobals) {
123+
// we are setting this here to foward it to the inspector later
124+
perThreadSetup.originalConsole = global.console;
123125
setupGlobalTimeouts();
124126
setupGlobalConsole();
125127
setupGlobalURL();

test/common/inspector-helper.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const fixtures = require('../common/fixtures');
77
const { spawn } = require('child_process');
88
const { parse: parseURL } = require('url');
99
const { getURLFromFilePath } = require('internal/url');
10+
const { EventEmitter } = require('events');
1011

1112
const _MAINSCRIPT = fixtures.path('loop.js');
1213
const DEBUG = false;
@@ -311,10 +312,12 @@ class InspectorSession {
311312
}
312313
}
313314

314-
class NodeInstance {
315+
class NodeInstance extends EventEmitter {
315316
constructor(inspectorFlags = ['--inspect-brk=0'],
316317
scriptContents = '',
317318
scriptFile = _MAINSCRIPT) {
319+
super();
320+
318321
this._scriptPath = scriptFile;
319322
this._script = scriptFile ? null : scriptContents;
320323
this._portCallback = null;
@@ -326,7 +329,10 @@ class NodeInstance {
326329
this._unprocessedStderrLines = [];
327330

328331
this._process.stdout.on('data', makeBufferingDataCallback(
329-
(line) => console.log('[out]', line)));
332+
(line) => {
333+
this.emit('stdout', line);
334+
console.log('[out]', line);
335+
}));
330336

331337
this._process.stderr.on('data', makeBufferingDataCallback(
332338
(message) => this.onStderrLine(message)));
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
const common = require('../common');
5+
common.skipIfInspectorDisabled();
6+
7+
const { NodeInstance } = require('../common/inspector-helper.js');
8+
const assert = require('assert');
9+
10+
async function runTest() {
11+
const script = 'require(\'inspector\').console.log(\'hello world\');';
12+
const child = new NodeInstance('--inspect-brk=0', script, '');
13+
14+
let out = '';
15+
child.on('stdout', (line) => out += line);
16+
17+
const session = await child.connectInspectorSession();
18+
19+
const commands = [
20+
{ 'method': 'Runtime.enable' },
21+
{ 'method': 'Runtime.runIfWaitingForDebugger' }
22+
];
23+
24+
session.send(commands);
25+
26+
const msg = await session.waitForNotification('Runtime.consoleAPICalled');
27+
28+
assert.strictEqual(msg.params.type, 'log');
29+
assert.deepStrictEqual(msg.params.args, [{
30+
type: 'string',
31+
value: 'hello world'
32+
}]);
33+
assert.strictEqual(out, '');
34+
35+
session.disconnect();
36+
}
37+
38+
common.crashOnUnhandledRejection();
39+
runTest();

0 commit comments

Comments
 (0)