开启远程调试
在 Electron 中开启远程调试,官网文档
const { app } = require('electron')app.commandLine.appendSwitch('remote-debugging-port', '9222')app.whenReady().then(() => {// do what you want})
应用启动成功后,http://127.0.0.1:9222/json/version 可以访问则代表通信成功,页面返回的内容是当前浏览器的版本信息
{"Browser": "Chrome/76.0.3809.146","Protocol-Version": "1.3","User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) vr-pro3/1.0.10 Chrome/76.0.3809.146 Electron/6.1.12 Safari/537.36","V8-Version": "7.6.303.31","WebKit-Version": "537.36 (@32557431e85a4fa6f2586cd61b380aadcac44d81)","webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/c765357a-1ce5-41bf-bcfb-88178a5b5670"}
通过这个端口我们就可以操控 Electron 应用啦,简单的命令可以通过http发送请求,见 官网文档
复杂操作则需要通过ws 请求 webSocketDebuggerUrl 来实现
截图案例
获取 webSocketDebuggerUrl
访问 /json/list 获取当前已打开的所有page信息,找到自己页面的 debuggerUrl
[ {"description": "","devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/C64D7C9E7F5E1C498433056A3889CBF1","id": "C64D7C9E7F5E1C498433056A3889CBF1","title": "devtools://devtools/bundled/devtools_app.html?remoteBase=https://devtools-frontend.appspot.com/serve_file/@32557431e85a4fa6f2586cd61b380aadcac44d81/&can_dock=true&toolbarColor=rgba(223,223,223,1)&textColor=rgba(0,0,0,1)&experiments=true","type": "page","url": "devtools://devtools/bundled/devtools_app.html?remoteBase=https://devtools-frontend.appspot.com/serve_file/@32557431e85a4fa6f2586cd61b380aadcac44d81/&can_dock=true&toolbarColor=rgba(223,223,223,1)&textColor=rgba(0,0,0,1)&experiments=true","webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/C64D7C9E7F5E1C498433056A3889CBF1"}, {"description": "","devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/EFDCD2C5C9AF82556B00C98D9AAB0E36","id": "EFDCD2C5C9AF82556B00C98D9AAB0E36","title": "client","type": "page","url": "file:///Users/apple/Documents/own/code-everyday/client-auto-test/client/index.html",// 就是你啦"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/EFDCD2C5C9AF82556B00C98D9AAB0E36"} ]
写一个简单的客户端,按照 DevTools Protocol 文档要求 发送截图指令,并将图片存入本地
const fs = require('fs');const WebSocket = require('ws')// webSocketDebuggerUrlconst ws = new WebSocket('ws://127.0.0.1:9222/devtools/page/EFDCD2C5C9AF82556B00C98D9AAB0E36')ws.on('open', () => {console.log('connection success')captureScreenshot()});ws.on("error", (err) => {console.log("error: ", err);});ws.on("close", () => {console.log("close");});ws.on('message', (message) => {console.log('res:')const object = JSON.parse(message);if (object.id === 1) {savePic(object.result.data)}});function captureScreenshot() {const message = {// id是指令id,业务功能自己维护id: 1,method: 'Page.captureScreenshot',parameters: {format: 'jpeg'}}ws.send(JSON.stringify(message))}function savePic(data) {fs.writeFile(`./screenshot/${new Date().getTime()}.jpg`, Buffer.from(data, 'base64'), () => {console.log('savePic success')});}
拓展
puppeteer 同样是通过 DevTools Protocol 来控制的,那么是否我可以自己封装一下方法来实现 puppeteer 的功能?🤔
这样的话,完全可以实现 electron 应用的自动化测试哦 🤔
