Rails + Minitest + Capybara: how to assert_select with span id - ruby-on-rails-5

in my view i have:
<span class = "info">
<span id="<%= account.id %>" data-account_id="<%= account.id %>" data-activated="<%= account.starts_at? %>">
<%= t(".account_activated") %>
</span>
</span>
What is the best way to test (system test with use of capybara) if there is "account has been activated" text displayed inside ?
I tried:
assert_selector "span##{acount.id}", text: "account has been activated"
but get Selenium::WebDriver::Error::InvalidSelectorError: invalid selector: An invalid or illegal selector was specified

In HTML5 the definitions were changed to allow ids to start with numbers, but CSS requires leading numbers to be escaped correctly (#\31 234 would match an id of '1234'). Because of this if you need to match an element by CSS with an id that may start with a number it's best to use the id option (supported by all Capybara selectors) and let Capybara merge it into the CSS
assert_selector "span", id: account.id, text: "account has been activated"
which will correctly escape and apply it to the CSS. If you just want to specify the id and not the element type(since the id should be unique on the page) you can use the :id selector type (rather than the default CSS selector type)
assert_selector :id, account.id, text: "account has been activated"

I've solved this issue.
This is because ID's should not begin with numbers (see here)
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be
followed by any number of letters, digits ([0-9]), hyphens ("-"),
underscores ("_"), colons (":"), and periods (".").
View code should be changed as follows:
<span class = "info">
<span id="**account_**<%= account.id %>" data-account_id="<%= account.id %>" data-activated="<%= account.starts_at? %>">
<%= t(".account_activated") %>
</span>
</span>
and
assert_selector "#account_#{account.id}", text: "account has been activated"

Related

ejs, how to add dynamic attributes of html tag?

I use express.js + ejs, I have two cases:
1.
prev
But it give me an error: Could not find matching close tag for "<%="./nundefined/nError: Could not find matching close tag for "<%=".
I want to get
prevDisabledClass ? <a href=''>prev</a> : <a href='?page=<%=+page - 1%>'>prev</a>
2.
like above, but dynamic add href attribute to html tag <a>
I want to get this:
prevDisabledClass ? <a>prev</a> : <a href='?page=<%=+page - 1%>'>prev</a>
How can I solve these two problem?
For the first one you currently have this:
prev
You can't nest <%=, try this instead:
prev
For the second one it'd be almost exactly the same but you'd move the condition around more of the output:
<a<%- prevDisabledClass ? '' : (' href="?page=' + (page - 1) + '"') %>>prev</a>
Here I've used <%- instead of <%= to ensure the " doesn't get HTML encoded.
It might be clearer to ditch the ?: altogether:
<% if (prevDisabledClass) { %>
<a>prev</a>
<% } else { %>
prev
<% } %>
There's some duplication but it's much easier to read.

rails3 content_tag with static attributes

The following is being properly generated into HTML code
<%= content_tag(:span, (t 'hints.h'), :class => "has-tip", :title => (t 'hints.s') ) %>
But I am trying to generate
<span data-tooltip aria-haspopup="true" class="has-tip" title="title bla bla">translated h</span>
and have found no way to generate these span attributes data-tooltip aria-haspopup="true" They cannot be part of the options hash given one has only a name... and the second one has a dash which impedes from defining it as a symbol :aria-haspopup
I suggest that you use the following:
content_tag(:span, t('hints.h'), :class => 'has-tip', :title => t('hints.s'), :'aria-haspopup' => true, :'data-tooltip' => '')
Note that you can use the dash character in symbols if you enclose them in quotes.
The data attribute you could also specify as nested hash like :data => {:tooltip => ''} instead of :'data-tooltip' => '', use whatever you prefer.
As for the boolean attribute data-tooltip, setting the value to an empty string is as good as omitting it (and your best option with Rails 3 ;)). See also:
http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-attributes

datepicker jquery ui and rails 3(.1)

Hi i am using the date picker jquery ui in combination with rails 3.1. The date picker looks brilliant, only the date isn't stored in the database? Only sometimes...? So that's a difficult error.
This is my .js file:
$(function() {
$("#question_deadline").datepicker({ duration: 'fast', maxDate: '+2m', minDate: 'now', showOn: "button", buttonImage: "calendar.gif", buttonImageOnly: true });
$("#question_deadline").datepicker("option", "showAnim", "drop");
$("#question_deadline").datepicker("option", "dateFormat", "DD, d MM, yy");
});
In my controller there's just plain rails script:
def create
#question = Question.new(params[:question])
if #question.save
redirect_to questions_path, :notice => "Successfully created question."
else
setup_questions
render :index
end
end
In views file _form.html.erb i use a text_field to display the date:
<div class="field">
<%= f.label :content, "Question" %><br />
<%= f.text_field :content, :placeholder => "type your question here.." %>
<%= f.text_field :deadline %><br />
</div>
Are there people who have experience with datepiacker jquery ui and rails, the ryan bates episode, didn't solve it, i think that was written in rails 2.3?
Regards,
Thijs
First, you need to show us the view where you have the datepicker element. If it's like this:
<input type="text" name="question_deadline" id="question_deadline" />
When you submit this form, the parameters you receive in your controller (in the method "create") is called question_deadline. So in that create method you should first write:
if params[:question_deadline] != ""
params[:question][:question_deadline] = params[:question_deadline]
end
#add a else if this date field is compulsory in the database
This step is important because the create method will read stuff from params[:question][:question_deadline] not from params[:question_deadline] which is returned from the view.
Thus params[:question][:question_deadline] is empty when you do #question.save
To display the date, you also need to show us the controller "show" method that should be something like:
#question = Question.find(params[:id]) #or any sql request that returns info about a question.
Then in the view you can retrieve it simply with:
<%= #question.question_deadline%>
Maybe with more code from you controller and view I can elaborate on that.
I think, Rails/Ruby is not able to parse a date in this format:
$("#question_deadline").datepicker("option", "dateFormat", "DD, d MM, yy");
// full day name, day (w/o leading zero), full month name, 4-digit year
In your controller, you might want to add a line such as
def create/update
...
#question.deadline = DateTime.strptime(params[:question][:deadline], '%A, %d %B, %Y')
# assuming my jquery-to-ruby format-mapping is adequate ;-)
if #question.save
...
end
Beware, that this code easily breaks on malformed date strings.
If you don't want to change the format to, e.g. 'yy-mm-dd' (in Ruby-land it's '%Y-%m-%d'), you may want to populate the selected date to another HTML element using the altField option and hide the actual datepicker input field via CSS:
$("#somewhere_else").datepicker(
dateFormat: "%yy-%mm-%dd",
altField: "#question_deadline",
altFormat: "DD, d MM, yy",
...
);
<%= form_for #question do |f| %>
...
<%= text_field_tag 'somewhere_else', #question.deadline %>
<%= f.hidden_field :deadline %>
...
<% end %>
That'll work, at least for me :-)
—Dominik
The other option is to update the way ActiveSupport parses dates. This is outlined in Default Date Format in Rails (Need it to be ddmmyyyy)

Giving 'TemplateError' can't convert String into Integer

I recently transfered my app from Rails2 to Rails3.
The code in 'app/views/distribution/index.html.erb' is like :-
<div style="padding-bottom:10px; padding-left:0px;float:left;display:<%= (!session[:album][#artist.id.to_s].empty? && !session[:album][#artist.id.to_s].nil?)?'block' : 'none' %>" id = "make_payment_enabled">
<%= link_to 'Make Payments',{:action => 'pay', :album=>#album.id}, :class => "button" %>
</div>
It's giving me TemplateError on line :-
<div style="padding-bottom:10px; padding-left:0px;float:left;display:<%= (!session[:album][#artist.id.to_s].empty? && !session[:album][#artist.id.to_s].nil?)?'block' : 'none' %>" id = "make_payment_enabled">
How to resolve the problem ?
Solution 1: In the ERB tag, try putting spaces around the 'or' question mark, i.e. ....nil?) ? 'block....
Solution Better: Do step one, then put that code in a helper. Will really help to clean up your views.
UPDATE:
A few other tips: you will want to switch the order of the conditions, because you will want to see if the value is nil before checking if it's an empty string.
Calling obj.blank? is the equivalent of calling obj.nil? && obj.empty?, so that could make the code a bit shorter. Even better, obj.present? is the same as !obj.blank?.
Therefore, that line could be simplified to:
session[:album][#artist.id.to_s].present? ? 'block' : 'none'
Happy Rails-ing!

Rails 3 - select_tag helper - Blank option tag

I have a select_tag populated from a #users array that I'm using to perform searches. When the user first lands on the page, I'd like it to display a blank or custom tag, rather than the first item in the array?
Is this an option using the select_tag helper? To insert a blank "" option?
My helper so far:
<%= select_tag :search_user, options_from_collection_for_select(#users, "id", "name"), :class => 'submittable'%>
You can use the option :include_blank => true as documented here.
I think the right way is
:prompt=>"your text"
So, rather than using the options_from_collections_for_select method, I was able to insert an item into my array using the options_for_select. Compared to my above code, I inserted "everyone" in the below snippet.
<%= select_tag :search_user, options_for_select(#users.collect{ |user| [user.name, user.id] }.insert(0,"Everyone")), :class => 'submittable'%>
Ruby on Rails 4.0.4 ActionView::Helpers::FormOptionsHelper
:prompt - set to true or a prompt string. When the select element
doesn't have a value yet, this prepends an option with a generic
prompt – “Please select” – or the given prompt string.
select(“post”, “person_id”, Person.all.collect {|p| [ p.name, p.id ] }, {prompt: 'Select Person'})
could become:
<select name="post[person_id]">
<option value="">Select Person</option>
<option value="1">David</option>
<option value="2">Sam</option>
<option value="3">Tobias</option>
</select>