Tester_at_work
Tester_at_work

Reputation: 99

Selenium : Element is found when using Thread.sleep(), but not Implicit/Explicit waits

I read about how beneficial in using Implicit/Explicit waits, and decided to abandon Thread.sleep() in my code. However, the result is opposite. Using Thread.sleep(), I can actually locate the element, while Implicit/Explicit waits result in the ElementClickInterceptedException: element click intercepted: [duplicate] error for the same element.

The element I am trying to simulate a click on is an "I AGREE" button located in a dialog box. The following is the DOM for the button which I am trying to click.enter image description here

And the following is the code to simulate the click.

Using Implicit Wait

driver.manage().timeouts().implicitlyWait(120, TimeUnit.SECONDS);
driver.findElement(By.xpath("/html/body/div[1]/div/div/div[4]/a")).click();

Result : ElementClickInterceptedException: element click intercepted: [duplicate] error

Using Explicit Wait

WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement I_Agree; 
I_Agree = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[1]/div/div/div[4]/a")));
I_Agree.click();

Result : ElementClickInterceptedException: element click intercepted: [duplicate] error

Using Thread.sleep()

Thread.sleep(20000);
driver.findElement(By.xpath("/html/body/div[1]/div/div/div[4]/a")).click();

Result : Element is found and click can be executed.

Hope to have advice on any mistakes I may have done.

Upvotes: 0

Views: 1004

Answers (1)

Prophet
Prophet

Reputation: 33361

implicitlyWait waits for the element existence. So in case of

driver.findElement(By.xpath("/html/body/div[1]/div/div/div[4]/a")).click();

Selenium will try clicking that element immediately after the goal element appears.
In many cases the element can still be not clickable so utilizing the implicitlyWait may often cause exceptions.
Using ExpectedConditions.visibilityOfElementLocated will mostly work better, but still there are several situations this will not work.
In some cases the goal element can be out of the visible screen. In this case you will have to scroll to the goal element in order to bring it into the visible screen and then click it properly.
In some other cases during the page rendering Selenium will indicate element as visible and clickable while actually some other element may be overlapping on the goal element so clicking on it will cause the wrong element accepting the click. However if you give some more wait the page rendering process will complete and now you can click the goal element properly.
This is seems to be your case.
In most cases the overlapping element will be some kind of spinner element.
If so you should add the ExpectedConditions.invisibilityOfElementLocated condition to wait until the spinner / other overlapping element is disappeared.
To give more precise answer we need to see the specific site you are working on and the actual test flow you are doing.
You can see more about the ElementClickInterceptedException here, here, here and at more resources.
UPD
From your comments I see you did not actually understand. Both implicitly and explicitly waits are pooling the DOM to find element matching the passed condition. In both cases at the moment the condition is met Selenium will immediately stop waiting and polling, it will return an element (or Boolean true in some cases) and continue to the next command.
Implicitly wait is waiting for element presence. So in many cases the element itself is still not finally rendered and may still not be clickable or visible but it is already present, so in your case

driver.findElement(By.xpath("/html/body/div[1]/div/div/div[4]/a"))

may return the element that is still not ready to be clicked on.
This is why it is preferred to use explicit waits like ExpectedConditions.visibilityOfElementLocated since in this case Selenium will wait polling the DOM until it finds the desired element to be visible, this is much more mature state of the element on the page and it can normally be clicked on this point.
However, sometimes it can be some spinner etc. on that element. This is some external problem. So in this case we need to add ExpectedConditions.invisibilityOfElementLocated to wait until that spinner is disappeared.
There are more cases explicit wait will not be enough to be applied on the element itself. Sometimes you will have to scroll the desired element into the view, sometimes you will even need to use JavaScript click etc.

Upvotes: 1

Related Questions