Testing Electron.js applications using Cypress - alpha release

Back to Cypress blog

Cypress is great for testing web applications in its built-in Electron.js browser or in an external Chrome browser. Today I am happy to announce that we have started work to support testing an external Electron.js application.

This is still a very early alpha release, meant to give interested users a chance to try it out and provide us with early feedback. Testing Electron applications might mean many different things to many people, so we at Cypress would like to follow the users as our guides.

In a nutshell, the Test Runner work is happening on branch test-electron-app-4964 which has a lot of features not yet available in the develop branch: custom browser list, controlling browser via remote debugger protocol, etc. We plan to build the Test Runner from this branch test-electron-app-4964 , at least for some platforms, so you can install it locally following our "Installing pre-release" instructions.

Once you have the pre-release version of the Test Runner installed, it is time to test your Electron app.  First, head over to cypress-io/cypress-electron-plugin and read its README - it will give you up-to-date description of how Cypress expects your application to be structured to be testable. For example, currently we expect the application to construct the main browser window using a factory function in a separate JavaScript file, like this example from cypress-io/cypress-example-electron we show the typical "main" file:

// main.js
const { app } = require('electron')
const MainBrowserWindow = require('./main_browser_window')

let win

function createWindow () {
  // Create the browser window.
  win = MainBrowserWindow()

  // and load whatever file you want
  // win.loadFile('aut.html')
  win.loadURL('http://localhost:4600')
}

app.on('ready', createWindow)

Notice how main.js uses MainBrowserWindow function to construct the window. Here is the browser factory file main_browser_window.js

// main_browser_window.js
const _ = require('lodash')
const { BrowserWindow } = require('electron')
module.exports = (options = {}) => {
  _.defaultsDeep(options, {
    width: 500,
    height: 500,
    webPreferences: {
      // for example, use Electron setting
      // to expose Node modules in the window
      nodeIntegration: true
    }
  })
  let win = new BrowserWindow(options)
  win.on('closed', () => {
    win = null
  })
  return win
}

Then install the @cypress/electron-plugin which adds a custom command to "visit" your apps' main window. The spec looks almost like a regular test:

// cypress/integration/spec.js
it('clicks', () => {
  // window creation and url load
  cy.electronVisitUrl('./main_browser_window.js', 'http://localhost:4600')
  cy.get('button')
    .click()
    .click()
  cy.get('#clicked').should('have.text', '2')
})

When Cypress runs, it first opens its own Runner window. When it encounters cy.electronVisitUrl the Test Runner loads YOUR file main_browser_window.js, then executes the exported browser factory function which pops up a new window. Technically, the new window is a child window of the Test Runner window, which allows the tests to access it and perform test actions.

Test Runner window opens your app's main window

Future work

In this release we have solved the technical challenge of opening a child application window using YOUR code yet being able to run Cypress test commands against it. We plan to iterate on the plugin's implementation and developer experience based on your feedback. Please look at the issues in cypress-io/cypress-electron-plugin/issues to make sure we know what you need and want from Electron application testing. Other noteworthy links:

  • Cypress issue #4964 is the main tracking issue for implementing Electron testing in Cypress.
  • Repo cypress-io/cypress-electron-plugin is the bridge between Cypress Test Runner and your testing code.
  • We have a starter application example showing Electron testing in action at cypress-io/cypress-example-electron We are looking for more application examples to demo testing against.