How to check if element is optically visible in Selenium2Library

11,442 views
Skip to first unread message

Mohan R

unread,
Aug 13, 2012, 2:33:52 PM8/13/12
to robotframe...@googlegroups.com
Selenium2Library has the keyword "Element Should Be Visible"  which according to the docs

Verifies that the element identified by locator is visible. Herein, visible means that the element is logically visible, not optically visible in the current browser viewport. For example, an element that carries display:none is not logically visible, so using this keyword on that element would fail.
 
But I need to verify if the element is optically visible, i.e checking on the display CSS attribute. How do I do it?  
Right now I am using  Get Element Attribute from Selenium2Library
I am passing it "<my_locator>@style" which returns "display : none". But I want the value of the display attribute. I tried "<my_locator>@style.display" and "<my_locator>@style:display" without success.  How do I accomplish this?


boolean isDisplayed()
Is this element displayed or not? This method avoids the problem of having to parse an element's "style" attribute.

David

unread,
Aug 13, 2012, 7:41:10 PM8/13/12
to robotframework-users
You might actually want getCssValue() method of a WebElement. Use it
against the "display" property as argument. That's from the core
WebDriver API. I don't know if Selenium2Library implements a get CSS
value type of keyword.

In Python Selenium 2 bindings, you would call
value_of_css_property(property_name), and your mention of isDisplayed
would be called is_displayed() from the WebElement object.

On Aug 13, 11:33 am, Mohan R <mohanraj....@gmail.com> wrote:
> Selenium2Library has the keyword "*Element Should Be Visible"  *which
> according to the docs
>
> Verifies that the element identified by locator is visible. Herein, visible
>
> > means that the element is *logically *visible, not *optically *visible in
> > the current browser viewport. For example, an element that carries
> > display:none is not logically visible, so using this keyword on that
> > element would fail.
>
> But I need to verify if the element is optically visible, i.e checking on
> the *display *CSS attribute. How do I do it?
> Right now I am using  *Get Element Attribute* from Selenium2Library
> I am passing it "<my_locator>@style" which returns "display : none". But I
> want the value of the display attribute. I
> tried "<my_locator>@style.display" and "<my_locator>@style:display" without
> success.  How do I accomplish this?
>
> Selenium seems to have a method to do thishttp://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/sel...

Kevin O.

unread,
Aug 14, 2012, 8:44:50 AM8/14/12
to robotframe...@googlegroups.com
Selenium2Library is like every other open source project in that the code is half the documentation.  Element Should Be Visible is just a checked call to this method from keywords/_element.py:
    def _is_visible(self, locator):
        element = self._element_find(locator, True, False)
        if element is not None:
            return element.is_displayed()
        return None
This is the same as the java method you mentioned.

There is no way to truly know if an element is optically visible in a browser via Selenium. CSS attributes won't tell you there is a floating div covering your element will they?  Sikuli can verify optical visibility, but I have never used it.

I think Get Element Attribute is not working for you because it is grabbing the attribute from the current html and the display attribute is being applied via CSS. Whatever it is, if you are going to just look at the display attribute then you won't accomplish any more than using Element Should Be Visible.

Mohan R

unread,
Aug 14, 2012, 11:10:38 AM8/14/12
to robotframe...@googlegroups.com
Thanks David. Kevin, what you are saying is true - there might be no way to truly ascertain optical visibility from Selenium. But value_of_css_property(property_name) looks like what I am after.

But David, how do I get access to the WebElement from within Selenium2Library ?

I managed to import it as
from Selenium2Library.keywords._selectelement import WebElement

But I do not know how to create an instance of WebElement.

WebElement expects a WebDriver to be passed in as parent in its __init__
def __init__(self, parent, id_):

The problem is I don't know how to get access to the WebDriver instance from Selenium2Library. I can import it as
from Selenium2Library.webdrivermonkeypatches import RemoteWebDriver

But how do I get an instance of it from Selenium2Library? 

Thanks,

Ed Manlove

unread,
Aug 14, 2012, 12:33:44 PM8/14/12
to mohanr...@gmail.com, robotframe...@googlegroups.com
You might be able to check on the position of the element in question and what the current window size and top pixel is; something similar to this request for whether or not scrollbars are present [1].

Ed

[1] https://github.com/rtomac/robotframework-selenium2library/issues/51

Kevin O.

unread,
Aug 14, 2012, 3:06:14 PM8/14/12
to robotframe...@googlegroups.com
something like this

from robot.libraries.BuiltIn import BuiltIn 

def element_should_be_really_visible(locator):
    s2l = BuiltIn().get_library_instance('Selenium2Library')
    element = s2l._element_find(locator, True, False)
    display = element.value_of_css_property('display')
   ...

Mohan R

unread,
Aug 16, 2012, 10:34:56 AM8/16/12
to robotframe...@googlegroups.com
Thanks Kevin. That worked great. Some related points and questions..

1. I have been using get_library_instance('Selenium2Library') in my parent page class (Page Object design pattern). But how do I use  get_library_instance('Selenium2Library')  when I inherit my parent class from  Selenium2Library?  

2. Regarding verifying visibility - I found that it is not just enough to verify the value of the 'display' attribute of the element you are interested in. You will also have to verify the value for all its parents. Because I ran into situations where the element's display attribute is not none but one of it parent's is none and hence the element was not visible (courtesy of jQuery I think - not sure). 

Thanks again,

Kevin O.

unread,
Aug 16, 2012, 8:27:32 PM8/16/12
to robotframe...@googlegroups.com
Have you looked at this blog on using the page object design while keeping all the code in the test data(resource files)? http://www.beer30.org/?p=54
We have stuck to that at work as the visibility of the page method implementation is much greater if you live in RIDE.

If you still want to do all your coding in Python here are my thoughts:
I don't think you should inherit from Selenium2Library unless you are going to use your library instead of Selenium2Library all the time, since your class will not have the state information you need.
You should just grab the instance of Selenium2Library in the __init__() of your page object and store it in a attribute of your page object (self._se_2_lib). In all your keywords you just use that attribute instead of calling get_library_instance(). This is similar to what I did in Java(WebDriver was passed into the constructor of the page object).  For that to work correctly, you need to make sure the import of Selenium2Library happens before your library.

This is all just my thoughts, as I have never tried what you are trying to do.

Thanks for the info on the visibility.  If I remember correctly, for is_displayed(), the web drivers get the calculated css attributes (using inheritance) as well as checking that there is at least one pixel for dimensions.

Pekka Klärck

unread,
Aug 17, 2012, 3:30:40 AM8/17/12
to korm...@gmail.com, robotframe...@googlegroups.com
2012/8/17 Kevin O. <korm...@gmail.com>:
> Have you looked at this blog on using the page object design while keeping
> all the code in the test data(resource files)? http://www.beer30.org/?p=54
> We have stuck to that at work as the visibility of the page method
> implementation is much greater if you live in RIDE.

I also like this approach and would use it unless complex programming
logic is needed, and even in that case I would consider only having
just the complex keywords in test libraries. To learn more about this
approach, you may also want to check out this excellent post by
Andreas Ebbert-Karroum:
http://blog.codecentric.de/en/2010/07/how-to-structure-a-scalable-and-maintainable-acceptance-test-suite/

> If you still want to do all your coding in Python here are my thoughts:
> I don't think you should inherit from Selenium2Library unless you are going
> to use your library instead of Selenium2Library all the time, since your
> class will not have the state information you need.
> You should just grab the instance of Selenium2Library in the __init__() of
> your page object and store it in a attribute of your page object.

I agree with all the above. Directly inheriting from the library you
want to extend may be a good idea, but as noted above you shouldn't
then use the original library otherwise. Different approaches in
extending existing test libraries, including inheritance and using
`BuiltIn.get_library_instance`, is discussed also in the User Guide:
http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html#extending-existing-test-libraries

Cheers,
.peke
--
Agile Tester/Developer/Consultant :: http://eliga.fi
Lead Developer of Robot Framework :: http://robotframework.org

Mohan R

unread,
Sep 11, 2012, 5:30:39 PM9/11/12
to robotframe...@googlegroups.com, korm...@gmail.com
Thank you for your replies Kevin and Pekka. 
Yes, I have read the mentioned blog articles - they helped me when designing the page objects.

Max Russell

unread,
Dec 21, 2017, 10:10:08 AM12/21/17
to robotframework-users
I'm trying to do something similar, but with the latest SeleniumLibrary, the _element_find doesn't seem to be available?

Barry

unread,
Feb 16, 2018, 12:31:11 PM2/16/18
to robotframework-users
I had trouble with this today, and just wrote a keyword to do:

ActionChains(driver).move_to_element(x).click().perform()

Thanks to this article, I found my driver (webdriver) by doing what Pekka suggested above.

If the element truly isn't visible, I'd use "Execute Javascript" to make it so (see Selenium sites on how to do this).

Thanks to folks on this thread and group for the great tips!

If my WebElement x is truly not visible, I'd do
Reply all
Reply to author
Forward
0 new messages