Capybara unable to select radio button in data tables - ruby-on-rails

I have a bit of an issue, im trying to select a radio button in a data-tables data. Im able to filter the single data-tables row down to one so it's the only one appearing on the page...but i've tried page.choose, page.find(<xpath>), page.find(<css>), i've also tried doing all the previous within a certain css selection and I can't quite figure out what's left to try.
The relevant HTML is here, unfortunately as this is a work item I can't post everything. however I AM able to click on the label if I specify the id via:
find(:xpath, "//label[#for='approve_row_5']").click however this doesn't actually seem to 'select' the radio button. I've also tried doing a wait after I filter the data-table results
anyways, here is the HTML for the 2 radio buttons after the row has been filtered (the radio buttons reside in a column)
<td class=" align-middle">
<div class="radio">
<input type="radio" name="approve_deny_row_5" id="approve_deny_row_5_approve" value="person_approve" data-ui-verify-key="test_approve" data-ui-verify-title="2017-07-13 14:59:46 -0400">
<label for="approve_deny_row_5_approve">
<span>Approve</span>
</label>
</div>
<div class="radio">
<input type="radio" name="approve_deny_row_5" id="approve_deny_row_5_deny" value="person_deny" data-ui-verify-key="test_deny" data-ui-verify-title="2017-07-13 14:59:46 -0400" data-ui-verify-url="/irrelevant/stuff">
<label for="approve_deny_row_5_deny">
<span>Deny</span>
</label>
</div>
</td>
I thought about just finding the span by the text and clicking it, which passes....but doesn't actually select the radio button. Also I tried searching by the specific value selector as well via a find('input[value="test_approve"]').click but that had no luck either
Any ideas?

Assuming the actual radio inputs are visible on the page (and not hidden to allow for styling) the methods that should work for this are
choose("Approve")
choose("Deny")
or
choose("approve_deny_row_5_approve")
choose("approve_deny_row_5_deny")
If those tell you they can't find the elements then it's most likely the input elements are actually hidden (for styling reasons) and you should be able to use the
choose('Approve', allow_label_click: true)
which will click on the label element associated with the input rather than the input element. That should produce the same result (setting the radio button) unless the behavior you're looking for is based on JS looking for a click on a very specific element (rather than the change event on the input). If that happens to be the case then you need to figure out exactly what element the JS is looking for clicks on, or fix the JS to behave in a more intuitive manner.

Related

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')

Adobe DTM: Event based rule to track form submission

I am trying to track form submission for a form using event based rule in DTM. I know that the ideal way to do it is to do via direct call rule but need to track the form fields as well through a data element and then into an eVar.
The form code looks something like this on the page:
<div style='display:none'>
<div id="popupform">
<div class="form_container">
<img src="/images/New-Offer-Pop-Up-Without-form_18-Jan-16.jpg" style="width: 100%;">
<form class="offerform" accept-charset="UTF-8" action="/site/sendtohs">
<div class="formrow"><input type="text" name="popup_fullname" class="new-input1 required" placeholder="Name" /></div>
<div class="formrow"><input type="email" name="popup_email" class="new-input1 required" placeholder="Email" /></div>
<div class="formrow"><input type="number" name="popup_phone" class="new-input1 required" placeholder="Mobile"
minlength="10" maxlength="15" /></div>
<input type="hidden" name="popup_url" value="/" /></br>
<p align="right"><input class="tbn newtbn" type="submit" name="submit" value="Submit" /></p>
</form>
</div>
<div class="offerform_success" style="display: none">
<img src="/images/Thank-you-pop-up-new-xyz.jpg" style="height: 440px; width: 100%; position: absolute;width: 99%;">
</div>
</div>
</div>
The even based rule in DTM is :
DTM Rule
The event fires when I click on the Submit button but the rule does not validates if the form fields have been filled or not. Any hints how can I add validation to the form submit event within DTM.
Targeting the form
Firstly, based on your screenshot vs. posted code, your event will not trigger because the form tag does not have an id attribute of "popupform" (or any id attribute at all) (You do have that as an id in a parent div, but that's not what you are targeting). So, you will need to remove that.
If you only want to target the form if it's within a div, then you will need to add it as a Rule Condition. Under Rule Conditions > Criteria, choose "Data > Custom", and click Add Criteria.
In the code box, add the following:
if ($(this).parents('#popupform').length)
return true;
return false;
Note: I'm using jQuery syntax here for brevity and easy cross-browser compatibility. The overall goal is this references the targeted form, and you want to check that it is within an html element with the popupform id. The jQuery above traverses up the form's ancestor chain to look for it. If it finds it, we return true. Otherwise we return false. Ultimately, custom rule conditions should return true if you want it to pass, or false if not. Also note that if you have multiple rule conditions (which you will; see below), all conditions must return true in order for the rule to trigger. If your site does not use jQuery or you do not want to use jQuery for this, then you will need to write your own code following the above concept.
Validating the form fields
Before I get into this, one thing I should note is in general you should not rely on client-side form validation for your forms. It is super easy to disable/get around it. You should be doing form validation with server-side code when the form is submitted, and then pop whatever you need to pop (form complete tracking or w/e) after it has been server-side validated.
Maybe you already have server-side validation in place but for whatever reason you can't control popping a dtm rule after validation, and this is your next best thing. Well hopefully the only thing you are doing is popping tracking and not using the dtm rule for actual site functionality, but even then, just want you to be aware that this is a "lesser evil" solution, not a "good" solution.
Having said that, you can again turn to a custom condition to make sure all the form fields are filled out. Here is a quick and dirty custom rule condition to demonstrate. Again, under Rule Conditions > Criteria, choose "Data > Custom", and click Add Criteria (so you will now have another custom code box). Add the following:
var isFieldsFilled=true;
$.each($(this).serializeArray(),function(i,v) {
if (!v.value||v.value=='')
isFieldsFilled=false;
});
return isFieldsFilled;
This code again uses jQuery to grab the form fields of the targeted form and loops through them and sets a flag to false if one is found not to have a value. Again, this is kind of quick and dirty and will work based on your current form example, but you may need to expand upon it in practice.

Capybara/Poltergeist, clicking on Hidden Checkbox?

I have some HTML for a Checkbox im trying to click:
<td class="surface center">
<div class="checkbox-inline checkbox-inline--empty">
<input type="hidden" value="0" name="stuff_check">
<input id="stuff_1" class="boolean optional" type="checkbox" name="stuff_1_checked" value="1" data-item="5">
<label class="optional" for="stuff_1">Checked</label>
</div>
</td>
When running a page.find_by_id('id').trigger('click') it does indeed work, just using click however it complains about Poltergeist possibly clicking another elements:
Capybara::Poltergeist::MouseEventFailed:
Firing a click at co-ordinates [-9468.5, 6] failed. Poltergeist detected another element with CSS selector '' at this position. It may
be overlapping the element you are trying to interact with. If you
don't care about overlapping elements, try using
node.trigger('click').
However I felt maybe this is because of it being set as "hidden", so I tried doing page.find_by_id('ID', :visible => false).click however it gave the same issue.
Any suggestions? Since I know using trigger.('click') isn't advised.
There is no way to do a proper click on a hidden element because there would be no way for a user to click on an element that doesn't appear on the screen.
Your example is confusing because the hidden element doesn't have the same name attribute as the checkbox element which is what I would normally expect in this kind of setup. Assuming that what you're really trying to do is check the "stuff_1" checkbox (and that is hidden via CSS) then you should be doing what a user of your app would have to do - click on the label.
page.find('label[for="stuff1"]').click
Try
within('.checkbox-inline checkbox-inline--empty') do
check('#stuff_1')
end
I really recommend using Pry to do this though as you'll save yourself a ton of pain finding which elements are where.

How to select items in this custom Vaadin combo box that uses an text input element?

The above pic shows the select list but it's not actually select list, it consist of 'Input' tag, So I tried to set the value using b.text_field.set("argentina") but it only focuses(color changes to yellow) but it's not setting the value, how could I do that?
The code for that select list is given below
<div class="v-filterselect v-widget v-has-width v-filterselect-prompt" role="combobox" style="width: 100%;">
<input tabindex="0" class="v-filterselect-input" id="gwt-uid-17" aria-labelledby="gwt-uid-16" style="width: 100%;" type="text" autocomplete="nope">
<div class="v-filterselect-button" role="button" aria-hidden="true">
</div>
</div>
The problem is that Watir-Classic calls the blur event after setting the value. As a value is not selected from the dropdown, Vaadin considers this as an invalid input and resets it back to "No country selected". You can see the same behaviour when you interact with the combobox manually:
Click the text field
Type "argentina"
Click somewhere else in the page (ie runs the blur event)
To populate the field, you need to select an item from the dropdown. Even though the input field is being cleared, the dropdown does remain (at least when Watir-Classic does it). As a result, we are able to select an item without extra work.
Here is an example using the Vaadin demo page:
require 'watir-classic'
browser = Watir::Browser.new
browser.goto('http://demo.vaadin.com/sampler/#ui/data-input/multiple-value/combo-box')
country = 'ARGENTINA'
browser.text_field(aria_labelledby: 'gwt-uid-16').when_present.set(country)
browser.div(id: 'VAADIN_COMBOBOX_OPTIONLIST').span(text: country).when_present.click
Note that this will not replicate the exact events generated when a user interacts with the field. However, if you are just using the control, rather than testing the field (ie a Vaadin developer), this is likely sufficient.

jquery mobile label wrapping checkbox generates DOM error

I'm creating a large dynamic form and want to create checkboxes and radio buttons like:
<label><input type="radio" name="myradio"><span class="foo">This is the Label</span></label>
This is for a number of reasons. There's nothing wrong with this as far as HTML spec goes.
But, jquery mobile generates a DOM error for every checkbox or radio button generated this way. It really seems to want:
<input type="radio" name="myradio" id="radio1"><Label for="radio1">...</label>
Any workarounds? Ideas?
This works fine: http://jsbin.com/ofuhaw/228/edit with latest JQM
Maybe you should just swap the order of elements.

Resources