New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IPC Main <-> Renderer Example Test #184
Comments
Yes, you can test window creation and IPC communication with electron-mocha in the main process, but you have to create some kind of setup for this yourself. Basically, you need to create the window and load your code into it -- if that code requires some IPC input you need to provide that of course. You can then set up IPC listeners to confirm that your renderer code sends the correct messages. By way of example, I can only point you to some of my own code and tests but this is highly specific to your app's window management. |
I've looked at the provided example, but I'm failing to see where you test the IPC. In
in
but where is the IPC call from renderer that then should trigger the Thanks. |
There are various points at which the renderer code calls back (like here) with IPC messages handled by window manager. In this case the tests just check that the window manger received messages (specifically, that the |
I'm running into a an interesting problem with I'm converting all IPC calls to .invoke() on the renderer side and .handle() on the main process side. My renderer does immediately fire off two IPC .invoke() calls when the app loads. And I can see the log messages in the main process that the IPC calls are being received before the e-mocha test is over, but the Sinon stub or spy never receives the call. Electron main process is handled in a Typescript class, Example 1 - fails:
I can see the console.log of the callback method before the test has finished, yet the Example 2 - also fails:
Here we're spying directly on ipcMain. A possibly as source of error is the It seems that Any suggestions on how to make this work ?
Thanks. |
Yes, best consult the Sinon documentation, because you're not using the API there as intended. In the first example, you're stubbing a string object. That means, you're creating stubs for all the methods on the string instance |
the examples were altered from real world as my main process is all Typescript in a dedicated class, I've updated above examples. The IPC communications from renderer come through as I can see log messages of the IPC callback in main when I run the Electron app, I got about 50 other e-mocha unit tests running on that same class and it's methods, Sinon stubbing/spying works just fine, but it does not seem to work with Have you ever stubbed |
updated above examples, lmk if you ever managed to stub or spy on In your provided examples, you used the |
If you stub a method, the original method is replaced on the context instance. In the updated example 1 you allegedly stub a method, yet the original is invoked (there's console output) so this means In the updated example 2:
There is nothing surprising about this. You seem to expect that So example 2 looks just fine, but the test makes no sense. Example 1 is a better way to test the fact that the IPC communication took place, but there must be an error in your setup. It looks like you create another This test works fine for me ( const { join } = require('path')
const sinon = require('sinon')
const { ipcMain, BrowserWindow } = require('electron')
describe.only('IPC Handlers', () => {
let spy
beforeEach(() => {
spy = sinon.spy()
ipcMain.handle('test', async () => spy())
})
afterEach(() => {
ipcMain.removeHandler('test')
})
it('can be invoked', async () => {
let win = new BrowserWindow({
webPreferences: {
contextIsolation: false,
nodeIntegration: true
}
})
await win.loadFile(join(__dirname, 'test.html'))
win.webContents.executeJavaScript(
`require('electron').ipcRenderer.invoke('test')`
)
// Allow some time for the IPC messages to be sent.
await new Promise((resolve) => setTimeout(resolve, 500))
win.destroy()
expect(spy.callCount).to.equal(1)
})
}) |
a big THANK YOU for this last response. You were dead on point, the Another big THANK YOU for the detailed example you posted, I'm sure this will help other folks that have been asking for more examples ! So here's a follow-up issue that I've been running into with e-mocha in regards to these IPC event handlers. I did not want to add this to the OP, but maybe you can chime in here. As mentioned, in my Electron
in the class constructor, In my e-mocha tests, I create a new instance of the class before every test, so that I can modify/mock/stub as needed. The problem that I'm facing is that if I run the But this instance itself had never registered any IPC handlers for that channel. After some testing, it appears that the class instance inside I can unregister a handler via As of right now, I'm doing that globally for each handler top of the e-mocha script (outside of any Is there a better approach to avoid the IPC event handler collision ? And to confirm, yes I can register/unregister new test handlers (with different names) like you did in your example and avoid collision like that, but in some tests I want to directly test the IPC handlers that the renderer in the real app uses, hence I need to run Thanks. |
In a given process, |
Following the Electron recommendations, I'm removing
remote
access completely in renderer and convert everything to beIPC via .invoke()
Is it possible to test IPC communication between Main/Renderer via e-mocha ?
If so, could you provide a simple e-mocha test on how to trigger an IPC event from renderer that is then received in main process (or vice versa) ?
I've looked through the provided test examples as well as projects that use e-mocha, but did not find a suitable example.
Thanks.
Electron 12.0.2
E-Mocha 9.3.3
Win x64
The text was updated successfully, but these errors were encountered: