Appium can not find any element - java

I'm have on automation project(java, appium, android)
In this project, the elements are stored in the database.
I get elements from database and try to find it:
1) Locator search using findElements:
if (!elementPath.equals("")){
List elementFound = driverCommands.findElements(By.xpath(elementPath));
if (elementFound.size() == 0){
return null;
}
return (AndroidElement) elementFound.get(0);
}
2) Locator search using findElement:
String elementPath = entity.getElementPath();
driverCommands.findElement(By.xpath(elementPath));
In both cases I get nothing. But if I add sleep() before usage findElemen(s) with a wait of at least 4 seconds, as shown in the example below, then the element will be found.
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!elementPath.equals("")){
List elementFound = driverCommands.findElements(By.xpath((elementPath));
if (elementFound.size() == 0){
return null;
}
return (AndroidElement) elementFound.get(0);
How can I solve this problem?

Related

POP function for Present&enabled checking in selenium (Java)

I working in selenium and now for checking visibility of element i use following wait until:
#FindBy (css=".delete-basket-modal-btn") WebElement deleteItemFromBasketCancelButton;
public void clickDeleteItemFromBasketCancelButton() throws InterruptedException {
wait.until(ExpectedConditions.elementToBeClickable(deleteItemFromBasketCancelButton));
deleteItemFromBasketCancelButton.click();
}
that's not good idea, this function is not checking for presence of element, so sometimes i get 'stale element reference element is not attached to the page document'
Now i trying to create universal function which will be inherited by all of mine page object class. In this function i need checking (5 sec) for presence, enability, clickability and visibilty of WebElement passed in argument.
For this moment i have new function below, but i dont know that is good approach for my problem
public void verifyElement(WebElement element) throws InterruptedException {
boolean isPresent = false;
for (int i = 0; i < 5; i++) {
try {
if (element != null) {
isPresent = true; // metoda do czekania na element
break;
}
} catch (Exception e) {
// System.out.println(e.getLocalizedMessage());
Thread.sleep(1000);
}
}
Assert.assertTrue(isPresent, "\"" + element + "\" is not present.");
boolean isEnabled = false;
for (int i = 0; i < 5; i++) {
try {
if (element.isEnabled()==true) {
isEnabled = true;
break;
}
}catch (Exception e) {
Thread.sleep(1000);
}
}
Assert.assertTrue(isEnabled, "\"" + element + "\" is not enabled.");
}
Do you have any suggestion or similar problem for this issue?
StaleElementReferenceException doesn't (necessarily) mean the element is not present, it means the DOM had changed/refreshed since the element was located, so the element reference which the driver holds is no longer valid. This is a disadvantage of using PageFactory model.
The solution is to locate the element just before the click operation, however this will break the consistency of the page object. Instead of using FindBy send By to the method and locate the element there
public void clickDeleteItemFromBasketCancelButton(By by) throws InterruptedException {
WebElement deleteItemFromBasketCancelButton = wait.until(ExpectedConditions.elementToBeClickable(by));
deleteItemFromBasketCancelButton.click();
}
The first written code is enough. To overcome stale element exception write code in try/catch block and use ExpectedConditions.stalenessOf(deleteItemFromBasketCancelButton) for presence, enability, clickability and visibilty (for any type of operation).
Try below one, hope it's help for you.
try{
wait.until(ExpectedConditions.elementToBeClickable(deleteItemFromBasketCancelButton));
deleteItemFromBasketCancelButton.click();
}
catch(Exception e){
wait.until(ExpectedConditions.refreshed(ExpectedConditions.stalenessOf(deleteItemFromBasketCancelButton)))
deleteItemFromBasketCancelButton.click();
}

Selenium Webdriver Element not exists condition fails

I have a If Else block within a while block. If element is present, click it to remove it and put it back to parent list. Else if element is not in the list then select from parent list and put it back.
The first time it works. It sees that the element is present, clicks it to removes it. On the second pass it fails when checking for the element
I tried with FindElement.IsDisplayed and !=null.
I get this exception :
org.openqa.selenium.NoSuchElementException: Unable to find element with css selector == select[id="idSelSelectedLanes"]>option[value="9012"] (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 30.16 seconds
What am I missing?
This is my first post here so apologize for any formatting issues.
thanks
count ++;
if(count % 2 == 0){
if(BROWSER.equals("IE")) {
// check if 9012 is present
if(driver.findElement(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]"))!=null){
try {
// since its present, click to remove
driver.findElement(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]")).click();;
Thread.sleep(1000);
} catch(NoSuchElementException e) {
System.out.println("Couldn't remove 9012");
}
} else {
try {
//Not present, so select from Available Lanes
driver.findElement(By.cssSelector("select[id=\"idSelAvailableLanes\"]>option[value=\"9012\"]")).isDisplayed();
} catch (NoSuchElementException e) {
System.out.println("Couldn't add 9012");
}
}
}
}
You need to put driver.findElement(...) in a try-catch block
count ++;
WebElement e;
if(count % 2 == 0) {
if(BROWSER.equals("IE")) {
// check if 9012 is present
try {
e = driver.findElement(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]"));
Thread.sleep(1000);
e.click()
} catch (NoSuchElementException e) {
System.out.println("Couldn't remove 9012");
// the else part goes here
}
}
}
Another approach is to use findElements instead of findElement to avoid the try-catch, and use .get(0) to get the element you want.
Another solution, you should check elementExist first using findElements, if it exists -> perform other actions
count ++;
WebElement e;
String e9012Css = "select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]";
if(count % 2 == 0) {
if(BROWSER.equals("IE")) {
// check if 9012 is present
e9012Existed = driver.findElements(By.cssSelector(e9012Css)).size() > 0;
if(e9012Existed) {
driver.findElement(By.cssSelector(e9012Css)).Click();
}
}
else {
System.out.println("Couldn't remove 9012");
}
}
try to use isElementPresent
if(isElementPresent(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]"))){
// since its present, click to remove
} else {
//Not present, so select from Available Lanes
}

Selenium Webdriver: best practice to handle a NoSuchElementException

After much searching and reading, I'm still unclear as to the best way to handle a failed assertion using Webdriver. I would have thought this was a common and core piece of functionality. All I want to do is:
look for an element
if present - tell me
if not present - tell me
I want to present the results for a non technical audience, so having it throw 'NoSuchElementExceptions' with a full stack trace is not helpful. I simply want a nice message.
My test:
#Test
public void isMyElementPresent(){
// WebElement myElement driver.findElement(By.cssSelector("#myElement"));
if(driver.findElement(By.cssSelector("#myElement"))!=null){
System.out.println("My element was found on the page");
}else{
System.out.println("My Element was not found on the page");
}
}
I still get a NoSuchElementException thrown when I force a fail. Do I need a try/catch as well? Can I incorporate Junit assertions and/or Hamcrest to generate a more meaningful message without the need for a System.out.println?
I have encountered similar situations. According to the Javadoc for the findElement and findElements APIs, it appears that the findElement behavior is by design. You should use findElements to check for non-present elements.
Since in your case, there's a chance that the WebElement is not present, you should use findElements instead.
I'd use this as follows.
List<WebElement> elems = driver.findElements(By.cssSelector("#myElement"));
if (elems.size == 0) {
System.out.println("My element was not found on the page");
} else
System.out.println("My element was found on the page");
}
you can do something to check if element exists
public boolean isElementExists(By by) {
boolean isExists = true;
try {
driver.findElement(by);
} catch (NoSuchElementException e) {
isExists = false;
}
return isExists;
}
What about using an xPath inside of a try-catch, passing the elementype, attribute and text as follows?
try {
driver.FindElement(
By.XPath(string.Format("//{0}[contains(#{1}, '{2}')]",
strElemType, strAttribute, strText)));
return true;
}
catch (Exception) {
return false;
}
Even running it in a try block, it behaves as if unhandled,
neither of the catch blocks runs when the selenium exception occurs.
try {
wait.Until(webDriver => webDriver.PageSource.Contains(waitforTitle));
wait.Until(webDriver => webDriver.FindElement(By.Id(waitforControlName)).Displayed);
}
catch (OpenQA.Selenium.NoSuchElementException nse) {
nse = nse = null;
success = false;
}
catch (Exception ex) {
ex = ex = null;
success = false;
}

Selenium - Java Wait for page to load fails in test scripts

I create test cases in Eclipse IDE using JAVA with some Selenium scripts.
My Problem is that sometimes, Continuous Run of Test Cases produce error/failed test in the selenium.waitForPageToLoad("30000") method. I made a solution that the method will loop until a specific condition is met so I came to this code. BUT THIS DOESN'T WORK.
This what happens: Run Junit Test > #Test1,2,3..n > page does not load # Test n > execute next line code > failed test in #Test n > because Page does not load so the next scripts cannot be done (missing required elements in the page because it doesn't load).
This what SUPPOSED to happen:Run Junit Test > #Test1,2,3..n > page does not load # Test n > wait for page to load until Specific condition is met (ex. Element X is already present in the page)> execute next line code > passed test in #Test n
I need a Solution that wait the Page to load until the element required for the next lines of scripts is present.
THIS CODE DOESN'T WORK. I badly need your help. Thanks
//Wait for Page to Load until Expected Element is not Present
public void waitForPageToLoadElement(final String isElementPresent){
boolean elementBoolean;
do{
selenium.waitForPageToLoad("30000");
elementBoolean = selenium.isElementPresent(isElementPresent);
if (elementBoolean==false){
try{Thread.sleep(3000);}
catch (Exception e) {
//catch
}}
}
while(elementBoolean==false);
}
//Wait for Page to Load until Expected Text is not Present
public void waitForPageToLoadText(String isTextPresent){
boolean elementBoolean;
do{
selenium.waitForPageToLoad("30000");
elementBoolean = selenium.isTextPresent(isTextPresent);
if (elementBoolean==false){
try{Thread.sleep(3000);}
catch (Exception e) {
//catch
}}
}
while(elementBoolean==false);
}
//Opens url until Expected Element is not Present
public void openUrl(String url){
boolean userNameBoolean, passwordBoolean;
do {
selenium.open(url);
userNameBoolean = selenium.isElementPresent("id=loginForm:username");
passwordBoolean = selenium.isElementPresent("id=loginForm:password");
if (userNameBoolean==false && passwordBoolean==false){
try{Thread.sleep(3000);}
catch (Exception e) {
//catch
}}
}while (userNameBoolean==false && passwordBoolean==false);
}
This type of logic might be helpful for you
public static void waitforElement(Selenium selenium,String element)
{
try
{
int second;
for (second = 0; ; second++)
{
if (selenium.isElementPresent(element))
{
break;
}
if (second >= 20)
{
break;
}
Thread.sleep(1000);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
Before doing any operation with any element just call this method for that element so that it will wait for that element until timeout reached (i.e., 20sec) if that element is not found.
Example
waitforElement(selenium,"id=loginForm:username");
selenium.type("id=loginForm:username","username");
waitforElement(selenium,"id=loginForm:password");
selenium.type("id=loginForm:password","password");
selenium.click("submit");

implicitwait and explicitwait not solving the issue in Selenium Webdriver with Java

I've been testing an application involving multiple ajax calls, so I required wait condition so that elements are present/visible once the ajax call is made. I used both methods implicitwait and explicitwait but none of them seem to be working for me as one or the other exceptions are generated as follows:
1.Unable to locate element
2.Element is disabled and so may not be used for actions
Implicit wait used as follows:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement we = driver.findElement(By.name("q"));
PROBLEM:
When I test this code, after browser opens, it throws exception in 2 seconds.
Result:Exception generated
Explicit Wait
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3);
WebElement element = wait.until(presenceOfElementLocated(By.name("q"));
PROBLEM:
When I test this code, after browser opens, it throws exception in 2 seconds
Result:Exception generated.
Also used visibilityOfElementLocated but it does not work for me.
Has anybody faced this issue or anybody has a solution for this??
I can't say that I have faced that issue before but I also wrote my own custom DOM polling class. Here's what I do.
private int Timer = 180;
private bool CheckForElement(WebDriver driver,string byType,string selector)
{
bool elementFound = false;
for (int i = Timer - 1; i > 0; i--)
{
if (!itemFound)
{
Thread.Sleep(1000); //sets the loop to check every second this can be done at a much faster or slower rate depending on your preferences
if (byType.ToLower() == "id")
{
try{
WebDriver element = driver.FindElement(By.Id(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
else if (byType.ToLower() == "tagname")
{
try{
WebDriver element = driver.FindElement(By.TagName(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
else if (byType.ToLower() == "cssselector")
{
try{
WebDriver element = driver.FindElement(By.cssSelector(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
else if (byType.ToLower() == "classname")
{
try{
WebDriver element = driver.FindElement(By.ClassName(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
}
else
{
i = 0; //stops the loop when the element is found
}
}
return elementFound ;
}

Categories

Resources