1'use strict'; 2const common = require('../common'); 3 4common.skipIfInspectorDisabled(); 5 6const assert = require('assert'); 7const { resolve: UrlResolve } = require('url'); 8const fixtures = require('../common/fixtures'); 9const { NodeInstance } = require('../common/inspector-helper.js'); 10 11function assertScopeValues({ result }, expected) { 12 const unmatched = new Set(Object.keys(expected)); 13 for (const actual of result) { 14 const value = expected[actual.name]; 15 assert.strictEqual(actual.value.value, value); 16 unmatched.delete(actual.name); 17 } 18 assert.deepStrictEqual(Array.from(unmatched.values()), []); 19} 20 21async function testBreakpointOnStart(session) { 22 console.log('[test]', 23 'Verifying debugger stops on start (--inspect-brk option)'); 24 const commands = [ 25 { 'method': 'Runtime.enable' }, 26 { 'method': 'Debugger.enable' }, 27 { 'method': 'Debugger.setPauseOnExceptions', 28 'params': { 'state': 'none' } }, 29 { 'method': 'Debugger.setAsyncCallStackDepth', 30 'params': { 'maxDepth': 0 } }, 31 { 'method': 'Profiler.enable' }, 32 { 'method': 'Profiler.setSamplingInterval', 33 'params': { 'interval': 100 } }, 34 { 'method': 'Debugger.setBlackboxPatterns', 35 'params': { 'patterns': [] } }, 36 { 'method': 'Runtime.runIfWaitingForDebugger' }, 37 ]; 38 39 await session.send(commands); 40 await session.waitForBreakOnLine( 41 0, UrlResolve(session.scriptURL().toString(), 'message.mjs')); 42} 43 44async function testBreakpoint(session) { 45 console.log('[test]', 'Setting a breakpoint and verifying it is hit'); 46 const commands = [ 47 { 'method': 'Debugger.setBreakpointByUrl', 48 'params': { 'lineNumber': 7, 49 'url': session.scriptURL(), 50 'columnNumber': 0, 51 'condition': '' } }, 52 { 'method': 'Debugger.resume' }, 53 ]; 54 await session.send(commands); 55 const { scriptSource } = await session.send({ 56 'method': 'Debugger.getScriptSource', 57 'params': { 'scriptId': session.mainScriptId }, 58 }); 59 assert(scriptSource && (scriptSource.includes(session.script())), 60 `Script source is wrong: ${scriptSource}`); 61 62 await session.waitForConsoleOutput('log', ['A message', 5]); 63 const paused = await session.waitForBreakOnLine(7, session.scriptURL()); 64 const scopeId = paused.params.callFrames[0].scopeChain[0].object.objectId; 65 66 console.log('[test]', 'Verify we can read current application state'); 67 const response = await session.send({ 68 'method': 'Runtime.getProperties', 69 'params': { 70 'objectId': scopeId, 71 'ownProperties': false, 72 'accessorPropertiesOnly': false, 73 'generatePreview': true 74 } 75 }); 76 assertScopeValues(response, { t: 1001, k: 1, message: 'A message' }); 77 78 let { result } = await session.send({ 79 'method': 'Debugger.evaluateOnCallFrame', 'params': { 80 'callFrameId': session.pausedDetails().callFrames[0].callFrameId, 81 'expression': 'k + t', 82 'objectGroup': 'console', 83 'includeCommandLineAPI': true, 84 'silent': false, 85 'returnByValue': false, 86 'generatePreview': true 87 } 88 }); 89 90 assert.strictEqual(result.value, 1002); 91 92 result = (await session.send({ 93 'method': 'Runtime.evaluate', 'params': { 94 'expression': '5 * 5' 95 } 96 })).result; 97 assert.strictEqual(result.value, 25); 98} 99 100async function runTest() { 101 const child = new NodeInstance(['--inspect-brk=0'], '', 102 fixtures.path('es-modules/loop.mjs')); 103 104 const session = await child.connectInspectorSession(); 105 await testBreakpointOnStart(session); 106 await testBreakpoint(session); 107 await session.runToCompletion(); 108 assert.strictEqual((await child.expectShutdown()).exitCode, 55); 109} 110 111runTest().then(common.mustCall()); 112