Capybara::ElementNotFound: Unable to find file field "file" - ruby-on-rails

Hi i am a beginner in rails and encounter some issues when i try to run rspec capybara test.
require 'rails_helper'
describe "Upload Process", :type => :feature do
it "Can upload a file" do
visit new_document_path
page.attach_file('file', '/Users/yaomin/Desktop/my_travel_pic/uploadtest.jpg', visible: false)
click_button 'Upload'
page.should have_content("Uploadtest")
end
end
but i got the error
Failures:
1) Upload Process Can upload a file
Failure/Error: attach_file('file', '/Users/yaomin/Desktop/my_travel_pic/uploadtest.jpg', visible: false)
Capybara::ElementNotFound:
Unable to find file field "file"
# /Users/yaomin/.rvm/gems/ruby-2.3.1/gems/capybara-2.13.0/lib/capybara/node/finders.rb:44:in `block in find'
# /Users/yaomin/.rvm/gems/ruby-2.3.1/gems/capybara-2.13.0/lib/capybara/node/base.rb:85:in `synchronize'
# /Users/yaomin/.rvm/gems/ruby-2.3.1/gems/capybara-2.13.0/lib/capybara/node/finders.rb:33:in `find'
# /Users/yaomin/.rvm/gems/ruby-2.3.1/gems/capybara-2.13.0/lib/capybara/node/actions.rb:256:in `attach_file'
# /Users/yaomin/.rvm/gems/ruby-2.3.1/gems/capybara-2.13.0/lib/capybara/session.rb:769:in `block (2 levels) in <class:Session>'
# /Users/yaomin/.rvm/gems/ruby-2.3.1/gems/capybara-2.13.0/lib/capybara/dsl.rb:52:in `block (2 levels) in <module:DSL>'
# ./spec/features/upload_test.rb:9:in `block (2 levels) in <top (required)>'
Finished in 0.40034 seconds (files took 1.99 seconds to load) 1 example, 1 failure
Failed examples:
rspec ./spec/features/upload_test.rb:5 # Upload Process Can upload a file
my view codes are
h1 Listing documents
table
thead
tr
th
th
th
tbody
- #documents.each do |document|
tr
td = link_to 'Show', document
td = link_to 'Edit', edit_document_path(document)
td = link_to 'Destroy', document, data: { confirm: 'Are you sure?' }, method: :delete
br
= link_to 'New Document', new_document_path
below is the new document view
h1 New document
= render 'form'
= link_to 'Back', documents_path
- if #document.folder
= link_to "Back to '#{#document.folder.name}' Folder", browse_path(#document.folder)
- else
= link_to "Back", root_url
and my form partial
= form_for #document do |f|
- if #document.errors.any?
#error_explanation
h2 = "#{pluralize(#document.errors.count, "error")} prohibited this document from being saved:"
ul
- #document.errors.full_messages.each do |message|
li = message
= f.label :file
= f.file_field :file
- f.hidden_field :folder_id
= f.submit "Upload"
For information, i can actually upload files manually but the upload test i run fails.
Thanks in advance for all your help :)

The first parameter passed to attach_file needs to be either the id, name, or associated labels text. In your case that's probably not 'file'. You state the associated label text is "Choose File" so probably something like
attach_file('Choose File', file_path)
is what you want (impossible to say exactly what the first parameter should be without the actual HTML). Other things that may work would be
attach_file('document_file', file_path) # match the elements id
attach_file('document[file]', file_path) # match the elements name
but again, the first parameter could be slightly different, the HTML will show what they should be.
The other issue that is common with file inputs is that they may be hidden with CSS (made transparent, etc) in order to style the same across browsers. If that is the case and you are using a JS capable driver you can use something like
attach_file('Choose File', file_path, make_visible: true)
which will attempt to make the field visible, set the file, and then restore the original CSS.

Related

Rails, Capybara - click_link on remote links doesnt work

I'm using Capybara to test my project. But i have a problem.
I have some remote forms on my project. They add records via ajax. When i'm testing with capybara it works well on development environment. It visits the page, fills in the form and submits. Booom, record has been added and test didnt fail.
But when i run rspec with test environments i'm getting unknown format exception.
1) add new address user adds new address
Failure/Error: find("input[value='Adres Ekle']").click
ActionController::UnknownFormat:
Account::AddressesController#create is missing a template for this request format and variant.
request.formats: ["text/html"]
request.variant: []
# ./spec/features/user_add_new_address_spec.rb:28:in `block (2 levels) in <top (required)>'
I've also tried to respond via js from controller like;
def create
request.format = :js
end
Then it returns;
1) add new address user adds new address
Failure/Error: find("input[value='Adres Ekle']").click
ActionController::UnknownFormat:
Account::AddressesController#create is missing a template for this request format and variant.
request.formats: ["text/javascript"]
request.variant: []
# ./spec/features/user_add_new_address_spec.rb:28:in `block (2 levels) in <top (required)>'
And my scenario if u want more info;
scenario 'user adds new address' do
expect(page).to have_content 'Kayıtlı Adreslerim'
find("a[title='Adres Ekle']").click
expect(page).to have_content 'Yeni Adres Ekle'
expect(page).to have_content 'Adres Başlığı'
fill_in 'address[name]', with:'Izmir Ofisi'
select('Izmir', :from => 'address[city_id]')
fill_in 'address[address]', with: 'Lorem ipsum dolor sit amet.'
find("input[value='Adres Ekle']").click # It submits remote: true form.
expect(page).to have_content 'Success!'
end
PS: my create action doesnt render something like that.
its like;
def create
#new_address = Address.new
#address = #current_account.addresses.new(address_params)
if #address.save
#check = true
else
#check = false
end
end
it renders: create.js.erb
<% if #check %>
if($('.addresses').length) {
$('.addresses').append('<%= j(render('account/addresses/address', address: #address)) %>');
}
if($('#did-addresses').length){
$('#did-addresses').append("<%= "<option selected='true' value='#{#address.id}'>#{#address.name}</option>".html_safe %>").selectpicker('refresh');
}
$('#new-address').html('<%= j(render('account/addresses/form', new_address: #new_address)) %>');
swal({
type: 'success',
title: "<%= t('response.success') %>",
text: "<%= t('flash.actions.create.notice', resource_name: Address.model_name.human) %>",
timer: 2000
});
quickview.close('#new-address');
<% else %>
<% #address.errors.each do |error| %>
<% end %>
<% end %>
$('.preloader').fadeOut();
I was facing the same case in rails 6 but I fixed it be adding js: true to the scenario and it automatically worked well.
scenario 'Should delete the feature', js: true do
# Your logic
# Your expectations
end
Since copying your development config over your test config fixed your issue, it sounds like you probably an error in one of your JS files. Normally in the test and production environment all of your JS assets get concatenated into one file which means an error in any one of them can prevent the code in the others from being executed. In the development environment each JS file is loaded separately which means an error in any file can only affect the rest of the code in that file. Check your the console in your browser for any JS errors when going to the page in question and fix them.

Encoding::CompatibilityError in Observations when access active directory from rails

I have established a connection to Active Directory through ldap/net. I am trying to pull AD attributes and values.
If I use the following code (using values.inspect) the query works.
<% #temp_search.each do |user| %>
TS = <%= user.sn %> <br>
<% user.each do |attribute, values| %>
<%= attribute %> <br>
<% values.each do |value| %>
<%= value.inspect %><br>
<% end %>
<hr style="border-color: red">
<% end %>
<% end %>
The portion of my controller doing the ldap query is s
filter = Net::LDAP::Filter.eq( "sn", "mendla" )
treebase = "dc=ccttapes1,dc=com"
#temp_search = ldap.search( :base => treebase, :filter => filter )
p ldap.get_operation_result
What I can't seem to get to is to just get the value for one particular attribute - for example, givenname.
I see results such as
cn
"Chris G. Mendla"
sn
"Mendla"
description
"Test account 1 for rails apps - DO NOT CHANGE PW"
givenname
"Chris"
initials
"G"
distinguishedname
"CN=Chris G. Mendla,OU=Users CCT,DC=CCTTAPES1,DC=com"
However, if I change <%= value.inspect %><br> to <%= value.givenname %><br> I get an error of
NoMethodError in Observations#index
Showing C:/Users/cmendla/RubymineProjects/employee_observations/app/views/observations/index.html.erb where line #61 raised:
undefined method `givenname' for "CN=Christopher Mendla,OU=Users CCT,DC=CCTTAPES1,DC=com":Net::BER::BerIdentifiedString
Rails.root: C:/Users/cmendla/RubymineProjects/employee_observations
Application Trace | Framework Trace | Full Trace
app/views/observations/index.html.erb:61:in `block (3 levels) in _app_views_observations_index_html_erb__474218211_78240600'
app/views/observations/index.html.erb:60:in `each'
app/views/observations/index.html.erb:60:in `block (2 levels) in _app_views_observations_index_html_erb__474218211_78240600'
app/views/observations/index.html.erb:58:in `block in _app_views_observations_index_html_erb__474218211_78240600'
app/views/observations/index.html.erb:56:in `each'
app/views/observations/index.html.erb:56:in `_app_views_observations_index_html_erb__474218211_78240600'
and if I try ``<%= givenname.value %>` I get
NameError in Observations#index
Showing C:/Users/cmendla/RubymineProjects/employee_observations/app/views/observations/index.html.erb where line #61 raised:
undefined local variable or method `givenname' for #<#<Class:0x9cd0230>:0x9fadaf0>
Rails.root: C:/Users/cmendla/RubymineProjects/employee_observations
Application Trace | Framework Trace | Full Trace
app/views/observations/index.html.erb:61:in `block (3 levels) in _app_views_observations_index_html_erb__474218211_83715540'
app/views/observations/index.html.erb:60:in `each'
app/views/observations/index.html.erb:60:in `block (2 levels) in _app_views_observations_index_html_erb__474218211_83715540'
app/views/observations/index.html.erb:58:in `block in _app_views_observations_index_html_erb__474218211_83715540'
app/views/observations/index.html.erb:56:in `each'
app/views/observations/index.html.erb:56:in `_app_views_observations_index_html_erb__474218211_83715540'
Request
My goal is to be able to search for an AD record by first and last names and then pull values for attributes such as mail or memberof.
(I am using ldap-net
In your example #temp_search should be an array of users that meet your search criteria. Each one of those users is a Net::LDAP::Entry object. On those objects you can call methods are available corresponding to the users attributes.
If only one user is returned, the Net::LDAP::Entry object will still be inside an array. In that case you could call something like:
#temp_search.first.cn
You can also call:
#temp_search.first.attribute_names to see all available attributes for that object.
For example, you could do something like:
<% #temp_search.each do |user| %>
#call user attributes
user.cn
user.memberof
#etc, other attributes
<% end %>

Rails: Capybara doesn't find a div element

I'm using Capybara with RSpec to check my Rails project.
I'm testing errors when form fields are not correctly filled. Here is the form (using haml):
= form_tag '/objects', :class => 'objects-form' do
%ul
%li= select_tag 'object', options_for_select([['Select an object', ''], ['Car', 'CAR'], ['Keys', 'KEYS'], ['Ambrella', 'AMBRELLA']]), :id => 'select-object'
%li= text_field_tag :quantity, nil
%li= submit_tag 'Buy', :id => 'object-submit'
When an error occurs (in this case, not choosing an object but only a quantity), a flash message is displayed (with a .flash-error class name):
- flash.each do |type, msg|
= content_tag :div, msg, :class => "flash-#{type}", :id => 'flash-msg'
So, here is my Capybara test:
it 'Should return error when no object selected' do
within 'form.objects-form' do
fill_in 'quantity', :with => '1'
click_button 'object-submit'
current_path.should == objects_path
save_and_open_page
page.should have_css 'div.flash-error'
end
end
But I get the following Capybara error:
Failure/Error: page.should have_css 'div.flash-error'
expected #has_css?("div.flash-error") to return true, got false
The opened page (using save_and_open_page) shows the error message with the appropriate div:
div#flash-msg.flash-error
I'm using the latest version of Capybara (since many similar problems on Stackoverflow are relative to old versions of Capybara) using gem 'capybara', :git => 'https://github.com/jnicklas/capybara.git'
Any idea? Thank in advance.
EDIT:
Corrected typing mistake on Capybara code, as detected by Alex.
The problem is your selector you are using in capybara is div#flash-error but your div is div#flash-msg.flash-error or more simply div.flash-error.

RSpec test link_to inside p tag

Is it possible to have a test for the following html structure?
<p class="all-jobs"><%= link_to "<< Back to all jobs", jobs_path %></p>
I tried doing it this way:
it { should have_selector('p.all-jobs', link: "<< Back to all jobs")}
The error is:
1) JobPages visit a job page
Failure/Error: it { should have_selector('p.all-jobs', link: "<< Back to all jobs")}
expected css "p.all-jobs" to return something
# ./spec/requests/job_pages_spec.rb:78:in `block (3 levels) in <top (required)>'
Okay, I got it to work with the following:
describe "should have a link to index page" do
it { should have_selector('a', title: "<< Back to all jobs", href: jobs_path) }
end

Cucumber `press button` failure (Capybara::ElementNotFound)

I'm a relative newbie starting up a new Ruby on Rails app. I started by following a combination of instructions at https://github.com/intridea/omniauth, http://www.communityguides.eu/articles/16, http://intridea.com/2011/1/31/easy-rails-admin-login-with-google-apps-and-omniauth?blog=company . At the point everything appeared to work correctly, I started to write my very first cucumber features and steps. I was able to get a couple of steps up and running, but I've been bogged down on a step that I thought was built in. I have a form with two submit_tags but I can't get a scenario to successfully pass a basic And I press "button" step.
possibly relevant gems:
rails (3.1.0.rc4)
capybara (1.0.0)
cucumber (1.0.1)
cucumber-rails (1.0.2)
nokogiri (1.4.7)
gherkin (2.4.5)
rack-test (0.6.0)
selenium-webdriver (0.2.2)
section of the form in question:
<%= form_tag :controller => "services", :action => "newaccount" do %>
<%= submit_tag "confirm", :id => "confirm", :title => "confirm", :value => "confirm", :text => "confirm", :name => "confirm" %>
<%= submit_tag "cancel", :id => "cancel", :title => "cancel", :value => "cancel", :text => "cancel", :name => "cancel" %>
<% end %>
scenario in question:
Scenario: I register with a valid and currently active google account
Given I am not registered
When I sign in with a valid and currently active google account
And I press "confirm" # <-- THE PROBLEMATIC STEP
Then I should see "Your account has been created and you have been signed in!"
I think this is the relevant web_step (straight from the default web_steps.rb which I have not edited at all):
When /^(?:|I )press "([^"]*)"$/ do |button|
click_button(button)
end
relevant cucumber output:
Scenario: I register with a valid and currently active google account # features/auth_and_auth/initial_tests.feature:6
Given I am not registered # features/step_definitions/authentication_steps.rb:1
When I sign in with a valid and currently active google account # features/step_definitions/authentication_steps.rb:5
And I press "confirm" # features/step_definitions/web_steps.rb:52
no button with value or id or text 'confirm' found (Capybara::ElementNotFound)
(eval):2:in `click_button'
./features/step_definitions/web_steps.rb:53:in `/^(?:|I )press "([^"]*)"$/'
features/auth_and_auth/initial_tests.feature:9:in `And I press "confirm"'
Then I should see "Your account has been created and you have been signed in!" # features/step_definitions/web_steps.rb:105
relevant html output:
<input id="confirm" name="confirm" text="confirm" title="confirm" type="submit" value="confirm">
<input id="cancel" name="cancel" text="cancel" title="cancel" type="submit" value="cancel">
As is obvious, I've accounted for value, id, text, as well as name and title. I also saw a post that said the input type had to be specified as submit which it appears to have been. And I've tried it with both the confirm button and the cancel button.
After searching everywhere that I know about, and trying every suggestion that looked even remotely relevant, I'm at an impasse. What am I missing?
I'm not sure if the code below is the best way to deal with the problem I encountered, but it is getting the relevant step to pass.
When /^(?:|I )press "([^"]*)"$/ do |button|
# click_button(button) # the original web_steps.rb version that fails
%{I press (button)} # my revised version that passes
end
I'd still appreciate any feedback on:
why the original web_steps.rb version fails,
whether this is an appropriate approach or not, and
if there is a more 'rails' way to deal with this.

Resources