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:
- Set explicitly in the interface method declaration or inside a compose statement
{
"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.
-
Otherwise, the method is assumed to return void.
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).
returnType | returned value |
---|---|
custom type | string with at least one '/', for example utam/pageObject/Input |
basic type | supported only for abstract methods |
boolean | boolean primitive (Boolean object in Java) |
frame | an element of frame type |
number | number primitive (Integer object in Java) |
pageObject | page object instance of unspecified type (not root page object) |
rootPageObject | root page object instance of unspecified type |
string | string primitive (String object in Java) |
void | Default 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.
- If a statement uses a matcher, the return type is always boolean
{
"element": "document",
"apply": "getUrl",
"matcher": {
"type": "stringContains",
"args": [{ "value": "homePage" }]
}
}
- A statement that applies a basic action to a basic element from the same JSON (not a chain)
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"
}
- A statement that invokes an element getter for an element from the same JSON (not a chain)
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 explicitreturnType
.
{
"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.
- set return type to return element marked with
"type" : ["actionable","clickable"]
{
"name": "getButton",
"returnType": ["actionable", "clickable"]
}
- set return type to return list of elements marked with
"type" : "editable"
{
"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:
- Java
assert pageObject.focus().hasFocus();
- JavaScript
await (await pageObject.focus()).hasFocus();
The returnSelf
statement must be the last statement inside the method and can't have any other JSON properties.