Use the Power Of TypeScript in AskUI
Tags: javascript, typescript, tutorial
Published: 2023-06-30 13:28:28

## Optimizing UI Automation with Functions in TypeScript

In the past, we've discussed using if and else statements, try and catch blocks, and for loops in TypeScript for building UI automations. 

However, to avoid repeating code and add real UI interactivity to your AskUI workflows, it's essential to harness the power of functions. Functions can help create reusable and efficient code for checking if elements are present and reacting accordingly.

## The Problem
When you want to check if an element is present on your UI you might do it like this and do something else when the element is not found:

```javascript
try {
    await aui.expect().text('<Your text here!>').exists().exec();
  } catch(error) {
    // Do something else
  }
```

This is totally fine, but once you create more sophisticated workflows you will notice that you need a variation of this code 1,2,3 ... x times.

You can do better if you extract this into a function!

## Extract into a function
To get started, create a `util.ts` file in the same folder as your automation file. First, import the `UiControlClient` into this file:

```javascript
import { aui } from './helper/jest.setup';
```

Then you can create a function in this file that takes a parameter `text` and returns `true` or `false` depending on if the element is present or not. This function is asynchronous and checks for the presence of a specific element on the screen. It returns a boolean value to indicate whether the element is present or not.

```javascript
export async function checkSuccess(text: string) {
  try {
    await aui.expect().text().withText(text).exists().exec();
    return true;
  } catch(error) {
    console.log(`${text} not found!`);
  }
  return false;
}
```

The `export` keyword makes sure we can use it in our actual AskUI-workflow file.
 
```javascript
// Do this in your actual AskUI workflow file at the start
import {checkSuccess} from './utils';

// Usage
if ((await checkSuccess('Success')) === false) {
  // React to text not being there
};
```

Implementing it like this makes it possible to reuse the this functionality for all text you need. It also improves the readability of your workflow file 🥳

## Endless Possibilities
You can wrap (nearly) any functionality you need in a handy function.

Here's an example of a `waitUntil()` function that you can use to wait for an element or an app to appear on the screen, even if it takes longer than a few seconds:

```javascript
// Retry the command 5 times with a
// wait time of 2 seconds between each try
async function waitUntil(askuiCommand: Promise<void>, maxTry = 5) {
    try {
        await askuiCommand;
    }
    catch (error) {
        if (maxTry == 0) {
            throw error;
        }
        console.log(`Retry predicting command, ${maxTry} tries left`);
        await aui.waitFor(2000).exec();
        await waitUntil(askuiCommand, maxTry - 1);
    }
}

// Wait for the text 'Github' to be displayed
await waitUntil(
    aui.expect().text().withText('Github').exists().exec();
)
```

## Conclusion
Leveraging functions in TypeScript significantly streamlines your UI automation efforts and provides numerous opportunities for optimization.