Capybara: Filled-in forms and save_and_open_page - ruby-on-rails

When I fill forms using capybara and page opens in browser, the fields are empty. Is it normal?
page.fill_in 'Email', :with => 'test#gmail.com'
save_and_open_page

It seems that filling stuff into a text field doesn't make it part of the DOM (specifically, the value attribute of the <input> element), so it won't show up in the page you get.
So yes, it looks like this is normal indeed.

Related

Capybara: fill_in: unable to find field

Code: https://github.com/jmopr/job-hunter/blob/master/scraper.rb
So i'm running a scraper on indeed.com but it seems to be unable to find the field q, which is the first field on the left. I'm 100% certain that the code is correct but i'm not sure why it isn't able to view the form. save_and_open_page CONFIRMS that it was able to view indeed.com successfully... yet is unable to locate the form.
Code:
def perform_search
# For indeed0
save_and_open_page
fill_in 'q', :with => #skillset
fill_in 'l', :with => #region
find('#fj').click
sleep(1)
end
Indeed.com HTML:
<input class="input_text" maxlength="512" size="31" aria-labelledby="what_label_top hidden_colon what_label_bot" name="q" autocomplete="off" id="what">
Required portions/redirects of the page are loaded from 'indeed.com' rather than 'www.indeed.com' - Change your capybara-webkit configuration to allow indeed.com.
Additionally, if you want to know what the driver is actually seeing, you're generally better off using save_and_open_screenshot rather that save_and_open_page (The latter will show you the html structure but not how capybara-webkit has rendered it)

How do I confirm a css element attribute with Capybara?

This may seem unusually basic but how do I confirm the presence of a pop up confirmation?
<a data-confirm="delete this video?" rel="nofollow" data-method="delete" href="/videos/21">Delete</a>
<a is the "tag"/"element" and data-confirm is an attribute. I want to test for the existence of the "data-confirm" attribute within the <a> element/tag
I have tried
expect(page).to have_css("a.data-confirm.delete this video?")
from
capybara assert attributes of an element
but no joy.
Edit:
I've tried the expectation from Arup's comment below
expect(page).to have_content "Content"
click_link "Delete"
expect(page).to have_css('a[data-confirm="delete this video?"]')
But it raises the following (same) error
Failures:
1) Visiting the video index page should search and save movies
Failure/Error: expect(page).to have_css('a[data-confirm="delete this video?"]')
expected #has_css?("a[data-confirm=\"delete this video?\"]") to return true, got false
but the page source shows it there and it is clearly working for the user
Any assistance would be very appreciated
You can write this expectation as:
expect(page).to have_css('a[data-confirm="delete this video?"]')
The answer by Arup is correct for the title of the question (and as he stated in the comments it's just valid CSS - https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors), however it's not actually testing the more detailed part of the question "how do I confirm the presence of a pop up confirmation". All it is doing is confirming the correct data attribute is on the link element to trigger the rails provided JS that should show a confirm.
If you wanted to actually test the confirm box is shown you would need to swap to using a JS capable driver - https://github.com/teamcapybara/capybara/tree/2.17_stable#drivers - and then use something like the following in your test
expect(page).to have_content "Content"
accept_confirm "delete this video?" do
click_link "Delete" # The action that will make the system modal confirm box appear
end
See - http://www.rubydoc.info/gems/capybara/Capybara/Session#accept_confirm-instance_method

Check the content of a field populated by javascript with Capybara before submit

I have a field whcih I am auto populating based on a dropdown on the page.
i.e. I select task_type and the task_name has task_type populated.
I can't work out how to test this. I basically just want to test what the current content of the field is.
Everything I try seems to be able to find the field but not check the content of it.
Then(/^"(.*?)" should contain "(.*?)"$/) do |field, text|
page.should have_field(field, :text => value)
end
I'm assuming I need to do some js trickery to get the info from the browser, but can't seem to work it out.
And I should see "Annual Accounts" in "task[name]"
Have tried task_name aswell and both fail with
find(field).should have_text(text)
With message
Unable to find css "task[name]"
if I use
page.should have_field(field, :text => text)
Then they fail with:
expected to find field "task_name" with text "Annual Accounts" but there were no matches. Also found "",
You can use the have_text helper
find(field).should have_text(text)
Right, both of these work:
Not sure what the difference between them is.
I also think this does an exact match. If anyone could let me know how to do a "contains" type match that would be really handy.
Then(/^I should see "(.*?)" in "(.*?)"$/) do |text, field|
# page.has_field?(field, :with => text)
page.should have_field(field, :with => text)
end

Capybara + Webkit: How to test client side validations - "required" input elements?

Using Rspec and Capybara, I'm trying to test a failing validation for a form, where a "required" input is not filled in, so it fails. New navigators understanding HTML5 provide built-in validations, and I understand Capybara is using that as well. Before, I was using
page.should have_error
which doesn't work for me anymore.
Someone knows how to test this now?
Many thanks!
David
HTML5 client side validations are tricky to find. I found this post with a great answer.
The code is:
describe "when I leave required field empty" do
it "I get an the correct html5 validation error" do
#Leave the field empty
click_on "Save" # or whichever button triggers the submit
message = page.find("#field_id_attr").native.attribute("validationMessage")
expect(message).to eq "Please fill out this field."
end
end
Basically the way it works is that the field element has an attribute called "validationMessage" and the process is:
Click submit - this triggers the error message
Get a reference to the native(html) attribute(as opposed to the Capybara page object attribute) called "validationMessage". This will give you the value or the message itself.
Assert that the value is as expected.
I am not familiar with RSpec so I am not sure about what does have_error.
You should think about what you want to test exactly.
You surely don't want to test the exact behavior (what message is displayed, and how) as it is specific to each browser. What you want to test, because this is not specific to the browser, is the fact that the form is not submitted.
For instance, for a basic html form at root, with a required radio button "My value".
# Check form can not be submitted without the radio button
visit '/'
click_button 'Submit'
assert_equal '/', current_path
# Check form can be submitted with the radio button
visit '/'
choose 'My value'
click_button 'Submit'
assert_equal '/next', current_path
You should also consider to test only the presence of required in your html code, as the browser is supposed to work as expected (test only your code, not other's code)
If there is an error message, you can something along the lines of
page.should have_content("error")
This depends on how you handle the errors, and whether you use javascript or not.
This is an old post, however I will try to answer it
have_error is a method provided by webkit, to check e.g. if ajax requests or javascript in general running fine
I use to test my validations in my model specs:
describe 'validations' do
it { is_expected.to validate_presence_of :competitor_name }
it { is_expected.to validate_presence_of :chassi }
it { is_expected.to validate_presence_of :auction }
it { is_expected.to validate_presence_of :car_template_id }
end
or like
expect(FactoryGirl.create(:customer)).to be_valid
to check if my Factory is valid.
If you need to check your notices by targeting invalid inputs, you could test the html of your notice by capybara with the following:
it 'searches for specific order_car by chassi and model' do
visit order_cars_search_detailed_path
fill_in 'order_car_chassi', with: '123456'
select 'Octavia', from: 'order_car_car_template_car_template_id'
click_button 'Search Order'
expect(page).to have_content('THIS IS MY NOTICE')
expect(page).to have_content('123456')
end
Hope I could help some others running into this question.

Finding a label with Webrat that contains a link

So I'm doing BDD with Cucumber and have a form with checkboxes populated from a database. The labels for the checkboxes contain hyperlinks. So far, not too exotic (note, this is HAML and not Erb, but it should be readable enough for any Rails person):
I would like my donation to support:
%br
- for podcast in #podcasts
= check_box_tag "donation[podcast_ids][]", podcast.id, true
= donation.label "donation[podcast_ids][]", link_to(podcast.name, podcast.url), :value => podcast.id
%br
The problem is that in my Cucumber features, I can't figure out how to find that checkbox to check it. The relevant part of the story is this:
Scenario: Happy path
Given I am on the home page
When I fill in "My email address" with "john#example.org"
# Skipped for brevity...
And I check the "Escape Pod" podcast
And I check the "PodCastle" podcast
And I press "I'm ready!"
Then I should see "Thank you!"
And there should be 2 podcast donation records
If I'm using the bare webrat_steps.rb file I get the following error:
Could not find field: "Escape Pod" (Webrat::NotFoundError)
I'm quite certain it's because of that link_to() method, which I'm using to make "Escape Pod" a hyperlink to the actual Web site. But I can't easily access link_to from my Cucumber step, and I can't figure out any reasonable way of pointing Webrat at the right checkbox short of kludging up a whole bunch of hyperlink code in my step (which makes it very brittle).
My BDD is stalled at this point. I don't want to take out the link just because it's hard to test. And it feels like it shouldn't be hard to test. Webrat is just limiting what I can pass into the checks() method. Can anyone suggest an elegant answer for this?
The short answer is the to use field_by_xpath or one of the other Webrat::Locators methods to select what element to manipulate in your step:
When(/^I check the "(.+?)" podcast$/) do |name|
check(field_by_xpath("//label/a[.=#{name}]")
end
You might need to play with that xpath a little, or use field_by_id instead. Remember it is looking got the html id of the tag not the id from the database.
Can you post what your HTML looks like in the rendered page near the problematic checkbox(es)? Sometimes you have to play with naming the field... I had all sorts of trouble with a login form... I ended up doing this:
<%= submit_tag 'Enter', {:id => "login_button"} %>
So that the following worked:
Given /^I am logged in as admin$/ do
visit login_path
fill_in "login", :with => "admin"
fill_in "password", :with => "password"
# click_button "login_button"
click_button
end
I know it's not a checkbox example, but maybe fiddling with your name/id/etc will work

Resources