Search code examples
seleniumcucumberwatirgeckodriver

How do I assert the visibility of an element in a web page?


I am doing feature descriptions for a web service with Watir. I need to validate the behaviour of the service under different browser conditions - specifically, I want to assert the visibility of an element (a simple link), under certain browser conditions:

@orcid_link = @browser.link(class: 'orcid', text: /orcid/i)
   assert @orcid_link.visible?

This doesn't seem to work though - I resize the window, and Watir thinks that the element is visible (when in fact it is present)

How do you assert the visibility of elements on a page with Watir?


Solution

  • There are no built-in methods for checking if an element is currently in the view port. However, you can make an approximation by running JavaScript.

    Fully In View Port

    A simple example of checking visibility can be taken from Florent B. in another question. Note that there a few of cavets for what this function does not account for. This script also defines "in the view port" as being entirely in the view port.

    This script can be executed using Watir:

    script = %q{
      var rect = arguments[0].getBoundingClientRect(); 
      return (
        rect.top >= 0 && 
        rect.left >= 0 && 
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && 
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) );  
    }
    browser.execute_script(script, @orcid_link)
    

    Partially In View Port

    You can also check if the element is partially in the view port - eg part of a large table. The following script, modified from another of Florent B.'s answers, checks if any corner of the element is in the view port:

    script = %q{
      var elem = arguments[0]
      var box = elem.getBoundingClientRect();
      corners = [
        document.elementFromPoint(box.left, box.top),
        document.elementFromPoint(box.right - 1, box.top),
        document.elementFromPoint(box.left, box.bottom - 1),
        document.elementFromPoint(box.right - 1, box.bottom - 1)
      ];
      results = corners.map( function(c) {
        for (; c; c = c.parentElement) { if (c === elem) return true; }
        return false;
      })
      return results.includes(true);
    }
    browser.execute_script(script, @orcid_link)
    

    If this solves your problem, we might be able to get it added to Watir.