Automated testing for Electron applications with continuous integration
Fullstack Developer and Tech Author
Visual Studio Code, one of the most popular code editors on the market at the time of writing, Slack, and the desktop version of WhatsApp all have something in common. They were all built with Electron.js. With major companies adopting Electron.js over native software development methods, Electron.js has established itself as a trustworthy framework for developing desktop applications.
No application is complete without testing, and Electron apps are not exempt from this rule. You can write tests that validate Electron.js applications are behaving as you expect them to, just like you can for browser applications. In this tutorial, I will demonstrate how to test Electron.js apps and take that a step further by automating your testing process with continuous integration (CI).
Prerequisites
To follow this tutorial, a few things are required:
- Basic knowledge of JavaScript
- Node.js installed on your system (>= 11)
- A CircleCI account
- A GitHub account
With all these installed and set up, you can begin.
Scaffolding an Electron app
To get started, you need to use a scaffold to create a new Electron.js application. As a head start, you will be using npx
with the create-electron-app
package to set it up. Run this command:
npx create-electron-app electron-test-app
This scaffolds a new app inside an electron-test-app
folder. This folder can be any named whatever you want.
Once the process is done, go into the root of the project (run cd electron-test-app
) and run this command:
npm start
This generates a temporary build of the application based on your OS platform and boots up the app.
Both the application and the Devtools open in the same application window. You don’t want the Devtools exposed, so terminate the application by running Ctrl + C
in the same CLI window where the app was run. Then go to the src/index.js
file and comment out this line:
mainWindow.webContents.openDevTools();
Run the app again with npm start
. This time, only the application screen is displayed with a header containing a “💖” emoji, the text Hello World!"
, and a paragraph with the text Welcome to your Electron application
. Note the contents of the page; you will be testing for these elements soon.
Setting up testing with Playwright
Your next step is to set up the testing frameworks required to perform end-to-end (E2E) testing of your app. You only need to install one testing library for this. Playwright is a popular choice for Electron app end-to-end testing.
Terminate the running process with CTRL + C
. Next, install Playwright as a development dependency using this command:
npm install --save-dev @playwright/test
Once these two are installed, you can add a test
script to the package.json
file. Inside the existing scripts
key, add the test
key/value pair from snippet:
{
...,
"scripts" : {
....,
"test" : "playwright test"
}
}
Now you have all you need to run tests on your Electron.js application.
Adding tests
Now it’s time to add tests to your application.
Inside the src
folder, create a new folder named __tests__
. Inside the __tests__
folder, create a new file named app.spec.js
. Paste this code in it:
const { test, expect, _electron: electron } = require('@playwright/test')
test('an h1 contains hello world"', async () => {
const electronApp = await electron.launch({ args: ['.'] })
// Wait for the first BrowserWindow to open
const window = await electronApp.firstWindow()
// Check for the presence of an h1 element with the text "hello"
const headerElement = await window.$('h1')
const headerText = await headerElement.textContent()
expect(headerText).toBe("💖 Hello World!")
// Close the app
await electronApp.close()
})
The test file starts by requiring an import of what you need from Playwright.
You create a single test, which is where all the interesting stuff happens. The test launches your Electron application and waits for the window to launch. Then it checks to see if you have a header (h1
) containing the string "💖 Hello World!"
. After it’s done, it closes the Electron application.
Save the test file and run the created tests. Run the test
script at the root of the project:
npm run test
As the tests run, the application boots up, flashes the start-up screen, and then disappears. When the application screen disappears, the tests are done running.
The test passes.
Automating our tests
Time to write our CI pipeline that automates our testing process. Inside the root of the project, create a new folder named .circleci
. Within this folder, create a file named config.yml
and enter the following code into it:
version: 2.1
jobs:
build:
docker:
- image: circleci/node:latest-browsers
# Steps to the job
steps:
- checkout
- run: npm i -D @playwright/test
- run: npx playwright install
- run:
name: Run Playwright specs
command: npm run test
In the file above, you pull in a Node.js
Docker image. Note that you are using an image with a -browsers
suffix to provide an environment with browsers installed. The image specified ensures that you have everything configured in our environment to get the Chrome driver working.
Commit and push these changes to your GitHub repository.
Connecting the project to CircleCI
Our next task is to get our Electron.js project set up on CircleCI.
Next, go to the organization homepage on the CircleCI dashboard and click Create Project.
![Add Project - CircleCI]
Select Github
, then select your project from the dropdown. Click Set Up Project to begin. Select your project from the dropdown. Give your project a name and click Create Project.
The project automatically picks up your configuration file, but won’t run the pipeline. To kick off your first pipeline run, push a small, meaningless commit.
To review the process details, expand the dropdown and click build.
Your tests are running perfectly. Awesome!
You can add more tests as you add more features to your application. With every push to your repository, you trigger the pipeline to run all your tests automatically. When a test fails, you are notified by CircleCI and you get information about why tests are failing.
Conclusion
Test-driven development (TDD) combined with continuous integration is a great way to be sure that you have not pushed any bugs to your production environment. In this tutorial, you have learned how to test Electron.js applications and you have automated your testing process using CircleCI.
Happy coding!