cucumber/webrat: how to test if a submit button is not disabled - capybara

Just starting to use cucumber with webrat. I have these feature steps:
When /^I choose a DVD$/ do
#just click the first one we see
check("optional-dvds[]")
end
Then /^I should be able to place my order$/ do
#the place my order button should be clickable
end
The button in question has this html:
<input disabled="disabled" id="submit_button" name="commit" type="submit" value="Please send this DVD">
and, when the user clicks on a dvd, some js runs and removes the disabled attribute from the button. So, the second step needs to check that it doesn't have an attribute "disabled" after doing the previous step. How do i test this? I can think of one way, of using xpath and checking that a disabled commit button doesn't exist on the page, but i'd rather do something more explicit (actually, more jquery-esqu) along the lines of (pseudocode)
$("#submit_button").attr("disabled").should be_false
or something along these lines. I know this is a horrible mashup of jquery and rspec btw :)

Try this one
page.should have_no_xpath "//input[#id='submit_button' and #disabled]"
or this one
page.should have_no_selector "#submit_button", :disabled => 'disabled'

Related

Ruby, Cucumber, & Capybara: selecting using regex

I am trying to select an input node using Capybara:
When /^the shopper clicks the "(.+)" button$/ do |button|
first(:css, text: /^#{button}/).click
end
The scenario that triggers the above step is:
And the shopper clicks the "PAY" button
The button in the view will always start with the text 'PAY' but it is followed by a space and then the total price of the products e.g. 'PAY $150'
The dollar amount will change but the PAY part won't. If I try the above code I get the following error:
And the shopper clicks the "PAY" button # features/step_definitions/shared_steps.rb:33
unexpected '$' after '' (Nokogiri::CSS::SyntaxError)
How can I properly grab the PAY button using Capybara and Regex?
The problem you're having is that you have specified a css selector type but not actually specified a CSS selector. Since it's an <input> element you could do
find(:css, 'input', text: /^#{button}/).click
However, since it's an input being used as a button I'm assuming it's of type submit, reset, image, or button. This means you can use the :button selector type (rather than :css) to make your clearer as to what you're actually doing. When finding a button Capybaras default behavior is to match on substrings so you should just be able to do
click_button(button)
which is the same as either of
find(:button, button).click
find_button(button).click
If that doesn't work for you please add the relevant HTML to your question.
As an aside, you should stay away from first whenever possible - it has a number of downsides.

Capybara (poltergeist) cannot find checkbox in form

I cannot get Capybara for find a checkbox element.
I've tried all the usual ways:
find_field
check
find
click_on
It's as if the element isn't there. If I select the parent element, and look at it's innerHTML the checkbox is included:
(byebug) all(:css, '.checkbox.form-group').last['innerHTML']
\n <input type=\"checkbox\" id=\"google_agreed_to_terms_at\" value=\"1\" required=\"true\" ng-model=\"agreed_to_terms\" required-notification=\"Please agree to the terms and conditions\" class=\"ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required\" bs-validation=\"\">\
but selecting the child elements it's not there:
(byebug) all(:css, '.checkbox.form-group').last.all :xpath, './*'
[#<Capybara::Node::Element tag="label"
path="//HTML[1]/BODY[1]/DIV[2]/DIV[1]/DIV[2]/FORM[1]/DIV[1]/LABEL[1]">]
I feel like I'm going mad.
Here's the relevant code (copied from save_and_open_page)
<div class="checkbox form-group">
<input type="checkbox" id="agreed_to_terms_at" value="1" required="true" ng-model="agreed_to_terms" required-notification="Please agree to the terms and conditions" class="ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required" bs-validation="">
<label class="label-light" for="agreed_to_terms_at">
I have read and agree to the terms</label>
</div>
I thought maybe rails was generating slightly non-compliant HTML, so I've gone to writing the checkbox by hand, but it didn't help.
What's going on here?
The checkbox is hidden to allow for uniform styling across all browsers. Since you have a label element correctly associated you can tell check to click the label instead of the actual checkbox
check('agreed_to_terms_at', allow_label_click: true)
which will click the checkbox if visible and if not it will click the label. If you want it to only click the label you can do
find(:label, 'I have read and agree').click
Or
find(:label, for:'agreed_to_terms_at').click
Due to CSS styling, the checkbox element was being hidden and the label used to present it. So the element was getting skipped over by capybara's default behaviour to ignore hidden elements.
I worked around it using
find('#agreed_to_terms_at', :visible => false).trigger('click')

How to test file attachment on hidden input using capybara?

I have hidden input inside of label:
<label for="upload">
<input class="hidden" type="file" name="file[picture]">
</label>
When I click on the label, I attach a file and then confirm.
After that modal window pops up and I need to find appropriate div class.
How can I test this with the help of capybara?
Update: Capybara 2.12 added a make_visible option to attach_file so if using 2.12+ you can first try
attach_file('file[picture]', 'path/to/file.png', make_visible: true)
before directly using execute_script yourself
File inputs are a special case since they are so often hidden for styling reasons and use a system modal for interaction. Capybara makes it hard to fill in hidden fields on a page because users generally can't interact with them, so for file inputs normal practice is to use execute_script to make them visible and then fill them in.
execute_script("$('input[name=\"file[picture]\"]').removeClass('hidden')") # assumes you have jQuery available - if not change to valid JS for your environment
attach_file('file[picture]', 'path/to/file.png') # takes id, name or label text of field not a random selector
Using Capybara '2.7.1':
attach_file('file[picture]', 'path/to/file.png', visible: false)
You can do something along the lines of:
find('label[for=upload]').click
attach_file('input[name="file[picture]"]'), 'path/to/file.png')
within '.modal-popup' do
expect(page).to have_content '.divclass'
end

how to uncheck a check box in a Ruby form at load time

I'm using Ruby on Rails to build a form that has a checkbox ; the behavior I'm trying to achieve is the following:
the user loads the form
the user fills in the form and enables the checkbox
when "Submit" button is clicked, some actions will be executed (because the checkbox is checked)
if the user loads the form again, the checkbox will be unchecked, so no actions are executed
the user can fill in the form again with new values and submit them, if desired
The behavior I'm seeing is that that in step 4, the actions are executed again immediately at the time the form is loaded, and this is undesired, because these actions have already been executed in step 3. For info, the actions I'm executing are also embedded in the same partial view file than the form itself. This is probably an improper way to do it, but it works fine, as far as the execution of actions is concerned.
I tried many things and tried all combinations of checked unchecked, the only one that displayed the box as unchecked is :checked=>"unchecked", but the behavior is still not the one I'm looking after.
What is the best way to implement this scenario?
The checkbox is configured as follows:
<%= f.label "CheckToApply" %>
<%= f.check_box :CheckToApply, :id=>"CheckToApply", :name=>"CheckToApply", :checked=>"unchecked", :value=>"0" %>
and compiles to the following:
<label for="test_Check to Apply">Check to apply</label>
<input name="CheckToApply" type="hidden" value="0" /><input id="CheckToApply" name="CheckToApply" type="checkbox" value="1" />
I tried many ways, like setting the value in the partial view
if #test.CheckToApply == 1
#test.CheckToApply=0
<... more actions are added here ...>
end
I tested by printing something inside the "if end" section and it seems to execute well, but it did not work, because every time the form is loaded, the actions are executed again before the user chooses the new values.

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.

Resources