How to click a link within a hidden div via capybara - ruby-on-rails

I am using capybara, rspec, and poltergeist in a Rails 4 application and am trying to click on the following link button via capybara.
<div class="form-group">
<input id="invoice_invoice_items_attributes_0__destroy" name="invoice[invoice_items_attributes][0][_destroy]" type="hidden" value="false">
<a class="btn btn-warning remove_fields existing" href="#">Remove Invoice Item</a>
</div>
If I have the following in rspec/capybara, it finds the hidden element:
find(:xpath, '//input[#id="invoice_invoice_items_attributes_0__destroy"]', visible: false)
If I try this, it doesn't find the link element:
find(:xpath, '//input[#id="invoice_invoice_items_attributes_0__destroy"]/a', visible: false)
The end goal is to do this:
find(:xpath, '//input[#id="invoice_invoice_items_attributes_0__destroy"]/a', visible: false)
How do I get there?

Your a tag isn't inside of the input field, so unless form-group div is hidden, you should be able to just do:
click_link 'Remove Invoice Item'
If form-group is hidden, then try:
find(".remove_fields", visible: false).click

Related

How to check for a disabled div that behaves like a button using Rails Capybara?

I have an div that work as button:
<div class="dropdown">
<div class="btn dropdown-toggle" data-toggle="dropdown" disabled="">Export to file</div>
<div class="dropdown-menu">
<a class="dropdown-item" fref="/1">1</a>
<a class="dropdown-item" href="/2">2</a>
<a class="dropdown-item" href="/3">3</a>
</div>
</div>
</div>
I need to check that it is not clickable using Capybara, i try this:
scenario 'do not allow export if tracking time empty' do
have_css(".dropdown>.btn[disabled].dropdown-toggle")
end
# and this
expect(page).to have_button("Export to", :disabled => true)
But this don't work, any suggestion ? Thankee)
For the HTML you've shown
expect(page).to have_css('.btn.dropdown-toggle[disabled]', text: 'Export to file')
should verify the HTML you've shown is on the page and visible. It won't actually test that the button is disabled - just that the element has the specified classes/attributes. That might be acceptable if you're using a 3rd party library to handle these buttons which has its own tests you trust. If you're handling the disabling of the button using your own JS though you might want to actually verify that it's disabled with something like
page.find('div.btn.dropdown-toggle[disabled]', text: 'Export to file').click
expect(page).not_to have_link('2', class: 'dropdown-item')
You can't use have_button because that finds HTML standard buttons elements (button, input type=button, etc).
Note: If you're using a lot of these buttons in your app you might want to look into writing a custom Capybara selector for dealing with them.
I'd suggest: don't test for elements attributes. Try to click it then test that nothing happens.

have trouble with using capybara-webkit attach_file upload an image

I want to test the function to add an image to the application. How can I do this. attach_file method is not work. I don't know why.
html:
<form id="edit_user_5577b0c4a851ac600c000002" class="form-horizontal user-settings" method="post" enctype="multipart/form-data" action="/tardis54" accept-charset="UTF-8">
<div id="upload-avatar" class="control-group">
::before
<label class="control-label" for="user_avatar">
Setting avatar
</label>
<div class="controls">
<div class="form-fileupload">
<div class="image-preview">
<img class="gravatar img-circle" width="60" height="60" src="http://gravatar.com/avatar/7046a07b25397e4a0c838a47c88d8742?default=identicon&secure=false&size=60" data-retina-url="http://gravatar.com/avatar/7046a07b25397e4a0c838a47c88d8742?default=identicon&secure=false&size=120" alt="tardis54"></img>
</div>
<span class="btn btn-fileinput btn-default">
<span>
Choose file ...
</span>
<input id="user_avatar" class="input-file" type="file" name="user[avatar]"></input>
</span>
</div>
</div>
</div>
<div class="form-actions pull-right">
<input class="btn btn-large btn-primary" type="submit" value="Update" name="commit"></input>
</div>
</form>
test code:
scenario "upload a custom avatar" do
attach_file("user[avatar]", Rails.root + "temp4.png")
end
error log:
Failure/Error: attach_file("user[avatar]", Rails.root + "temp4.png")
Capybara::Webkit::ClickFailed:
Failed to click element /html/body/div[#id='content']/div/div/div/div/div/div[2]/form[#id='edit_user_5580e19da851ac6a51000002']/div[#id='upload-avatar']/div/div/span/input[#id='user_avatar']
because of overlapping element /html/body/div[#id='content']/div/div/div/div/div at position 740, 627;
It looks like you're using CSS to overlay another element on top of the HTML input. Some people do this because it's difficult to style HTML file inputs directly. However, doing so breaks capybara-webkit, because it needs to click on the actual HTML input field and the styled element is positioned on top of it.
This is being discussed in a GitHub issue.
You can work around it in the test by using execute_script to hide the overlay element, and then attempting to upload the file.
I find a way to solve this problem.
script = "$('#user_avatar').css({opacity: 100, display: 'block', position: 'relative', left: ''});"
page.execute_script(script)
I could assume that input[type=file] is not visible, thus you need initially make it visible f.e. execute javascript $("input[type=file]").show() and than attach file
Here's my implementation of #tardis answer (which itself is an implementation of #joe-ferris' suggestion). I put it as an answer to be able to use code formatting.
# spec/support/file_uploads.rb
module FileUploads
# Enables file uploads by capybara-webkit on pages that
# style file their input fields
def attach_file_styled_input(element_id, file)
page.execute_script("$('##{element_id}')" +
".css({opacity: 100, display: 'block', position: 'relative', left: ''});")
attach_file element_id, file
end
end
Don't forget to include this support module in spec/rails_helper.rb:
config.include FileUploads
Then use it in your feature spec like this (not spectacular):
attach_file_styled_input 'my_input_id', 'my_file'

Can't find element in Capybara even though it exists

I am writing some Capybara tests, and am failing at what seemed to be quite straight forward search. I have HTML:
<div id="divId">
<div class="unimportantClass">
</div>
<form id="formId">
<div>
</div>
<h2>Irrelevant text</h2>
<p>Equally irrelevant</p>
<span class="remarkableSpan">
<i class="whatever"> </i>
Some text
<input id="targetTag">
</input>
</span>
</form>
</div>
I am trying to confirm existence of "targetTag"
Everything goes well in
expect(page).to have_css('div#divId form#formId span.remarkableSpan')
but with
expect(page).to have_css('div#divId form#formId span.remarkableSpan input')
or
expect(page).to have_css('div#divId form#formId span.remarkableSpan input#targetTag')
it fails to find it. Any ideas what is causing it?

Click on element with capybara

I have a yes/no slider on a web page that i need to interact with. I need to click on one of the elements so that the value changes from true to false or false to true. Using the id i can get the value of the element with
find_field('passcode_policies__allow_simple').find('option[selected]').value
But i have tried over and over to simulate a click on this object to change the value and have been unsuccessful.
<div class="control-group">
<select class="toggle" id="passcode_policies__allow_simple" name="passcode_policies[][allow_simple]" style="display: none; " tabindex="-1">
<option value="true" selected="selected">Yes</option>
<option value="false">No</option>
</select>
<div class="ui-switch off" tabindex="0">
<div class="ui-switch-mask">
<div class="ui-switch-master" style="left: -38px; ">
<div class="ui-switch-upper">
<span class="ui-switch-handle" style="left: 33px; "></span>
</div>
<div class="ui-switch-lower">
<div class="ui-switch-labels">
Yes
No
</div>
</div>
</div>
</div>
<div class="ui-switch-middle" style="width: 60px; ">
</div>
</div>
<label class="inline">Allow simple value</label>
<span class="help-block">Permit the use of repeating, ascending, and descending character sequences</span>
</div>
If you're using Selenium, headless webkit or phantomjs (poltergeist gem) you should be able to call the simple
click_link 'Yes'
but if you're just using straight up capybara you will have to interact with the select element with something like
select('Yes', :from => 'passcode_policies__allow_simple')
and you can check the visibility and whatnot with this capybara: page.should have_no_content doesn't work correctly for display:none element
Working solution:
within(:css, '#passcode_policies__allow_simple + .ui-switch') do
click_link 'No'
end

Can't find element to click on using Capybara + Rails3

Background: I'm using Capybara with Rspec to test a Rails 3 app.
Driver used: Selenium
Problem:
I can't find the "Sign in" button in order to click on from within my test.
HTML code:
<form accept-charset="UTF-8" action="/" class="filter_form" id="login" method="post">
<fieldset>
<div class="modal-body">
<div class="clearfix login-fields">
<label for="user_email">Email</label>
<div class="input login-inputs">
<input class="input-text" id="user_email" name="user[email]" placeholder="email" size="30" type="email" value="">
</div>
</div>
<div class="clearfix login-fields">
<label for="user_password">Password</label>
<div class="input login-inputs">
<input class="input-text" id="user_password" name="user[password]" placeholder="password" size="30" type="password">
</div>
</div>
</div>
<div class="modal-footer">
<input class="btn btn-primary login_btn" id="btn_login" name="commit" type="submit" value="Sign in">
Forgot password...
Cancel
</div>
</fieldset>
</form>
Failing test
it "should login correctly if the right credentials are given", :js => true do
Capybara.default_wait_time = 5
Capybara.reset_sessions!
visit '/'
click_link('login_link') #this will bring a modal window with the code posted above using js
within("#login") do
fill_in 'user_email', :with => "my-email#example.com"
fill_in 'user_password', :with => "mypwd"
end
response.should have_selector('input#btn_login') #This passes
click_on("input#btn_login") #Here it fails, saying it can't find an element with that selector
response.should have_selector(:xpath, '//div[#class="alert-message block-message info"]')
end
My test file is inside spec/requests.
Any ideas?
Thanks!
Please try this:
page.find("#btn_login").click
This: https://stackoverflow.com/a/11348065/1504796
Is the right answer.
click_on does not take a CSS selector, but instead the text or id of a link. You want click_on("btn_login"). No hash sign or anything.
try
find('#id',:visible => true).click
Try adding "gem 'launchy'" to your Gemfile and put
"save_and_open_page" line before failed line in step file.
REFERENCE: http://techiferous.com/2010/04/using-capybara-in-rails-3/
It looks like you're trying to click on a submit button inside some modal css. You'll need to invoke whatever displays that modal element first.
I don't think click_on will take a locator like that--I think it may want just an id, name or value. As an experiment, try replacing click_on("input#btn_login") with:
page.find('#btn_login').click
click_button("Sign in")
find(:xpath, "//*[#id='btn_login']").click (or .trigger('click'))
If else fails, go through the console and see if you can check the presence of the button: document.getElementById("btn_login")
If you know the link text, you can use page.find_link(text).click. (source)
Try adding a save_and_open_page before the line in question. This should allow you to see the page and any errors that may prevent the clicking action.
I use capybara with chrome
Capybara.register_driver :chrome do |app| Capybara::Selenium::Driver.new(app,
:browser => :chrome)
end
Capybara.javascript_driver = :chrome
and install chrome driver:
brew install chromedriver
http://collectiveidea.com/blog/archives/2011/09/27/use-chrome-with-cucumber-capybara/

Resources