Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check if an element is completely visible on the screen?

I'm using Selenium WebDriver with the Chrome driver on OS X, implementing in Python.

I'm trying to write a test that verifies if a variety of HTML elements are completely on the screen (for example, I have a tag cloud, and because of my poor implementation, sometimes some of the words slip off the edges of the browser window, so they are half-visible).

driver.find_element_by_css_selector("div.someclass").is_displayed(), which is the only solution I can find documented elsewhere, doesn't seem to work; that returns True even if the element is partially visible.

Is there a way that I can check the entire element (including padding etc.) is visible within the standard browser viewport?

I'm implementing in Python, so Python-flavored answers would be most useful.

like image 956
Andrew Ferrier Avatar asked Jan 13 '16 15:01

Andrew Ferrier


People also ask

How do you check if an element is hidden?

Another way to check if an element is hidden is to use the window. getComputedStyle() method. It will return the display property value of the object. We can check if the string is equal to none meaning the element is hidden and do something.

How do you know if an element is visible after scrolling?

The best method I have found so far is the jQuery appear plugin. Works like a charm. Mimics a custom "appear" event, which fires when an element scrolls into view or otherwise becomes visible to the user.

Can element be seen?

Elements are considered visible if they consume space in the document. Visible elements have a width or height that is greater than zero.


1 Answers

You could acquire the element's position and size as well as the window's current X/Y offsets (position) and size to determine whether or not the element is completely in view.

With this information, you can conclude that, in order for the element to be completely within the window, the following must be true:

  • The window's left bound must be less than or equal to the element's left bound
  • The window's right bound must be greater than or equal to the element's right bound
  • The window's top bound must be less than or equal to the element's top bound.
  • The window's bottom bound must greater than or equal to the element's bottom bound.

First, get the element's location and size. The location property will give you the coordinates of the top-left corner of the element in the canvas. The size property will give you the width and height of the element.

elem = driver.find_element_by_id('square100x100')
elem_left_bound = elem.location.get('x')
elem_top_bound = elem.location.get('y')

elem_width = elem.size.get('width')
elem_height = elem.size.get('height')

You can determine if the current window view meets this criteria by getting the X/Y offsets (position) and the size of the window.

You can get the offsets by executing some javascript. The following should work for all compliant browsers. I personally tested in Chrome, Firefox, and Safari. I know IE will probably need a little massaging.

win_upper_bound = driver.execute_script('return window.pageYOffset')
win_left_bound = driver.execute_script('return window.pageXOffset')
win_width = driver.execute_script('return document.documentElement.clientWidth')
win_height = driver.execute_script('return document.documentElement.clientHeight')

With the above, we've determined the size and position of the element as well as the size and position of the viewing window. From this data, we can now do some calculations to tell if the element is in view.

def element_completely_viewable(driver, elem):
    elem_left_bound = elem.location.get('x')
    elem_top_bound = elem.location.get('y')
    elem_width = elem.size.get('width')
    elem_height = elem.size.get('height')
    elem_right_bound = elem_left_bound + elem_width
    elem_lower_bound = elem_top_bound + elem_height

    win_upper_bound = driver.execute_script('return window.pageYOffset')
    win_left_bound = driver.execute_script('return window.pageXOffset')
    win_width = driver.execute_script('return document.documentElement.clientWidth')
    win_height = driver.execute_script('return document.documentElement.clientHeight')
    win_right_bound = win_left_bound + win_width
    win_lower_bound = win_upper_bound + win_height

    return all((win_left_bound <= elem_left_bound,
                win_right_bound >= elem_right_bound,
                win_upper_bound <= elem_top_bound,
                win_lower_bound >= elem_lower_bound)
              )

This will also include padding and borders on an element, but not margins. If you want margins to be factored in, you'll want to get the value of the relevant CSS properties.

Additionally, you may want to check other things like opacity, whether it's displayed, z-index, etc.

like image 52
sytech Avatar answered Oct 04 '22 11:10

sytech