electron-userland / spectron

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

Electron app opening multiple windows or processes in spectron test #589

Open karthik22061993 opened 4 years ago

karthik22061993 commented 4 years ago

My electron app works as expected but it keeps on opening new windows when I run spectron test that tests for number of windows opened.

Electron version - v8.0.2 , "spectron": "^10.0.1" . I am not sure how to check exact version of spectron. I am just running a small demo, below I will give code snippet

Note: I am running the spectron test pointing to .exe file generated by electron-packager.

Does Anyone have an idea what is the issue if possible how to solve it?

main.js

const { app, BrowserWindow } = require('electron')

function createWindow () {

  let win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  win.loadFile('index.html')
}

app.whenReady().then(createWindow)

index.js

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

test.js

const assert = require('assert');
const path = require('path');
const Application = require('spectron').Application;
const electronPath = require('electron');

const app = new Application({
    path: 'C:/demoElectronApp/winx64/demoelectronapp-win32-x64/demoelectronapp.exe',
  });

  describe('client_settings_app', function () {
    this.timeout(10000);

    beforeEach(() => {
      return app.start();
    });

    it('shows only one initial window', async () => {
      const count = await app.client.getWindowCount();
      return assert.equal(count, 1);
    });
  })

package.json

{
  "name": "demoelectronapp",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "electronpackage": "electron-packager . --out winx64"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "path": "^0.12.7"
  },
  "devDependencies": {
   "electron": "^8.2.2",
    "electron-packager": "^14.2.1",
    "assert": "^2.0.0",
    "mocha": "^7.1.1",
    "spectron": "^10.0.1"
  }
}

Versions Installed npm ls --depth=0 demoelectronapp@1.0.0 C:\demoCLS\demoElectronApp +-- assert@2.0.0 +-- electron@8.2.2 +-- electron-packager@14.2.1 +-- mocha@7.1.1 +-- path@0.12.7 `-- spectron@10.0.1 –

jesusiglesias commented 4 years ago

Same problem here!

XRenSiu commented 3 years ago

You can try to add chromeDriverArgs: ['remote-debugging-port=9222'] as AppConstructorOptions.

Rajesh2015 commented 3 years ago

@XRenSiu I Faced the same issue where it was opening mutiple windows after adding chromedriverargs I see only one window but end up getting Cannot call non W3C standard command while in W3C mode.Not sure where I can make this w3c mode to false

XRenSiu commented 3 years ago

you can add webdriverOptions, but I don't think this is the right approach.

troppoli commented 3 years ago

@Rajesh2015, I think you're seeing the trouble that I am. Attempting to add some webdriverOptions means that you have to take responsibility for all the config options. @XRenSiu this is the trouble for you too, because the path goes to chrome instead of electron.

If you drill into your npm folder node_modules\spectron\lib\application.js around line 203...

    const options = {
      hostname: self.host,
      port: self.port,
      waitforTimeout: self.waitTimeout,
      connectionRetryCount: self.connectionRetryCount,
      connectionRetryTimeout: self.connectionRetryTimeout,
      logLevel: 'silent',
      capabilities: {
        'goog:chromeOptions': {
          binary: launcherPath,
          args: args,
          debuggerAddress: self.debuggerAddress,
          windowTypes: ['app', 'webview']
        }
      },
      logOutput: DevNull()
    };

    if (self.webdriverLogPath) {
      options.outputDir = self.webdriverLogPath;
      options.logLevel = 'trace';
    }

    Object.assign(options, self.webdriverOptions);

Here, spectron is preparing the options that it will send use to create webdriver. Spectron will use your webDriverOptions if you pass one when you create a new Spectron Application. So if you want to add in a w3c: false you have to replicate a lot of code. As a test you can tweak the code here after the Object.assign and add options.capabilities['goog:chromeOptions'].w3c = false;

This does get my electron11 app off the ground. Then it promptly has some trouble in Application.prototype.start around line 59. The call of setTimeouts results in errors about a mismatch of the function sig. Commenting out this section worked for me:

    // .then(function () {
    //   return self.client.setTimeouts(
    //     self.waitTimeout,
    //     self.waitTimeout,
    //     self.waitTimeout
    //   );
    // })

I'm curious if this also works for you. I'm about to try reproing this in a test environment.

troppoli commented 3 years ago

just to follow up, after breaking this down, it seems that I don't have trouble until protractor gets involved. A clean repo with just spectron seems oka.