When projects and teams are just starting out, testing is usually not the main focus. However, as projects grow and get more users more emphasis is placed on testing, in particular, automated testing which can be reused and can be done as part of development tasks.
In this regard Monokle is not that different from other projects or teams, we needed to hit the ground running and just build something, see where it goes and focus on tests later on. Now we’re in a position where we need to make sure that core functionality is not unintentionally affected as new features get added, so having a baseline integration test that runs with our nightly builds makes total sense.
But hey... better late than never and so our story with Electron and integration tests begins.
Monokle is built using Electron which is used to build desktop applications across multiple platforms using a web framework like react. There are multiple testing frameworks out there but very few which are able to run on multiple OS’s and test Electron applications such as Monokle. We decided to use Playwright - as it is both open-source and seems to have Electron support baked in.
Playwright works similarly to other testing frameworks (Selenium, Cypress); it launches the actual application and mimics the actions a user would do, clicking on elements, writing things in text inputs, going through different flows. Assertions are added to make sure the expected results happen in the UI - for example, the opening of a panel or changing a label. Although more time-consuming, launching an application in this way is preferable to running it from source code, since this more closely mimics the end-user experience. There might be small differences.
Let’s dive into the actual tests
First, we need to install some dependencies:
npm install –save-dev @playwright/test playwright playwright-core xvfb-maybe asar
- Playwright is the testing library we are using;
- xvfb-maybe is used to run the tests;
- asar is used to parse OS packages.
Create configuration file
Create a playwright.config.ts similar to this:
To find parse and run the electron final build we used the functions (findLatestBuild, parseElectronApp) from here.
The credit for these very useful functions goes to Spaceage who made them.
Copy-paste those functions into an electronHelpers.ts file.
In the same file create a startApp function which will be used in our tests to start the actual app.
In the end, the electronHelpers.ts should look something like this:
Using this logic we are able to easily test OS-specific functionalities such as working with folders and files which are crucial for a code editor such as Monokle.
Automate on GitHub
To get the most of our tests, we’ve added them in our nightly builds so we can see if we’ve broken anything during the day. The reason for not adding them to run on every commit was that it takes ~20 minutes for everything to run, which would have led to extended waiting times in our development cycle.
We have set up Playwright to take screenshots and record videos, these files can be accessed from the Github actions as well to get a real-time view of how the tests are working or failing.
Go to: the action => click on it => click on summary => click on output.
Below is a snippet for running Electron tests as part of Github actions. We have a complete flow here.
As the Monokle project grows so will our end to end testing, here are a few steps we plan to add in the near future:
- Breakout the logic from the electronHelpers.ts file into an npm library which can be maintained and reused independently of our projects;
- Breakout specific antd logic(modal, tree, pane) models into a library which can be reused for testing by other people;
- Expand the tests we have for the general functionality of Monokle.