spectron icon indicating copy to clipboard operation
spectron copied to clipboard

Mocking electron modules

Open davej opened this issue 7 years ago • 15 comments

Is there any way to mock electron modules from spectron?

Currently, I have to add all my mocks to the main process directly in my application code. So my mocks get shipped with the app, which is far from ideal. I remove the code in my build process but it would be much better to have the mocks added by spectron instead.

My current setup looks something like the following:

tests/e2e.js

// ...
new Application({
  path: electronPath,
  env: { RUNNING_IN_SPECTRON: '1' },
  args: ['.'],
});
// ...

main.js

const electron = require('electron');
// ...
if (process.env.RUNNING_IN_SPECTRON) {
  electron.dialog.showOpenDialog = (opts, cb) => {
    if (opts.title === 'Choose Site Folder') {
      cb(['/Users/dave/lorem/ipsum/My Site']);
    }
  };
}
// ...

davej avatar Jul 22 '16 22:07 davej

Yeah, this isn't currently possible since spectron only have access to run code in the renderer process and these APIs would need to be mocked in the main process.

One thing you could do now is add something like ['.', '-r', './tests/mocks.js'] to the args array and preload the mocks that way to no pollute your regular app code.

kevinsawicki avatar Jul 25 '16 16:07 kevinsawicki

One thing you could do now is add something like ['.', '-r', './tests/mocks.js'] to the args array and preload the mocks that way to no pollute your regular app code.

Oh, great idea! Didn't think of that, I'll give it a go now.

davej avatar Jul 25 '16 16:07 davej

@kevinsawicki: Hmmm, didn't seem to work for me?

    app = new Application({
      path: electronPath,
      env: { SPECTRON: '1' },
      args: ['.', '-r', join(__dirname, 'mocks.js')],
    });

davej avatar Jul 25 '16 16:07 davej

args: ['.', '-r', join(__dirname, 'mocks.js')]

Sorry, I think '.' needs to be last in the array.

kevinsawicki avatar Jul 25 '16 16:07 kevinsawicki

@kevinsawicki 👍 Working a charm now!

davej avatar Jul 25 '16 16:07 davej

This method was working on development build. this.app = new Application({ path: electron, args: ['-r', ${__dirname}/../mocks.js, 'app'] });

When I tried to test packed app. That doesn't working this.app = new Application({ path: './release/mac/MyApp.app/Contents/MacOS/MyApp', args: ['-r', ${__dirname}/../mocks.js, './release/mac/MyApp.app/Contents/Resources/app/main.js'] });

Any idea on this?

topmat avatar Nov 23 '16 16:11 topmat

@davej : Are you able to provide an example of how you did it ? I can't seem to get it right either ~

etiennejcharles avatar Jan 06 '17 17:01 etiennejcharles

Given this file structure.

image

This is what I did to get it right.

args: [path.join(__dirname, '..'), '-r', path.join(__dirname, 'mocks.js')]

  1. The first argument correspond to the path of your main.js file. (wherever that may be)

  2. The second arguments corresponds to the require statement to preload with -r your files (in your case, your mocks). i.e electron main.js -r test/mocks.js should work in your console if you have electron installed globally.

  3. The 3rd corresponds to your mocks path. (edited)

In main.js I did the following.

//...
const mock = require('./test/mock')
//...
function createWindow () {
  if(process.env.RUNNING_IN_SPECTRON){
      mock(dialog);
  }
//...

In my mock

module.exports = function(dialog){
  dialog.showOpenDialog = (opts, cb) => {
    if (opts.title === 'Choose Site Folder') {
      cb(['/Users/dave/lorem/ipsum/My Site']);
    }
  }
}

~ Sadly it took me 3 hours to find, I hope this helps anyone else.

etiennejcharles avatar Jan 06 '17 18:01 etiennejcharles

@etiennejcharles is preloading "mock.js" really necessary? It seems that const mock = require('./test/mock') is enough.

Also this seems to be dirty, having mocks in your production code :neutral_face:

michaelworm avatar Feb 06 '18 13:02 michaelworm

The spectron-fake-dialog https://www.npmjs.com/package/spectron-fake-dialog seems like a good example of doing this mock, mentioned in another thread but reposting here :)

cmdcolin avatar May 15 '18 00:05 cmdcolin

Here's how I recently mocked require('electron'):

https://github.com/electron/update-electron-app/blob/0dac0813245fe5e872a407ea61e661e8bd49588e/test.js#L7-L22

zeke avatar May 15 '18 00:05 zeke

Hmm. This "-r" trick isnt working for me. Unfortunately, I have no idea where to find the cli args documentation either... :/

ccorcos avatar Jul 08 '21 23:07 ccorcos

@ccorcos The only place where I could find "documentation" was ... by typing electron -h in a terminal. I think this is actually a node option. Note that electron -r mocks.js main.js works but electron main.js -r mocks.js does not.

And in my mock.js :

const { dialog } = require('electron')
dialog.showMessageBoxSync = () => {
return true
}
dialog.showMessageBox = () => {
return true
}

jdexyz avatar Jul 20 '21 15:07 jdexyz

How are you all running your tests? Im using the following to run a jest/spectron test

npm test filename

I've tried OP's setup and @etiennejcharles but it doesn't seem to be working. What am I missing?

EmilyCamacho avatar Apr 06 '22 21:04 EmilyCamacho

How are you all running your tests? Im using the following to run a jest/spectron test

npm test filename

I've tried OP's setup and @etiennejcharles but it doesn't seem to be working. What am I missing?

Yeah it's been a while I've worked with Electron @EmilyCamacho - the API's most likely have changed since I wrote the above - I don't even use the same editor 😆

Wish there was a to be better way to do this 😅 - Sorry I can't help

etiennejcharles avatar May 23 '22 18:05 etiennejcharles