Is there a way to determine if an element is clickable in Chrome Browser using Selenium and Watir?

跟風遠走 提交于 2019-12-06 07:22:34

Watir 6.15.0+

Element#obscured? has been added to check for this scenario. You can now do:

browser.element(id: 'target').wait_while(&:obscured?).click

Watir pre-6.15.0

For older versions, you will need to take a different approach.

I would try waiting for the overlapping element to go away. If the overlapping is something like an overlay that will eventually disappear, it's relatively straightforward - eg:

browser.element(id: 'overlapping_element').wait_while(&:present?)

If the overlapping element gets moved rather than disappears or you don't know the overlapping element, you could try approximating the overlapping element check. When Chrome clicks an element, it gets the element's center location and then clicks at that point. If there the top-level element at that point is not your element, the exception is thrown. The following wait will do this check until there is no overlapping element:

target = browser.button
target_children = target.elements.to_a
browser.wait_until do
  location = target.location
  size = target.size
  center = [location.x + size.width/2, location.y + size.height/2]
  element_at_point = browser.execute_script("return document.elementFromPoint(#{center[0]}, #{center[1]});")
  [target, target_children].flatten.include?(element_at_point)
end
target.click

Note that I haven't had to do this before, so I don't know if there are edge cases. Seemed to work with Chrome and Firefox.

I can suggest you to wait this button to show on the web page. I experienced the same problem (I was using XPath in my tests). To fix it:

Firstly I defined 2 helper methods because I had to reuse them a lot. One for searching of a exact element on the page(this method is usually takes a while to return a result so you don't need to sleep the browser) and one for clicking a button with given "id".

module Helpers
  module Common
    def wait_for_element_id(value)
      find(:xpath, "(//*[@id='#{value}'])[1]")
    end

    def click_button_with_id(value)
      first(:xpath, "//button[@id='#{value}']").click
    end
  end
end

After that in your test you can use the helper methods like:

it 'clicks on the login button and magic is executed' do
  logout(user)
  wait_for_element_id('button_login')
  click_button_with_id('button_login')

  expect(magic).to be_executed
end

I am also not sure but you can also experience the same project because of the browser window size (button is not shown because the size is too low) or because of the "headless" mode of your tests.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!