Choosing a radio button from its labels with Capybara - capybara

I have a dynamically generated form that looks like this:
Do you like Pizza?
[ ] Yes [ ] No
The HTML looks like this:
<form>
<div class="field">
<label>Do you like Pizza?</label>
<input
type="radio" value="true"
id="reply_set_replies_attrs_0_pizza_true"
name="reply_set[replies_attrs][0][pizza]">
</input>
<label for="reply_set_replies_attrs_0_pizza_true">Yes<label>
<input
type="radio" value="false"
id="reply_set_replies_attrs_0_pizza_false"
name="reply_set[replies_attrs][0][pizza]">
</input>
<label for="reply_set_replies_attrs_0_pizza_false">No<label>
</div>
</form>
I'd like to get check those radio buttons with Capybara. How can I do this? I don't always know the ids of the radio buttons, because there's a few of them and when I also ask about Popcorn and Chicken I don't want to depend on knowing their order.
Is there a way to do something like...
field = find_label("Do you like pizza?").parent('field')
yes = field.find_label('Yes')
yes.click
?

Note that when using find, the :text option does a partial text match. Therefore, you could find the div directly:
find('div.field', :text => 'Do you like Pizza?').choose('Yes')
(Also using choose makes radio button selection easier.)

not bad!
label = find('label', :text => "Do you like Pizza?")
parent = label.find(:xpath, '..')
parent.find_field("Yes").click

Related

Capybara cannot select checkbox

I feel like I have tried everything, but I cannot select a checkbox in my application.
I have two checkboxes that look like this. One with 'cheese' and one with 'pickles'. they're auto generated with Rails form_with's = form.check_box
<input name="foods[]" type="hidden" value="0" autocomplete="off">
<input class="foodCheckbox" type="checkbox" value="cheese" name="food[]" id="food_cheese">
<a target="_blank" href="MyString">cheese</a>
Now to my testing. I have tried the following:
1.
check('food_cheese')
check('#food_cheese')
find("food_cheese").click
find("#food_cheese").click
find("food_cheese", visible: false).click
find("#food_cheese", visible: false).click
find(:css, "#food_cheese").set(true)
find(:css, "#food_cheese", visible: false).execute_script('this.checked = true')
The page finds the checkboxes. I cannot click the label because it is a link. When I do save_and_open nothing is selected. How do I select a checkbox?
You can use
find("#food_cheese").execute_script("this.click()")
or
page.execute_script("document.querySelector('#food_cheese').click()")

Thymeleaf - Always keep the HTML element but conditionally show a value

I need Thymeleaf to always include a label element but only conditionally show a value for it.
If message.type is equal to warning it should show the message.text. Otherwise, the HTML DOM should still contain the label element.
I've tried this but then the label element is missing from the HTML when the message.type is not equal to warning.
<label id="message" th:if="${message.type == 'warning'}"
th:value="${message.text}" th:text="${message.text}"></label>
I'm trying to accomplish something like this:
<label id="message" th:value="${message.type=='warning' ?
message.text: ''}" th:text="${message.type=='warning'?
message.text: ''"></label>
If the message.type is warning, I would expect HTML like this:
<label id="message">My warning message</label>
Otherwise, I would like to have HTML like this:
<label id="message"></label>
Many different ways to accomplish this. You already have one that I would expect to work. (why do you say it doesn't work?) Also, I'm not sure why you are including th:value in your tags (I'm including them to match your question).
<label
id="message"
th:value="${message.type == 'warning'? message.text : ''}"
th:text="${message.type == 'warning'? message.text : ''}"></label>
You could also do something like this:
<label th:if="${message.type == 'warning'}" id="message" th:value="${message.text}" th:text="${message.text}"></label>
<label th:unless="${message.type == 'warning'}" id="message"></label>
or like this (assuming an extra span wouldn't mess up the markup you are wanting):
<label id="message"><span th:if="${message.type == 'warning'}" th:text="${message.text}" /></label>

Grails RadioGroup, how to bind labels to radio name

I'm struggling arround with the g:radioGroup tag -- I want to create some radios and some labels correspondig to the radios:
<g:radioGroup name="stateOfHealth" value="${review.stateOfHealth}" id="stammp"
labels="['1','2','3','4','5']"
values="['bad','suboptimal','well','veryWell','excellent']">
<span class="radioSpan"> ${it.radio}</span>
<label for="${ ???? }">${it.label}</label>
</g:radioGroup>
What do I need to do to insert in the label's "for" attribute to match the right radio?
You don't need to set the for attribute, just wrap the radio with the label, like this:
<g:radioGroup name="stateOfHealth" value="${review.stateOfHealth}" id="stammp"
labels="['1','2','3','4','5']"
values="['bad','suboptimal','well','veryWell','excellent']">
<label>
<span class="radioSpan">${it.radio}</span>
${it.label}
</label>
</g:radioGroup>

select checkbox with hidden input type

Folks,
I am using watir-webdriver, I have a piece in my HTML DOM which gets generated on the fly when I enter some credentials, this piece has a bunch of checkboxes, the number of checkboxes vary, I have to select one checkbox, below is an example of this, here I want to select the second checkbox(the one that has value "BS" for the input type hidden but the value for input type checkbox is same for all):
<li class="dir">
<input type="checkbox" value="1" onclick="$(this).next('.should_destroy').value = (this.checked?0:1)" name="should_not_destroy">
<input class="should_destroy" type="hidden" value="1" name="import[dir_attributes][][should_destroy]">
<input type="hidden" value="" name="import[dir_attributes][][id]">
<input type="hidden" value="Automation" name="import[dir_attributes][][path]">
<span class="dir_mode">Include</span>
Automation
</li>
<li class="dir">
<input type="checkbox" value="1" onclick="$(this).next('.should_destroy').value = (this.checked?0:1)" name="should_not_destroy">
<input class="should_destroy" type="hidden" value="1" name="import[dir_attributes][][should_destroy]">
<input type="hidden" value="" name="import[dir_attributes][][id]">
<input type="hidden" value="BS" name="import[dir_attributes][][path]">
<span class="dir_mode">Include</span>
BS
</li>
I may be able to do this with XPATH, but wanted to try a non XPATH solution. The input type hidden has the appropriate value that I need, for example above the second checkbox has value "BS" for input type hidden. I tried to use the hidden method like this:
h = ##browser.hidden(:value, "BS")
h.select
But I dont know what to do after this. I am trying to select the checkbox based on the value of the hidden element. Any feedback is much appreciated.
I would suggest using the visible elements instead. I think it makes it easier to read the test and seems more stable.
Try:
##browser.li(:class => 'dir', :text => /BS/).checkbox.set
Here we go, I think this will do it
Since you have to select the checkbox based on the hidden, you're going to have to go up a level to the containing li, then drill down to the checkbox
#browser.hidden(value: 'BS').parent.checkboxes.first.set

How to assign a value to a accepts_nested_attributes_for model

This is a follow-up to this question where's the appropriate place to handle writing the current_user.id to an object I have the following model. An item which has_many assets. I'm am using accepts_nested_attributes_for :assets in the item.
I'd like to assign the current_user.id value to each asset. Normally I just do #item.update_attributes(params[:item]) to save it. Is there a simple one line way of setting the user_id for each asset in this scenario?
Looking in dev log, I see the value here:
item[assets_attributes][10][asset]
Should I just iterate through all of these and set a user_id value?
thx
here's some more of the html (items -> menu_item; had left out above to simplify). The proposed controller sol'n below does not seem to work. I'm fine with doing at the level of controller. Any help appreciated.
<div class='image-row'>
<input id="menu_item_assets_attributes_18_asset" name="menu_item[assets_attributes][18][asset]" type="file" />
<input id="menu_item_assets_attributes_18_description" name="menu_item[assets_attributes][18][description]" size="30" type="text" />
</div>
<div class='image-row'>
<input id="menu_item_assets_attributes_19_asset" name="menu_item[assets_attributes][19][asset]" type="file" />
<input id="menu_item_assets_attributes_19_description" name="menu_item[assets_attributes][19][description]" size="30" type="text" />
</div>
<div class='image-row'>
<img alt="D5cc413a1748fb43b0baa2e32e29b10ac2efda10_huntbch_thumb" src="/images/371/d5cc413a1748fb43b0baa2e32e29b10ac2efda10_huntbch_thumb.jpg?1329917713" />
<div class='img-row-description'>
<label for="menu_item_assets_attributes_20_description">Description</label>
<input id="menu_item_assets_attributes_20_description" name="menu_item[assets_attributes][20][description]" size="60" type="text" value="here is my comment" />
<label for="menu_item_assets_attributes_20_destroy">Destroy</label>
<input name="menu_item[assets_attributes][20][_destroy]" type="hidden" value="0" /><input id="menu_item_assets_attributes_20__destroy" name="menu_item[assets_attributes][20][_destroy]" type="checkbox" value="1" />
</div>
This answer is probably a little bit muddier than your previous one.
If each asset must have an item, then it might be more sensible to remove the idea of an owning user from an asset entirely: you can always find the owning user by querying the attached item, something like #asset.item.user. However, if users can own assets independently of items, I don't think this will work for you.
If assets are always created in a nested manner for items, a before_create for the asset could assign the value you want. Something like this in asset.rb:
before_create :assign_user
def assign_user
self.user = self.item.user if self.item && self.item.user
end
Finally, if you just want to do it in the controller, Wolfgang's answer is really good and will add the user_id to each asset_attributes.
How about iterating over the params array and setting the value like so:
params[:item][:assets_attributes].map! do |asset_params|
asset_params[:user_id] = current_user.id
end
Now you can use update_attributes( params[:item] ) as before.

Resources