chrome-debugging-client
Version:
An async/await friendly Chrome debugging client with TypeScript support
159 lines • 5.98 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("./common");
const child_process_1 = require("child_process");
const fs = require("fs");
const path = require("path");
const PORT_FILENAME = "DevToolsActivePort";
class BrowserSpawner {
spawn(executablePath, dataDir, isContentShell, options) {
return __awaiter(this, void 0, void 0, function* () {
let portFile = path.join(dataDir, PORT_FILENAME);
// delete port file before launching
yield tryDeleteFile(portFile);
let args = this.getArguments(dataDir, isContentShell, options);
let process = new BrowserProcess(executablePath, args);
try {
let port = 0;
let tries = 0;
while (true) {
if (++tries > 10) {
throw new Error("failed waiting for port file");
}
yield common_1.delay(200);
port = yield tryReadPort(portFile);
process.validate();
if (port > 0) {
process.remoteDebuggingPort = port;
process.dataDir = dataDir;
break;
}
}
return process;
}
catch (err) {
yield process.dispose();
throw err;
}
});
}
getArguments(dataDir, isContentShell, options) {
let windowSize = options && options.windowSize || {
width: 414,
height: 736
};
let additionalArguments = options && options.additionalArguments || [];
let args = [
// base switches
"--disable-breakpad",
"--noerrdialogs",
// content switches
"--allow-insecure-localhost",
"--disable-hang-monitor",
"--disable-notifications",
"--disable-web-security",
"--disable-v8-idle-tasks",
"--disable-xss-auditor",
"--ignore-certificate-errors",
"--no-sandbox",
"--reduce-security-for-testing",
"--safebrowsing-disable-auto-update",
"--v8-cache-options=none",
"--process-per-tab",
"--use-mock-keychain",
"--password-store=basic",
// first available ephemeral port
"--remote-debugging-port=0"
].concat(additionalArguments);
if (isContentShell) {
return args.concat([
`--data-path=${dataDir}`,
`--content-shell-host-window-size=${windowSize.width}x${windowSize.height}`,
"about:blank"
]);
}
return args.concat([
"--disable-add-to-shelf",
"--disable-background-networking",
"--disable-client-side-phishing-detection",
"--disable-component-extensions-with-background-pages",
"--disable-component-update",
"--disable-default-apps",
"--disable-domain-reliability",
"--disable-extensions",
"--disable-features=NetworkPrediction",
"--disable-popup-blocking",
"--disable-prompt-on-repost",
"--disable-sync",
"--metrics-recording-only",
"--no-default-browser-check",
"--no-experiments",
"--no-first-run",
"--no-ping",
"--no-proxy-server",
`--user-data-dir=${dataDir}`,
`--window-size=${windowSize.width},${windowSize.height}`,
"about:blank"
]);
}
}
exports.default = BrowserSpawner;
class BrowserProcess {
constructor(executablePath, args) {
this.hasExited = false;
this.remoteDebuggingPort = 0;
let process = child_process_1.spawn(executablePath, args);
process.on("error", err => this.lastError = err);
process.on("exit", () => this.hasExited = true);
this.process = process;
this.pid = process.pid;
}
dispose() {
return new Promise(resolve => {
if (this.hasExited) {
resolve();
}
else {
this.process.on("exit", resolve);
this.process.kill();
// race
setTimeout(resolve, 2000);
setTimeout(() => this.process.kill("SIGKILL"), 2000);
}
}).then(() => {
this.process.removeAllListeners();
}).catch((err) => console.error(err));
}
validate() {
if (this.hasExited) {
throw new Error("process exited");
}
if (this.lastError) {
throw this.lastError;
}
}
}
function tryDeleteFile(filename) {
return new Promise(resolve => fs.unlink(filename, err => resolve()));
}
function tryReadPort(filename) {
return new Promise(resolve => {
fs.readFile(filename, "utf8", (err, data) => {
if (err) {
resolve(0);
}
let port = parseInt(data, 10);
// handles NaN if write was created but port not written
port > 0 ? resolve(port) : resolve(0);
});
});
}
//# sourceMappingURL=browser-spawner.js.map