How to test in Capybara if an element is clickable? - ruby-on-rails

I need to test in Capybara if on a page an input text box is visible and clickable. I know how to test about visibility, but I couldn't find a method like .clickable or something in that spirit. How does one do this in Capybara?

It sounds like the OP's needs have been met, but for future explorers, here's some tools to tell if something is clickable.
Test whether the thing can be clicked (Rspec && Capybara):
it "is clickable" do
expect{ find('.your_selector').click }
.not_to raise_error(Capybara::Poltergeist::MouseEventFailed)
end
it "isn't clickable" do
expect{ find('.your_selector').click }
.to raise_error(Capybara::Poltergeist::MouseEventFailed)
end
Click it if possible and do something else if not, per Joe Susnick's answer:
clickable = expect{ find('.your_selector').click }.not_to raise_error(Capybara::Poltergeist::MouseEventFailed)
if clickable
plan_a
else
plan_b
end

Putting this as an answer, from comments on the original question.
You don't need to test clickability (i.e getting the input field to blink when clicked on), because I think that's browser dependent. You don't need to do anything to get that functionality. So if it's visible, and an input field, clicking in it will get that result. Otherwise, if it's not visible, it can't be clicked on anyways, so you're fine. I don't think you need to test anything about clickability, just visibility.

An element can be "visible" without being clickable. I'm actually working on finding a workaround now for selecting a button that's behind an opaque layover. I want to be able to say something like:
if find_button("Change Location").visible?
click it
else
something else
end
I haven't found an answer for this that isn't a hacky workaround so any advice would help. Instead of dismissing the question

Related

node.trigger("click") - Capybara

I have an element I'd like to use this on node.trigger("click") but I'm not sure how to find the element. it is a link_to and I'm relatively new to integration tests os I'm trying to find a answer to this question.
Here is the element
<%= link_to '✚ Invite Another Team Member', "#email", data: { invitation_modal_add: "" } %>
Here is my test I'd like to change.
click_link "✚ Invite Another Team Member"
Id like to replace that with something like this
link.trigger("click")
Because that is what capybara is telling me to try at the moment because I'm getting this error
Capybara::Poltergeist::MouseEventFailed:
Firing a click at co-ordinates [0, 0] failed. Poltergeist detected another element with CSS selector 'html.no-mobile.wf-loading.js.touch-events body.accounts.users.index div.jquery-modal.blocker' at this position. It may be overlapping the element you are trying to interact with. If you don't care about overlapping elements, try using node.trigger('click').
To find the element you can just do
link = find(:link, "✚ Invite Another Team Member")
However before you start using trigger you should read the part of the error message before that - "if you don't care about overlapping elements". If you're actually testing your app you probably do care about overlapping elements since they can prevent your user from actually being able to click the link, and the fact that it's trying to click the link at 0,0 may indicate an issue with your page layout. You should probably try setting a larger window size (window_size option when registering your driver - https://github.com/teampoltergeist/poltergeist#customization) so the link is not overlapped, make sure the link isn't fully hidden/collapsed in some way, or use execute_script with JS to scroll the page so the element becomes interactable. If you really don't care about a user actually being able to click the link then feel free to use #trigger

how to make sure a link is clicked with watir-rails

I am using watir to perform some functions
I need to show that a link is actually clicked by the watir-driver, so I'm trying to put somthing to the console if a link is clicked as follow:
puts "profile clicked" if click_my_profile_link(browser)
and:
def self.click_my_profile_link(browser)
browser.div(class: "topbar").when_present
.link(class: 'my-profile').click
end
but nothing gets printed to the console when the link gets clicked. this behaviour is the same for everywhere I have a click action. Another example is:
puts "Next button clicked" if browser.input(id: 'next', value: 'Next').fire_event :click
How can I get some kind of log when there is a click action fired like this? thanks
Procedural methods are called for their action/side-effect and shouldn't be expected to have a response.
If you didn't get an error, then Watir found the element and sent a click command to it.
So maybe this is sufficient expect {click_my_profile_link(browser)}.to_not raise_error
Typically you write tests to verify the result of the link. In this case that would be something like expect(browser.title == "My Profile Title").to be true
You could create an AfterHook that will take an additional action after every navigation and click, but it wouldn't distinguish between the two, and I really don't think that is what you actually want.

Make capybara wait for an element to disappear

After a click on some element I expect a placeholder to disappear and another element to appear after an AJAX call is finished.
find(someLocator).click
expect(page).not_to have_css(disappearingPlaceholderLocator)
expect(page).to have_css(appearingElementLocator)
The first expectation fails though and the AJAX call is not executed.
I think this is somehow related to this SO question but I just can't figure out how.
This works when the expectations are flipped.
find(someLocator).click
expect(page).to have_css(appearingElementLocator)
expect(page).not_to have_css(disappearingPlaceholderLocator)

How can I detect that a dom element has been deleted

I'm just getting started learning rspec and capybara; I see many examples of testing new content being loaded into a dom, but not so much of verifying that an element has been removed.
I'd like to find an element, click the link to make it disappear, and verify that it is gone.
Something like:
item = find(".list-delete")
item.click
page.driver.browser.switch_to.alert.accept
page.should not_have(item)
I would try the following:
item = find(".list-delete")
item.click
page.driver.browser.switch_to.alert.accept
item.reload.should be_nil

Using Capybara w/ Selenium, how would I click a table row?

Would simply like to know if there's an alternative to click_link / click_button that can be used with any element as some of my clickable elements are not standard html clickables such as tr elements, but they still contain href attributes.
Javascript enabled.
Use Javascript then:
page.execute_script("$('whatever_you_want').click()");
I had the same situation with a html month view, I had to choose a day of month. I kept it as simple as I could and this is only one way of doing this.
# Choose July 22 (at this point in time)
assert page.has_css? '#calendar'
within '#calendar' do
find('td', :text => '22').click
end
Are you using cucumber? Not sure if it's any use to you, but here's a cucumber step definition for clicking anything with selenium:
Then /^I click "(.+)"$/ do |locator|
selenium.click locator
end
I have tried the javascript solution in past, it works in the sense that the button do gets clicked, but cucumber fails to recognise it as a completed step.

Resources