0
votes

IOSElements contain the .setValue() method, which types much faster than sendKeys(). However, if I set my elements (using @FindBy annotations) to IOSElement rather than WebElement, PageFactory will return an error:

java.lang.IllegalArgumentException: Can not set io.appium.java_client.ios.IOSElement field screens.LoginScreen.signInEmail to org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$62bef779

Additionally, I cannot cast WebElements to IOSElements, as that will return an error from the JVM as well (cannot cast).

Is there a way to initialize IOSElements using the PageFactory design? My sample code is as follows:

public class LoginScreen {

private WebDriver driver;

@FindBy(className = "UIATextField")
public IOSElement signInEmail;

@FindBy(className = "UIASecureTextField")
public IOSElement signInPassword;

@FindBy(id = "Log in")
public IOSElement loginButton;

@FindBy(id = "Forgot your password?")
public IOSElement forgotPasswordButton;

public LoginScreen(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}

public SomeOtherObject login(String email, String password) {
    signInEmail.setValue(email);
    signInPassword.setValue(password);
    loginButton.click();
    return new SomeOtherObject(driver);
}

}

2

2 Answers

0
votes

You could try using the @iOSFindBy annotation for locators of WebElement type. You can find some example on the Appium github page.

Another thing that I'm thinking of for you example, is to try casting to MobileElement instead of WebElement.

EDIT:

I've tried this now and I'm able to use @iOSFindByannotation along with IOSElement locators type. I've set up a simple class, using in my Maven pom.xml the following:

<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>2.1.0</version>
</dependency>

Then, the test class, as follows:

import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.pagefactory.iOSFindBy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;

public class ATestClass {
    private WebDriver driver;

    @iOSFindBy(className = "classname")
    public IOSElement testing;

    public ATestClass(WebDriver driver)
    {
        this.driver = driver;
        PageFactory.initElements(new AppiumFieldDecorator(driver), this);
    }

    public void ATestMethod()
    {
        testing.click();
    }
}

Note: Same thing goes when MobileElement locators type, so in case you're still seeing any errors, check whatever dependencies you're having as most likely those are the ones that are causing your errors.

0
votes

Looks like my problem was that I was using a remote instance of WebDriver, like so:

this.driver = new WebDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

However, I can get an instance of IOSDriver with an identical set up:

this.driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

This accepts IOSElements when passed to PageFactory.initElements(); - No errors.