browser tools are even better now
This commit is contained in:
@@ -2,17 +2,19 @@
|
||||
|
||||
import { spawn, execSync } from "node:child_process";
|
||||
import puppeteer from "puppeteer-core";
|
||||
import { homedir, platform } from "node:os";
|
||||
import { existsSync } from "node:fs";
|
||||
|
||||
const useProfile = process.argv[2] === "--profile";
|
||||
|
||||
if (process.argv[2] && process.argv[2] !== "--profile") {
|
||||
console.log("Usage: browser-start.js [--profile]");
|
||||
console.log("\nOptions:");
|
||||
console.log(" --profile Copy your default Chrome profile (cookies, logins)");
|
||||
console.log(" --profile Copy your default browser profile (cookies, logins)");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const SCRAPING_DIR = `${process.env.HOME}/.cache/browser-tools`;
|
||||
const SCRAPING_DIR = `${homedir()}/.cache/browser-tools`;
|
||||
|
||||
// Check if already running on :9222
|
||||
try {
|
||||
@@ -21,10 +23,66 @@ try {
|
||||
defaultViewport: null,
|
||||
});
|
||||
await browser.disconnect();
|
||||
console.log("✓ Chrome already running on :9222");
|
||||
console.log("✓ Browser already running on :9222");
|
||||
process.exit(0);
|
||||
} catch {}
|
||||
|
||||
// Detect platform and find browser binary
|
||||
const isMac = platform() === "darwin";
|
||||
const isLinux = platform() === "linux";
|
||||
|
||||
function findBrowser() {
|
||||
// Try to find browser using `which` command
|
||||
const candidates = isMac
|
||||
? ["Helium", "Google Chrome", "Chromium", "Microsoft Edge"]
|
||||
: ["helium", "chromium", "google-chrome", "google-chrome-stable", "chrome", "brave", "edge"];
|
||||
|
||||
for (const name of candidates) {
|
||||
try {
|
||||
if (isMac) {
|
||||
// On macOS, check /Applications
|
||||
const appPath = `/Applications/${name}.app/Contents/MacOS/${name}`;
|
||||
if (existsSync(appPath)) {
|
||||
return appPath;
|
||||
}
|
||||
} else {
|
||||
// On Linux, use `which`
|
||||
const result = execSync(`which ${name} 2>/dev/null`, { encoding: "utf-8" }).trim();
|
||||
if (result) return result;
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function findProfilePath() {
|
||||
const home = homedir();
|
||||
if (isMac) {
|
||||
return [
|
||||
`${home}/Library/Application Support/Helium`,
|
||||
`${home}/Library/Application Support/Google/Chrome`,
|
||||
`${home}/Library/Application Support/Google/Chrome Canary`,
|
||||
`${home}/Library/Application Support/Chromium`,
|
||||
`${home}/Library/Application Support/Microsoft Edge`,
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
`${home}/.config/helium`,
|
||||
`${home}/.config/chromium`,
|
||||
`${home}/.config/google-chrome`,
|
||||
`${home}/.config/google-chrome-stable`,
|
||||
`${home}/.config/BraveSoftware/Brave-Browser`,
|
||||
`${home}/.config/microsoft-edge`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
const browserPath = findBrowser();
|
||||
if (!browserPath) {
|
||||
console.error("✗ Could not find a Chromium-based browser (tried: helium, chromium, google-chrome, edge, brave)");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Setup profile directory
|
||||
execSync(`mkdir -p "${SCRAPING_DIR}"`, { stdio: "ignore" });
|
||||
|
||||
@@ -35,24 +93,42 @@ try {
|
||||
|
||||
if (useProfile) {
|
||||
console.log("Syncing profile...");
|
||||
execSync(
|
||||
`rsync -a --delete \
|
||||
--exclude='SingletonLock' \
|
||||
--exclude='SingletonSocket' \
|
||||
--exclude='SingletonCookie' \
|
||||
--exclude='*/Sessions/*' \
|
||||
--exclude='*/Current Session' \
|
||||
--exclude='*/Current Tabs' \
|
||||
--exclude='*/Last Session' \
|
||||
--exclude='*/Last Tabs' \
|
||||
"${process.env.HOME}/Library/Application Support/Google/Chrome/" "${SCRAPING_DIR}/"`,
|
||||
{ stdio: "pipe" },
|
||||
);
|
||||
const profilePaths = findProfilePath();
|
||||
let synced = false;
|
||||
|
||||
for (const sourcePath of profilePaths) {
|
||||
if (existsSync(sourcePath)) {
|
||||
try {
|
||||
execSync(
|
||||
`rsync -a --delete \
|
||||
--exclude='SingletonLock' \
|
||||
--exclude='SingletonSocket' \
|
||||
--exclude='SingletonCookie' \
|
||||
--exclude='*/Sessions/*' \
|
||||
--exclude='*/Current Session' \
|
||||
--exclude='*/Current Tabs' \
|
||||
--exclude='*/Last Session' \
|
||||
--exclude='*/Last Tabs' \
|
||||
"${sourcePath}/" "${SCRAPING_DIR}/"`,
|
||||
{ stdio: "pipe" },
|
||||
);
|
||||
console.log(`✓ Synced profile from ${sourcePath}`);
|
||||
synced = true;
|
||||
break;
|
||||
} catch (e) {
|
||||
// Try next path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!synced) {
|
||||
console.log("⚠ No existing browser profile found, starting fresh");
|
||||
}
|
||||
}
|
||||
|
||||
// Start Chrome with flags to force new instance
|
||||
// Start browser with remote debugging
|
||||
spawn(
|
||||
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||
browserPath,
|
||||
[
|
||||
"--remote-debugging-port=9222",
|
||||
`--user-data-dir=${SCRAPING_DIR}`,
|
||||
@@ -62,7 +138,7 @@ spawn(
|
||||
{ detached: true, stdio: "ignore" },
|
||||
).unref();
|
||||
|
||||
// Wait for Chrome to be ready
|
||||
// Wait for browser to be ready
|
||||
let connected = false;
|
||||
for (let i = 0; i < 30; i++) {
|
||||
try {
|
||||
@@ -79,8 +155,8 @@ for (let i = 0; i < 30; i++) {
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
console.error("✗ Failed to connect to Chrome");
|
||||
console.error("✗ Failed to connect to browser");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`✓ Chrome started on :9222${useProfile ? " with your profile" : ""}`);
|
||||
console.log(`✓ Browser started on :9222${useProfile ? " with your profile" : ""}`);
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -218,6 +219,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@@ -829,7 +831,8 @@
|
||||
"version": "0.0.1367902",
|
||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz",
|
||||
"integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==",
|
||||
"license": "BSD-3-Clause"
|
||||
"license": "BSD-3-Clause",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
@@ -1797,6 +1800,7 @@
|
||||
"resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.11.1.tgz",
|
||||
"integrity": "sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@puppeteer/browsers": "2.6.1",
|
||||
"chromium-bidi": "0.11.0",
|
||||
@@ -1814,6 +1818,7 @@
|
||||
"resolved": "https://registry.npmjs.org/puppeteer-extra/-/puppeteer-extra-3.3.6.tgz",
|
||||
"integrity": "sha512-rsLBE/6mMxAjlLd06LuGacrukP2bqbzKCLzV1vrhHFavqQE/taQ2UXv3H5P0Ls7nsrASa+6x3bDbXHpqMwq+7A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/debug": "^4.1.0",
|
||||
"debug": "^4.1.1",
|
||||
@@ -1983,7 +1988,8 @@
|
||||
"version": "0.0.1521046",
|
||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1521046.tgz",
|
||||
"integrity": "sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w==",
|
||||
"license": "BSD-3-Clause"
|
||||
"license": "BSD-3-Clause",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/puppeteer/node_modules/puppeteer-core": {
|
||||
"version": "24.31.0",
|
||||
|
||||
Reference in New Issue
Block a user