Utilizing the electron executable with Puppeteer directly requires some workarounds and flag adjustments due to their differences in API. Electron lacks certain key functionalities found in the chrome.* API, essential for proper operation of Chromium browser. Many flags do not yet have suitable replacements, such as the headless flag.
Outlined below are two methods to achieve this. However, it is crucial to adhere to the following points:
- Ensure that Puppeteer is connected before launching the application.
- Verify you have the correct version of Puppeteer or Puppeteer-core matching the Chrome version running within Electron!
Option 1: Leveraging puppeteer-in-electron
Among various alternatives, a recent addition includes the puppeteer-in-electron package, enabling the running of Puppeteer inside an Electron app utilizing Electron itself.
To begin, install the necessary dependencies:
npm install puppeteer-in-electron puppeteer-core electron
Subsequently, execute the code snippet provided below.
import {BrowserWindow, app} from "electron";
import pie from "puppeteer-in-electron";
import puppeteer from "puppeteer-core";
const main = async () => {
const browser = await pie.connect(app, puppeteer);
const window = new BrowserWindow();
const url = "https://example.com/";
await window.loadURL(url);
const page = await pie.getPage(browser, window);
console.log(page.url());
window.destroy();
};
main();
Option 2: Obtain the debugging port and establish connection
Alternatively, one can acquire the remote-debugging-port of the Electron app and connect to it. This approach was shared by trusktr on the Electron forum.
import {app, BrowserWindow, ...} from "electron"
import fetch from 'node-fetch'
import * as puppeteer from 'puppeteer'
app.commandLine.appendSwitch('remote-debugging-port', '8315')
async function test() {
const response = await fetch(`http://localhost:8315/json/versions/list?t=${Math.random()}`)
const debugEndpoints = await response.json()
let webSocketDebuggerUrl = debugEndpoints['webSocketDebuggerUrl ']
const browser = await puppeteer.connect({
browserWSEndpoint: webSocketDebuggerUrl
})
// utilize Puppeteer APIs now!
}
// Establish your window, etc., then proceed with:
// after window load, connect Puppeteer:
mainWindow.webContents.on("did-finish-load", () => {
test()
})
Both solutions above rely on the usage of webSocketDebuggerUrl to address the issue.
Additional Information
Since many individuals use Electron for bundling applications, it's worth mentioning:
If building puppeteer-core and puppeteer-in-electron, ensure the utilization of hazardous
and electron-builder
to facilitate functioning of get-port-cli
.
Place hazardous at the beginning of main.js:
// main.js
require ('hazardous');
Unpack the get-port-cli script and specify in package.json:
"build": {
"asarUnpack": "node_modules/get-port-cli"
}
Upon completion of the build process: