Take the 2-minute tour ×
Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. It's 100% free, no registration required.

The goal of my test is to assert that a popup does not appear after certain actions. Previously to test if the popup exist, i have used exception handling.

try:

    self.driver.find_element_by_id("fancybox-close").click()

except Exception ('ElementNotVisibleException'):

    print "No popup"

This works fine for the test : to assert if popup exists.

But as soon as i change the goal to : assert if popup does not exist

the exception handling solution becomes very expensive (exception handling takes a lot of time in python) and a test that would execute in 3 secs now takes up to a minute.

Is there a way around this? A quicker way to check if an element does not exist using webdriver python binding ?

share|improve this question
    
How many times would you estimate that code fragment is executed over the course of your one-minute test? –  user246 Jul 17 '12 at 14:20
    
It is just executed once, but it just stalls on the "except" part for 90% of the 1 minute. –  user1411110 Jul 17 '12 at 19:42
    
That sounds suspicious. On modern hardware, I would expect "slow" exception handling to mean additional microseconds, or perhaps even additional milliseconds, but certainly not 54 seconds. –  user246 Jul 17 '12 at 22:57
    
I should probably use a profiler to get the exact time spent in that try/catch block . But from past test results, the test where no exception was raised ran within 4 - 8 secs while the one where it was raised ran for about a minute or just over. There were no other changes in the code. –  user1411110 Jul 17 '12 at 23:23
add comment

4 Answers

up vote 2 down vote accepted

I haven't used the Python bindings, but as far as I know they should be equivalent to the Java ones.

If I were you I would try to find the Python equivalents of findElements() and isDisplayed() that are available in the Java bindings.

For example, I would do something similar to this:

// ...
myElementList = driver.findElements(By.Id("fancybox-close"))
if (myElementList.isEmpty()) {
    // The element doesn't exist. findElements, in plural, returns a list of the matching elements, or an empty list if no one is found
else {
    // We know it exists, now we need to know if it's displayed (visible) or not
    if (myElementList[0].isDisplayed()) {
        // This means the element is visible
    else {
        // ...
    }

}

Hope it helps

share|improve this answer
    
Ignacio, this is a great idea. python bindings have a find_elements() and is_displayed(). I am however having trouble with checking if the list is empty or not. I get an error message saying "built in function id is not JSON serializable. Will have to look in it. But otherwise this is a great idea. Thanks! –  user1411110 Jul 17 '12 at 19:39
    
isEmpty() is a Java method for lists. In Python, I think you should check the length of the list (len(driver.find_elements(...)) == 0)? I cannot check this for myself right now. –  Ignacio Contreras Pinilla Jul 17 '12 at 19:43
    
In python to check if the list is empty you just have to do if not a : where a =[] is a list. That is what i am doing. if not self.driver.find_elements(By.id("fancybox-close")) : –  user1411110 Jul 17 '12 at 19:53
    
And it doesn't work? –  Ignacio Contreras Pinilla Jul 17 '12 at 19:56
1  
Cool. Now you should look for an equivalent of isDisplayed() (if an element is not displayed it will throw the exception you were using when clicked) for Python as I said in the answer :) –  Ignacio Contreras Pinilla Jul 17 '12 at 20:18
show 6 more comments

Here's another example much like the one from Ignacio, but in C#:

    //Displayed
    public static bool IsElementDisplayed(this IWebDriver driver, By element)
    {
        if (driver.FindElements(element).Count > 0)
        {
            if (driver.FindElement(element).Displayed)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }
    }

    //Enabled
    public static bool IsElementEnabled(this IWebDriver driver, By element)
    {
        if (driver.FindElements(element).Count > 0)
        {
            if (driver.FindElement(element).Enabled)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }
    }
share|improve this answer
add comment

The test is slow not due to slow exception handling, but because driver waits for elements thats are not found. In this case driver waits for the pop-up - maybe it will appear.

Try to use self.driver.implicitly_wait(0)

This will tell driver not to wait if it cannot find some elements.

share|improve this answer
add comment

You can potentially speed it up using various ways:

  • Implicit wait This is mentioned by tstempko. However, implicit wait has a drawback. This makes the driver to not waiting for all UI element when it is set to '0'. In your case, it is not ideal. There might a time that you really have to wait for UI element to show up, then your test will break for no valid reason.
  • Explicit wait You can setup an explicit wait just for this call. This allows a more robust way of waiting for the UI element to show up.
  • Javascript executor for me, there are some web elements which are just too 'unreliable' to detect all the time. What I will use is the javascript executor like this:

    String cmd = "$('#header-username').click()";
    ((JavascriptExecutor)driver).executeScript(cmd);
    

    Good thing about JavaScriptExcutor is that as long as the javascript is loaded, you can execute it. The browser does not need to wait for the element to be rendered. The downside of this is that it is not mimic user's behavior. I use this only to get through to the next test area that I am interested in.

On a side note, rather than the try-except method you have, you might want to try to code it this way:

wait = new WebDriverWait(driver, TIMEOUT);
e = wait.until(ExpectedConditions.visibilityOf(oldPasswordField))
e.click()

Unfortunately, my code is in Java. I think there is a similar method in Python equivalent.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.