Interfaces
UTAM provides the ability to declare a page object as an interface to abstract page object APIs (declared public methods) from the implementation.
One of the most common use cases is for mobile: a page or component in a mobile application can be WebView or pure native. Creating a page object for a WebView page is the same as creating a page for desktop. However, for a native page, you can create an interface that's shared between the iOS and Android platforms, and have implementations of the interface for both platforms.
Interface Declaration
Declare an interface in a separate JSON file.
An interface can contain these properties:
-
interface
Boolean. To distinguish an interface from a regular page object, set theinterface
property totrue
. -
methods
Array. Declare an interface's API as an array of objects in themethods
property. Each method object has the following properties:-
name
of the method. The name should be unique within themethods
array. -
If the method returns a value, set the
returnType
. If the method returns an array, set thereturnAll
property totrue
. See supported return types. -
Declare method parameters, if needed, in an
args
array of objects. Each object has the following properties:-
name
of the parameter -
type
of the parameter. See supported argument types.
-
-
-
root
Boolean (Optional). Setroot
totrue
when the page objects that implement the interface should be marked as root. A page object that implements the interface should also setroot
totrue
. A root page object can be loaded directly inside the browser. See root element. -
exposeRootElement
Boolean (Optional). If set totrue
, UTAM creates a public method that returns an instance of the element with the given type. The name of the getter isgetRoot
. -
type
(Optional). The type of the root element. See basic element types.
Here's an interface with four methods.
{
"interface": true,
"methods": [
{
"name": "openMenuSection"
},
{
"name": "clickTabBarItem",
"args": [
{
"name": "item",
"type": "string"
}
]
},
{
"name": "hasTabBarItem",
"returnType": "boolean",
"args": [
{
"name": "item",
"type": "string"
}
]
},
{
"name": "getTabBarItems",
"returnType": ["clickable"],
"returnAll": true
}
]
}
For every declared interface, the UTAM Java compiler generates a Java interface with method declarations:
public interface NavTabBar extends RootPageObject {
void openMenuSection();
void clickTabBarItem(String item);
Boolean hasTabBarItem(String item);
List<GetTabBarItemsElement> getTabBarItems();
interface GetTabBarItemsElement extends Clickable {}
}
Interface Implementation
A page object declares that it implements a declarative interface by using the implements
property.
{
"implements": "utam-lightning/pageObjects/global/navigationMenu",
"elements": [],
"methods": []
}
The page object must:
-
Implement all methods declared in the interface
-
Be in the same directory as the interface.
Let's look at an example of a page object that has different implementations for different mobile platforms.
To support multiple implementing JSON page objects for a single UTAM interface, use the profile
property. This property enables UTAM to choose the appropriate implementation depending on the test context. Profile is an array of objects. Set a platform
property in profile
to define the supported platforms. The supported values for platform are:
-
ios_phone
-
ios_tablet
-
android_phone
-
android_tablet
For example, addConnAndroidImpl.utam.json
defines a shared implementation for Android phone and tablet.
{
"implements":"utam-salesforceapp/pageObjects/authentication/addConn",
"profile":[
{
"platform": ["android_phone", "android_tablet"]
}
],
....
}
addConnAndroidPhoneImpl.utam.json
is for Android phone only.
{
"implements":"utam-salesforceapp/pageObjects/authentication/addConn",
"profile":[
{
"platform": "android_phone"
}
],
....
}
addConniOSImpl.utam.json
is for iOS phone and tablet.
{
"implements":"utam-salesforceapp/pageObjects/authentication/addConn",
"profile":[
{
"platform": ["ios_phone", "ios_tablet"]
}
],
...
}
addConniOSTabletImpl.utam.json
is for iPad only.
{
"implements":"utam-salesforceapp/pageObjects/authentication/addConn",
"profile":[
{
"platform": "ios_tablet"
}
],
...
}
In the compiler configuration file, you must configure all possible profile values for your module. Otherwise, the compiler throws an error, such as:
utam.core.framework.consumer.UtamError: profile 'platform' does not support value 'android_tablet'
Here's an example of a Java compiler configuration file in compiler.config.json
with a profiles
property. The configuration file name can be anything. It must just match the name passed as a runtime parameter to the compiler.
{
....
"profiles": [
{
"name": "platform",
"values": [
"ios_phone",
"ios_tablet",
"android_phone",
"android_tablet"
]
}
]
}
The compiler configuration file defines the supported platform
values.
Interface Implementation Resolution at Run Time
When an instance of the page object is created in a test at runtime, UtamLoader decides which implementating class should be instantiated. UtamLoader references a dependency injections config file, which is a JSON file that declares pairs of an interface and an implementation for each profile.
The dependency injections config is created during page object generation and looks like this:
{
"platform": {
"ios_tablet": [
{
"interface": "utam.pageObjects.auth.AddConn",
"implementation": "utam.pageObjects.auth.AddConnIOSTabletImpl"
}
],
"android_phone": [
{
"interface": "utam.pageObjects.auth.AddConn",
"implementation": "utam.pageObjects.auth.AddConnAndroidPhoneImpl"
}
]
}
}
This particular config tells UtamLoader that if the active profile is "ios_tablet", and UtamLoader.load(AddConn.class)
is invoked, use the AddConnIOSTabletImpl
implementation class.
For more details about setting active profiles and using depenency injections configs, please check out the Java guide and the JavaScript guide.
Default implementation
If an implementing page object doesn't have a profile
property, it's considered a default implementation and is picked up by default.
{
"default": {
"impl": [
{
"interface": "utam.pageObjects.auth.AddConn",
"implementation": "utam.pageObjects.auth.AddConnCrossPlatformImpl"
}
]
}
}