Search code examples
javascriptwebviewautomationelectron

Electron automating webview with multiple js scripts


I want to create a desktop app using Github's Electron. Essentially, the app will open external webpages, like google.com and perform various automation tasks such as clicking, typing, etc.

So far my index.html file has a webview with a preloader and requires a renderer js file.

<webview
id="webview"
preload="./preload.js"
src="https://google.com"></webview>

<script>
require('./renderer');
</script>

Here is renderer.js

const { ipcRenderer: ipc } = require('electron');

document.addEventListener('DOMContentLoaded', function(event) {
  const webview = document.getElementById('webview');
  const btn = document.getElementById('devtools');

});

Here is preload.js

const { ipcRenderer: ipc } = require('electron');

console.log('Hey, this is being run in the context of the webview renderer process');

Ideally I would have a separate js file that would act as a script for a specific site. Example, google.js might automate google, while facebook.js might automate facebook. google.js, for example, will have code looking something like this:

function loadHomepage () {
webview.loadURL(https://google.com);
}
function clickGoogleSearchButton () {
$('#googleSearchButtonId').click()
}

1. How would I include these various script files? Would they be included in my index.html? If the user clicks a button to automate google, how can I load the automation script for google and have it act on the webview? Each script should obviously have access to the webview variable I created in the render.js file so that the scripts can do things like webview.loadUrl(...)

2. Ideally the user would select a script and then be able to start and stop that script. How exactly can I communicate from the index.html file to the selected script that it should start/stop?

TL;DR Overall, I want to accomplish something like this:

-user clicks a button to select the current automation script

-a start and stop button appear

-the user clicks the start button

-the selected script begins running that performs various actions on the webview

-the user clicks stop and the current script is unloaded


Solution

  • It's been a while since this was asked, but you need to look into IPC messages to the webview. I have my preload script listening for various messages and taking actions based on the message sent. Something like this:

    processInboundMessage(data: WebViewMsg) {
        switch (data.operation) {
          case WebViewOperation.GetElementText:
            this.processMessageGetElementText(data);
            break;
          case WebViewOperation.GetSelectedText:
            this.processMessageGetSelectedText(data);
            break;
          case WebViewOperation.SetElementValue:
            this.processMessageSetElementValue(data);
            break;
          case WebViewOperation.TriggerEvent:
            this.processMessageTriggerClick(data);
            break;
          case WebViewOperation.HttpGet:
            this.processMessageHttpGet(data);
            break;
          case WebViewOperation.HttpPost:
            this.processMessageHttpPost(data);
            break;
          case WebViewOperation.GetJsVariableValue:
            this.processMessageGetJsVariableValue(data);
            break;
          case WebViewOperation.AddBorder:
            this.processMessageAddBorder(data);
            break;
          case WebViewOperation.RegisterListener:
            this.processMessageRegisterListener(data);
            break;
        }
      }
    

    When the action is complete, the preload script replies to the host:

    respondToHost(data: WebViewMsg) {
        ipcRenderer.sendToHost(data.returnChannel, data);
      }
    

    Where data is the payload to be sent back to the host and data.returnChannel is a GUID that the host checks for whenever a message is received.