Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/TracerBench/chrome-debugging-client
An async / await friendly debugging client for chrome
https://github.com/TracerBench/chrome-debugging-client
Last synced: about 2 months ago
JSON representation
An async / await friendly debugging client for chrome
- Host: GitHub
- URL: https://github.com/TracerBench/chrome-debugging-client
- Owner: TracerBench
- License: bsd-2-clause
- Created: 2016-01-29T17:11:11.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2023-07-18T20:41:28.000Z (over 1 year ago)
- Last Synced: 2024-10-28T21:04:57.217Z (3 months ago)
- Language: TypeScript
- Homepage:
- Size: 2.77 MB
- Stars: 134
- Watchers: 10
- Forks: 19
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-chrome-devtools - chrome-debugging-client
README
# chrome-debugging-client
[![Build Status](https://travis-ci.org/tracerbench/chrome-debugging-client.svg?branch=master)](https://travis-ci.org/tracerbench/chrome-debugging-client)
[![npm](https://img.shields.io/npm/v/chrome-debugging-client.svg)](https://www.npmjs.com/package/chrome-debugging-client)
[![install size](https://packagephobia.now.sh/badge?p=chrome-debugging-client)](https://packagephobia.now.sh/result?p=chrome-debugging-client)An async/await friendly Chrome debugging client with TypeScript support,
designed with automation in mind.## Table of Contents
* [Features](#features)
* [Examples](#examples)
* [Print URL as PDF](#print-url-as-pdf)
* [Node Debugging](#node-debugging)## Features
* Promise API for async/await (most debugger commands are meant to be sequential).
* TypeScript support and uses "devtools-protocol" types, allowing you to pick a protocol version.
* Launches Chrome with a new temp user data folder so Chrome launches an isolated instance.
(regardless if you already have Chrome open).
* Opens Chrome with a pipe message transport to the browser connection and supports
attaching flattened session connections to targets.
* Supports cancellation in a way that avoids unhandled rejections, and allows you to add combine
additional cancellation concerns.
* Supports seeing protocol debug messages with `DEBUG=chrome-debugging-client:*`
* Use with race-cancellation library to add timeouts or other cancellation concerns to tasks
using the connection.
* The library was designed to be careful about not floating promises (promises are
chained immediately after being created, combining concurrent promises with all
or race), this avoids unhandled rejections.## Examples
### Print URL as PDF
```js file=examples/printToPDF.js
#!/usr/bin/env node
const { writeFileSync } = require("fs");
const { spawnChrome } = require("chrome-debugging-client");/**
* Print a url to a PDF file.
* @param url {string}
* @param file {string}
*/
async function printToPDF(url, file) {
const chrome = spawnChrome({ headless: true });
try {
const browser = chrome.connection;// we create with a target of about:blank so that we can
// setup Page events before navigating to url
const { targetId } = await browser.send("Target.createTarget", {
url: "about:blank",
});const page = await browser.attachToTarget(targetId);
// enable events for Page domain
await page.send("Page.enable");// concurrently wait until load and navigate
await Promise.all([
page.until("Page.loadEventFired"),
page.send("Page.navigate", { url }),
]);const { data } = await page.send("Page.printToPDF");
writeFileSync(file, data, "base64");
// attempt graceful close
await chrome.close();
} finally {
// kill process if hasn't exited
await chrome.dispose();
}console.log(`${url} written to ${file}`);
}if (process.argv.length < 4) {
console.log(`usage: printToPDF.js url file`);
console.log(
`example: printToPDF.js https://en.wikipedia.org/wiki/Binomial_coefficient Binomial_coefficient.pdf`,
);
process.exit(1);
}printToPDF(process.argv[2], process.argv[3]).catch((err) => {
console.log("print failed %o", err);
});```
### Node Debugging
```js file=examples/nodeDebug.js
#!/usr/bin/env node
const { spawnWithWebSocket } = require("chrome-debugging-client");async function main() {
const script = `const obj = {
hello: "world",
};
console.log("end");
`;// start node requesting it break on start at debug port that
// is available
const node = await spawnWithWebSocket(process.execPath, [
// node will pick an available port and wait for debugger
"--inspect-brk=0",
"-e",
script,
]);async function doDebugging() {
const { connection } = node;// Setup console api handler
connection.on("Runtime.consoleAPICalled", ({ type, args }) => {
console.log(`console.${type}: ${JSON.stringify(args)}`);
});// We requested Node to break on start, so we runIfWaitingForDebugger
// and wait for it to break at the start of our script.
// These commands must be sent concurrently with
// the pause event setup.
const [
{
callFrames: [
{
location: { scriptId },
},
],
reason,
},
] = await Promise.all([
connection.until("Debugger.paused"),
connection.send("Debugger.enable"),
connection.send("Runtime.enable"),
connection.send("Runtime.runIfWaitingForDebugger"),
]);
// Right now we are paused at the start of the script
console.log(`paused reason: ${reason}`); //= paused: Break on start
console.log(`set breakpoint on line 3`);
await connection.send("Debugger.setBreakpoint", {
location: {
lineNumber: 3,
scriptId,
},
});console.log("resume and wait for next paused event");
const [breakpoint] = await Promise.all([
connection.until("Debugger.paused"),
connection.send("Debugger.resume"),
]);
const {
callFrames: [{ location, callFrameId }],
} = breakpoint;
console.log(`paused at line ${location.lineNumber}`);console.log("evaluate `obj`");
const { result } = await connection.send("Debugger.evaluateOnCallFrame", {
callFrameId,
expression: "obj",
returnByValue: true,
});
console.log(JSON.stringify(result.value)); //= {"hello":"world"}console.log("resume and wait for execution context to be destroyed");
await Promise.all([
connection.until("Runtime.executionContextDestroyed"),
connection.send("Debugger.resume"),
]);
}try {
await doDebugging();// Node is still alive here and waiting for the debugger to disconnect
console.log("close websocket");
node.close();// Node should exit on its own after the websocket closes
console.log("wait for exit");
await node.waitForExit();console.log("node exited");
} finally {
// kill process if still alive
await node.dispose();
}
}main().catch((err) => {
console.log("print failed %o", err);
});```