click on second ambiguous link with Capybara - ruby-on-rails

I want to click on the second of the two following links:
photo
photo
As you can see, the URLs are actually different, but the link title, "photo", is the same in both. I am not using IDs on my links, and there is no nesting class context by which to distinguish the links.
Ideally, I would like to be able to click even a third, or nth ambiguous link.
An example of a DSL for this purpose would be something like:
click_link photo.title, match: 2

I find that using all is easier to read than locating by xpath:
all('a', :text => 'photo')[1].click
However, it not as fast as using xpath.

You should be able to use xpath for this. Something like:
find(:xpath, '//a[text()='photo'][2]').click

Related

Watir - How do I collect all links where the span contains aria_label "Multimedia"

I have written a ruby code where the browser object finds all links and then I store them one by one in an array if they match a specific regex.
#browser.links.collect(&:href).each do |link|
matches = regex.match(link)
array_of_multimedia << matches[:multimedia_id] if matches
end
I am trying to create a filter where I only iterate over those links where the span inside the second child div contains the aria-label as Multimedia.
Attached is the screenshot of the HTML structure.HTML structure
I tried a few approaches like finding all spans and then going bottom up to the parent's parent of the span but its not giving me the href.
#browser.spans(aria_label: "Multimedia").each do |span|
span.parent.parent.a.hreflang #Didn't work
span.parent.parent.a.link.href #Didn't work
span.parent.parent.href.text #Didn't work
element.tag_name #This shows "a" which is correct though
end
I also tried a top down approach by doing
#browser.links.collect(&:href).each do |link|
link_element = #browser.link(href: link)
link_element.children.following_sibling(aria_label: "Multimedia").present? #Didn't work
end
So far, no luck in getting the actual hrefs. Will appreciate any help!
Because the span is inside the link tag, it's going to be easier to go bottom up
Do as much as you can with the Watir locators rather than multiple loops.
The parent method takes arguments:
#browser.spans(aria_label: 'Multimedia').map {|span| span.parent(tag_name: 'a').href }
As for what you tried:
# parent.parent is the link, so calling `#a` is looking for a link nested inside the link
span.parent.parent.a.hreflang
span.parent.parent.a.link.href
# href should give you a String, you shouldn't need to call #text method on it
span.parent.parent.href.text
# element isn't defined here, but try just element.href
element.tag_name
Also note that Element#href method is essentially a wrapper for Element#attribute_value('href').

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

Capybara - check for the existence of a data attribute on a link

I have a link with a specific attribute on my page. Using Rspec + Capybara how can I check for the existence of this link?
Foo
Does not work:
page.find(:css, 'a[data-content="This is a discrete bar chart."]')
Works:
page.find(:css, 'a#test')
I have the same query, but the quotes are different.
find("a[data-method='delete']").click
and works for me.
Here are some different ways:
expect(page).to have_selector("a[href='#'][data-content='This is a discrete bar chart.']")
page.has_selector?("a[href='#'][data-content='This is a discrete bar chart.']")
page.find("a[href='#'][data-content='This is a discrete bar chart.']") # returns the node found
If you don't have access to page but have access to rendered, then
expect(Capybara.string(rendered)).to have_selector("a[href='#'][data-content='This is a discrete bar chart.']")
It could be an issue of Capybara finding too many results. Maybe change 'find' to 'all' and see if you get an array of results that you could select from. Best of luck.
This worked for me when searching for a link's title attribute (tooltip):
Then(/^I should see tooltip "(.*?)" on link "(.*?)"$/) do |tip, link|
within('#results') do
link = find(:link, link)
expect(link['title']).to eql(tip)
end
end
NOTE: the within is optional and useful for reducing chances of ambiguity.
HTML Source code:
<a title="Owner: lfco Fire Department" href="/water_supplies/597df82566e76cfcae000018">Hydrant LFCO One</a>

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