ElectronIntroduction
Electron is an open source framework for building cross-platform desktop applications. It is developed by GitHub and first released in 2013. Electron allows developers to use web technologies such as HTML, CSS, and JavaScript to build desktop applications that run on operating systems such as Windows, macOS, and Linux.
Here are some key features and benefits:
-
Cross-platform: Electron runs on multiple operating systems, including Windows, macOS, and Linux. This means developers can build applications using the same code base and deploy them on different platforms.
-
Based on web technology: Electron uses web technology as the foundation on which applications are built. Developers can use HTML, CSS, and JavaScript to build user interfaces and application logic, making the development process more familiar and accessible.
-
Strong ecosystem: Electron has a large developer community and rich third-party libraries and plug-ins. Developers can leverage these resources to speed up the development process, solve problems, and extend application functionality.
-
Customization capabilities: Electron provides a rich API that can access the functions of the underlying operating system. Developers can use these APIs to interact with the operating system, access the file system, create system tray applications and other functions.
-
Debugging and tool support: Electron integrates developer tools, including Chrome developer tools, to help developers debug and optimize performance. Additionally, there are many third-party tools and libraries that can be used to build, test, and deploy Electron applications.
-
Application Distribution: Electron provides tools to package and distribute applications. Developers can package applications as executables or installers and publish them to app stores or otherwise distribute them to users.
Electron has been widely used in various fields, including code editors, chat applications, desktop clients, etc. Many well-known applications, such as Visual Studio Code, Slack, and GitHub Desktop, are built using Electron.
In summary, Electron provides a way to simplify and accelerate desktop application development, enabling developers to build cross-platform applications using familiar web technologies.
It is the underlying technology of the current Kujiale desktop client.
Framework introduction
Three ways to conduct automated testing (using the WebDriver interface, using Playwright, and using a custom test driver) are introduced in the official documentation:
https://www.electronjs.org/zh/docs/latest/tutorial/automated-testing
After actual operation, we found that the operation of the official website omitted many key steps, and it was not possible to directly run through our own project, which required a certain amount of research.
Check puppeteer-electron related warehouses:
https://github.com/peterdanis/electron-puppeteer-demo
https://github.com/nondanee/puppeteer-electron
Way | Frame | star quantity | Advantages given by GPT | Disadvantages given by GPT |
---|---|---|---|---|
Use WebDriver interface | WebdriverIO | 8.2k | WebdriverIO is a mature web automation testing framework that supports multiple browsers and platforms. It provides a rich API and plug-ins, making test writing more convenient and flexible. Has a powerful waiting mechanism to ensure element visibility and page loading completion. Supports parallel test execution to improve testing efficiency. The community is active, the documentation is rich, and it’s easy to learn and use. | Because WebdriverIO is based on the WebDriver protocol, the execution speed may be relatively slow. You may encounter some difficulties when dealing with certain special cases, such as modal dialog boxes and desktop applications. |
Selenium | / | 27.2k | Selenium is the most widely used web automation testing framework, supporting multiple programming languages and browsers. Has strong ability to position elements and can flexibly interact with the page. Supports parallel execution of tests, improving testing efficiency. The community is large and there is a wide range of support and resources available. | Selenium is not designed for desktop applications, so you may encounter some limitations and issues when testing Electron applications. For some advanced features, such as handling modal dialog boxes and file uploads, you may need to write custom logic. |
Use Playwright | playwright | 53.6k | Playwright is an emerging cross-browser automated testing framework that supports multiple browsers and platforms. It provides a clean API that makes it easy to interact with pages and manipulate elements. It has a powerful waiting mechanism that can wait for elements to appear and page loading to complete. Supports advanced functions such as screenshots and screen recording. | Relative to Selenium and WebdriverIO, Playwright has a smaller community and may find fewer resources and support. In some special cases, such as when dealing with desktop applications and modal dialog boxes, you may encounter some limitations. |
Use custom test driver | node | 96.9 k | / | / |
Remote debug | Puppeteer | 84.1k | Powerful browser automation: Puppeteer provides a simple and The powerful API can be used to simulate users performing various operations in the browser, such as clicking, filling out forms, taking screenshots, etc. Complete control of the browser environment: Puppeteer can control the underlying Chromium browser instance, allowing it to modify and monitor all aspects of the browser, such as network requests, user agents, storage, etc., making testing more flexible and reliable. Support debugging and error troubleshooting: Puppeteer has debugging tools that can help developers locate and fix problems in testing, including visual regression issues, performance issues, etc. Multi-platform support: Puppeteer can run on multiple platforms, including Windows, Mac and Linux, and is suitable for automated testing of cross-platform Electron applications. | Steep learning curve: Puppeteer’s API is relatively complex and requires a certain learning cost, especially for people without much browser automation experience. Relatively slow execution speed: Due to the need to start the browser, simulate user interaction and other steps, using Puppeteer for automated testing may be slower than other testing frameworks. Test environment configuration: Using Puppeteer for Electron automated testing requires configuring the relevant environment, including installing the correct version of the Chromium browser and Puppeteer library, which may cause some trouble. |
Preparation
Use navigator.appVersion to view the chromedriver version currently used by the client
> navigator.appVersion < '104.0.5112.124 qunheclient/1.0.0 kujialesoft/12.3.9 kujialeclient/12.3.9 utm_industry=kujiale/12.3.9 utm_campaign=autoUpdate'
Use process.versions.electron to view the current client electron version
> process.versions.electron < '20.3.8'
Set domestic ELECTRON source
npm config set ELECTRON_MIRROR https://npm.taobao.org/mirrors/electron/
Framework trial Demo
WebdriverIO
Related documentation: https://webdriver.io/docs/desktop-testing/electron/
Requires node version 16+
Install using scaffolding:
yarn create wdio .
choose:
zhongxin@zhongxindeMacBook-Pro demo2 % yarn create wdio. yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... success Installed "[email protected]" with binaries: -create-wdio [############################################### ####] 53/53 -:.............................-:. + + `` + `...` `...` + ` ./ + / + .:://:::` `::///::` ` + + + /. . + oo + + /: + ooo + -/ /- + ooo + -/ ./ + + oo + . -ooo + + /- + ooo + -/ /- + ooo + -/ .: + + ooo. - + o + + `::///:-` `::///::` + + o + - ``. /. ````` ````` .: .`` .-----------------------------. `-:::::::::::::::::::::::::::::::::::::::::::::::::::-` . + oooo/:---------------------------------:/oooo + . `.--/oooo- :oooo/--.` .::-``:oooo` .oooo-``-::. ./-` -oooo`--.: :.-- .oooo- `-/. -/` `-/oooooooo/.` `/- ` + ` `/ + oooooooooooooooooooooooooooooooooooooooooo + :` . + ` -/ + o/.:oooooooooooooooooooooooooooooooooooooo:-/o/ + . -/ .o + -oooosoooososssssooooo------------------:oooo- `oo` + . -/ .o + -oooodooohyyssosshoooo` .oooo- oo. + . -/ .o + -oooodooysdooooooyyooo` `.--.`` .:::-oooo- oo. + . -/ .o + -oooodoyyodsoooooyyooo.//-..-:/:.`.//.`./oooo- oo. + . -/ .o + -oooohsyoooyysssysoooo + -` `-:::. .oooo- oo. + . -/ .o + -ooooosooooooosoooooo + //oooo- oo. + . -/ .o + -oooooooooooooooooooooooooooooooooooo- oo. + . -/ .o + -oooooooooooooooooooooooooooooooooooo- oo. + . - + o + ` -oooo---:///:----://::------------------:oooo- `oo + - + ooooooo/`-oooo``:-```.:`.:.`. + /- .::::::::::` .oooo-` + ooooooo + oooooooo + `-oooo`- - `/` .: + -/-`/` .::::::::::: .oooo-. + oooooooo + -/ + ://-/ -oooo-`:`.o-`:.:-````.: .///:`````` -oooo-`/-//: + :- + : :..--:-:. + ooo + /://o + /-.-::-....-::::-....--/ + ooo + .:.: --.-- / - /./`-:-` .:/// + /ooooo/ + /// + + + ooooo/ + ///:. .-:.` + ./ : :-:/. :`ooooo`/` .:.ooooo : ./--- :`ooooo`/` .:.ooooo : :`ooooo./` .:-ooooo : :`ooooo./` .:-ooooo : `...:- + + + + + :/. ./: + + + + + -:...` :-.````````/../ /.-:````````.:- -/::::::::://:/ + ` + /: + ::::::::::: + . :oooooooooooo + + / + + + oooooooooooo- Webdriver.IO Next-gen browser and mobile automation test framework for Node.js Installing @wdio/cli to initialize project... ? Success! =============================== WDIO Configuration Wizard =============================== ? What type of testing would you like to do? Desktop Testing - of Electron Applications > https://webdriver.io/docs/desktop-testing/electron ? What is the path to your compiled Electron app? ./dist ? Which framework do you want to use? Jasmine (https://jasmine.github.io/) ? Do you want to use a compiler? No! ? Do you want WebdriverIO to autogenerate some test files? Yes ? Where should these files be located? /Users/zhongxin/gitproject/desktopui/demo2/test/specs/**/*.js ? Which reporter do you want to use? spec, allure ? Do you want to add a plugin to your test setup? ? Do you want to add a service to your test setup? electron ? Do you want me to run `npm install` Yes Installing wdio packages: - @wdio/local-runner@latest - @wdio/jasmine-framework@latest - @wdio/spec-reporter@latest - @wdio/allure-reporter@latest -wdio-electron-service added 78 packages, and changed 1 package in 11s 97 packages are looking for funding run `npm fund` for details ? Success! Creating a WebdriverIO config file... ? Success! Autogenerating test files... ? Success! Adding "wdio" script to package.json. ? Success! Successfully setup project at /Users/zhongxin/gitproject/desktopui/demo2 Join our Discord Community Server and instantly find answers to your issues or queries. Or just join and say hi ! https://discord.webdriver.io Visit the project on GitHub to report bugs or raise feature requests: https://github.com/webdriverio/webdriverio To run your tests, execute: $ cd /Users/zhongxin/gitproject/desktopui/demo2 $ npm run wdio Done in 72.80s.
Install chromedriver
npm i -D chromedriver@104
Modify the wdio.conf.js file
capabilities: [{ browserName: 'chrome', 'goog:chromeOptions': { binary: 'chromedriver/bin/chromedriver', // Path to the Electron binary file args: [/* command line arguments */] // optional, such as 'app=' + /path/to/your/app/ } }], services: [[ 'electron', { appPath: '/Users/zhongxin/Downloads', appName: "Kujiale", appArgs: ['foo', 'bar=baz'], chromedriver: { port: 9519, logFileName: 'wdio-chromedriver.log', chromedriverCustomPath: 'chromedriver/bin/chromedriver' // resolves to chromedriver binary }, electronVersion: '20.3.8', } ]],
Taking the mac m1 computer as an example, after downloading the client from the official website, open the dmg file and put Kujiale.app in the /Users/zhongxin/Downloads/mac-arm64/kujiale.app location
Modify the test script test.e2e.js and complete the login
import { browser } from '@wdio/globals'describe('Electron Testing', () => { it('should print application metadata', async () => { console.log('Listen to white test') await browser.$('//*[text()="Account login"]').click() await browser.$('//input[@placeholder="Enter mobile phone number/email"]').setValue("[email protected]") await browser.$('//input[@placeholder="Enter password"]').setValue("xxxx") await browser.$('//button[text()="Login"]').click() await browser.pause(5000) await browser.saveScreenshot('./test.png') }) })
After running the test wdio run ./wdio.conf.js, the client will be awakened and the login operation will be completed, and then a screenshot will be taken.
Selenium
Create a new empty folder and initialize it with npm
npm init
zhongxin@zhongxindeMacBook-Pro demo2 % npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (demo2)version: (1.0.0)description:entry point: (index.js)test command:git repository:keywords:author:license: (ISC)About to write to /Users/zhongxin/gitproject/desktopui /demo2/package.json: { "name": "demo2", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" & amp; & amp; exit 1" }, "author": "", "license": "ISC" }Is this OK? (yes)
Install & run chromedriver
npm install --save-dev [email protected]./node_modules/.bin/chromedriver
Install selenium
npm install --save-dev selenium-webdriver
Write test scripts
const webdriver = require('selenium-webdriver')const { Builder } = require('selenium-webdriver'); (async function myTest() { let driver = await new Builder() .usingServer('http://localhost:9515') .withCapabilities({ 'goog:chromeOptions': { binary: '/Users/zhongxin/Downloads/mac-arm64/kujiale.app/Contents/MacOS/kujiale' } }) .forBrowser('chrome') // Note: use .forBrowser('electron') for selenium-webdriver <= 3.6.0 .build() console.log('Listen to white test') await driver.sleep(5000) await driver.findElement(webdriver.By.xpath('//*[text()="Account login"]')).click() await driver.findElement(webdriver.By.xpath('//input[@placeholder="Enter mobile phone number/email"]')).sendKeys("[email protected]") await driver.findElement(webdriver.By.xpath('//input[@placeholder="Enter password"]')).sendKeys("xxxx") await driver.findElement(webdriver.By.xpath('//button[text()="Login"]')).click() await driver.sleep(5000) await driver.takeScreenshot().then( function (image, err) { require('fs').writeFile('test.png', image, 'base64', function (err) { console.log(err) }) }) await driver.quit() })();
playwright
Official documentation: https://playwright.dev/docs/api/class-electron
Install
npm init playwright@latest
zhongxin@zhongxindeMacBook-Pro demo3 % npm init playwright@latest Need to install the following packages: [email protected] to proceed? (y) Getting started with writing end-to-end tests with Playwright: Initializing project in '.' ? Do you want to use TypeScript or JavaScript? · JavaScript ? Where to put your end-to-end tests? · tests ? Add a GitHub Actions workflow? (y/N) · false ? Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true Initializing NPM project (npm init -y)… Wrote to /Users/zhongxin/gitproject/desktopui/demo3/package.json: { "name": "demo3", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" & amp; & amp; exit 1" }, "keywords": [], "author": "", "license": "ISC" } Installing Playwright Test (npm install --save-dev @playwright/test)… added 3 packages in 5s Downloading browsers (npx playwright install)… Writing playwright.config.js. Writing tests/example.spec.js. Writing tests-examples/demo-todo-app.spec.js. Writing package.json. ? Success! Created a Playwright Test project at /Users/zhongxin/gitproject/desktopui/demo3 Inside that directory, you can run several commands: npx playwright test Runs the end-to-end tests. npx playwright test --ui Starts the interactive UI mode. npx playwright test --project=chromium Runs the tests only on Desktop Chrome. npx playwright test example Runs the tests in a specific file. npx playwright test --debug Runs the tests in debug mode. npx playwright codegen Auto generate tests with Codegen. We suggest that you begin by typing: npx playwright test And check out the following files: - ./tests/example.spec.js - Example end-to-end test - ./tests-examples/demo-todo-app.spec.js - Demo Todo App end-to-end tests - ./playwright.config.js - Playwright Test configuration Visit https://playwright.dev/docs/intro for more information. ? Happy hacking!
Install electron
npm i [email protected]
Run the development project:
https://gitlab.qunhequnhe.com/fe/up/desktop
https://gitlab.qunhequnhe.com/desktop/base/main
Generate entry file:/Users/zhongxin/gitproject/main/app/dist/main.js
Test script:
const {_electron: electron} = require('@playwright/test'); (async () => { const electronApp = await electron.launch({ cwd: '/Users/zhongxin/gitproject/main/app/dist', args: ['main.js'] }); console.log('Start testing') const window = await electronApp.firstWindow(); await window.waitForTimeout(3000) window.on('console', console.log); console.log(await window.title()); await window.screenshot({path: 'intro.png'}); await window.click('text=Account login'); await window.fill('input[placeholder="Enter mobile phone number/email"]', '[email protected]') await window.fill('input[placeholder="Enter password"]', 'xxxx') await window.click('button[title="Account password login"]'); await window.waitForTimeout(3000) await window.locator('text=Login').last().click(); await window.waitForTimeout(3000) await window.screenshot({path: 'test.png'}); await electronApp.close(); })();
This method is very troublesome and is more suitable for testing during the development stage.
Puppeteer
Create a new empty folder and initialize it with npm
npm init
Install related packages
npm i [email protected] puppeteer-core
Run local electron and enable debugging
const {spawn} = require("child_process");const port = 9200; spawn( "/Users/zhongxin/Downloads/mac-arm64/kujiale.app/Contents/MacOS/kujiale", [`--remote-debugging-port=${port}`], {shell: true} );
Write test scripts
const puppeteer = require("puppeteer-core");const port = 9200; (async () => { let app = await puppeteer.connect({ browserURL: `http://localhost:${port}`, }); const pages = await app.pages(); const [page] = pages; await (await page.$x('//button[text()="Account login"]'))[0].click(); await (await page.$x('//input[@placeholder="Enter mobile phone number/email"]'))[0].type('[email protected]') await (await page.$x('//input[@placeholder="Enter password"]'))[0].type('xxxx'); await (await page.$x('//button[text()="Login"]'))[0].click(); await page.screenshot({path: 'test.png'}); setTimeout(async () => await app.close(), 5000) })()
Summary
Framework | Environment preparation | Support status |
---|---|---|
WebdriverIO | Simple: just put the downloaded installation package into the specified path | Good support |
Selenium | Medium: Place the downloaded installation package into the specified path+ Launch chromedriver | Support General |
playwright | Difficulty: Deploy & Run Code | Experimental nature |
Puppeteer | Medium: Download the installation package Put it in the specified path + start the application | Supports general |
Since Hades uses Puppeteer, use Puppeteer first.
Subsequently, an operation to start electron is encapsulated and added to beforeAll, so that the old UI automation test code can be reused.