Parallel Execution of AskUI Workflows with Jest

August 7, 2024
Tutorials
The image is a promotional graphic for a tutorial or informational content about "Parallel Execution with Jest." The background is dark blue with a neon green border. The text "Parallel Execution with Jest" is prominently displayed in bright green and purple. The graphic includes a Jest logo in the top right corner and an illustration of a man looking thoughtful in the bottom right corner. At the bottom, there is an abstract representation of runners in motion, suggesting the theme of parallelism and speed.
linkedin icontwitter iconfacebook iconmail icon

Have you ever needed to run your AskUI Workflows in parallel on multiple devices to speed up the execution?

That is possible with a little bit of configuration in Jest, the runner used to execute AskUI Workflows, and multiple AskUI Controllers.

This blog will walk you through the setup for two Android devices and running a bunch of workflows.

Prerequisites

The image is a diagram illustrating the architecture of a system involving a local device and an inference server, connected via a series of processes and data flows. Your Local Device: Contains an Operating System connected to the askui UI Controller through InputEvents. The askui UI Controller communicates with the askui Control Client via ControlCommands. The askui Control Client can send and receive Screenshots and Annotations from the Inference Server. Inference Server: Performs various detection and classification tasks through Object Detection, Icon Classification, Custom Element Detection, and OCR modules. A Fusion module integrates the outputs of these detection and classification tasks. The Fusion module sends back the results to the askui Control Client on the local device. This diagram highlights the interaction between the local device and the inference server for processing and analyzing UI elements and screenshots.

Start AskUI Controllers

⚠️ The commands shown below start the AskUI Controller on your local machine as we are controlling two Android devices. If you want to run your workflows on a remote machine, install and start the controllers there. Do not forget to get the IP of the remote machine for the URL to the controller!

Windows

-- CODE language-bash line-numbers -- # Open AskUI Shell askui-shell # Start first AskUI Controller on Port 6769 for android device 0 (emulator-5556) AskUI-StartController -RunInBackground -DisplayNum 0 -Runtime android -Port 6769 # Start second AskUI Controller on Port 6770 for android device 1 (emulator-5554) AskUI-StartController -RunInBackground -DisplayNum 1 -Runtime android -Port 6770

Jest

Next comes Jest, the javascript framework AskUI uses to run its workflows.

.env For Configuration Environment Variables

First, we want to have a way to configure how many parallel processes are running workflows. For this, we install the dotenv package like this:

-- CODE language-bash line-numbers -- npm install --save-dev dotenv

Then we create a file .env in the root of the project and fill it with the following. We set the JEST_MAX_WORKER to two as we have two Android devices:

-- CODE language-bash line-numbers -- ASKUI_WORKSPACE_ID= ASKUI_TOKEN= JEST_MAX_WORKER=1

Configure Maximum Parallel Workers in jest.config.ts

We need the max workers feature from Jest which allows us to specify the number of workers that should run in parallel. It can be configured in the file jest.config.ts. We use the environment variable JEST_MAX_WORKER from the .env file.

-- CODE language-ts line-numbers -- import type { Config } from '@jest/types'; import 'dotenv/config'; const config: Config.InitialOptions = { preset: 'ts-jest', testEnvironment: '@askui/jest-allure-circus', setupFilesAfterEnv: ['./helpers/askui-helper.ts'], sandboxInjectedGlobals: [ 'Math', ], maxWorkers: process.env.JEST_MAX_WORKER ? parseInt(process.env.JEST_MAX_WORKER) : 1 }; // eslint-disable-next-line import/no-default-export export default config;

Connect AskUI Controllers in askui-helper.ts

In the askui-helper.ts we hold an array of all AskUI Controller URLs we want to target. We take the configured maxWorkers and the workerId to connect each worker with a different AskUI Controller.

⚠️ If you do not use two Android devices and the AskUI Controller runs on a remote system, you must change the URLs in the uiControllerDeviceList.

-- CODE language-ts line-numbers -- import { UiControlClient } from 'askui'; import 'dotenv/config'; // List of AskUI Controller connected to remote devices const uiControllerDeviceList = ["ws://127.0.0.1:6769", "ws://127.0.0.1:6770"] // Client is necessary to use the askui API let aui: UiControlClient; jest.setTimeout(60 * 1000 * 60); let maxWorkers: number; let workerId: number; let uiControllerUrl: string; beforeAll(async () => { maxWorkers = parseInt(process.env.JEST_MAX_WORKER, 10); // Our env variable defined in .env file workerId = parseInt(process.env.JEST_WORKER_ID, 10); // Each Jest Worker starts as its own process and the index begins with 1. See https://jestjs.io/docs/environment-variables#jest_worker_id expect(maxWorkers).toBeLessThanOrEqual(uiControllerDeviceList.length) // Select one Android Device per Worker uiControllerUrl = uiControllerDeviceList[workerId - 1] aui = await UiControlClient.build({ uiControllerUrl: uiControllerUrl, }); await aui.connect(); console.log("Jest Worker: ", workerId, "/", maxWorkers, " connect to '", uiControllerUrl, "'") }); ...

When you start your run with this configuration you will see that the *.test.ts files will be executed in parallel and ONLY once. Each worker will generate a separate report, giving you detailed insights into the execution.

The important thing is that each worker is completely independent and encapsulated. This means the setup process from askui-helper.ts will run separately for each worker! This ensures that the workflows do not interfere with each other.

Conclusion

With a little bit of Jest configuration and multiple AskUI Controllers you can parallelize the execution of your AskUI Workflows.

If you have questions or need support, do not hesitate to join our Outverse-Community.

Johannes Dienst
·
August 7, 2024
On this page