capybara /cucumber can't find radio - selenium

I'm having an issue finding a radio button. Here is a snippet of the html:
<form action="/" id="frm-info" method="post"><input id="ClickedButton" name="ClickedButton" type="hidden" value="" /><input name="__RequestVerificationToken" type="hidden" value="KTQF3bkKPP0OirvtL1EYsW-Q77zq-8H9YAPqeoBB9ewpNSYoc0dOEout26qrtMmX6xBx0_roxqWRwCXAlwZRTyW9ZBTBjwNgifWqws6hyOFIRmc6O-7P6jZXbZNYJ5Pazt9Hmg2" /> <div class="row borGreyPad mlmrcolor bb0">
<div class="col-sm-12 coverImage">
<div class="col-md-7 col-lg-6 fr xs-fl">
<div class="frm-content axaborderBlue mt10">
<div class="pl25 pt15 pr15 pb10">
<p class="large-heading">Enter some basic information to get started</p>
<div class="row ">
<div class="row pl15">
<div class="col-sm-4 r xs-l mb5 f14">Application Taken: *</div>
<div class="col-sm-8 mb5">
<div class="groupBox">
<span class="dib f14 ">
<input id="ApplicationTaken" name="ApplicationTaken" tabindex="1" type="radio" value="ApplicationInPerson" /><span class="dib mr10 ">In Person</span>
</span>
<span class="dib f14 ">
<input id="ApplicationTaken" name="ApplicationTaken" tabindex="2" type="radio" value="ApplicationByPhone" /><span class="dib mr10 ">By Phone</span>
</span>
</div>
I want to select the radio button with name "ApplicationTaken" and value "ApplicationInPerson"
I've tried several different ways including:
When I click on the radio with name
"([^"]*)" and value "([^"]*)"$/ do |myName, myValue|
choose("#{myName}", :option => "#{myValue}")
end
and
When I click on the radio with name
"([^"]*)" and value "([^"]*)"$/ do |myName, myValue|
find(:xpath, "//input[#value='#{ myValue }']", match: :first).set(true)
end
I keep seeing the following error:
"Unable to find radio button "ApplicationTaken" with value "ApplicationInPerson".
I've also tried by ID, no luck. I CAN select a button on this page and fill in text fields, I just can't select radio buttons or drop downs. Thanks

Since you're using capybara try:
choose('Visible Text')
See:
https://gist.github.com/zhengjia/428105

For starters, you have two radio buttons with the same id. This is bad - you should not have duplicate ids on a page. Attempting to find an element by ID when there are duplicates is very unpredictable.
What's most likely happening is that it's finding the first element with a matching ID, and then checking the value attribute. When that doesnt match, it says the element could not be found, because it does not continue onto the next matching ID (because of the way id selectors work internally)
I see you're also using xpath to find the element. You generally should be using CSS instead of xpath for finding your elements.
So leaving the ID out, and using CSS instead, find('input[name=ApplicationTaken][value= ApplicationInPerson]') should get you the element you're looking for.

Related

unique xpath combined two attributes

Ho do I make unique xpath to let the robot locate into second field?
i used this but failed:
Click //div[contains(#class,'ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search') and contains(text(),'Select Source(s)')]
First Field:
<div class="ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search">
<div class="ant-select-selector">
<div class="ant-select-selection-overflow">
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
<div class="ant-select-selection-search" style="width: 3px;">
<input autocomplete="off" type="search" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_9_list" aria-autocomplete="list" aria-controls="rc_select_9_list" aria-activedescendant="rc_select_9_list_7" value="" id="rc_select_9" style="opacity: 0;" aria-expanded="false" readonly="" unselectable="on">
<span class="ant-select-selection-search-mirror" aria-hidden="true"> </span>
</div>
</div>
</div>
<span class="ant-select-selection-placeholder">attribute(s)</span>
</div>
</div>
second field:
<div class="ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search">
<div class="ant-select-selector">
<div class="ant-select-selection-overflow">
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
<div class="ant-select-selection-search" style="width: 3px;">
<input autocomplete="off" type="search" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_10_list" aria-autocomplete="list" aria-controls="rc_select_10_list" aria-activedescendant="rc_select_10_list_0" value="" id="rc_select_10" style="opacity: 0;" aria-expanded="false" readonly="" unselectable="on">
<span class="ant-select-selection-search-mirror" aria-hidden="true"> </span>
</div>
</div>
</div>
<span class="ant-select-selection-placeholder">Select Source(s)</span>
</div>
</div>
this xpath works (when I test at chrome developer console, it is detected) but when robot executed the script, it does not really click into the field. the drop-down list does not display.
Click //div[#class="ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search"]
error:
FAIL
Message: TimeoutError: locator.click: Timeout 10000ms exceeded.
=========================== logs ===========================
waiting for selector "//span[contains(#class,'ant-select-selection-placeholder') and contains(text(),'Select Source(s)')] >> nth=0"
selector resolved to hidden <span class="ant-select-selection-placeholder">Select Source(s)</span>
attempting click action
waiting for element to be visible, enabled and stable
element is not stable - waiting...
element is visible, enabled and stable
scrolling into view if needed
done scrolling
checking that element receives pointer events at (1080.4,304.7)
<div class="ant-select-selection-overflow">…</div> intercepts pointer events
retrying click action, attempt #1
waiting for element to be visible, enabled and stable
element is visible, enabled and stable
scrolling into view if needed
done scrolling
checking that element receives pointer events at (1080.4,304.7)
[ Message content over the limit has been removed. ]
element is visible, enabled and stable
scrolling into view if needed
done scrolling
checking that element receives pointer events at (1080.4,304.7)
<div class="ant-select-selection-overflow">…</div> intercepts pointer events
you are not so far from solution to select the uniq div
text equals:
//div[contains(#class,'ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search') and .//span[text()='Select Source(s)']]
if you want the expression contains:
//div[contains(#class,'ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search') and .//span[contains(.,'Select Source(s)')]]
You can give an index according to your best match like
(//*[#class='ant-select SearchPrompter_advInput__3P9Jf ant-select-multiple ant-select-allow-clear ant-select-show-search'])[2]
Try to use the span tag and parent keyword in the xpath to find the required div tag element.
As per the HTML Code, Xpath would be something like this.
//span[contains(text(),'Select Source')]/parent::div/parent::div/parent::div

Element should have been "select" but was "span" in selenium

Toggle button is present in an web application similar to
http://www.dhtmlgoodies.com/index.html?whichScript=on-off-switch
Search for "option two" in the above link.
Html code of the button is like this when turned Off
<div class="field-block button-height">
<label style="width:175px" class="label" for="input-2"><b>Case Association</b><sup>*</sup>
<span id="reqCaseAssociationTD" style="display: none;">
required</span>
</label>
<p style="margin:0px" class="field switch">
<label style="margin:0 0 4px" class="cb-enable"><span>On</span></label>
<label style="margin:0 0 4px" class="cb-disable selected"><span>Off</span></label>
<input type="checkbox" class="checkbox" id="caseAssociation">
</p>
<span style="margin-top:8px;margin-left:2px" data-tooltip="Simulataneous post from the same user (Twitter and Facebook) would get associated with the previous open case of the user." class="helpText showToolTip"></span>
</div>
Html code of the button is like this when turned ON
<div class="field-block button-height">
<label style="width:175px" class="label" for="input-2"><b>Case Association</b><sup>*</sup>
<span id="reqCaseAssociationTD" style="display: none;">
required</span>
</label>
<p style="margin:0px" class="field switch">
<label style="margin:0 0 4px" class="cb-enable selected"><span>On</span></label>
<label style="margin:0 0 4px" class="cb-disable"><span>Off</span></label>
<input type="checkbox" class="checkbox" id="caseAssociation" checked="checked">
</p>
<span style="margin-top:8px;margin-left:2px" data-tooltip="Simulataneous post from the same user (Twitter and Facebook) would get associated with the previous open case of the user." class="helpText showToolTip"></span>
</div>
Used the following identifiers
//Case Association Turned On
#FindAll(#FindBy(how = How.CSS, using = "a.cb-enable.selected"))
public List<WebElement> caseAssociationIsON;
//Case Association Turned OFF
#FindAll(#FindBy(how = How.CSS, using = "a.cb-disable.selected"))
public List<WebElement> caseAssociationIsOFF;
While running using the selenium getting the error
org.openqa.selenium.support.ui.UnexpectedTagNameException: Element
should have been "select" but was "span"
How do fix this. If more details are needed, please suggest.
I don't see any element that would match your selector, you should use label instead of a, like:
label.cb-enable.selected
and
label.cb-disable.selected
or use a selector based on input. a means link and you don't have any.
In case you still have the error what happens is that you must add an specific route:
In my case:
enter image description here
This is the resultant code:
enter image description here

Can't get Cucumber/Capybara to find radio buttons

I'm having trouble getting Cucumber to "choose" a radio button and hoping someone can give me a sanity check. Without quoting a huge mass of HTML junk, here's the relevant portion (which I collected from print.html). It's within a modal div that is activated by a button. I can "click" that button and see the modal window appear (I'm running it as a #javascript scenario in Selenium).
<div class="modal-body pagination-centered">
<img src="/assets/payment.png" alt="Payment" />
<form novalidate="novalidate" method="post" id="edit_cart_1" class="simple_form edit_cart" action="/carts/complete" accept-charset="UTF-8">
<div style="margin:0;padding:0;display:inline">
<input type="hidden" value="✓" name="utf8" />
<input type="hidden" value="put" name="_method" />
</div>
<div class="control-group hidden cart_property_id">
<div class="controls">
<input type="hidden" name="cart[property_id]" id="cart_property_id" class="hidden" />
</div>
</div>
<div id="payment_fat_buttons" class="fat-buttons">
<div class="vertical-button-wrapper">
<input type="radio" value="cash" name="cart[payment_type]" id="cart_payment_type_cash_pay" data-property-id="1" />
<label for="cart_payment_type_cash_pay">Cash</label>
</div>
<div class="vertical-button-wrapper">
<input type="radio" value="credit" name="cart[payment_type]" id="cart_payment_type_credit_pay" data-property-id="1" />
<label for="cart_payment_type_credit_pay">Credit</label>
</div>
</div>
<div style="display: none;" id="cart_room_number_area_pay">
<div class="control-group string optional cart_room_number">
<label for="cart_room_number_pay" class="string optional control-label">Room number</label>
<div class="controls">
<input type="text" value="" size="50" name="cart[room_number]" id="cart_room_number_pay" class="string optional" />
</div>
</div>
</div>
<input type="checkbox" value="1" style="display: none;" name="receipt" id="receipt" />
<div class="sell-modal-footer">
<input type="submit" value="Complete With Receipt" name="commit" id="cart_complete_with_receipt" data_disable_with="Processing..." class="btn btn-danger" />
<input type="submit" value="Complete Sale" name="commit" data_disable_with="Processing..." class="btn btn-danger" />
</div>
</form>
</div>
I've tried as many different equivalent ways of getting at it that I can think of. Most obviously just by the label, or the ID, like:
choose 'cart_payment_type_cash_pay'
choose 'Cash'
which just gives me the error:
Unable to find radio button "cart_payment_type_cash_pay" (Capybara::ElementNotFound)
I thought it might have something to do with the modal dialog, visibility, etc. but I introduced the ID #payment_fat_buttons just for testing, and when I look for it like this:
find('#payment_fat_buttons').choose('Cash')
it finds that DIV OK, but still not the radio button. I also tried getting at it with :xpath on the whole page, and within a scope like:
within(:xpath, "//div[#id='payment_methods']") do
find(:xpath, ".//input[#id='cart_payment_type_cash_pay']").choose
end
which acts like it can also find the outer DIV, but not the radio button - I get the error:
Unable to find xpath ".//input[#id='cart_payment_type_cash_pay']" (Capybara::ElementNotFound)
Generally, it seems like I can find any arbitrary element around the radio buttons with :xpath or CSS expressions, just not the radio buttons. I can also push the submit buttons on the form without any problem. I tried dropping the data attributes as a test - no difference. Any help would be greatly appreciated. This is driving me nuts because it seems so simple, and yet I'm getting nowhere. I need to choose that for a big segment of Scenarios, so if I can't figure it out, I'll have to resort to something hokey and horrible. Many thanks in advance...
Relevant versions from Gemfile.lock:
rails (3.2.13)
cucumber (1.3.8)
gherkin (2.12.2)
cucumber-rails (1.4.0)
capybara (2.1.0)
selenium-webdriver (2.35.1)
I finally figured this one out. Capybara wasn't finding the radio button because buried deep in my styles was some CSS that hid it in order to change the appearance. Once I realized that, I figured out that I could side-step the whole issue of finding the radio button by just doing a click on the label instead:
find(:xpath, "//label[#for='the_radio_button_id']").click
I didn't realize it was possible to get at radio buttons that way - but in any case, it solves the issue of how to click a radio button that Capybara won't find due to styling or other issues. Hope that helps someone else.

Choose second radio button using capybara

From the following html how can i choose the second radio button .In the page load first radio button is selected when i use the following code
page.choose('#PPRINT')
<div id="printOpns" class="span6">
<div class="row"> <div class="span2" align="center">
<input id="Print" class="radio" type="radio" checked="" value="EPrint" name="printO"></div>
</div>
<div class="row"><div class="span2" align="center">
<input id="PPRINT" class="radio" type="radio" value="FPrint" name="printO">
</div>
</div>
</div>
The Capybara API for the choose method says "Find a radio button and mark it as checked. The radio button can be found via name, id or label text." This means that the text that is supplied to the choose method must match the name, id or label of the radio button.
choose does not support css-selectors. Therefore, when you do:
page.choose('#PPRINT')
Capybara is looking for a name, id or label that equals "#PPRINT".
You want to do (ie no "#"):
page.choose('PPRINT')

Selenium test an iterface where misses id and title and other sensible information

I'm working for a client who wants me to do selenium/junit tests but the whole user interface doesn't show any id for the html code nor title for the page, just content like "Welcome in ...", how whould you do to check that one is on the home page or in the page for the login for example?
This is an example of the html:
<div class="site-body m-welcome" data-module="welcome">
<div class="inner">
<h1 class="starred dark"><span>Welcome to ...</span></h1>
<div class="choices">
<div class="choice">
Become a xxxxx
</div>
<span class="or"><span>Or</span></span>
<form action="http://www.alink/welcome" method="post" class="choice" data-response-type="json">
<input type="text" name="plate_number" id="car_plate_validation_plate_number" value="" maxlength="8" class="plate required numberplate" placeholder="Enter number plate">
<button type="submit" class="btn btn-primary">Become an yyyyy</button>
<div class="invalid-message inline-modal" data-behavior="modal">
<h1>Sorry - you are not eligible to join the company</h1>
<p>See am I eligile? for full eligibility critera.</p>
</div>
</form>
</div>
You can use XPath to find almost all elements, I wouldn't use it often but in your case (where nothing has IDs) you'll probably need to use it very often:
IWebElement element = driver.FindElement(By.XPath, "//*[text='Welcome in ...']");
That will get you the first element of any type that has the text within it of "Welcome in ..."
For checking if you are on a certain page, I guess you'll have to search for an element that is unique to that page and no other pages.
You'll need to show us some of the HTML if you want more specific examples.
Example of html:
<div class="site-body m-welcome" data-module="welcome">
<div class="inner">
<h1 class="starred dark"><span>Welcome to ...</span></h1>
<div class="choices">
<div class="choice">
Become a xxxxx
</div>
<span class="or"><span>Or</span></span>
<form action="http://www.alink/welcome" method="post" class="choice" data-response-type="json">
<input type="text" name="plate_number" id="car_plate_validation_plate_number" value="" maxlength="8" class="plate required numberplate" placeholder="Enter number plate">
<button type="submit" class="btn btn-primary">Become an yyyyy</button>
<div class="invalid-message inline-modal" data-behavior="modal">
<h1>Sorry - you are not eligible to join the company</h1>
<p>See am I eligile? for full eligibility critera.</p>
</div>
</form>
</div>