How To Do Assertions in AskUI
Tags: tutorial, testing, typescript
Published: 2023-04-17 07:38:19

Real interactivity is what characterizes what an end-user is doing on a User Interface (UI). This is why it is important to extract data from your UI into your tool and use it later, for assertions for example 🔧.

We will show two ways to use AskUI for real interactivity by extracting text out of your UI and use it for assertions:

1. AskUI assertions
2. Jest assertions

## Prerequisites
* AskUI SDK installed: [Windows](https://docs.askui.com/docs/general/Getting%20Started/Installing%20AskUI/getting-started), [Linux](https://docs.askui.com/docs/general/Getting%20Started/Installing%20AskUI/getting-started-linux), [macOS](https://docs.askui.com/docs/general/Getting%20Started/Installing%20AskUI/getting-started-macos)
* A browser to open [this page](https://authenticationtest.com/bootstrapAuth/)

## Explaining the Use Case
When you open [the page linked](https://authenticationtest.com/bootstrapAuth/) above it takes  you to an interactive login form.

We will do the following steps to create a real end-user workflow:

1. Enter the E-Mail and Password
2. Extract the captcha value
3. Enter it into the designated captcha textfield
4. Click the **Login**-button
5. Verify the login succeeded by searching for the text **Login Success**

### Enter E-mail and Password
The first thing we need to do is enter the given values for _E-Mail_ and _Password_.

```typescript
// Get focus on browser window
// Do not forget to move your mouse pointer
// over to the browser window!
await aui.mouseLeftClick().exec();

await aui.typeIn('bootstrap@authenticationtest.com')
         .textfield()
         .contains()
         .text()
         .withText('E-Mail Address')
         .exec();
await aui.typeIn('pa$$w0rd')
         .textfield()
         .contains()
         .text()
         .withText('Password')
         .exec();
```

### Extract the CAPTCHA Value
Now we start with the interactive part 🥳. Extract the value of the text _CAPTCHA_ with `get()`. We find the text above the textfield that contains the value `123456` and match the CAPTCHA with some TypeScript-RegEx-magic.

```typescript
const texts = await aui.get()
                       .text()
                       .above()
                       .textfield()
                       .contains()
                       .text()
                       .withText('123456').exec();

// texts contains an array!
// The phrase with the captcha is the first element
const captchaInText = texts[0];

// We have to extract the value with TypeScript
// It is 6 digits long: Matching it with RegEx
// Match is also an array and we want the first element
const captcha = captchaInText.text.match(/\d{6}/)[0];
```

### Enter the CAPTCHA Value Into the Designated Textfield
Feed the extracted value back to the textfield designated for it. Also lose the focus so we do not interfere with Optical Character Recognition (OCR) when we want to assert the value is really there.

```typescript
await aui.typeIn(captcha)
         .textfield()
         .contains()
         .text().withText('123456')
         .exec();

// Lose focus on the textfield
// Cursor may interfere with OCR
await aui.pressKey('tab').exec();
```

### Assert with Jest-Assertions That the Value was Entered Correctly

To assert if the CAPTCHA was entered successfully we will show you two approaches to find the correct textfield and extract its value:

```typescript
// IMPORTANT:
// Add this line to the top of your file
import {expect} from '@jest/globals';

// APPROACH 1
// Assert that the captcha was actually entered
// Extract the actual value first
const actuallyEntered = await aui.get()
  .text()
  .withTextRegex('^\\d{6}')
  .exec();
expect(actuallyEntered[0].text).toBe(captcha);

// APPROACH 2    
const actuallyEntered2 = await aui.get()
  .text()
  .below()
  .text()
  .withTextRegex(".*in the box")
  .exec();
expect(actuallyEntered2[0].text).toBe(captcha);
```

### Click the Login-Button
If the assertions do not fail we get to click the _Log in_-button.

```typescript
await aui.click().button().withText('Log In').exec();
```

### Verify Success with AskUI Assertions
When developing the code we noticed that sometimes the success window opened in a new browser tab. But sometimes not 😋

So we had to wrap our assertion in a `try/catch`-block to account for this scenario. If the **Success**-Page shows in the same browser tab the first instruction will succeed. If not it will throw an error.

In the `catch`-clause we will then try to switch to the next browser tab and find the **Success**-message there. If we fail again the login must have failed.

```typescript
// Sometimes the site opens the success message
// in another tab
try {
  await aui.expect()
           .text()
           .withText('Login Success')
           .exists()
           .exec();
} catch(error) {
  // Switch to next browser tab
  // Windows Linux: control + tab
  // await aui.pressTwoKeys('control', 'tab').exec();
      
  // macOS: CMD + option + right arrow
  await aui.pressThreeKeys('command', 'alt', 'right')
           .exec();
  
  await aui.expect()
           .text()
           .withText('Login Success')
           .exists()
           .exec();
}
```

## Complete Code

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

import {expect} from '@jest/globals';

describe('jest with askui', () => {
  
  it('assert', async () => {

    // Get focus on browser window
    // Do not forget to move your mouse pointer
    // over to the browser window!
    await aui.mouseLeftClick().exec();

    await aui.typeIn('bootstrap@authenticationtest.com')
             .textfield()
             .contains()
             .text()
             .withText('E-Mail Address')
             .exec();
    await aui.typeIn('pa$$w0rd')
             .textfield()
             .contains()
             .text()
             .withText('Password')
             .exec();

    const texts = await aui.get()
                           .text()
                           .above()
                           .textfield()
                           .contains()
                           .text()
                           .withText('123456')
                           .exec();

    // texts contains an array!
    // The phrase with the captcha is the first element
    const captchaInText = texts[0];

    // We have to extract the value with TypeScript
    // It is 6 digits long: Matching it with RegEx
    // Match is also an array and we want the first element
    const captcha = captchaInText.text.match(/\d{6}/)[0];

    await aui.typeIn(captcha)
             .textfield()
             .contains()
             .text()
             .withText('123456')
             .exec();
    
    // Lose focus on the textfield
    // Cursor may interfere with OCR
    await aui.pressKey('tab').exec();

    // Assert that the captcha was actually entered
    // Extract the actual value first
    const actuallyEntered = await aui.get()
                                     .text()
                                     .withTextRegex('^\\d{6}')
                                     .exec();
    expect(actuallyEntered[0].text).toBe(captcha);
    
    const actuallyEntered2 = await aui.get()
                               .text()
                               .below()
                               .text()
                               .withTextRegex(".*in the box")
                               .exec();
    expect(actuallyEntered2[0].text).toBe(captcha);

    await aui.click()
             .button()
             .withText('Log In')
             .exec();

    // Sometimes the site opens the success message
    // in another tab
    try {
      await aui.expect()
               .text()
               .withText('Login Success')
               .exists()
               .exec();
    } catch(error) {
      // Switch to next browser tab
      // Windows Linux: control + tab
      // await aui.pressTwoKeys('control', 'tab').exec();
      
      // macOS: CMD + option + right arrow
      await aui.pressThreeKeys('command', 'alt', 'right')
               .exec();
  
      await aui.expect()
               .text()
               .withText('Login Success')
               .exists()
               .exec();
    }

  });
});
```

## Conclusion
In this tutorial, you learned how to assert values in your UI 

With this knowledge, you can now craft your own interactive UI-workflows 😎.

## Get Support
If you have a recurring or persisting issue, don’t hesitate to ask the [Discord community](https://discord.gg/Gu35zMGxbx) for help!