我有一个电子应用程序,它首先启动一个启动器窗口(在渲染器进程中),它启动多个后台服务。在这些后台服务成功启动后,它会将"services-running"
其发送ipcRenderer
回主进程,而主进程又会通过关闭启动器窗口并启动主应用程序窗口来对该事件做出反应。该事件当然是由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();
});
});
});
第一个测试工作正常。第二次测试最终会在超时后失败,虽然我可以subscribed
在主窗口弹出之前在 shell 上看到,所以肯定会触发事件。
我阅读了nodeIntegration
需要启用才能使用 spectron 访问完整电子 api 的文档,我所有的渲染器进程都是{nodeIntegration: true}
在它们各自的webPreferences
. 但是由于我对主进程感兴趣,我认为这不适用(或者至少我认为它不应该,因为主进程本身就是一个节点进程)。
所以我的主要问题是,我将如何绑定ipcMain
事件并将其包含在我的断言中。另外我怎么知道启动器窗口何时关闭并且“主”窗口已打开?
作为奖励,我对 spectron api 有一些理解问题。
如果我查看is
spectron.d.ts
的electron
属性,它又是 a并且直接具有该属性。所以在我的理解中访问应该是(这是未定义的),远程来自哪里以及为什么它在.Application
Electron.AllElectron
MainInterface
ipcMain
ipcMain
app.electron.ipcMain
spectron.d.ts
SpectronClient
所有返回的方法Promise<void>
。所以我必须await
或then
那些。如果我查看 javascript 示例,它们会链接客户端语句:
return app.client
.waitUntilWindowLoaded()
.getTitle().should.equal('Launcher');
这在打字稿中不起作用,因为您不能Promise<void>
明显地链接到...在 js 中如何工作?