【发布时间】:2019-11-15 06:14:00
【问题描述】:
我有一个电子应用程序,它首先启动一个启动器窗口(在渲染器进程中),该窗口启动多个后台服务。在这些后台服务成功启动后,它会将其ipcRenderer 上的"services-running" 发送回主进程,主进程反过来通过关闭启动器窗口并启动主应用程序窗口来响应该事件。活动当然是ipcMain.on('services-running',...)收到的
我分别对所有处理程序进行了单元测试,所以这些都很好,现在我想集成测试通过ipcMain 的事件。
这是我的集成测试目前的样子:
import { Application } from 'spectron';
import * as electron from "electron";
import { expect } from 'chai';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
let app: Application;
global.before(() => {
app = new Application({
path: "" + electron,
args: ["app/main.js"],
env: {
ELECTRON_ENABLE_LOGGING: true,
ELECTRON_ENABLE_STACK_DUMPING: true,
NODE_ENV: "integrationtest"
},
startTimeout: 20000,
chromeDriverLogPath: '../chromedriverlog.txt'
});
chai.use(chaiAsPromised);
chai.should();
});
describe('Application', () => {
before('Start Application', () => {
return app.start();
});
after(() => {
if(app && app.isRunning()){
return app.stop();
}
});
it('should start the launcher', async () => {
await app.client.waitUntilWindowLoaded();
return app.client.getTitle().should.eventually.equal('Launcher');
});
it('should start all services before timing out', async (done) => {
console.log('subscribed');
app.electron.remote.ipcMain.on('services-running', () => {
done();
});
});
});
第一个测试工作正常。虽然在主窗口弹出之前我可以在 shell 上看到subscribed,但在达到超时后第二次测试最终会失败,因此肯定会触发该事件。
我在文档中读到需要启用nodeIntegration 才能使用spectron 访问完整的电子API,我所有的渲染器进程都以{nodeIntegration: true} 在它们各自的webPreferences 中启动。但由于我对主进程感兴趣,我认为这不适用(或者至少我认为不应该,因为主进程本身就是一个节点进程)。
所以我的主要问题是,我将如何绑定到 ipcMain 事件并将其包含在我的断言中。另外我怎么知道启动器窗口何时关闭并且“主”窗口已打开?
作为奖励,我对 spectron api 有一些理解问题。
如果我查看
spectron.d.ts,Application的electron属性是Electron.AllElectron类型,而MainInterface又是MainInterface并直接具有ipcMain属性。因此,据我了解,访问ipcMain应该是app.electron.ipcMain(未定义),远程来自哪里以及为什么它在spectron.d.ts中不可见。SpectronClient上的方法都返回Promise<void>。所以我必须await或then那些。如果我查看它们链接客户端语句的 javascript 示例:
return app.client
.waitUntilWindowLoaded()
.getTitle().should.equal('Launcher');
这在 typescript 中不起作用,因为您显然无法链接到 Promise<void>,......这在 js 中如何工作?
【问题讨论】:
-
你有什么运气吗?我也在尝试收听 ipcMain 事件...
-
@mottosson 我提出了我的解决方法作为答案。我认为这是一个关于如何处理模拟内部库内容的非常通用的解决方案。从那以后一直在使用这种方法,在其他一些其他语言的项目中也是如此,目前它仍然有效。
标签: typescript electron spectron ipcmain