node.jselectronhar

How can you record a `.har` of an Electron `webContents` session?


I have a Javascript application that spawns Electron and does a bunch of stuff in it.

I'm trying to debug a strange network issue I'm having, and to do this, I'd like to use a HAR file to store a log of all the HTTP requests being made by Electron.

Is this possible?


Solution

  • Yes, it can be done using chrome-har-capturer - you can pass a bunch of events from the webContents.debugger and then chrome-har-capturer will transform them into a HAR for you.

    Example code:

    const chromeHarCapturer = require('chrome-har-capturer')
    
    let log = []
    const webContents = browserWindow.webContents
    
    webContents.debugger.on("message", function(event, method, params) {
      // https://github.com/cyrus-and/chrome-har-capturer#fromlogurl-log-options
      if (!["Page.domContentEventFired", "Page.loadEventFired", "Network.requestWillBeSent", "Network.dataReceived", 
            "Network.responseReceived", "Network.resourceChangedPriority", "Network.loadingFinished", 
            "Network.loadingFailed"].includes(method)) {
        // not relevant to us
        return
      }
      log.push({method, params})
    
      if (method === 'Network.responseReceived') { // the chrome events don't include the body, attach it manually if we want it in the HAR
        webContents.debugger.sendCommand('Network.getResponseBody', {
          requestId: params.requestId
        }, function(err, result) {
          result.requestId = params.requestId
          log.push({
            method: 'Network.getResponseBody',
            params: result
          })
        })
      }
    })
    
    webContents.debugger.once("detach", function() {
      // on detach, write out the HAR
      return chromeHarCapturer.fromLog("http://dummy-url-for-whole-session", log).then(function(har) {
        const path = `/tmp/${Number(new Date())}-har.json`
    
        fs.writeJson(path, log)
    
        log = []
      })
    })
    
    // subscribe to the required events
    webContents.debugger.attach()
    webContents.debugger.sendCommand('Network.enable')
    webContents.debugger.sendCommand('Page.enable')