Reputation: 321
I have an error when I try to check if some element is visible. My method is the following:
if find(:xpath, "//td[text()='#{subtab}']").visible?
find(:xpath, "//td[text()='#{subtab}']").click
else
find(:xpath, "//td[text()='#{tab}']").click
find(:xpath, "//td[text()='#{subtab}']").click
end
In if find(:xpath, "//td[text()='#{subtab}']").visible?
, I have:
Capybara::ElementNotFound:
Unable to find xpath "//td[text()='Plan List2']"
but when the element is correctly visible, it works good.
Upvotes: 0
Views: 2289
Reputation: 49950
By default capybara won't find non-displayed elements - if you really want find to return both visible and non-displayed elements you can do
find(:xpath, "//td[text()='#{subtab}']", visible: :all)
a better solution would be to do
if page.has_no_xpath?("//td[text()='#{subtab}']")
# if the subtab is not visible click the tab
find(:xpath, "//td[text()='#{tab}']").click
end
find(:xpath, "//td[text()='#{subtab}']").click
Upvotes: 1
Reputation: 925
EDIT: Looking better at your code, looks like what you want is just verify if the element is present, without waiting... so just ignore the wait portion (still useful if you encounter some related problem), and use the following (which was also suggested in the answer below) to verify if an element is present:
has_xpath?("//td[text()='#{subtab}']")
ORIGINAL:
The problem is that when you are fire the find method from capybara, it will attempt to map the element from your page. if the element is not present in the DOM, then it will never call the .visible? method...
Latest versions of Capybara removed wait_until functionality, so in this case you will need to implement a waiter yourself...
Below is an example of how you can work around that issue:
def wait_until
Timeout.timeout(20) do
sleep(0.1) until value = yield
end
end
Then
wait_until { has_xpath?("//td[text()='#{subtab}']") }
The has_xpath? will return true or false based on the presence of the element in the DOM, you will loop through that check with the method above and it will only move to the next step until the check above returns true, then you can go ahead and use the .visible? method (although it might not be necessary after you assured the element is present in the DOM)....
Upvotes: 2
Reputation: 762
Give a try with ':visible => true' with xpath, may be syntax error but just give you an idea.
if find(:xpath, "//td[text()='#{subtab}']", visible: false).visible?
find(:xpath, "//td[text()='#{subtab}']").click
else
find(:xpath, "//td[text()='#{tab}']").click
find(:xpath, "//td[text()='#{subtab}']").click
end
Upvotes: 1