Jen
Jen

Reputation: 109

Selenium Webdriver (Ruby) : Cannot click on button - element not found

This is the page code:

<div class="modal-buttons">

    <button class="button-orange" ng-click="cancel()">
        <span>

            Cancel

        </span>
        <span class="icon cancel"></span>
    </button>
    <button class="button-orange" ng-click="apply()">
        <span>

            Apply

        </span>
        <span class="icon run"></span>
    </button>

As you can see - this modal has two buttons and I have tried a dozen different ways - but I just want to click on the button labeled "apply" No matter which route I take - it just keeps saying element not visible.

Here are some of the things I've tried:

#   @driver.find_element(:class, "button-orange")[2].click
#   @driver.find_element(:xpath, "//div[4]/div/div[2]/div[3]/button[2]").click
# @driver. find_element(:link_text, 'Apply').click
#   @driver. find_element(:tag, 'Apply').click
# @driver.find_element(:css, "input[value='Apply']").click();
#  @driver.find_element(:css, "input[value='Apply']").click();
# @driver.find_element(:xpath, "//button[contains(text(),'Apply')]").click
# @driver.find_element(:xpath, "//button[contains(text(),'apply')]").click
# @driver.find_element(:xpath, "//input[@value='Apply']").click();
#   @driver.find_element(:class, "button-orange.icon-run").click
#  @driver.find_element(:css,'a[class$="button-orange"]').click
#   @driver.find_element(:xpath, "").clear

The exact error I get is:

Error: test_login_to_chute(LoginToChute)
  Selenium::WebDriver::Error::ElementNotVisibleError: element not visible
    (Session info: chrome=36.0.1985.125)
    (Driver info: chromedriver=2.10.267521,platform=Windows NT 6.3 x86_64)
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/response.rb:51:in `assert_ok'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/response.rb:15:in `initialize'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/http/common.rb:59:in `new'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/http/common.rb:59:in `create_response'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/http/default.rb:66:in `request'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/http/common.rb:40:in `call'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/bridge.rb:634:in `raw_execute'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/bridge.rb:612:in `execute'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/remote/bridge.rb:369:in `clickElement'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.42.0/lib/selenium/webdr
iver/common/element.rb:54:in `click'
C:/Analytics/AutomatedTesting/DevEnv/Wonderland/Full Regression/2.login_to_chute
.rb:165:in `test_login_to_chute'
     162:       @driver.find_element(:xpath, "(//input[@type='text'])[8]").clear

     163:       @driver.find_element(:xpath, "(//input[@type='text'])[8]").send_
keys "25"
     164:
  => 165: @driver.find_element(:xpath, "//div[4]/div/div[2]/div[3]/button[2]").c
lick

Upvotes: 0

Views: 5264

Answers (3)

Heena Shaikh
Heena Shaikh

Reputation: 11

There are several reasons behind this error. I was getting the same error and here is how I narrowed down the possible causes.

  1. The Item can be located in the iframe, in this case you have to switch to the iFrame and locate the element

  2. Another reason can be the element is not yet displayed and you are performing operations on it. In this case you can apply explicit wait as below.

    wait = Selenium::WebDriver::Wait.new(:timeout => 10)
    wait.until{browser_driver.find_element(:xpath,'***').displayed?}
    

    Using this chunk in your code can help you to wait for maximum 10 seconds till the item is displayed

  3. It is possible that, your xpath is returning more than 1 web element to the driver i.e. more than 1 element can be located with the same xpaths. In this case make sure that your xpath is more specific and returning only one web element. My issue was solved with 3rd possibility.

Upvotes: 1

Jen
Jen

Reputation: 109

Thank you all so much for helping.

Here's what ended up being the deal.

Because the website is all one angular page, it's loading a bunch of things in the background. Including multiple other buttons that aren't actually visible.

So here's what I ended up using:

@driver.find_elements(:xpath, "//button")[-1].click

And I updated my find_element variable to only find visible elements.

def find_visible_element(how, what)
 elems = @driver.find_elements(how, what).select { |e| e.displayed? }
 len = elems.length
 if len == 0
  raise "No matches found."
 elsif len > 1
  raise "Ambiguous match. Found #{len} matches."
 end
 elems.first
end

Upvotes: 1

Kache
Kache

Reputation: 16677

Wait unti the javascript modal is fully loaded (using a Wait block, for example)

Also, you have to use the correct selector. Frankly, quite of few of your example selectors don't make any sense in the context of the html you posted.

In Chrome's inspector, make sure what it is that a mouseclick would click on. Have you tried selecting the <span>?

Try some of these:

:css => "button.button-orange[ng-click='apply()']"
:xpath => "//button[@ng-click='apply()']"
:xpath => "//button/span[contains(text(),'Apply')]/.."

:css => "button.button-orange[ng-click='apply()'] > span"
:xpath => "//button[@ng-click='apply()']/span"
:xpath => "//button/span[contains(text(),'Apply')]"

By the way, chrome's element inspector has a find function that can search xpath as well as css too for selector testing.

Upvotes: 0

Related Questions