electron-userland / spectron

DEPRECATED: 🔎 Test Electron apps using ChromeDriver
http://electronjs.org/spectron
MIT License
1.68k stars 229 forks source link

Mocking electron modules #94

Open davej opened 8 years ago

davej commented 8 years ago

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']);
    }
  };
}
// ...
kevinsawicki commented 8 years ago

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.

davej commented 8 years ago

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 commented 8 years ago

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

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

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

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

davej commented 8 years ago

@kevinsawicki 👍 Working a charm now!

topmat commented 7 years ago

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?

etiennejcharles commented 7 years ago

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

etiennejcharles commented 7 years ago

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.

michaelworm commented 6 years ago

@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:

cmdcolin commented 6 years ago

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 :)

zeke commented 6 years ago

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

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

ccorcos commented 3 years ago

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

jdexyz commented 3 years ago

@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
}
EmilyCamacho commented 2 years ago

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?

etiennejcharles commented 2 years ago

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