Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium Wait doesn't wait for Element to be Clickable

Tags:

c#

wait

selenium

I have a page that is dynamically loaded and contains a button. I am trying to wait for the button to be available to be clicked with selenium using the C# bindings. I have the following code:

WebDriverWait wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(30));
        wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("addInspectionButton")));

        var button = Driver.Instance.FindElement(By.Id("addInspectionButton"));
        button.Click();

this doesn't work though. The click event is never fired. The selenium script doesn't throw an exception alerting that the element with an ID of "addInspectionButton" doesn't exist. It just isn't able to click it. If i add a Thread.Sleep(3000) Between the wait statement and the line where I get a handle on the button element it works.

Am i not using the ExpectedConditions.ElementToBeClickable correctly here?

like image 770
J. Nick Baughan Avatar asked Oct 30 '22 23:10

J. Nick Baughan


1 Answers

It turns out that an event was being bound to the button after the button was dynamically added to the page. So the button WAS being clicked but nothing was happening. The sleep thread being placed in the code was just giving the client side event time to be bound.

My solution was to click the button, check for the expected result, and then repeat if the expected result wasn't in the DOM yet.

Since the expected result was for a form to open I polled the DOM like this:

button.Click();//click button to make form open
        var forms = Driver.Instance.FindElements(By.Id("inspectionDetailsForm"));//query the DOM for the form
        var times = 0;//keep tabs on how many times button has been clicked
        while(forms.Count < 1 && times < 100)//if the form hasn't loaded yet reclick the button and check for the form in the DOM, only try 100 times
        {

            button.Click();//reclick the button
            forms = Driver.Instance.FindElements(By.Id("inspectionDetailsForm"));//requery the DOM for the form
            times++;// keep track of times clicked
        }
like image 186
J. Nick Baughan Avatar answered Nov 15 '22 04:11

J. Nick Baughan