|
|
|
'use strict';
|
|
|
|
const common = require('../common');
|
|
|
|
common.skipIfInspectorDisabled();
|
|
|
|
const assert = require('assert');
|
|
|
|
const inspector = require('inspector');
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
// This test case will set a breakpoint 4 lines below
|
|
|
|
function debuggedFunction() {
|
|
|
|
let i;
|
|
|
|
let accum = 0;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
accum += i;
|
|
|
|
}
|
|
|
|
return accum;
|
|
|
|
}
|
|
|
|
|
|
|
|
let scopeCallback = null;
|
|
|
|
|
|
|
|
function checkScope(session, scopeId) {
|
|
|
|
session.post('Runtime.getProperties', {
|
|
|
|
'objectId': scopeId,
|
|
|
|
'ownProperties': false,
|
|
|
|
'accessorPropertiesOnly': false,
|
|
|
|
'generatePreview': true
|
|
|
|
}, scopeCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
function debuggerPausedCallback(session, notification) {
|
|
|
|
const params = notification['params'];
|
|
|
|
const callFrame = params['callFrames'][0];
|
|
|
|
const scopeId = callFrame['scopeChain'][0]['object']['objectId'];
|
|
|
|
checkScope(session, scopeId);
|
|
|
|
}
|
|
|
|
|
|
|
|
function waitForWarningSkipAsyncStackTraces(resolve) {
|
|
|
|
process.once('warning', function(warning) {
|
|
|
|
if (warning.code === 'INSPECTOR_ASYNC_STACK_TRACES_NOT_AVAILABLE') {
|
|
|
|
waitForWarningSkipAsyncStackTraces(resolve);
|
|
|
|
} else {
|
|
|
|
resolve(warning);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async function testNoCrashWithExceptionInCallback() {
|
|
|
|
// There is a deliberate exception in the callback
|
|
|
|
const session = new inspector.Session();
|
|
|
|
session.connect();
|
|
|
|
const error = new Error('We expect this');
|
|
|
|
console.log('Expecting warning to be emitted');
|
|
|
|
const promise = new Promise(waitForWarningSkipAsyncStackTraces);
|
|
|
|
session.post('Console.enable', () => { throw error; });
|
|
|
|
assert.strictEqual(await promise, error);
|
|
|
|
session.disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
function testSampleDebugSession() {
|
|
|
|
let cur = 0;
|
|
|
|
const failures = [];
|
|
|
|
const expects = {
|
|
|
|
i: [0, 1, 2, 3, 4],
|
|
|
|
accum: [0, 0, 1, 3, 6]
|
|
|
|
};
|
|
|
|
scopeCallback = function(error, result) {
|
|
|
|
const i = cur++;
|
|
|
|
let v, actual, expected;
|
|
|
|
for (v of result['result']) {
|
|
|
|
actual = v['value']['value'];
|
|
|
|
expected = expects[v['name']][i];
|
|
|
|
if (actual !== expected) {
|
|
|
|
failures.push('Iteration ' + i + ' variable: ' + v['name'] +
|
|
|
|
' expected: ' + expected + ' actual: ' + actual);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const session = new inspector.Session();
|
|
|
|
session.connect();
|
|
|
|
let secondSessionOpened = false;
|
|
|
|
const secondSession = new inspector.Session();
|
|
|
|
try {
|
|
|
|
secondSession.connect();
|
|
|
|
secondSessionOpened = true;
|
|
|
|
} catch (error) {
|
|
|
|
// expected as the session already exists
|
|
|
|
}
|
|
|
|
assert.strictEqual(secondSessionOpened, false);
|
|
|
|
session.on('Debugger.paused',
|
|
|
|
(notification) => debuggerPausedCallback(session, notification));
|
|
|
|
let cbAsSecondArgCalled = false;
|
|
|
|
assert.throws(() => {
|
|
|
|
session.post('Debugger.enable', function() {}, function() {});
|
|
|
|
}, TypeError);
|
|
|
|
session.post('Debugger.enable', () => cbAsSecondArgCalled = true);
|
|
|
|
session.post('Debugger.setBreakpointByUrl', {
|
|
|
|
'lineNumber': 12,
|
|
|
|
'url': path.resolve(__dirname, __filename),
|
|
|
|
'columnNumber': 0,
|
|
|
|
'condition': ''
|
|
|
|
});
|
|
|
|
|
|
|
|
debuggedFunction();
|
|
|
|
assert.deepStrictEqual(cbAsSecondArgCalled, true);
|
|
|
|
assert.deepStrictEqual(failures, []);
|
|
|
|
assert.strictEqual(cur, 5);
|
|
|
|
scopeCallback = null;
|
|
|
|
session.disconnect();
|
|
|
|
assert.throws(() => session.post('Debugger.enable'), (e) => !!e);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function testNoCrashConsoleLogBeforeThrow() {
|
|
|
|
const session = new inspector.Session();
|
|
|
|
session.connect();
|
|
|
|
let attempt = 1;
|
|
|
|
process.on('warning', common.mustCall(3));
|
|
|
|
session.on('inspectorNotification', () => {
|
|
|
|
if (attempt++ > 3)
|
|
|
|
return;
|
|
|
|
console.log('console.log in handler');
|
|
|
|
throw new Error('Exception in handler');
|
|
|
|
});
|
|
|
|
session.post('Runtime.enable');
|
|
|
|
console.log('Did not crash');
|
|
|
|
session.disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
common.crashOnUnhandledRejection();
|
|
|
|
|
|
|
|
async function doTests() {
|
|
|
|
await testNoCrashWithExceptionInCallback();
|
|
|
|
testSampleDebugSession();
|
|
|
|
let breakpointHit = false;
|
|
|
|
scopeCallback = () => (breakpointHit = true);
|
|
|
|
debuggedFunction();
|
|
|
|
assert.strictEqual(breakpointHit, false);
|
|
|
|
testSampleDebugSession();
|
|
|
|
await testNoCrashConsoleLogBeforeThrow();
|
|
|
|
}
|
|
|
|
|
|
|
|
doTests();
|