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.

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 the interface property to true.

  • methods Array. Declare an interface's API as an array of objects in the methods property. Each method object has the following properties:

    • name of the method. The name should be unique within the methods array.

    • If the method returns a value, set the returnType. If the method returns an array, set the returnAll property to true. See supported return types.

    • Declare method parameters, if needed, in an args array of objects. Each object has the following properties:

  • root Boolean (Optional). Set root to true when the page objects that implement the interface should be marked as root. A page object that implements the interface should also set root to true. A root page object can be loaded directly inside the browser. See root element.

  • exposeRootElement Boolean (Optional). If set to true, UTAM creates a public method that returns an instance of the element with the given type. The name of the getter is getRoot.

  • type (Optional). The type of the root element. See basic element types.

Here's an interface with four methods.

For every declared interface, the UTAM Java compiler generates a Java interface with method declarations:

A page object declares that it implements a declarative interface by using the implements property.

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.

addConnAndroidPhoneImpl.utam.json is for Android phone only.

addConniOSImpl.utam.json is for iOS phone and tablet.

addConniOSTabletImpl.utam.json is for iPad only.

In the compiler configuration file, you must configure all possible profile values for your module. Otherwise, the compiler throws an error, such as:

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.

The compiler configuration file defines the supported platform values.

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:

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.

If an implementing page object doesn't have a profile property, it's considered a default implementation and is picked up by default.