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.
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());
}
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.
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.
(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.
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.
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?
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:
@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 ?