初试 Electron 远程调试

开启远程调试

在 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')
const 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 应用的自动化测试哦 🤔

目录