PageFactory PageObjectModel issues

@Priyank_Shah @SergeyTichomirov @amedvedev @Aleksei @wreed @wreed @jlipps @bhaskar

I am also using the Page Factory model where I have a package under which all my page object classes are. And then another package that contains my test case execute classes along with my AbstractPage class.
My Abstract page class contains:
protected IOSDriver getDriver()
{
if (driver == null)
{
URL serveraddress = null;
// ----ALL MY CAPABILITIES GO HERE-----
try
{
serveraddress = new URL(“http://127.0.0.1:4723/wd/hub”);
//serveraddress = new URL(“http://127.0.0.1:4444/wd/hub”);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
driver = new IOSDriver(serveraddress, capabilities);
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}
return driver;
}

In every Page Object class I am doing this:
public settingsPO(IOSDriver driver)
{
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}

And then in every Test case class I am using this:
IOSDriver driver = getDriver();

  • So my issue is that whenever I am running the test locally everything is fine and dandy…however when I run the test on a cloud-based CI tool it is failing always at the points wherever I am identifying objects using the Page object methodology. If you could please advise a way around this that would be greatly appreciated! Thanks.

we do it in another way.

Base Page:

public abstract class Page {
    protected WebDriver driver;

    public Page(WebDriver driver) {
        this.driver = driver;
       PageFactory.initElements(new AppiumFieldDecorator(driver, 30, TimeUnit.SECONDS), this);
    }
}

Page example:

public class CallPage extends Page {

    //Action bar
    @AndroidFindBy(id = "homeButton")
    private List<AndroidElement> homeButton;
    @AndroidFindBy(id = "backButton")
    private List<AndroidElement> backButton;

    // and other elements here .....

    public CallPage(WebDriver driver) {
        super(driver);
    }

    public boolean isCallPageLoaded() {
        return !homeButton.isEmpty() && !backButton.isEmpty();
    }
}

Base Test:

public class BaseTest {
    protected static AppiumDriver driver = null;
    // testNG staff here...
}

Test:

public class test_Call extends BaseTest {
    private CallPage callPage;

    callPage = new CallPage(driver);
    assertTrue("Call page is NOT loaded", callPage.isCallPageLoaded());
}
4 Likes

Also you are able to use io.appium.java_client.pagefactory.WithTimeout annotation when the waiting for a certain element/list of elements differs from the general value.

It is an addition to @Aleksei’s sample.
Also java_client has WIKI now: Home · appium/java-client Wiki · GitHub
It is not finished yet but there is a lot of useful information.
About page objects: java-client/docs/Page-objects.md at master · appium/java-client · GitHub

1 Like

Everyone…I am still having that problem I am not sure why.
I have set Implicit wait and also Pagefactory driver for 10 seconds…still it cannot locate element on Travis-CI.
It runs just fine on my local machine though. Also I notice that only the Login flow is successfully working on Travis CI and everything else is not locatable. Critical information is also that the Build language is Objective-C and my scripts are written in JAVA. Please advise.
Here is error:
org.openqa.selenium.NoSuchElementException: Can’t locate an element by this strategy: Locator map:

  - native content: "By.AccessibilityId: Compose Button" 

  - html content: "by id or name "newMsg

I am not sure what html content means…its just some random value I gave to the IOSElement.
Thanks.

I am starting to think maybe it is some environment variable issue that is not being set on the CI machine causing it to not pick up the Page factory elements. Some variable that must have been set on my local machine…because it works just fine on my local machine.

Thanks.

@Priyank_Shah @Aleksei @SergeyTichomirov

(First plz read my last 2 posts here)
So I am also getting the same issue on Travis even if I try to directly go to the elements without using the Page Factory (like just doing a [ wait.until(ExpectedConditions.elementToBeClickable(MobileBy.AccessibilityId(“Contacts”))).click(); ]]

I guess it is nothing to do with PageFactory but just everything in general. Only the itial login flow (which includes 4-5 screens) works.

@afwang @Igor_Boyarinov @amitjaincoer191 @Ankit_Jain @Neto18 @jablaze

Are you able to observe your devices while the job is running? If you can, you should see what’s happening with the devices when your tests fail.

If you can’t see what’s happening, add in some statements to take some screenshots and the XML page source. You might be able to piece something together from that information. Find a way to get a copy of all your Appium logs as well.

Nope its cloud based CI tool. All it says is that it cannot locate element. Maybe the VM has xcode or Instruments issues?

Are you at least able to take screenshots or retrieve XML page sources?

ok…I think I know what you are trying to say. If I do a getPageSource I can then tell what text is appearing when the tests are failing…and then I can tell what screen the app is on. Lets say if the pageSource tells me that the text is not what I expect it to be…it maybe the previous page still because the new one failed to load on the CI Virtual machine. What then?

Thanks.

Yes. Both the screenshot and XML page source should help you see what’s happening remotely. The screenshot is useful because sometimes pictures tell much more than words can. The XML layout, combined with the screenshot, should give you a complete view of the state of your app’s UI at the moment of failure.

Hi @Styris, I am having this same issue when i run the test on cloud device. The test runs absolutely fine with the real devices but giving this error on running with testdroid cloud. Can you suggest the solution?

org.openqa.selenium.NoSuchElementException: Can’t locate an element by this strategy: Locator map:

  • native content: “By.id: com.dispatchr.mobile.workr:id/text_email”
  • html content: “by id or name “email””

@Aleksei can you please clarify what is the type of driver being passed in test_call ?

Is it belongs to WebDriver or AppiumDriver ?

Thanks,
Vikram

@VikramVI added into original post

@Aleksei Thanks a ton for your time.

But I found an issue related to this

https://github.com/appium/java-client/issues/572 ( 1.6.3 + Java client latest version )

can you please clarify if this is working on your end ?

i do not have problem with it for elements that specified @FindBy or @AndroidFindBy and so on.

@SergeyTichomirov please clarify if element level timeout overrides default timeout specified in PageFactory.initElements or it is additional time gets added on top of default timeout ?

This is time that overrides default timeout values (which were defined in PageFactory.initElements)

in that abstract class, there i found a ‘PageFactory’ that i never used