0

Check my code of a method that I use to wait for elements in selenium webdriver I call it in this way waitForElement(By.id(idOfElement));

public void waitForElement(By by) {
    for (int second = 0;; second++) {
        //System.out.println("seconds : " + second);
        if (second >= 15) {
            System.out.println("element not found");
            break;
        }
        try {
            if (driver.findElement(by).isDisplayed()) {
                driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); 
                //System.out.println("found element before click");
                driver.findElement(by).click();
                //System.out.println("found element after click");
                return;
            }
        } catch (Exception e) {
//              e.printStackTrace();
            //System.out.println("inside exception");
        }
    }
    //System.out.println("click on element after being not found");
    driver.findElement(by).click();
}

this method should find element and clicks on it

it worked fine and it was supposed to click the element then return from the method but now it fails because driver clicks the element which redirects to another page and after new page appears driver instead of returning from method it enters the catch exception and finally code fails because driver trying to find that element that was in previous page

any help to fix this method?

Update: There is a return after the first click If the element was found it should go out of the method the problem here is that sometimes executing code finds the element and clicks it and don't reach the code after the first click (which is return;) And I used this method to avoid exception of element not found because sometimes I use waits and elements exists but code fails because the element wasn't found or because of an exception says "time out receiving message from renderer"

Asmaa Elhussainy
  • 45
  • 1
  • 2
  • 8
  • It will always fail if the element doesn't exist. – Roman C Jan 12 '16 at 13:32
  • the problem here is it finds the element and clicks it then I get redirected to a new page and driver tries to find the element that was clicked in the previous page – Asmaa Elhussainy Jan 12 '16 at 13:40
  • and I want the method to fail if the element wasn't existing because I call this method in happy test scenario in another test scenarios that if the element wasn't found test should be failed – Asmaa Elhussainy Jan 12 '16 at 13:47
  • The second click is not in the catch, it is outside the for loop so is always going to be processed. – Ardesco Jan 13 '16 at 10:09
  • There is return; after first click if it was found then it should go to return to go out of the method – Asmaa Elhussainy Jan 13 '16 at 10:55
  • No the return will drop you out of the for loop, not the method. – Ardesco Jan 13 '16 at 12:01
  • No I'm lying, too much JavaScript over the past couple of months *DOH* It will return out of the method, but it may not break out of the loop if the catch gets invoked (or if you have a finally hidden away somewhere). You are better off using continue; to break out of the loop. You still don't need the final driver.findElement(by).click(); though, just remove it. – Ardesco Jan 13 '16 at 12:11
  • Ok I have removed it – Asmaa Elhussainy Jan 13 '16 at 12:23

2 Answers2

0

Your problem seems to come from the fact you don't switch the driver to the new page. So if by page you mean :

Community
  • 1
  • 1
e1che
  • 1,241
  • 1
  • 17
  • 34
0

That method is horrific. You have lots of code that isn't needed, a try|catch that isn't required and if no error is thrown you are going to try and click the element twice.

I would suggest rewriting it like this:

WebDriverWait wait = new WebDriverWait(driver, 15, 100);
WebElement myElement = wait.until(ExpectedConditions.elementToBeClickable(By.id("my-id")));
myElement.click();

This used the provided ExpectedConditions class that is in the selenium support package:

import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

The code above will create a web driver wait object that will wait up to 15 seconds for a condition to become true. The condition will be checked every 100ms. The Expected condition will return an element when it resolves to true (in this case we are waiting for the element to become clickable, since you want to click on it).

Once you have a wait object defined you can reuse that wait object again and again for different conditions so you don't need to reinitialise it every time. For example:

WebDriverWait wait = new WebDriverWait(driver, 15, 100);
WebElement myElement = wait.until(ExpectedConditions.elementToBeClickable(By.id("my-id")));
myElement.click();
WebElement anotherElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("another-element")));
//TODO do something with another element

You could also set wait names that describe the wait time:

WebDriverWait fifteenSecondWait = new WebDriverWait(driver, 15, 100);
WebDriverWait fiveSecondWait = new WebDriverWait(driver, 5, 100);

I would suggest never using implicitlyWait in your code, always use explicit waits instead. Mixing explicit and implicit waits can have unintended consequences, and if you forget to unset implicit waits you will make your tests very slow when you check that things are not there.

Ardesco
  • 7,281
  • 26
  • 49
  • I tried every thing explicit wait, implicit wait, or pageLoadTimeout each leads to an exception "timed out receiving message from renderer " I created this method because of that exception – Asmaa Elhussainy Jan 13 '16 at 11:12
  • The explicit wait code above will do what you are attempting to do properly. The "timed out receiving message from renderer" sounds like an old chromedriver bug (https://bugs.chromium.org/p/chromedriver/issues/detail?id=402). Check you are using the latest version of chromedriver and try removing all the implicit waits from your code. – Ardesco Jan 13 '16 at 12:05
  • I am using the latest version and I have tried the explicit wait you provided it didn't work because of that exception – Asmaa Elhussainy Jan 13 '16 at 12:28
  • Have you tried removing all implicit waits from your code and setting browser logging to off? – Ardesco Jan 13 '16 at 12:34
  • Yes I have removed the implicit waits, you mean history? by setting browser logging to off?? – Asmaa Elhussainy Jan 13 '16 at 12:54