Created
April 11, 2021 04:23
-
-
Save dougpagani/4681838a12a7821c096640d491649a43 to your computer and use it in GitHub Desktop.
This has quite a few pieces of debugging instrumentation/dead-code, but it has some convenient magic to it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const WSE_FILE = './.wsaddress' | |
const fs = require('fs') | |
// https://stackoverflow.com/questions/12871740/how-to-detach-a-spawned-child-process-in-a-node-js-script | |
// https://github.com/puppeteer/puppeteer/issues/4061 | |
const LAUNCH_CONFIG = { | |
headless: false, | |
// handleSIGHUP: false, | |
// handleSIGINT: false, | |
// handleSIGTERM: false, | |
// args: dontBackgroundArgs | |
// slowMo: 25, | |
} | |
// const dontBackgroundArgs = [ | |
// '--disable-background-timer-throttling', | |
// '--disable-backgrounding-occluded-windows', | |
// '--disable-renderer-backgrounding' | |
// ]; | |
const puppeteer = require('puppeteer') | |
const { spawnSync, spawn, execSync, exec } = require('child_process') | |
function importWSEndpointIfItExists() { | |
if (fs.existsSync(WSE_FILE)) { | |
return fs.readFileSync(WSE_FILE).toString().trim() | |
} | |
} | |
async function launchNewBrowserAndSaveWSE() { | |
let args = puppeteer.defaultArgs() | |
args = args.filter( arg => arg !== '--headless' ) | |
args = args.filter( arg => arg !== 'about:blank' ) | |
const chromiumProgram = puppeteer.executablePath() | |
const source = spawn( | |
chromiumProgram, | |
[ ...args, "--remote-debugging-port=9222" ], | |
{ detached: true, stdio: [ 'ignore', 'pipe', 'pipe' ] }, | |
) | |
const stdoutWSEPromise = readIOSourceForWSE(source.stdout) // just for flagging unlogged chrome instances | |
const stderrWSEPromise = readIOSourceForWSE(source.stderr) | |
const fastFailingStderrWSE = await Promise.race([ | |
stderrWSEPromise, | |
stdoutWSEPromise, | |
]) | |
fs.writeFileSync(WSE_FILE, fastFailingStderrWSE) | |
console.log("Logged WSE to file") | |
return await puppeteer.connect({ ...LAUNCH_CONFIG, browserWSEndpoint: fastFailingStderrWSE }) | |
// https://2ality.com/2018/05/child-process-streams.html | |
// await echoReadable(source.stdout); // (B) | |
// Exec way: | |
// const executionStatement = chromiumProgram + ' ' + [ ...args, "--remote-debugging-port=9222" ].join(' ') | |
// console.log('executionStatement:', executionStatement) | |
// execSync(executionStatement) | |
} | |
function cutOutWSEUrlFromSTDOUT(haystack) { | |
// const example1 = "DevTools listening on ws://127.0.0.1:9222/devtools/browser/36f86b67-2ce8-49de-9ee5-c11936e95e0c" | |
const needle = haystack.split(' ')[3] | |
return needle | |
} | |
function readIOSourceForWSE(sourceStream) { | |
return new Promise( (resolve, reject) => { | |
setTimeout( () => { | |
reject('Timeout hit') | |
}, 100000000) | |
sourceStream.on('data', (chunk) => { | |
line = chunk.toString().trim() | |
console.log('line: ', line) | |
if (line === '') { | |
// ignore | |
return | |
} | |
else if ("Opening in existing browser session." === line) { | |
reject(new Error(`An unregistered version of chromium is running. Please quit it and try this script again.`)) | |
} | |
else if (line.match(/^DevTools listening on ws/) ) { | |
resolve(cutOutWSEUrlFromSTDOUT(line)) | |
// e.g. "DevTools listening on ws://127.0.0.1:9222" | |
} | |
else { | |
reject(new Error(`unknown response when trying to resolve WS endpoint for browser: "${line}"`)) | |
} | |
// if output | |
// DevTools listening on ws://127.0.0.1:9222 | |
}); | |
}) | |
} | |
async function echoReadable(readable) { | |
for await (const line of chunksToLinesAsync(readable)) { // (C) | |
console.log('LINE: '+ chomp(line)) | |
} | |
} | |
async function getBrowser() { | |
const wse = importWSEndpointIfItExists() | |
if (wse === undefined || wse === '') { | |
return await launchNewBrowserAndSaveWSE() | |
} | |
try { | |
const connectionOptions = { ...LAUNCH_CONFIG, browserWSEndpoint: wse } | |
return await puppeteer.connect(connectionOptions) | |
} catch (error) { | |
if ( | |
error.message.includes('connect ECONNREFUSED') | |
|| error.message.includes('Invalid URL') | |
) { | |
return await launchNewBrowserAndSaveWSE() | |
} | |
throw error | |
} | |
} | |
;( async () => { | |
const browser = await getBrowser() | |
const page = await browser.newPage() | |
await page.goto('https://make.autotiv.com') | |
})() | |
;( async () => { | |
// let wsendpoint | |
// while (true) { | |
// } | |
// process.exit(0) | |
// const browser = puppeteer.connect() | |
// const page = await browser.newPage() | |
// await browser.disconnect() | |
}) | |
function configureProcessToNotDetachChrome(browser) { | |
// process.removeListener('exit',process.rawListeners('exit')[process.rawListeners('exit').length-1]); | |
process.on('SIGINT', async () => { | |
console.log("disconnecting browser") | |
await browser.disconnect() | |
}) | |
console.log("Raw listeners:", process.rawListeners('exit')) | |
} | |
// For a fancier invocation, build from here: | |
// https://gist.github.com/benjamingr/0237932cee84712951a2 | |
process.on('unhandledRejection', (reason) => { | |
console.log("\x1b[38;5;1m UPR: ", reason) | |
}); | |
[ | |
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", "SIGABRT", "SIGEMT", | |
"SIGFPE", "SIGBUS", "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", | |
"SIGURG", "SIGTSTP", "SIGCONT", "SIGCHLD", "SIGTTIN", "SIGTTOU", "SIGIO", | |
"SIGXCPU", "SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGINFO", | |
"SIGUSR1", "SIGUSR2", | |
].map( (signal) => { | |
if ("SIGINT" === signal) return // dont define process.on(SIGINT) | |
process.on(signal, () => { | |
console.log(signal + " fired") | |
}) | |
}) | |
// process.on('SIGCHLD', () => { | |
// }); | |
console.log(process.pid) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment