简体   繁体   中英

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

I have created a Page Object in Java with Appium and Selenium 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 ;

This would mean regardless of whether I am using Android or iOS I would still just use the one variable called 'verifyTitle'.

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

findElement
(org.openqa.selenium.By)
in DefaultGenericMobileDriver cannot be applied
to
(io.appium.java_client.MobileElement)

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

Any help would be greatly appreciated.

Thanks

Matt

Yes, lots of mixing of object types in your original example. You're on the right track with the @OSFindBy annotations. Once you have those defined you already have the element so no need to find it again. The following would be all you'd need:

verifyTitle.getText()

See this blog post for more information on the Page Object Model (POM).

Summary:

import all the good stuff including PageFactory;

public class YourPage {
  private WebDriver driver;

  public YourPage(AppiumDriver<MobileElement> driver) {
    this.driver = driver;
    PageFactory.initElements(new AppiumFieldDecorator(driver), this);
  }

  @AndroidFindBy(id = "android_button")
  @iOSFindBy(id = "ios_button")
  private MobileElement that_button;

  public void pushTheButton() {
    that_button.click()
  }
}

Note: above code is untested / written off the top of my head / I don't write Java for a living. Prone to error, but should give you the idea.

This Working with Me, My Project Selenium, TestNG and Appium use PageFactory.initElements

public class Login extends Setup {

    @Test
    public void loginAlert() throws InterruptedException {
        

    Button button = new Button(driver);
            PageFactory.initElements(driver, button);
            Input input = new Input(driver);
            PageFactory.initElements(driver, input);
        
        
        Input input1 = new Input(driver);
        System.out.println("Test Alert Login");
        button.ById("navigation_more");
        button.ById("btnLogin");
        input.ById("et_email_or_phone_number", "dikakoko.com");
        input1.ById("tet_password", "dikakoko");
        
    }
}

Below this is the function I called above.

public class Input {
    AppiumDriver<MobileElement> driver;
    Root root = new Root();

    public Input(AppiumDriver<MobileElement> driver) {
        this.driver = driver;
    }

    public void ById(String selector, String textValue) {
        MobileElement element = driver.findElement(By.id(root.element() + ":id/" + selector));
        waitForVisible(driver, element);
        Actions actions = new Actions(driver);
        actions.moveToElement(element);
        actions.click();
        actions.sendKeys(textValue);
        actions.build().perform();
        System.out.println("Input: " + textValue);
    }
    
    private void waitForVisible(AppiumDriver<MobileElement> driver, MobileElement element) {
        try {
            Thread.sleep(5000);
            System.out.println("Waiting for element visibility");
            WebDriverWait wait = new WebDriverWait(driver, 20);
            wait.until(ExpectedConditions.visibilityOf(element));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

and This

public class Button {

    AppiumDriver<MobileElement> driver;
    Root root = new Root();

    public Button(AppiumDriver<MobileElement> driver) {
        this.driver = driver;
    }

    public void ById(String selector) {
        MobileElement element = driver.findElement(By.id(root.element() + ":id/" + selector));
        Actions actions = new Actions(driver);
        actions.moveToElement(element);
        actions.click();
        actions.build().perform();
        System.out.println("Button is Clicked!");
    }
}

I Use This

Button button = new Button(driver);
PageFactory.initElements(driver, button);
Input input = new Input(driver);
PageFactory.initElements(driver, input);

My References : From www.seleniumeasy.com

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM