1'use strict'; 2const Path = require('path'); 3 4const { test } = require('tap'); 5 6const startCLI = require('./start-cli'); 7 8test('custom port', (t) => { 9 const CUSTOM_PORT = '9230'; 10 const script = Path.join('examples', 'three-lines.js'); 11 12 const cli = startCLI([`--port=${CUSTOM_PORT}`, script]); 13 14 return cli.waitForInitialBreak() 15 .then(() => cli.waitForPrompt()) 16 .then(() => { 17 t.match(cli.output, 'debug>', 'prints a prompt'); 18 t.match( 19 cli.output, 20 new RegExp(`< Debugger listening on [^\n]*${CUSTOM_PORT}`), 21 'forwards child output'); 22 }) 23 .then(() => cli.quit()) 24 .then((code) => { 25 t.equal(code, 0, 'exits with success'); 26 }); 27}); 28 29test('random port', (t) => { 30 const script = Path.join('examples', 'three-lines.js'); 31 32 const cli = startCLI(['--port=0', script]); 33 34 return cli.waitForInitialBreak() 35 .then(() => cli.waitForPrompt()) 36 .then(() => { 37 t.match(cli.output, 'debug>', 'prints a prompt'); 38 t.match( 39 cli.output, 40 /< Debugger listening on /, 41 'forwards child output'); 42 }) 43 .then(() => cli.quit()) 44 .then((code) => { 45 t.equal(code, 0, 'exits with success'); 46 }); 47}); 48 49test('random port with --inspect-port=0', (t) => { 50 const script = Path.join('examples', 'three-lines.js'); 51 52 const cli = startCLI([script], ['--inspect-port=0']); 53 54 return cli.waitForInitialBreak() 55 .then(() => cli.waitForPrompt()) 56 .then(() => { 57 t.match(cli.output, 'debug>', 'prints a prompt'); 58 t.match( 59 cli.output, 60 /< Debugger listening on /, 61 'forwards child output'); 62 }) 63 .then(() => cli.quit()) 64 .then((code) => { 65 t.equal(code, 0, 'exits with success'); 66 }); 67}); 68 69test('examples/three-lines.js', (t) => { 70 const script = Path.join('examples', 'three-lines.js'); 71 const cli = startCLI([script]); 72 73 return cli.waitForInitialBreak() 74 .then(() => cli.waitForPrompt()) 75 .then(() => { 76 t.match(cli.output, 'debug>', 'prints a prompt'); 77 t.match( 78 cli.output, 79 /< Debugger listening on [^\n]*9229/, 80 'forwards child output'); 81 }) 82 .then(() => cli.command('["hello", "world"].join(" ")')) 83 .then(() => { 84 t.match(cli.output, 'hello world', 'prints the result'); 85 }) 86 .then(() => cli.command('')) 87 .then(() => { 88 t.match(cli.output, 'hello world', 'repeats the last command on <enter>'); 89 }) 90 .then(() => cli.command('version')) 91 .then(() => { 92 t.match(cli.output, process.versions.v8, 'version prints the v8 version'); 93 }) 94 .then(() => cli.quit()) 95 .then((code) => { 96 t.equal(code, 0, 'exits with success'); 97 }); 98}); 99 100test('run after quit / restart', (t) => { 101 const script = Path.join('examples', 'three-lines.js'); 102 const cli = startCLI([script]); 103 104 function onFatal(error) { 105 cli.quit(); 106 throw error; 107 } 108 109 return cli.waitForInitialBreak() 110 .then(() => cli.waitForPrompt()) 111 .then(() => cli.stepCommand('n')) 112 .then(() => { 113 t.match( 114 cli.output, 115 `break in ${script}:2`, 116 'steps to the 2nd line'); 117 }) 118 .then(() => cli.command('cont')) 119 .then(() => cli.waitFor(/disconnect/)) 120 .then(() => { 121 t.match( 122 cli.output, 123 'Waiting for the debugger to disconnect', 124 'the child was done'); 125 }) 126 .then(() => { 127 // On windows the socket won't close by itself 128 return cli.command('kill'); 129 }) 130 .then(() => cli.command('cont')) 131 .then(() => cli.waitFor(/start the app/)) 132 .then(() => { 133 t.match(cli.output, 'Use `run` to start the app again'); 134 }) 135 .then(() => cli.stepCommand('run')) 136 .then(() => cli.waitForInitialBreak()) 137 .then(() => cli.waitForPrompt()) 138 .then(() => { 139 t.match( 140 cli.breakInfo, 141 { filename: script, line: 1 }, 142 'is back at the beginning'); 143 }) 144 .then(() => cli.stepCommand('n')) 145 .then(() => { 146 t.match( 147 cli.breakInfo, 148 { filename: script, line: 2 }, 149 'steps to the 2nd line'); 150 }) 151 .then(() => cli.stepCommand('restart')) 152 .then(() => cli.waitForInitialBreak()) 153 .then(() => { 154 t.match( 155 cli.breakInfo, 156 { filename: script, line: 1 }, 157 'is back at the beginning'); 158 }) 159 .then(() => cli.command('kill')) 160 .then(() => cli.command('cont')) 161 .then(() => cli.waitFor(/start the app/)) 162 .then(() => { 163 t.match(cli.output, 'Use `run` to start the app again'); 164 }) 165 .then(() => cli.stepCommand('run')) 166 .then(() => cli.waitForInitialBreak()) 167 .then(() => cli.waitForPrompt()) 168 .then(() => { 169 t.match( 170 cli.breakInfo, 171 { filename: script, line: 1 }, 172 'is back at the beginning'); 173 }) 174 .then(() => cli.quit()) 175 .then(null, onFatal); 176}); 177 178test('auto-resume on start if the environment variable is defined', (t) => { 179 const script = Path.join('examples', 'break.js'); 180 181 const cli = startCLI([script], [], { 182 env: { NODE_INSPECT_RESUME_ON_START: '1' } 183 }); 184 185 return cli.waitForInitialBreak() 186 .then(() => { 187 t.match( 188 cli.breakInfo, 189 { filename: script, line: 10 }, 190 'skips to the first breakpoint'); 191 }) 192 .then(() => cli.quit()) 193 .then((code) => { 194 t.equal(code, 0, 'exits with success'); 195 }); 196}); 197