user2379867
user2379867

Reputation:

Bringing elements behind fixed element into view with page-object gem

My page contains two divs at the top (a header and another section) that are fixed while the rest of the page can be scrolled. I need to hover over a link element and then click on a button that appears when hovering over the link. Since I am using the page-object gem I tried to use scroll_into_view. However the link still remains behind the fixed divs. This prevents the button from showing. Is there anything that can be done to force it into view? Links at the top and bottom of the scrollable area of the page work fine but items in the middle of the page have issues as they appear behind the fixed divs when scrolled. I am using ruby+watir-webdriver with page-object gem.

Unfortunately I can't post the site.

My code looks something like this:

class MyPage
  div(:items, :class => 'product_items')

  def index_for(product)
    index = items_elements.find_index{|x| x.h4_element.text == product}
    index
  end

  def add_product(product)
    index = index_for(product)
    product = items_elements[index.to_i]
    product.link_element(:class => 'product_more_info').when_present.scroll_into_view
    product.link_element(:class => 'product_more_info').hover
    product.button_element(:class => 'product_info_button').when_present.click
  end
end

The links in the middle of the page remain behind the fixed divs. When it hovers it actually triggers a nav dropdown that is in the header since the link is directly behind it. Seems to work for 70% of the links. The 30% in the middle are the issue right now.

Upvotes: 1

Views: 998

Answers (1)

Justin Ko
Justin Ko

Reputation: 46836

I think I have reproduced your problem with the following page. When the div element to hover on is scrolled into view, it appears below the menu. Hovering does not cause the onmouseover to trigger.

<html>
  <body>
    <div style="position:fixed; left:0; top:0; z-index=99999; border:2px solid red; width:100%">menu</div>
    <div class="spacer" style="height:2000px"></div>
    <div id="hoverable" onmouseover="document.getElementById('target').style.display = '';">to hover</div>
    <button id="target" style="display:none;">the button</button>
    <div class="spacer" style="height:2000px"></div>
  </body>
</html>

One solution that works (at least for this example page), was to try hovering over the element. If the button did not appear, assume that the menu is in the way, scroll back up the page a bit and try again. Assuming the above page, this could be done with the page object:

class MyPage
  include PageObject

  div(:hoverable, :id => "hoverable")
  button(:target, :id => "target")

  def hover()
    # Try to hover over the element
    hoverable_element.when_present.hover

    # If the button element does not appear, the menu must be in the way.
    # Scroll back up 100 px so that the div appears below the menu and try again.
    unless target_element.visible?
      execute_script('window.scrollBy(0,-100);')
      hoverable_element.hover
    end

    # Check that the button appears as expected
    p target_element.visible?
    #=> true
  end
end

Applying the same idea to your page object, the add_product method would become:

def add_product(product)
  index = index_for(product)
  product = items_elements[index.to_i]
  product.link_element(:class => 'product_more_info').hover
  unless button_element(:class => 'product_info_button').visible?
    execute_script('window.scrollBy(0,-100);')
    product.link_element(:class => 'product_more_info').hover
  end
  product.button_element(:class => 'product_info_button').click
end

Upvotes: 0

Related Questions