---
schema_version: "1"
id: 13c3d7d2cd7ec0db2524ecd0bd0eb52eab2b90b907a459fc8d0220910415f4c2
title: Nullable Versus isPresent
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/lwc/utam/guide/nullable-vs-ispresent.md
canonical_url: https://developer.salesforce.com/docs/platform/utam/guide/nullable-vs-ispresent.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 6a2b188bb7b3729492c327d8d86021906cd8abda54fbc18f0aee3fed4ce5080f
products:
  - UI Test Automation Model
  - lwc
---
# Nullable Versus isPresent

Consider these two cases that validate the absence of an element:

1. Log in to an application with minimal access rights and check that a "Setup" button isn't present.
2. After entering login credentials, check that the login form is no longer on the screen.

The key difference is that for the first use case, the button element was _never in the DOM_. We call it a nullable element. For the second use case, the login form element _was present in the DOM but no longer is_. We call it a stale element.

The following sections provide examples for both types of use cases.

## Check nullable element presence

When a test invokes an element's getter method, the framework attempts to find the element and return its value. In the first use case, a test invokes the getter for the Setup button.

Unless the element is marked as `nullable`, an error is thrown if the element isn't found.

If the element is marked as `nullable`, the getter returns `null` if the element isn't found.

```json
{
  "shadow": {
    "elements": [
      {
        "name": "setupButtonHTMLElement",
        "type": "clickable",
        "public": true,
        "nullable": true,
        "selector": { "css": "button.setup" }
      },
      {
        "name": "setupButtonCustomElement",
        "type": "utam-my/pageObjects/button",
        "public": true,
        "nullable": true,
        "selector": { "css": "my-button" }
      }
    ]
  }
}
```

A test or an imperative extension can check or assert a getter's returned value for `null` and act accordingly.

JavaScript example:

```js
const setupButton = await page.getSetupButtonHTMLElement();
const setupButtonCustom = await page.getSetupButtonCustomElement();
// assert for null
expect(setupButton).toBeNull();
expect(setupButtonCustom).toBeNull();
// OR check for null and apply action
if (setupButton) {
  // do something if element is present
  ...
}
if (setupButtonCustom) {
  // do something if element is present
  ...
}
```

Java example:

```java
SetupButton setupButton = page.getSetupButtonHTMLElement();
Button setupButtonCustom = page.getSetupButtonCustomElement();
// assert for null
assert setupButton == null;
assert setupButtonCustom == null;
// OR check for null and pply action
if (setupButton != null) {
  // do something if element is present
  ...
}
if (setupButtonCustom != null) {
  // do something if element is present
  ...
}
```

If the elements weren't marked as `"nullable": true`, the `page.getSetupButtonHTMLElement()` or `page.getSetupButtonCustomElement()` getters would throw an exception if the element isn't present.

## Check nullable list presence

The `nullable` behavior is the same for a list of elements.

```json
{
  "shadow": {
    "elements": [
      {
        "name": "setupButtonHTMLElementsList",
        "type": "clickable",
        "public": true,
        "nullable": true,
        "selector": { "css": "button.setup", "returnAll": true }
      },
      {
        "name": "setupButtonCustomElementsList",
        "type": "utam-my/pageObjects/button",
        "public": true,
        "nullable": true,
        "selector": { "css": "my-button", "returnAll": true }
      }
    ]
  }
}
```

A test or an imperative extension can check or assert a getter's returned value for `null` and act accordingly.

JavaScript example:

```js
const setupButtons = await page.getSetupButtonHTMLElementsList();
const setupButtonsCustom = await page.getSetupButtonCustomElementsList();
// assert for null
expect(setupButtons).toBeNull();
expect(setupButtonsCustom).toBeNull();
```

Java example:

```java
List<SetupButton> setupButtons = page.getSetupButtonHTMLElement();
List<Button> setupButtonsCustom = page.getSetupButtonCustomElement();
// assert for null
assert setupButtons == null;
assert setupButtonsCustom == null;
```

## Compose checking presence of a nullable element

For better encapsulation, keep the element private and declare a compose method to check that its getter returns not null:

```json
{
  "elements": [
    {
      // same element, but not public
      "name": "setupButton",
      "nullable": true,
      "selector": { "css": "button.setup" }
    }
  ],
  "methods": [
    {
      "name": "isSetupButtonPresent",
      "compose": [
        {
          "element": "setupButton",
          "matcher": {
            "type": "notNull"
          }
        }
      ]
    }
  ]
}
```

Note the syntax in the compose method. We used `element` and omitted `apply` to call the getter method.

The generated `isSetupButtonPresent` method calls the getter for the `setupButton` element, checks if its value isn’t null, and returns a boolean value.

A test or an imperative extension can assert or check the element's presence and act accordingly.

```js
if (await homePage.isSetupButtonPresent()) {
  // do something
}
```

## Compose checking presence with containsElement

Another option is to check for an element's presence using the `containsElement` action first and then act accordingly.

```json
{
  "elements": [
    {
      // same element, but not public
      "name": "myButton",
      "type": "clickable",
      "selector": { "css": "button.my" }
    }
  ],
  "methods": [
    {
      "name": "isMyButtonPresent",
      "compose": [
        {
          "element": "root",
          "apply": "containsElement",
          "args": [
            // first arg - selector to search for
            {
              "type": "locator",
              "value": { "css": "button.my" }
            },
            // second arg - expand or not the shadow root of the parent, false is default
            { "value": false }
          ]
        }
      ]
    },
    {
      "name": "clickMyButton",
      "compose": [
        {
          "element": "myButton",
          "apply": "click"
        }
      ]
    }
  ]
}
```

Example of usage from a test:

- JavaScript

```js
if (await homePage.isMyButtonPresent()) {
  await clickMyButton();
}
```

- Java

```js
if (homePage.isMyButtonPresent()) {
  clickMyButton();
}
```

## isPresent returns false for a Stale Element

A `getMyElement().isPresent()` call returns `true` for an existing element or throws an error for a non-nullable absent element. The `isPresent()` call returns `false` when an element **becomes** absent or stale because the page was refreshed.

```java
myForm = homePage.getForm();
// do something in the form until it's gone
assert myForm.isPresent() == false;
```

The `isPresent` call returns false when the form element became stale. Consider our second use case earlier where the login form is no longer on the screen after the login is complete.

### Save an element instance in a variable

Remember that invoking an element's getter triggers finding the element inside its parent. To use `isPresent`, save an instance of the element before it becomes stale to avoid an error that the element isn't found when its getter is invoked. The `myForm = homePage.getForm()` calls saves the form before it becomes stale.

### Calling isPresent on a nullable element can throw NullPointerException

If an element is marked as nullable, a test should check for a null value before calling any method, including `isPresent`, on it.

```java
myForm = homePage.getForm();
// assuming the form is nullable
assert myForm != null && myForm.isPresent() == false;
```

## Wait for absence of a stale element

If an element was present but it takes time for it to become absent, use `waitForAbsence`. For example, an application might do some processing after we save changes in a form but doesn't hide the form immediately.

- JavaScript example

```js
const myForm = await homePage.getForm();
await myForm.waitForAbsence();
```

- Java example

```java
PageObject myForm = homePage.getForm();
myForm.waitForAbsence();
```

## Wait for presence in beforeLoad

If a test must wait for a certain element to be present inside a page object root, it's a best practice to make the wait a part of loading the page object by overriding the page object's load method.

A page Object is "loaded" when a test either call `UtamLoader.load(Class)` or invokes a getter method that returns the page object from inside its enclosing page object.

In this example, the page object overrides page loading by waiting for an element with a given selector using the `containsElement` action:

```json
{
  "beforeLoad": [
    {
      "apply": "waitFor",
      "args": [
        {
          "type": "function",
          "predicate": [
            {
              "element": "root",
              "apply": "containsElement",
              "args": [
                // first arg - selector to search for
                {
                  "type": "locator",
                  "value": { "css": "i-am-slow" }
                },
                // second arg - expand the shadow root of the parent
                { "value": true }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

**note:** We can't use a nullable element in this example. A `beforeLoad` statement can invoke methods only against root or a document object because the page isn't fully loaded yet.

The predicate in the `waitFor` statement has to return a truthy value (not null, not false and doesn’t throw) for the method to complete without an error.

In our example, the root element should contain an element with the given selector inside its shadowRoot.

## Wait for nullable element presence

In some cases, it can take some time for an element to render. Such a wait isn't always allowed in a `beforeLoad` override such as in the previous example. For example, the element might not be inside root or its loading might not be stateless.

```json
{
  "elements": [
    {
      "name": "parent",
      "selector": { "css": ".containsSlowElement" },
      "elements": [
        {
          "name": "slowElement",
          "selector": { "css": "i-am-slow" }
        }
      ]
    }
  ],
  "methods": [
    {
      "name": "waitForSlowElement",
      "compose": [
        {
          "apply": "waitFor",
          "args": [
            {
              "type": "function",
              "predicate": [
                {
                  "element": "slowElement"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

The predicate in the `waitFor` statement has to return a truthy value (not null, not false and doesn’t throw) for the method to complete without an error.

In this example, the method repeatedly calls the slowElement getter until it stops throwing an error that element isn't found or until a timeout is reached.

## Wait for nullable list presence

To wait for a list of elements, we can use the same approach as in the previous example. The only exception is that the element is marked with `returnAll`. This example also uses a custom type:

```json
{
  "elements": [
    {
      "name": "parent",
      "selector": { "css": ".containsSlowElement" },
      "elements": [
        {
          "name": "slowCustomElements",
          "selector": { "css": "i-am-slow" },
          "type": "utam-my/pageObjects/custom"
        }
      ]
    }
  ],
  "methods": [
    {
      "name": "waitForSlowElementsList",
      "compose": [
        {
          "apply": "waitFor",
          "args": [
            {
              "type": "function",
              "predicate": [
                {
                  "element": "slowCustomElements"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

As in the previous example, this method repeatedly calls the `slowCustomElements` getter until it stops throwing an error that the element isn't found or until a timeout is reached.
