:::info 给我个机会,我想当个好测试 :::

开启远程调试

在 Electron 中开启远程调试,官网文档

  1. const { app } = require('electron')
  2. app.commandLine.appendSwitch('remote-debugging-port', '9222')
  3. app.whenReady().then(() => {
  4. // do what you want
  5. })

应用启动成功后,http://127.0.0.1:9222/json/version 可以访问则代表通信成功,页面返回的内容是当前浏览器的版本信息

  1. {
  2. "Browser": "Chrome/76.0.3809.146",
  3. "Protocol-Version": "1.3",
  4. "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",
  5. "V8-Version": "7.6.303.31",
  6. "WebKit-Version": "537.36 (@32557431e85a4fa6f2586cd61b380aadcac44d81)",
  7. "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/c765357a-1ce5-41bf-bcfb-88178a5b5670"
  8. }

通过这个端口我们就可以操控 Electron 应用啦,简单的命令可以通过http发送请求,见 官网文档
复杂操作则需要通过ws 请求 webSocketDebuggerUrl 来实现

截图案例

获取 webSocketDebuggerUrl

访问 /json/list 获取当前已打开的所有page信息,找到自己页面的 debuggerUrl

  1. [ {
  2. "description": "",
  3. "devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/C64D7C9E7F5E1C498433056A3889CBF1",
  4. "id": "C64D7C9E7F5E1C498433056A3889CBF1",
  5. "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",
  6. "type": "page",
  7. "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",
  8. "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/C64D7C9E7F5E1C498433056A3889CBF1"
  9. }, {
  10. "description": "",
  11. "devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/EFDCD2C5C9AF82556B00C98D9AAB0E36",
  12. "id": "EFDCD2C5C9AF82556B00C98D9AAB0E36",
  13. "title": "client",
  14. "type": "page",
  15. "url": "file:///Users/apple/Documents/own/code-everyday/client-auto-test/client/index.html",
  16. // 就是你啦
  17. "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/EFDCD2C5C9AF82556B00C98D9AAB0E36"
  18. } ]

写一个简单的客户端,按照 DevTools Protocol 文档要求 发送截图指令,并将图片存入本地

  1. const fs = require('fs');
  2. const WebSocket = require('ws')
  3. // webSocketDebuggerUrl
  4. const ws = new WebSocket('ws://127.0.0.1:9222/devtools/page/EFDCD2C5C9AF82556B00C98D9AAB0E36')
  5. ws.on('open', () => {
  6. console.log('connection success')
  7. captureScreenshot()
  8. });
  9. ws.on("error", (err) => {
  10. console.log("error: ", err);
  11. });
  12. ws.on("close", () => {
  13. console.log("close");
  14. });
  15. ws.on('message', (message) => {
  16. console.log('res:')
  17. const object = JSON.parse(message);
  18. if (object.id === 1) {
  19. savePic(object.result.data)
  20. }
  21. });
  22. function captureScreenshot() {
  23. const message = {
  24. // id是指令id,业务功能自己维护
  25. id: 1,
  26. method: 'Page.captureScreenshot',
  27. parameters: {
  28. format: 'jpeg'
  29. }
  30. }
  31. ws.send(JSON.stringify(message))
  32. }
  33. function savePic(data) {
  34. fs.writeFile(`./screenshot/${new Date().getTime()}.jpg`, Buffer.from(data, 'base64'), () => {
  35. console.log('savePic success')
  36. });
  37. }

拓展

puppeteer 同样是通过 DevTools Protocol 来控制的,那么是否我可以自己封装一下方法来实现 puppeteer 的功能?🤔
这样的话,完全可以实现 electron 应用的自动化测试哦 🤔