2

I'm working with Selenium WebDriver for a few weeks, my Project is almost done, but there's something taking my patience away.

In my project, I divided everything in classes, so there's a class where I put my elements, declared as the following example (and in the same class, I put the functions implemented on my tests):

    [FindsBy(How = How.XPath, Using = "//div[@class='k-widget k-window' and not(contains(@style,'display: none;'))]//button[text()='Confirmar']")]
    private IWebElement GenericConfirmButton { get; set; }

One of my functions is:

    private void ClickConfirmButtonIfVisible()
    {
        if (GenericConfirmButton.IsVisible())
            GenericConfirmButton.SetClick();
    }

The function IsVisible() performs the code below (its in another class):

    public static bool IsVisible(this IWebElement element)
    {
        try
        {
            new WebDriverWait(GeneralProperties.Driver, TimeSpan.FromMilliseconds(0))
                .Until(ExpectedConditions.ElementToBeClickable(element));
            if (element.Enabled && element.Displayed)
            {
                return true;
            }
            else
            return false;
        }
        catch (WebDriverTimeoutException)
        {
            return false;
        }
    }

So, my problem is: this function IsVisible() is taking about 5 seconds to execute (if the element does not exist). My purpose with this is that, if I hit the button "Confirmar", it must check if the element exists and, if not, return false.

I've already tried to use ElementExists instead of ElementToBeClickable but I don't know how to do that (because I use an separeted class to declare the IWebElement element and this function needs a By declaration). I would like to use ElementExists (I believe it would run faster than now). Or, if you know any other way and could help me, I really would aprecciate it.

That's all. Thanks!

  • Have you tried replacing the XPath selector with a CSS selector instead? This article suggests that the CSS selector is more performant: http://elementalselenium.com/tips/32-xpath-vs-css – DaveRead Jul 13 '17 at 14:16
  • Hmm not yet, because the elements on the site I'm performing tests are 99% dynamic, so all the researches I did says to get to use XPath selector. I will try the CSS selector anyway. Thanks! – Evelyn Harumi Jul 13 '17 at 14:37
  • 1
    This is tough because if you have it return immediately... what if the element would have existed if you waited a half second? This is generally why I try to avoid if statements in my test logic. If you can write your logic to know if it should be visible or not(which you should know in your test case), that is what you should do. To me this is a sign of test logic that is trying to be too clever, which generally leads to frustration. – mrfreester Jul 13 '17 at 15:41
  • @mrfreester That's correct. I've followed this line in the beggining, but I had this crazy idea about letting Selenium take the action for me. So, as suggested by you, I will write my code to respect the steps (even because that's totally possible). Thanks very much! – Evelyn Harumi Jul 13 '17 at 16:23
  • 1
    Great! I hope that works for you @EvelynHarumi ..Side note: It sounds like you have an **Implicit Wait** set somewhere in your code for 5 seconds. I've opted to never set **Implicit Wait** and exclusively use **Explicit Waits** like you've done with your `WebDriverWait`. There is also [this issue](https://stackoverflow.com/questions/29474296/clarification-on-the-cause-of-mixing-implicit-and-explicit-waits-of-selenium-doc) that can come from mixing **explicit** and **implicit** waits. – mrfreester Jul 13 '17 at 16:26
  • @mrfreester OMG! That's it! I removed the implicit waits and now it's working fine! I've read about not mixing explicit with implicit but I don't know why I ended up doing it hahaha Thank you so much! – Evelyn Harumi Jul 13 '17 at 16:33
  • @EvelynHarumi since that worked for you I'll put that as an answer, although I imagine there could be some alternate solutions using some custom waiting strategies :) – mrfreester Jul 13 '17 at 16:38

1 Answers1

3

It is waiting 5 seconds because somewhere in your code you are setting ImplicitlyWait on the driver. You can remove that, but if you have other tests that rely on Implicit Waits those could be impacted.

Generally speaking, I would suggest only using explicit waits, partially do to an issue with unexpected wait times combining explicit and implicit waits.

This issue can also be avoided by making sure your test logic doesn't get too clever by avoiding if statements in your logic. In this case, basically your test case should know if the button is there or not, so the logic should reflect that.

mrfreester
  • 1,981
  • 2
  • 17
  • 36