I'd asked a question about this date field a few days ago but was able to test against the ID though the text label of the field was not being found even though the source clearly shows it.
Now I'm testing the actual value of the date. My test is simple:
assert page.has_content?("2015-02-26"), "Content - 2015-02-26 not available."
Here's the source of the page loaded in the browser:
<div class="form-group date required visit_date_of_visit">
<label class="date required control-label" for="visit_date_of_visit_1i">
<abbr title="required">*</abbr> Date of visit</label>
<input class="date required form-control" value="2015-02-26" type="date" name="visit[date_of_visit]" id="visit_date_of_visit" /></div>
As you see, the value is there.
Now, this is the source. In the actual browser this is 02/26/2015 as I have it formatted that way and the actual code works. Even though it shows this as the value, the code itself shows something else. But the test does not find this OR that.
Any ideas?
Why don't be more specific? and instead searching in all page content just search for fields:
page.has_field?('name_of_filed', :with => 'filed_value')
In your case
page.has_field?('visit[date_of_visit]', :type => 'date', :with => '2015-02-26')
For more options visit Capybara documentation
Related
Sorry for my English.
I need to change input value format, for example: from "1000000" to "1 000 000 $".
In my views of rails app, I have this line of code:
<%= ng_text_field('total_price', 'selected.data.total_price', 'Full price', ng_readonly: '!selected.permissions.update') %>
In helper:
def ng_text_field(name, ng_model, placeholder, options = {})
result = <<-HTML
<div class="form-group" ng-class='{"has-error":errors.#{name}}' #{options[:ng_if] && "ng-if=\"#{options[:ng_if]}\""}>
<label for="#{name}" class="col-sm-3 control-label">#{placeholder}</label>
<div class="col-sm-9">
<input id="#{name}"
type="text"
class="form-control"
name="#{name}"
placeholder="#{placeholder}"
ng-model="#{ng_model}"
#{options[:ng_readonly] && "ng-readonly=\"#{options[:ng_readonly]}\""}>
<p class="help-block small" ng-if="errors.#{name}">{{errors.#{name} | join:',' }}</p>
</div>
</div>
HTML
result.html_safe
end
I am know Angular very little, I have tried some ways and all this ways was incorrect. :(
Could anyone give advice of some help?
Thank you in advance
You're going to need to create a new directive that requires ngModel and applies the appropriate $parser/$formatter to it.
https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$parsers
A good example of how to do this is (displaying as uppercase but always storing data as lowercase):
ngModel Formatters and Parsers
You should be able to then add the ability to include other directives in your 'options' argument so that they get added correctly to the output.
I'm using a cucumber/ruby/capybara/siteprism framework and I'm having problems identifying elements as either we're missing the ids, names, etc or they create them with a in real time.
I was mainly trying to define some of those elements in a siteprism page object model. For example, I was trying to enter some data in the 'input' field for 'First Name' below:
<div class="control-group">
<label class="control-label" for="input_field_dec_<random_number>">
First Name
<span class="required"></span>
</label>
<div class="controls">
<input id="input_field_dec_<random_number>" class=" span5" type="text" value="" scripttofire="SetUserFirstName('input_field_dec_<random_number>')" required="required" name="input_field_dec_<random_number>" data-val-required="First Name is required" data-val-regex-pattern="^[a-zA-Z0-9_ \-\']*$" data-val-regex="Only alphabetic and numeric characters allowed" data-val="true">
<span class="field-validation-valid help-inline" data-valmsg-for="input_field_dec_<random_number>" data-valmsg-replace="true"></span>
</div>
</div>
Is there a way to pass the label text (eg: 'First Name' - ignoring the spaces around, something like - contains='First Name') and then find the input element inside to set it up?
I was thinking something along the lines of:
element :first_name_field, :xpath, "//label[contains(text()='Continue'])/<and here something to find the input field?>" but cannot figure it out...
Capybara provides a bunch of built-in "selectors" that can be used for this, and you can add your own if you find it necessary. You can see the provided selectors by either building the Capybara docs yourself (rubydocs doesn't run the custom yard code used to generate that part of the docs) or by browsing the file where they are implemented - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L47
For your original example you can use the :field selector
element :first_name_field, :field, 'First Name'
which will match on the inputs associated label text. For you second example (from the comments) where the input and label have no connection (wrapped or for attribute) you should be able to do something like
element :some_field, :xpath, ".//label[contains(normalize-space(string(.)), 'label text')]/following-sibling::*[1]/self::input"
If you wanted to make that reusable you could add your own "selector" like
Capybara.add_selector(:sibling_input) do
label "Label adjacent sibling input"
xpath do |locator|
XPath.descendant(:label)[XPath.string.n.is(locator)].next_sibling(:input)
end
end
which could then be used as
element :some_field, :sibling_input, 'label text'
My HTML/ERB looks like this
<fieldset class="row notifications">
<legend>
<hr class="dash blue inline">
<%= t :my_notifications %>
</legend>
<label>
<%= f.check_box(:subscribed_to_news) %>
<span></span>
<span class="checkbox-text"><%= t :accepts_to_receive_news %></span>
<br>
</label>
</fieldset>
When I debug my Cucumber test with Capybara, I do find the notification checkbox f.check_box(:subscribed_to_news) in this mess
page.find('.notifications label')['innerHTML']
# => "\n\t\t<input name=\"user[subscribed_to_news]\" type=\"hidden\" value=\"0\"><input type=\"checkbox\" value=\"1\" checked=\"checked\" name=\"user[subscribed_to_news]\" id=\"user_subscribed_to_news\">\n\t\t<span></span>\n\t\t<span class=\"checkbox-text\">blahblahblah</span>\n\t\t<br>\n\t"
But for some reason I cannot find the nested inputs nor find them by ID
page.find('.notifications label input')
# => Capybara::ElementNotFound Exception: Unable to find css ".notifications label input"
page.find('.notifications label #user_subscribed_to_news') # => Capybara::ElementNotFound Exception: Unable to find css ".notifications label #user_subscribed_to_news"
Selecting the label does work though
page.find('.notifications label')
# => #<Capybara::Node::Element tag="label" path="//HTML[1]/BODY[1]/DIV[1]/MAIN[1]/SECTION[1]/FORM[1]/FIELDSET[3]/LABEL[1]">
What am I doing wrong ? I just want to check the damn checkbox :'(
Most likely reason is the checkbox is actually hidden by CSS and then replaced with images to enable identical styling of checkboxes across different browsers. If you're using the latest Capybara you can have it click it the label when the checkbox is hidden by calling
page.check('user_subscribed_to_news', allow_label_click: true) # you can also set Capybara.automatic_label_click = true to default to this behavior
or if using an older capybara you would need to click the label yourself
page.find(:label, "blahblahblah").click #match on labels text
or
page.find(:label, for: 'user_subscribed_to_news').click #match on labels for attribute if set
It would seem that the checkbox is unreachable via normal css /xpath...
I got away using some javascript
page.execute_script(%Q{document.querySelector('#{area} input##{selector}').click()})
I have a search form which I return to after searching, to be able to refine the search. I just added a checkbox to that form.
In the view:
<%= f.input :available_tomorrow, as: :boolean, label: false,
inline_label: t('public.search.form.available_tomorrow.label'),
input_html: { name: :available_tomorrow, value: params[:available_tomorrow],
id: :available_tomorrow } %>
In the model:
attr_reader :available_tomorrow
HTLM produced:
<div class="form-group boolean optional search_available_tomorrow">
<input name="available_tomorrow" type="hidden" value="0">
<label class="checkbox">
<input class="boolean optional" id="available_tomorrow" name="available_tomorrow" type="checkbox" value="1">
Available tomorrow
</label>
</div>
When I check the box, all search parameters appear fine in the url querystring but that one:
&available_tomorrow=0&available_tomorrow=1
Looks like the value property of both field is sent, and neither changes. If I uncheck the box, I only get &available_tomorrow=0 in the querystring. The second part is only added if the checkbox is checked.
Everything works as intended (the search does return the right results depending on the checkbox state, the checkbox is in the right state when the search form is updated). But that querystring is ugly with both available_tomorrow parameters, looks like the first one should never appear. Ideas?
This is normal behavior for a form with a checkbox when you POST the form: If the checkbox is not checked, only the hidden field with value 0 is sent with the formdata. If the checkbox is checked, the input with the value 1 is also sent.
The hidden field for the checkbox is always sent, this is because otherwise no value for the checkbox would be sent.
Long story short: don't mind the querystring in your search url, nobody will ever look at them. :)
my login page( build with simple form) add by default html attributes for browser validation on email input that chrome doesn't recognize and show "Please match the requested format."
Maybe is Chrome bug(on firefox works), so have tried to disable browser validation with simple form config
SimpleForm.html5 and SimpleForm.browser_validations(false by default), restarted rails but remain the same input:
<input autofocus="autofocus" class="string email optional form-control
input-xlarge" id="customer_email" maxlength="255"
name="customer[email]" pattern="\A[^#\s]+#([^#\s]+\.)+[^#\s]+\z"
size="255" type="email">
have tried also to add on form html: {novalidate: true}, same output
finally have tried to add on input_filed :novalidate => true, the html output change to:
<input autofocus="autofocus" class="string email optional form-control
input-xlarge" id="customer_email" maxlength="255"
name="customer[email]" pattern="\A[^#\s]+#([^#\s]+\.)+[^#\s]+\z"
size="255" type="email" novalidate="novalidate">
but browser validation and chrome error is present.
Any idea to resolve?
PS: Use Bootstrap and the login form is from Devise resource.
You can remove the pattern attribute from the input element that is causing a problem. You just need to set pattern: false on the input field.
So your input field might look something like this:
<%= f.input_field :email, type: 'email', required: true, autofocus: true, class: 'form-control', pattern: false %>
(nil doesn't work; it has to be false.)
This worked for me in Rails 4.