Method Return Types

The UTAM compiler needs to know the return type for every method to generate the method signature in the type declaration (TypeScript) or in the interface code (Java). For example:

JavaScript

returnPrimitive(): Promise<string>;

Java

List<SomeCustomType> returnCustomList();

Depending on the method, the return type can be:

{
    "returnType": "string",
    "returnAll": true
}

The return type of the last compose statement is considered the compose method's return type. Setting the return type at the level of a compose method's declaration isn't allowed.

Supported return types

The returnType property can have one of the following values. Each of them except void can be combined with "returnAll" : true to return a list (Java) or an array (JavaScript).

returnTypereturned value
custom typestring with at least one '/', for example utam/pageObject/Input
basic typesupported only for abstract methods
booleanboolean primitive (Boolean object in Java)
framean element of frame type
numbernumber primitive (Integer object in Java)
pageObjectpage object instance of unspecified type (not root page object)
rootPageObjectroot page object instance of unspecified type
stringstring primitive (String object in Java)
voidDefault if explicit returnType isn't set and can't be inferred

Inferring the return type

In some cases, the UTAM compiler can infer a statement's return type from the context.

{
    "element": "document",
    "apply": "getUrl",
    "matcher": {
        "type": "stringContains",
        "args": [{ "value": "homePage" }]
    }
}

In this example, getText is known to return a string. If basicElementsList is an element of a basic type whose selector is marked with returnAll to return a list of elements, UTAM deduces that the return type is List<String> (Java) or string[] (JavaScript).

{
    "element": "basicElementsList",
    "apply": "getText"
}

This JSON statement invokes a getter for the same basic element from the previous example. Assuming that the element is declared with "type" : "actionable", UTAM knows to return List<Actionable>.

{
    "elements": [
        {
            "name": "basicElementsList",
            "type": "actionable",
            "selector": {
                "css": ".action",
                "returnAll": true
            }
        }
    ],
    "methods": [
        {
            "name": "test",
            "compose": [
                {
                    "element": "basicElementsList"
                }
            ]
        }
    ]
}

The behavior is the same if you invoke a custom element getter. In this example, the UTAM compiler deduces that the return type for the test method is Custom.

{
    "elements": [
        {
            "name": "customElement",
            "type": "utam/pageObjects/custom",
            "selector": {
                "css": "my-utam"
            }
        }
    ],
    "methods": [
        {
            "name": "test",
            "compose": [
                {
                    "element": "customElement"
                }
            ]
        }
    ]
}

Compose statement return type

The returnType should be explicitly set when it's not void and the statement isn't using a matcher.

Statement applies an action to a custom element

In this example, the test method invokes the public returnsString method on the custom page object so the returnType should be explicitly set.

{
    "elements": [
        {
            "name": "customElement",
            "type": "utam/pageObjects/custom",
            "selector": {
                "css": "my-utam"
            }
        }
    ],
    "methods": [
        {
            "name": "test",
            "compose": [
                {
                    "element": "customElement",
                    "apply": "returnsString",
                    "returnType": "string"
                }
            ]
        }
    ]
}

Statement applies an action to a document

The UTAM compiler doesn't recognize return types for methods applied to the document element. You need an explicit returnType.

{
    "methods": "getCurrentUrl",
    "compose": [
        {
            "element": "document",
            "apply": "getUrl",
            "returnType": "string"
        }
    ]
}

Statement applies an action to a frame element

The UTAM compiler doesn't recognize return types for methods applied to the frame element.

Even though getClassAttribute is a basic action, frame isn't recognized as a basic element and the compiler doesn't know the return type. You need an explicit returnType.

{
    "elements": [
        {
            "name": "privateFrame",
            "type": "frame",
            "selector": {
                "css": "iframe"
            }
        }
    ],
    "methods": [
        {
            "name": "getFrameClass",
            "compose": [
                {
                    "returnType": "string",
                    "element": "privateFrame",
                    "apply": "getClassAttribute"
                }
            ]
        }
    ]
}

Chain statement

When a statement is "chained" (invoked on the result of the previous statement), the UTAM compiler doesn't know the return type. It almost always should be set explicitly (except for void or a matcher).

{
    "elements": [
        {
            "name": "customElement",
            "type": "utam/pageObjects/custom",
            "selector": {
                "css": "my-utam"
            }
        }
    ],
    "methods": [
        {
            "name": "getFrameClass",
            "compose": [
                {
                    // return type can be omitted
                    // because it's a "can infer return" cases
                    "element": "customElement"
                },
                {
                    "returnType": "utam/pageObjects/anotherPageObject",
                    "element": "anotherPageObjectInsideCustomElement",
                    "chain": true
                },
                {
                    "returnType": "string",
                    "apply": "getTextFromAnotherPageObject",
                    "chain": true
                }
            ]
        }
    ]
}

returnType inside a predicate

In a waitFor statement, the return type is the returnType of the last statement inside the predicate.

In this example, the last predicate statement returns "string", so the predicate statement is also assumed to return string.

{
    "methods": [
        {
            "name": "returnWaitRootPageObject",
            "compose": [
                {
                    "apply": "waitFor",
                    "args": [
                        {
                            "type": "function",
                            "predicate": [
                                {
                                    "apply": "someMethod",
                                    "returnType": "string"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

All the rules for inferring a return type inside the predicate also apply. A return type is inferred whenever possible.

Abstract method return type

When you create an interface, the JSON compiler can't infer any return types, so each method's return type should be declared explicitly. Otherwise, the method is assumed to return void.

An interface must declare all public methods including element methods as well as compose methods. Here's an example:

{
    "interface": true,
    "methods": [
        {
            "name": "doNothingAndReturnVoid"
        },
        {
            "name": "getInnerText",
            "returnType": "string"
        },
        {
            "name": "customElementsList",
            "returnType": "utam/pageObjects/customType",
            "retrunAll": true
        }
    ]
}

returnType for basic elements

An element method might need to return basic types. Such a returnType isn't supported for a compose method because in a regular page object it's done via element declaration.

{
    "name": "getButton",
    "returnType": ["actionable", "clickable"]
}
{
    "name": "getAllButtons",
    "returnType": "actionable",
    "returnAll": true
}

returnSelf statement

In a compose method, it can be useful to return an instance of the current page object instead of returning void, so that methods can be invoked in a chain inside a test or inside another compose method.

An "apply": "returnSelf" statement in a compose method or the beforeLoad method means that the generated method will have return this as its last statement. The method returns an instance of the current page object.

{
    "elements": [
        {
            "name": "myElement",
            "selector": {
                "css": ".css"
            },
            "type": ["actionable", "clickable"]
        }
    ],
    "methods": [
        {
            "name": "focus",
            "compose": [
                {
                    "element": "myElement",
                    "apply": "focus"
                },
                {
                    "apply": "returnSelf"
                }
            ]
        },
        {
            "name": "hasFocus",
            "compose": [
                {
                    "element": "myElement",
                    "apply": "isFocused"
                }
            ]
        }
    ]
}

This method returns the same page object so it can be chained. For example:

assert pageObject.focus().hasFocus();
await (await pageObject.focus()).hasFocus();

The returnSelf statement must be the last statement inside the method and can't have any other JSON properties.