How do I create Page Object Model that works for Android AND iOS

I have created a Page Object in Java that is currently working for an Android app as shown below:

public class MattVerifyPage extends PageObject{

private AppiumDriver driver = FrameworkInitialize.driver;

By verifyTitle = By.xpath("/hierarchy/android.widget.TextView");

public void verifyTitle(String expectedTitle){

    String actualTitle = driver.findElement(verifyTitle).getText();

However, I need it to work an the Android app and the iOS app, the xpath selector is different for both apps. I think I need to do something like this:

@AndroidFindBy(xpath = “androidxpath”)
@iOSFindBy(xpath = “iOSxpath”)
public MobileElement verifyTitle ;

However, when I do this, the driver.findElement line (String actualTitle = driver.findElement(verifyTitle).getText() shows the following error:

in DefaultGenericMobileDriver cannot be applied

I think I am comparing AppiumElements with SeleniumElements but I’m not sure how to resolve it.

Any help would be greatly appreciated.



@Matt882 when you use Appium annotation they already do all job to find element. All left is use it.

@AndroidFindBy(xpath = “androidxpath”)
@iOSFindBy(xpath = “iOSxpath”)
public MobileElement verifyTitle ;

String actualTitle = verifyTitle.getText();

first example from google search to see all PageObject - >

or some example at java-client Appium code:

Thanks Aleksei. I have changed my page object to look like this:

public class MattVerifyPage extends PageObject{
private AppiumDriver driver;

public MattVerifyPage(AppiumDriver driver) {
    this.driver = driver;
    PageFactory.initElements(new AppiumFieldDecorator(driver), this);

@AndroidFindBy(xpath = "Androidxpath")
@iOSFindBy(xpath = "iOSxpath")
public MobileElement verifyTitle ;

public void verifyTitle(String expectedTitle){

    String actualTitle =verifyTitle.getText();


In my test step file the page is instantiated using this code:

MattVerifyPage VerifyPage = new MattVerifyPage(driver);

However, when I run the test I get the error shown below. I am also using Serenity so if there is no obvious problem with my code above it must be a Serenity issue:

java.lang.IllegalArgumentException: Can not set io.appium.java_client.MobileElement field to com.sun.proxy.$Proxy19
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(
at java.lang.reflect.Field.set(
at net.thucydides.core.annotations.locators.SmartElementProxyCreator.lambda$new$3(
at net.thucydides.core.annotations.locators.SmartElementProxyCreator.proxyElements(
at net.thucydides.core.webdriver.DefaultPageObjectInitialiser.apply(
at net.serenitybdd.core.pages.PageObject.setDriver(
at net.serenitybdd.core.pages.PageObject.setDriver(
at net.thucydides.core.steps.PageObjectDependencyInjector.updatePageObject(
at net.thucydides.core.steps.PageObjectDependencyInjector.instantiatePageObjectIfNotAssigned(
at net.thucydides.core.steps.PageObjectDependencyInjector.injectDependenciesInto(
at net.serenitybdd.core.Serenity.injectDependenciesInto(
at net.serenitybdd.core.Serenity.initializeWithNoStepListener(
at cucumber.runtime.SerenityObjectFactory.newInstance(
at cucumber.runtime.SerenityObjectFactory.cacheNewInstance(
at cucumber.runtime.SerenityObjectFactory.getInstance(
at cucumber.runtime.StepDefinitionMatch.runStep(
at cucumber.api.TestStep.executeStep(
at cucumber.runner.Runner.runPickle(
at cucumber.runtime.Runtime.runFeature(
at cucumber.api.cli.Main.main(
at ✽.I see the title is “MattVerify”(C:/dev/GBG_Automation/src/test/resources/features/01_GBG Verify/01_01_SamsungS9_Android_OS8.feature:6)

It is problem in your serenity/cucumber. Your example works correctly in pure Java.

One suggestion is move constructor to basePage.

Hi @Aleksei

I would like to ask if PageObject model in Android can work in Appium Webview or hybrid app? Currently using CSS selector when using a selector. Does it also works or can be applied to Appium Webview? If it does, do I also use this @AndroidFindBy annotations in webview/hybrid app? What is the equivalent of @AndroidFindBy annotations when using css selector page object model? Thank you @Aleksei


@p0well493 Hi.
Appium decorator work everywhere: android, ios, hybid app webView or even pure web (no mobile tests at all).

NB!!! Before use it you need switch to WebView with hybridApp!

to use CSS:

import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.time.Duration;

public class MyPagePage {

    private static int DEFAULT_WAIT_TIME = 20;
    private WebDriver driver;

    @FindBy(css = "button[class^='CountrySelector-']")
    private WebElement countrySelectButton;

    public MyPagePage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(new AppiumFieldDecorator(driver, Duration.ofSeconds(DEFAULT_WAIT_TIME)), this);

    public MyPagePage clickCountrySelectButton() {;
        return this;
1 Like