我们正在寻求开发一个 ElectronJS 应用程序,用于在我们的办公室工作中实现特定的网站自动化,其中包括常见的任务,如登录、表单填写、报告下载等。
我们已经尝试了 ElectronJS、Spectron、NightmareJS、Puppeteer 等的基本教程,它们都可以单独工作,但是关于相互集成的文档非常少(尽管打开了 github 问题)。
我们希望实现以下目标:
- 登录状态(
session
)不应在 ElectronJS 应用关闭时删除,并且应在应用重启时可用。 - 在现有
browserWindow
上启动一些自动化任务(如下载、表单填写等)的菜单按钮很少
我们不需要 headless 自动化,在这种情况下,幕后会发生一些魔法。我们只需要当前页面上基于菜单/按钮点击的操作/任务。
NightmareJS
、Puppeteer
等似乎都启动了自己的网页实例(因为它们是为测试独立应用程序而构建的)但我们需要的是自动化现有的 BrowserWindows
。
puppeteer
或 nightmarejs
是实现此类目标的正确工具吗?如果是,有任何文件吗?
否则,我们是否应该在控制台中注入(inject)我们自己的原生 JS 事件,如 mouseclick
等事件来执行操作?
最佳答案
您可以使用puppeteer-core
。 core
版本默认不下载 Chromium,如果你想控制 Electron 应用程序则不需要它。
然后在测试中调用 launch
方法,将 electron
定义为可执行文件而不是 Chromium,如以下代码片段所示:
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);
}
})();
Electron 5.x.y 及更高版本的更新(目前最高为 7.x.y,我尚未在 8.x.y beta 上对其进行测试),其中使用 puppeteer.connect
而不是 启动
方法:
// 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);
});
});
获取pid
和使用kill
是可选的。对于在某些 CI 平台上运行脚本并不重要,但对于本地环境,您必须在每次尝试失败后手动关闭 Electron 应用程序。
简单的演示 repo : https://github.com/peterdanis/electron-puppeteer-demo
关于javascript - 如何自动化 ElectronJS 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51847667/