最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to automate ElectronJS app - Stack Overflow

programmeradmin0浏览0评论

We're looking to develop an ElectronJS app for particular website automation at our desk job, which includes mon tasks like login, form filling, report downloading etc.

We've tried basic tutorial of ElectronJS, Spectron, NightmareJS, Puppeteer etc and all of them work fine separately, but very less documentation (although open github issues) are available on integration of each other.

We want to achieve following:

  • Login state (session) should not be deleted on ElectronJS app closing and should be available on restart of app.
  • Few menu buttons which initiates some automation tasks like download, form fill etc on existing browserWindow

We don't need headless automation, where some magic happens behind the scene. We need menu/button click based actions/tasks on current page only.

NightmareJS, Puppeteer etc all seems to start their own instances of web pages (since because they were built for testing of standalone apps) but what we need is automation of existing BrowserWindows.

Is puppeteer or nightmarejs correct tools for such goals? If yes, any documentation?

Or else, should we inject our own native JS events like mouseclick etc events in console to perform action?

We're looking to develop an ElectronJS app for particular website automation at our desk job, which includes mon tasks like login, form filling, report downloading etc.

We've tried basic tutorial of ElectronJS, Spectron, NightmareJS, Puppeteer etc and all of them work fine separately, but very less documentation (although open github issues) are available on integration of each other.

We want to achieve following:

  • Login state (session) should not be deleted on ElectronJS app closing and should be available on restart of app.
  • Few menu buttons which initiates some automation tasks like download, form fill etc on existing browserWindow

We don't need headless automation, where some magic happens behind the scene. We need menu/button click based actions/tasks on current page only.

NightmareJS, Puppeteer etc all seems to start their own instances of web pages (since because they were built for testing of standalone apps) but what we need is automation of existing BrowserWindows.

Is puppeteer or nightmarejs correct tools for such goals? If yes, any documentation?

Or else, should we inject our own native JS events like mouseclick etc events in console to perform action?

Share Improve this question edited Aug 14, 2018 at 18:37 D Joe asked Aug 14, 2018 at 18:25 D JoeD Joe 511 silver badge3 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 4

You can use puppeteer-core. core version by default does not download Chromium, which you do not need if you want to control an Electron app.

In the test you then call launch method, where you define electron as the executable file instead of Chromium, like in following snippet:

const electron = require("electron");
const puppeteer = require("puppeteer-core");

const delay = ms =>
  new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, ms);
  });

(async () => {
  try {
    const app = await puppeteer.launch({
      executablePath: electron,
      args: ["."],
      headless: false,
    });
    const pages = await app.pages();
    const [page] = pages;

    await page.setViewport({ width: 1200, height: 700 });
    await delay(5000);
    const image = await page.screenshot();
    console.log(image);
    await page.close();
    await delay(2000);
    await app.close();
  } catch (error) {
    console.error(error);
  }
})();

Update for electron 5.x.y and up (currently up to 7.x.y, I did not test it on 8.x.y beta yet), where puppeteer.connect is used instead of launch method:

// const assert = require("assert");
const electron = require("electron");
const kill = require("tree-kill");
const puppeteer = require("puppeteer-core");
const { spawn } = require("child_process");

let pid;

const run = async () => {
  const port = 9200; // Debugging port
  const startTime = Date.now();
  const timeout = 20000; // Timeout in miliseconds
  let app;

  // Start Electron with custom debugging port
  pid = spawn(electron, [".", `--remote-debugging-port=${port}`], {
    shell: true
  }).pid;

  // Wait for Puppeteer to connect
  while (!app) {
    try {
      app = await puppeteer.connect({
        browserURL: `http://localhost:${port}`,
        defaultViewport: { width: 1000, height: 600 } // Optional I think
      });
    } catch (error) {
      if (Date.now() > startTime + timeout) {
        throw error;
      }
    }
  }

  // Do something, e.g.:
  // const [page] = await app.pages();
  // await page.waitForSelector("#someid")// 
  // const text = await page.$eval("#someid", element => element.innerText);
  // assert(text === "Your expected text");
  // await page.close();
};

run()
  .then(() => {
    // Do something
  })
  .catch(error => {
    // Do something
    kill(pid, () => {
      process.exit(1);
    });
  });

Getting the pid and using kill is optional. For running the script on some CI platform it does not matter, but for local environment you would have to close the electron app manually after each failed try.

Simple demo repo: https://github./peterdanis/electron-puppeteer-demo

Automation Script in Java using Selenium and ChromeDriver

package setUp;

import helper.Constants;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;


public class Test {

       public static void main(String[] args) {

             System.setProperty(Constants.WebDriverType, Constants.WebDriverPath + Constants.WindowsDriver);

             ChromeOptions opt = new ChromeOptions();

             DesiredCapabilities capabilities = new DesiredCapabilities();

             capabilities.setCapability("chromeOptions", opt);
             capabilities.setBrowserName("chrome");
             capabilities.setVersion("73.0.3683.121");

             ChromeOptions options = new ChromeOptions();
             options.merge(capabilities);
             options.setBinary("C:\\\\Program Files\\\\Audio\\\\Audio-Configuration\\\\Audio-Configuration.exe");
             options.setCapability("chromeOptions", options);
             ChromeDriver driver = new ChromeDriver(options);

             try {
                    Thread.sleep(5000);
                    WebElement webElement = driver.findElement(By.xpath(
                                 "/html/body/app-root/mat-drawer-container/mat-drawer/div/app-bottom-side-nav/div/app-settings-nav/div/div/a/div"));                        
                    webElement.click();
             } catch (Exception e) {
                    System.out.println("Exception trace");
                    System.out.println(e);
             }
       }
}

Automation Script in JavaScript using Spectron (built on top-of ChromeDriver and WebDriverIO).

const Application = require("spectron").Application;

const path =
  "C:/Program Files/Audio/Audio-Configuration/Audio-Configuration.exe";
const myApp = new Application({
  path: path,
  chromeDriverArgs: ["--disable-extensions"],
  env: {
    SPECTRON: true,
    ELECTRON_ENABLE_LOGGING: true,
    ELECTRON_ENABLE_STACK_DUMPING: true
  }
});

const windowClick = async app => {
  await app.start();
  try {
    // Identifying by class name
    await app.client.click(".ic-setting");

    // Identifying by Id
    // await app.client.click("#left-btn");
  } catch (error) {
    // Log any failures
    console.error("Test failed", error.message);
  }
  // Stop the application
     await app.stop();
};

windowClick(myApp);

Spectron is the best match for electron build applications.

You will have access to all electron API.we can start and stop your app by spectron only.

We can run both packaged app or with out even packaging.

https://electronjs/spectron

You can use Spectron but if you want to look at documentation, Spectron is using webdriverio which has good documentation.

I remend you to use Spectron because I tried to automate my tests with java-selenium but it fails some of case. If you want to use selenium, write below code to set capabilities to setup electron app to chromedriver.

 ChromeOptions options = new ChromeOptions();
    options.setBinary(binaryPath);
    options.addArguments("--app=" + argPath);
    options.setCapability("chromeOptions", options);
    driver = new ChromeDriver(options);   

Hope this will help to you.

If integrating with electron nightmare is a very good library to achieve this even it will be ready to distribute with it, here is the following useful documentation for the same resource1 and

发布评论

评论列表(0)

  1. 暂无评论