Selenium WaitDriver does not wait for an item to be clickable

When I click on a button, it displays me a form with other buttons, and I want to click on one of them. Here is a video with this (very brief), please see http://screencast.com/t/zyliSemW1s1

So I click the Buy Tickets button just like that:

button.Click(); 

And then I wait for the next button to be available.

I am using the following code:

 WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(15)); IWebElement element = wait.Until(ExpectedConditions.ElementToBeClickable(myButton)); 

After that, I click the button that I was waiting for:

 element.Click(); 

And I get the error: The item cannot be pressed at this point.

As I know, the ExpectedConditions.ElementToBeClickable () method expects 2 conditions: the element is visible and the element is enabled.

When I use Thread.Sleep (3000), before clicking on the second button, the code works and the button is available.

I saw a similar problem, and the solution was to wait for the handlers of this button: Selenium Wait does not wait for Element to be clicked

But what if I don’t know what can handle this? I think it handles jQuery, and I use the following code to wait until it stops executing:

 var ajaxIsComplete = (bool) ((IJavaScriptExecutor)Driver).ExecuteScript("return jQuery.active == 0"); 

If it returns false, I wait and check again.

But that still doesn't work.

So now my thread is as follows:

  • I click the Buy Tickets button
  • I'm waiting for jQuery to stop executing
  • I'm waiting for the item to be accessible using the ExpectedConditions.ElementToBeClickable () method
  • I click on an element and it returns me an error that cannot be pressed.

Please guys tell me what is wrong in my flow and how to properly manage it.

Update : I am adding button HTML code:

I click on this:

 <button class="btn btn-warning play-now" name="button" type="submit">Buy Tickets</button> 

And wait for it:

 <img alt="Credit Card" class="merchant" src="https://numgames-production.s3.amazonaws.com/uploads/merchant/image/21/CC_Offline.png?AWSAccessKeyId=AKIAJ2Q64HPERGHAJJUA&amp;Expires=1470984765&amp;Signature=Qj%2BFSQ3ElctkY6KTMfzp%2FedPjPo%3D"> 
+5
source share
2 answers

Instead of using ElementToBeClickable, try using presenceOfElementLocated. I think your expected element is missing in the DOM, so try using presenceOfElementLocated first. When it is present in the DOM, use ElementToBeClickable.

0
source

Denis

As mentioned in the comments on the OP, here are a few small extension methods that may help your quest:

 public static void WaitForAjax(this IWebDriver driver, int timeoutSecs = 10, bool throwException = false) { for (var i = 0; i < (timeoutSecs*10); i++) { var javaScriptExecutor = driver as IJavaScriptExecutor; var ajaxIsComplete = javaScriptExecutor != null && (bool)javaScriptExecutor.ExecuteScript("return jQuery.active == 0"); if (ajaxIsComplete) return; Thread.Sleep(100); } if (throwException) { throw new Exception("WebDriver timed out waiting for AJAX call to complete"); } } public static bool ElementExists(this IWebDriver driver, By condition) { return ElementExists(driver, condition, new TimeSpan()); } public static bool ElementExists(this IWebDriver driver, By condition, TimeSpan timeSpan) { bool isElementPresent = false; if (timeSpan == default(TimeSpan)) { timeSpan = TimeSpan.FromMilliseconds(15000); } var driverWait = new WebDriverWait(driver, (TimeSpan)timeSpan); driverWait.IgnoreExceptionTypes(typeof(WebDriverTimeoutException)); isElementPresent = driverWait.Until(x => x.FindElements(condition).Any()); return isElementPresent; } public static IWebElement FindElementAfterWait(this IWebDriver driver, By condition, int fromSeconds = 90) { bool isElementPresent = false; IWebElement singleElement = null; var driverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(fromSeconds)); driverWait.IgnoreExceptionTypes(typeof(WebDriverTimeoutException)); try { isElementPresent = driverWait.Until(ExpectedConditions.ElementExists(condition)) != null; if (isElementPresent) { singleElement = driver.FindElement(condition); } } catch { // log any errors } return singleElement; } 

usages:

 bool elementExists = _driver.ElementExists(By.Id("submitButton")); var submitButton = _driver.FindElementAfterWait(By.Id("submitButton")); submitButton.Click(); _driver.WaitForAjax(); // then do other code stuff... 

I hope the combo of them can save you a fix.

0
source

All Articles