Page object gem with Bootstrap - ruby

I have been using the Ruby page object gem successfully for the last few months, however the new software I'm testing is using Bootstrap so it has become harder.
e.g I'm trying to select from a dropdown, which is normally simple, but with Bootstrap the original HTML isn't visible to the driver:
<select class="currency-selector" style="display: none;">
<option value="GLOBAL">All</option>
<option selected="" value="GBP">GBP</option>
</select>
So this isn't working.
select_list(:original_currency, :class => 'currency-selector')
What is visible to the driver is all the Bootstrap generated code which looks more like this:
<ul class="dropdown-menu inner selectpicker" role="menu" style="max-height: 164.5px; overflow-y: auto; min-height: 80px;">
<li rel="0">
<li class="selected" rel="1">
<a class="" style="" tabindex="0">
<span class="text">GBP</span>
<i class="glyphicon glyphicon-ok icon-ok check-mark"></i>
</a>
</li>
<li rel="2">
<li rel="3">
</ul>
Is there a nice way around this problem and still using the page object gem or will I be forced to use selenium more directly?

Can you use ID's instead of class selectors? I looked over at the page object gem (as I use capybara as my alternative) and it seems straightforward.
select_list(:original_currency, :id => "currency-list")
Next you'd just add that ID to your HTML
<select class="currency-selector" style="display: none;" id="currency-list">
<option value="GLOBAL">All</option>
<option selected="" value="GBP">GBP</option>
</select>
You're right that bootstrap generates a lot so I think ID's will make your tests less brittle.

Related

How can I add value fields to the drop down items?

I have a drop down with Small Medium and Large (code below).
I want to capture some text for each line - e.g. Small Tom; Medium Dick; Large Harry.
Supplementary question - can I get more than one name per size - e.g. Small Quantity 3 ;Tom, Dick, Harry
<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_s-xclick" /> <input type="hidden" name="hosted_button_id" value="B98VUHC4Y2HSU" />
<table>
<tr>
<td><input type="hidden" name="on0" value="Size" />Size
</td>
</tr>
<tr>
<td><select name="os0">
<option value="Small (S)">Small (S) </option>
<option value="Medium (M)">Medium (M) </option>
<option value="Large (L)">Large (L) </option>
</select>
</td>
</tr>
</table><input type="image" src="https://www.paypalobjects.com/en_GB/i/btn/btn_cart_LG.gif" border="0"
name="submit" alt="PayPal – The safer, easier way to pay online!" />
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif"
width="1" height="1" />
</form>
No you cannot do that. Check out some information referenced here in another thread. You could try using some sort of bootstrap version of it. It isn't possible with just HTML.
As for that extra question, would you want to? You would have to parse through the return string to separate the values.
Here is a Bootstrap version of it from that thread.
HTML:
<ul class="nav" role="navigation">
<li class="dropdown"> --Select Country--<b class="caret"></b>
<ul class="dropdown-menu" role="menu" aria-labelledby="drop2">
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">USA</a>
</li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">UK</a>
</li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Russia</a>
</li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Others <input type="text" id="other"/></a>
</li>
</ul>
</li>
</ul>
JQuery:
$('.dropdown-menu input').click(function (e) {
e.stopPropagation();
});
$('.dropdown-menu li').click(function(){
$('.dropdown-toggle b').remove().appendTo($('.dropdown-toggle').text($(this).text()));
});
Bootstrap JS Example
I accept that what I asked for is not possible or at least not in my competence.
I have realised that what I really want is different The more I thought about it the easier it got.
But for any future enquirer
I need to add one line in the cart for each unique combination of two variables OS0 (Size) and OS1 (Name) and Paypal does that anyway. Only if the pair are duplicated does it bump up the quantity on the existing line.
I call this one closed

Kendo ui Multselect - overriding style

so i have a web page displaying a Kendo MultiSelectFor tag. all works fine.
The user's data is unfortunately very long so the drop-down selection items get wrapped. the users do not like this.
Is there a way to override the size of the drop down list so that is wider than the selected items listbox (which sits above)?
The html snippet below is what I have - (but won't run pretty)
So far I have been trying to override some styles using something like this:
#accommodationsMultiselect .k-valid {
left:-100px; width: 600px
}
i have not been able to affect any change so far. thanks in advance
JB
<html>
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<title></title>
</head>
<body>
<div class="form-group">
<label for="AccommodationIDs">Accommodations</label>
<div>
<div class="k-widget k-multiselect k-header" deselectable="on" title="" style="">
<div class="k-multiselect-wrap k-floatwrap" deselectable="on">
<ul role="listbox" deselectable="on" class="k-reset" id="accommodationsMultiselect_taglist">
<li class="k-button" deselectable="on">
<div>
<span deselectable="on">
<span class="k-state-default">Calculator - provided by family</span>
</span>
</div>
</li>
<li class="k-button" deselectable="on">
<div>
<span deselectable="on">
<span class="k-state-default">Computer for Essay</span>
</span>
</div>
</li>
<li class="k-button" deselectable="on">
<div>
<span deselectable="on">
<span class="k-state-default">Extended Time - Time and a half (1.5x)</span>
</span>
</div>
</li>
</ul>
<input class="k-input k-valid" style="width: 25px;" accesskey="" autocomplete="off" role="listbox" title=""
aria-expanded="false" tabindex="0" aria-owns="accommodationsMultiselect_taglist accommodationsMultiselect_listbox"
aria-disabled="false" aria-busy="false" aria-activedescendant="bd81cf39-1dbe-431d-985c-57c3d3a11027" />
</div>
<select id="accommodationsMultiselect" multiple="multiple" name="accommodationsMultiselect" data-role="multiselect"
style="display: none;" aria-disabled="false" class="k-valid">
<option value="b08e686b-01bb-4cce-8aaa-fe836741c98e" selected="selected">Extended Time - Time and a half
(1.5x)</option>
<option value="b9812a54-fc87-494b-8bc3-453318143ee5">Double Time (2x)</option>
<option value="aa562f06-0c72-4bf8-9cd9-3e0b0c9d56df">Mark Answers in Test Booklet</option>
<option value="79795988-8722-4970-9c20-55cc90c3d732">Large Print Test and Circle Answers in Test Booklet</option>
<option value="dc4018db-a800-40d6-adbd-1afaefd72ddb" selected="selected">Calculator - provided by family</option>
<option value="03696d5b-65a9-4f1a-b548-1559ac5bceaf" selected="selected">Computer for Essay</option>
<option value="d08d568a-4861-4fae-a2e0-cde6f7f9ecec">Computer with Spell Check for Essay</option>
<option value="81a57096-847c-48c2-a217-eac0ca43eca7">Computer for Essay - provided by family</option>
<option value="e7eee91c-25a1-471c-9c0e-e1d454061834">Computer with Spell Check for Essay - provided by family</option>
<option value="f90a8609-6d65-4164-9652-883fbfce4c52">Computer for Essay - computer and printer provided by
family</option>
<option value="d25c1216-86e4-4c6b-b4a4-716ccc2ec41f">Computer with Spell Check for Essay - computer and printer
provided by family</option>
<option value="b4245a2b-a556-4481-b782-f704ca60bc14">Reader (may have limited availability at select ISEE test
locations)</option>
<option value="13fc2384-fa03-4a8a-b883-ffd484961c1e">Scribe (may have limited availability at select ISEE test
locations)</option>
<option value="23c68259-6137-4ddf-8208-8d433df65fa2">Scribe for Essay only (may have limited availability at select
ISEE test locations)</option>
<option value="1c7347d6-2d59-4670-aecc-cbca9b493d3b">Other (may have limited availability for "Other"
accommodations requested)</option>
</select>
</div>
</div>
</div>
</body>
</html>
Get a reference to the multiselect and simply set the .width() of it's .list.
var multiSelect = $("#multiselect").kendoMultiSelect({
animation: false
}).getKendoMultiSelect();
multiSelect.list.width(500);
// Or even:
// multiSelect.list.width("auto");
Check you http://dojo.telerik.com/#Stephen/uLAbU for a working example.
This technique works for DropDownLists and ComboBoxes as well, possibly other "dropdown" type controls.

Select span for select2 using Capybara

I'm trying to write a custom method that allows me to use our custom select2 country_search element. The elements are a bit wonky, but the snippet of HTML looks like this:
<div class="control-group select optional admins_customer_form_object_country_id">
<label class="select optional control-label" for="admins_customer_form_object_country_id">Country</label>
<div class="controls">
<select id="admins_customer_form_object_country_id" class="select optional select2-hidden-accessible" name="admins_customer_form_object[country_id]" tabindex="-1" aria-hidden="true">
<option value=""></option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<span class="select2 select2-container select2-container--classic select2-container--below select2-container--focus" dir="ltr" style="width: 220px;">
<span class="selection">
<span class="select2-selection select2-selection--single" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-labelledby="select2-admins_customer_form_object_country_id-container">
<span class="select2-selection__rendered" id="select2-admins_customer_form_object_country_id-container">
<span class="select2-selection__placeholder">Select Country</span>
</span>
<span class="select2-selection__arrow" role="presentation">
<b role="presentation"></b>
</span>
</span>
</span>
<span class="dropdown-wrapper" aria-hidden="true"></span>
</span>
</div>
</div>
I wrote a helper that should select the correct span and perform a click on it, but I'm stuck selecting the span I want. I'm trying to select the outer visible span which has class select2 select2-container select2-container--classic select2-container--below select2-container--focus but I keep getting invalid XPath errors.
This is what I have so far:
def select_country(label:, value:)
# Select our label first
label_element = first("label", text: label)
# Now navigate through the entire tree, and click the correct SPAN element.
within(label_element) do
select2_container = find(:xpath, "..") # Up one level to the parent div
select2_container = select2_container.find("div.controls") # Down one level into the div.container
select2_container = select2_container.find(:xpath, "./*[1]") # select the span element surrounding all.
end
end
With the last line I can select the select element from the tree, but I can't get the span sibling whatever I try.
If I'm reading correctly you want the span that is the child of div.controls, replacing the last two finds with the following should do that
select2_container = select2_container.find('div.controls > span')
You can add classes to the span in the css selector if needed but in your html it's the only span child so it's not necessary

select dropdown from options when options are in separate tags

I am a beginner in using webdriver and Here is the code with which i am working.
I want to click on a dropdown and again click on the list of values provided for that dropdown.
Please help me, i looked for other threads, but they are different.
<ul>
<li class="size select required">
<div id="dk_container_partNumber-55414" class="dk_container dk_theme_size dk_focus"
tabindex="" style="display: block;">
<a class="dk_toggle" style="width: 162px;">
<div class="dk_options">
<ul class="dk_options_inner">
<li class="dk_option_current">
<li class="">
<a data-dk-dropdown-value="605930243">S</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930251">M</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930260">L</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930278">XL</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930286">XXL</a>
</li>
</ul>
</div>
</div>
<select id="partNumber-55414" class="size-select" name="partNumber" style="display: none;">
<option data-property="CAT_SELECTSIZE" selected="selected" value="">Select Size</option>
<option value="605930243">S</option>
<option value="605930251">M</option>
<option value="605930260">L</option>
<option value="605930278">XL</option>
<option value="605930286">XXL</option>
</select>
I wish to select "S" and the same must be seen on the dropdown.
I am able to click on the dropdown and see the list of options using the below code :
driver.findElement(By.xpath("//(more xpath goes here)/ul/li[#class = 'size select required']/div/a/span")).click();
I tried the below code to select "S", but in vain :
Select SizeDropdown = new Select(driver.findElement(By.xpath("//(more xpath here)/ul/li[#class = 'size select required']/select")));
//driver.findElement(By.xpath("(//(more xpath here)/ul/li[#class = 'size select required']/select)/option[2]")).click();
//Below line gets and clicks the first option of Select Size 'S'
//SizeDropdown.getFirstSelectedOption().click();
//SizeDropdown.selectByVisibleText("S");
//SizeDropdown.selectByIndex(1);
//SizeDropdown.selectByValue("S");
I tried each command separately (after uncommenting),but could not see the "S" as the label of the dropdown as if it is selected by me.
Have you tried simplifying your xpath?
I use something like this to select an option from a drop down without first clicking to expand it:
Select select = new Select(driver.findElement(By.xpath("//select[#id='partNumber-55414']"));
select.selectByVisibleText("S");

Zurb Css framework dropdown Issue

I am using Zurb Css framework, As documented on foundation.zurb.com/docs/forms.php I used the same code as provided as below
<label for="customDropdown">Dropdown Label</label>
<select style="display:none;" id="customDropdown">
<option SELECTED>This is a dropdown</option>
<option>This is another option</option>
<option>Look, a third option</option>
</select>
<div class="custom dropdown">
This is a dropdown
<ul>
<li>This is a dropdown</li>
<li>This is another option</li>
<li>Look, a third option</li>
</ul>
</div>
But I Cannot see any drop down , The code above is copy pasted from their website.
Thank You.
It was silly mistake I forgot to put class='custom' for the form element.

Resources