How can I detect that a dom element has been deleted - ruby-on-rails

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

Related

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 to test in Capybara if an element is clickable?

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

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.

Using click_link with Cucumber Scenario

I have the following Feature file which is attempting to visit a page, select a link then edit user data.
Scenario: Edit an existing member of the club
Given I go to the member list page
And I choose the first item
And I fill in the "First Name" with "Bloggs
When I press "Update"
Then I should be on the member list page
And I should see "Bloggs"
and the member_step.rb file contains
Given /^I choose the first item$/ do
#save_and_open_page
visit members_path
click_link "1"
end
My routes.rb file has
Gfs::Application.routes.draw do
resources :members
end
The problem is that I can't get the click_link "1" step to work. The intention is that it will
Navigate to the '/members' index page
The index page displays a list of users each prefixed with a number, that is the link.
Select the link
What I know is that the index page does display a list, my route works ('/members), but my Cucumber is failing and I'm not basking in the glory of green.
The save_and_open_page diagnostic shows only the title of the index page and not the details, as though the controller is not accessing the data
Suggestions are most welcome.
Is there a Background where you create the members data? If not, it may be that the data does not exist.
I'd also suggest adding a step like
And I should not see "Bloggs"
before you update the record.
If I understood your cuke correctly, you really won't see the "1" link because:
Given I go to the member list page <-- first step
And I choose the first item <-- second step
...which expands to:
Given I go to the member list page <-- first step
visit members_path
click_link "1"
why are you visiting the member's path after you just visited the member list page? you should be checking that you ARE in the member's path. Something like:
Given I have existing users(generate members here using factory or whatever)
And I go to the member list page( go to member page)
When I follow "1" (click the first member)
Then I should be on the "1"'s member page
When I fill in...etc you get the point
Hope that helps!
I'm going to suggest that IFF the "1" is a true html anchor link, then you might consider using
And I follow "1"
You could easily wrap this in your own syntax to make it more aesthetically pleasing but the And I follow... step is one that you get out of the box in web_steps.rb.
Another gain in using that one is that you can use a selector to make the click more specific:
And I follow "1" within ".my-kickbutt-div"
Or something along those lines.
Another thing to check into. If you have #javascript enabled you might be seeing incorrect data in your save_and_open_page. My app is javascript/ajax heavy and I have to open the output in a browser with javascript turned off to see what is really visible there :P This might not be your issue, but just in case...

Resources