Capybara element not found haml button - ruby-on-rails

I have a diagnostic spec and i believe there is some inconsistency in my use of the language between the spec and the view files. However i have not been able to resolve the problem. The test is as follows
it "updates a diagnostic report" do
diagnostic_info = FG.create(:diagnostic_info)
diagnostic_info.save!
visit edit_admin_diagnostic_path(diagnostic_info)
fill_in 'diagnostic_info_notes', with: "test notes"
click_button "Save"
page.should have_content("Saved")
page.should have_content("test notes")
end
the view is
.field
= label_tag :notes
= f.text_field "notes"
= submit_tag #diagnostic.data["Save"], method: :put, data: { confirm: "Are you sure?" }
and the failure is
1) /admin/diagnostics updates a diagnostic report
Failure/Error: click_button "Save"
Capybara::ElementNotFound:
Unable to find button "Save"
I have been trying to change the syntax in the view file so that the submit tag is instead a button. This is because i thought the problem was the use of tag rather than button. However I have not been able to do this with haml syntax successfully.

Rails has built in support for localization and internationalization. No need to roll your own.
# app/views/diagnostics/edit.haml.erb
.field
= label_tag :notes
= f.text_field "notes"
= submit_tag I18n.t('.save'), method: :put, data: { confirm: "Are you sure?" }
The translations are stored in YAML files located in config/locales.
# config/locales/en.yml
en:
diagnostics:
edit:
save: 'Save'
You can also use your translations in your specs:
it "updates a diagnostic report" do
diagnostic_info = FG.create(:diagnostic_info)
diagnostic_info.save!
visit edit_admin_diagnostic_path(diagnostic_info)
fill_in 'diagnostic_info_notes', with: "test notes"
click_button I18n.t('diagnostics.edit.save') # Note that we need full path
page.should have_content(I18n.t('diagnostics.edit.save'))
page.should have_content("test notes")
end

Related

RSpec Capybara unable to accept alert

I've got below form:
<%= form_with url: kyc_document_upload_path, multipart: true, data: { turbo_confirm: "Are you sure to upload file?" } do |f| %>
<%= f.hidden_field :document_type, value: item %>
<%= f.label :file, 'Upload', name: "upload_button" %>
<%= f.file_field :file, class: "inputfile", accept: ".pdf", onchange: 'this.form.requestSubmit()' %>
<% end %>
Now I want to test this using Capybara. So what I did was:
it 'show message' do
login_as user
visit profile_path
expect(page).not_to have_css '#Upload'
attach_file("#{Rails.root}/spec/fixtures/files/sample.pdf") do
accept_alert "Are you sure to upload file?" do
first(:label, 'Upload').click
end
end
expect(page).not_to have_table
end
But it produces me an error:
Capybara::ModalNotFound:
Unable to find modal dialog with Are you sure to upload file?
How to accept these alert? If I remove accept_alert block to be:
it 'show message' do
login_as user
visit profile_path
expect(page).not_to have_css '#Upload'
attach_file("#{Rails.root}/spec/fixtures/files/sample.pdf") do
first(:label, 'Upload').click
end
expect(page).not_to have_table
end
I've got an error:
Selenium::WebDriver::Error::UnexpectedAlertOpenError:
unexpected alert open: {Alert text : Are you sure to upload file?}
(Session info: headless chrome=107.0.5304.87)
As mentioned in my comment, it looks like the alert is being triggered by the onchange handler of the file input. That means it wouldn't be triggered until the file selection is done, which is when attach_file returns - therefore you've likely got the accept_alert in the wrong place, and instead need
accept_alert "Are you sure to upload file?" do
attach_file("#{Rails.root}/spec/fixtures/files/sample.pdf") do
first(:label, 'Upload').click
end
end

Rails: Capybara::ElementNotFound

I'm trying to solve a challenge, but I received an error message from Cabybara saying:
`Failure/Error: fill_in 'Name', with: 'Vostro 2017'
Capybara::ElementNotFound: Unable to find visible field "Name" that is not disabled`
My new.html.erb is:
<%= form_for #item, url: {action: "create"} do |f|%>
<%= f.label 'Name' %>
<%= f.text_field :name %>
<%= f.label 'Description' %>
<%= f.text_field :description %>
<%= f.label 'Features' %>
<%= f.text_field :features %>
<%= f.label 'Asset number' %>
<%= f.text_field :assetNumber %>
<%= f.submit%>
<% end %>
And my item_controller.rb is:
class ItemController < ApplicationController
def show
#items = Item.find(params[:id])
end
def new
#item = Item.new
end
def create
#item = Item.new(item_params)
#item.save
redirect_to #item
end
private
def item_params
params.require(:item).permit(:name, :description, :features, :assetNumber)
end
end
The rspec file that is being used to do the test is:
require 'rails_helper'
feature 'User creates a new inventory item' do
scenario 'successfully' do
visit new_item_path
fill_in 'Name', with: 'Vostro 2017'
fill_in 'Description', with: 'Dell Notebook'
fill_in 'Features', with: '16gb, 1Tb, 15.6"'
fill_in 'Asset number', with: '392 DLL'
click_button 'Create Item'
expect(page).to have_content 'Vostro 2017'
expect(page).to have_content 'Dell Notebook'
expect(page).to have_content '16gb, 1Tb, 15.6"'
expect(page).to have_content '392 DLL'
end
end
I'm using ruby-2.3.5 and rails 4.1.0.
I'm beginner in ruby/rails and I can't figure out what's wrong with my code.
Could somebody help me to solve that?
I appreciate in advance.
You could do this, assuming your input has an id of name:
find("input[id$='name']").set "Vostro 2017"
or:
find("#name").set "Vostro 2017"
You might also try lower-casing Name:
fill_in 'name', with: "Vostro 2017"
Capybara will target the name or the id attribute, so the second example should work.
Rails generates form input names with using form object.
fill_in 'item[name]', with: "Vostro 2017"
fill_in 'item[description]', with: 'Dell Notebook'
fill_in 'item[features]', with: '16gb, 1Tb, 15.6"'
fill_in 'item[assetNumber]', with: '392 DLL'
If you look at the actual HTML of the page instead of the erb template (always better to include the HTML unless your question is specifically about the erb) you'll notice your labels aren't actually associated with the input elements (no matching for attribute to the id of the input). Obviously for Capybara to find the element by label text ('Name' in your case) the label would have to be correctly associated with the element. To fix that you need to use f.label - http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label - correctly. If you want to specify the text of the element (vs using text extracted from i18n translation) that would be
f.label :name, 'Name'
I realized what I was doing wrong, so let's go:
I changed the instance variable items inside def show action to item (not pluralized) and I changed an atribute from assetNumber to asset_number, so this way the Cabybara test could understand correctly.
Thanks guys.

Capybara::ElementNotFound: Unable to find field "title"

I could not resolve this issue. Please help me. It gives me element not found error.
spec/features/todos/create_spec.rb
require 'spec_helper'
describe "Creating todos" do
let(:user) { FactoryGirl.create(:user)}
before(:each) do
visit root_path
click_link "Login"
fill_in "Email", with: "user#gmail.com"
fill_in "Password", with: "password"
click_button "Sign in"
end
it "redirects to the todos index page" do
visit "/todos"
fill_in "title", with: "MyString"
click_button "Create"
expect(page).to have_title("MyString")
end
my view code.
_new_form.html.erb
<%= form_for current_user.todos.new, remote:true do |f| %>
<div class="input-group">
<%= f.text_field :title, class: "form-control", placeholder: "title" %>
<span class="input-group-btn">
<%= f.submit "Create", class: "btn btn-success" %>
</span>
</div>
<% end %>
spec_helper.rb
def sign_in
#user = FactoryGirl.create(:user)
controller.stub(:authenticate_user!).and_return(true)
#user
end
If you have the code running on a server locally, inspect the element and the name of the field is what Capybara needs to run. Generally, if the form is nested, the name rails will come up with (in this case) is something like todos[title].
So, spec/features/todos/create_spec.rb should look something like:
require 'spec_helper'
...
it "redirects to the todos index page" do
visit "/todos"
fill_in "todos[title]", with: "MyString"
click_button "Create"
expect(page).to have_title("MyString")
end
Found my answer.
In the view file I've a text_field with title with an id. The id = todo_title in the console
But am calling title in the test . Here the capybara not been able to find title. It was todo_title
After using
fill_in "todo_title"
It worked like charm.
In your form, there must be an element with the name as "title". From the docs:
fill_in(locator, options = {}) ⇒ Object
Locate a text field or text area and fill it in with the given text The field can be found via its name, id or label text.

testing cloudinary direct image upload with capybara rspec

I'm trying to test cloudinary direct uploading through capybara but capybara is saying that it cannot find the image upload field. How do you test direct uploading?
picture_spec.rb
require 'spec_helper'
feature "User Pictures" do
let(:user) { create(:user) }
describe "Uploading an image" do
describe "for profile photo" do
it "raises an error when clicked outside cropping image so image is not cropped" do
visit new_user_picture_path(user)
attach_file('#photo upload', "#{Rails.root}/spec/support/images/PRATIQUE_BIG.png")
click_on "Valider Photo"
expect(page).to have_content "SVP crop votre image et celle-ci doit mesurer au moins 100 x 100px"
end
end
end
end
new picture page
= form_for(#photo, :url => url, role: "form") do |f|
.form_line.form-group
.upload_button_holder
= link_to "Parcourir", "#", class: "btn btn-default upload_button form-control"
#photo-upload= f.cl_image_upload :image, class: "form-control"
%span.status
.form-group
.form_control
.preview
= f.hidden_field :crop_x
= f.hidden_field :crop_y
= f.hidden_field :crop_w
= f.hidden_field :crop_h
.form-group
= f.submit "Valider Photo", class: "btn btn-lg btn-success"
= hidden_field_tag :direct, params[:direct]
%p= link_to "Retour à Mon Profil", profile_path(current_user.user_code)
// Configure Cloudinary jQuery plugin
= cloudinary_js_config
Capybara then gives back Unable to find file field "photo-upload"
The name of the field in case of cl_image_upload is always file. photo-update is the id of the surrounding div. You can assign an id to the file input field by passing html: {id: "my-id"} to cl_image_upload. BTW. class also belongs inside the html hash parameter.

Element not found in Capybara

I keep getting this error:
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Morning' found.
I've reset spork, done a full db reset, tried assigning an ID to the form element, etc. What could possibly be the issue here?
days_controller_spec.rb
require 'spec_helper'
describe DaysController do
describe "New" do
describe "with valid information" do
it "should create a new entry" do
visit 'days#new'
fill_in "Morning", with: "Test"
click_button "Submit"
end
end
end
end
days_controller.rb
<%= form_for #day do |f| %>
<%= f.label :morning %>
<%= f.text_field :morning %>
<%= f.button :submit %>
<% end %>
Looks like you app is using JavaScript. With capybara you need to add :js => true option to the block that's dealing with JS pages.
Try:
it "should create a new entry", :js => true do
You may also need to way for the form to be rendered before trying to fill_in the field.
Also, I recommend you check out capybara's integration DSL. Read more about it here
Turns out that syntax was all correct, but the issue was that the test was in the wrong RSpec spec file. When I swapped this test into an integration_test file, it worked perfectly.

Resources