how to test using ui selectmenu (jQuery) and selenium - jquery-ui

I'm trying to "record" a functional test using the selenium IDE plugin for Firefox (version 3.6). Im using the jQuery plugin ui selectmenu (I think its version 1.8). Im trying to "record" the selection of an element in a dropdown / select component. This dropdown is a ui select enhanced component. Therefore the actual select element is hidden and you end up selecting span elements and something else. This is what selenium records:
<tr>
<td>click</td>
<td>//a[#id='type-button']/span[2]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>ui-selectmenu-item-416</td>
<td></td>
</tr>
The problem is that the second part uses a number suffix, a kind of counter (416). This value is different for every page load, and therefore I don't see how I can automate it!?
How can I get a predictable result and test this?, or is there some other way to do it?
thanks!

The jQuery selectmenu widget is painful to automate with Selenium. A simple record-playback will hardly ever work. Try the following steps to automate the selection -
Type in the item you need to select.
Hit Backspace so the selectBox can "search" for the item.
Simulate the down arrow key for the searched item.
Select the first item from the dropdown list.
Here is the source code (in Java) for these steps. You should be able to adapt these to the IDE.
selenium.type("selectMenu_descriptor", "item_to_be_selected");
selenium.typeKeys("selectMenu_descriptor", "\b");
selenium.keyDown("selectMenu_descriptor", "\\40");
selenium.click("css=a.ui-corner-all[tabindex=\"-1\"]");

I also found that this was effective, if you don't care about taking screenshots with the jQuery UI controls running.
var jse = (IJavaScriptExecutor)theDriver;
jse.ExecuteScript("try { $(yourSelector).selectmenu('destroy'); } catch (ex) { }");
It's a little messy, but if you call it before you need to handle selecting dropdown options by text, it does the trick.

Related

Select2 4.0.0 cascading dropdowns

I'm using select2.full.js
I'm not using any require.js to help me pull in modules, I'm basically using my know how from everything I learned in v3.5
I've been trying countless of hours, wrapping my head around this, but I have no idea how to make ajax cascading dropdowns.
Example: You load up the page, there is the first select2 dropdown that pulls data using ajax automatically (you don't enter anything.. data is there on the page load from the server), a default value is selected. Since that default value is selected, the second select2 drop down will use that value to make an ajax call to populate its own list. Now, when I select another value in the first select2 dropdown, the second select2 dropdown will reflect those changes with the new dataset.
What I've able to come up with was a 3 dropdowns that you can populate on a page load, but when you do any ajax request, the dropdown data doesn't change.
It's been two years since I used select2, and the library keeps changing, the documentation keeps changing, I'm at my wits end with this library. But I feel drawn to it by the bootstrap support, and the look and feel. The functionality, the way to implement things, the documentation is just so unbelievably awful.
I don't have any useful code at all, I've been pulling, plugging, modifying, etc.. and now I'm moving to my hair and teeth.
ANY useful example to do this would be awesome.
Just found my answer..
I was using the templating:
<select id="test">
<option value="1">1</option>
<option value="2">2</option>
</select>
to:
data = [{id: "1", text: "1"}, {id: "2", text: "2"}];
<input id="test" type="hidden" />
and just kept my jquery on select2 the same. So it was really just a change in the templating from to that solved it.
However, the only downside to this is that when you are refreshing new data from these drop downs, the highlighted (selected value) is always the first item in the drop down list, even though that's not the selected value shown in the dropdown.
Here is a small code snippet to make Select2 (v4.x) cascading dropdown - https://gist.github.com/ajaxray/187e7c9a00666a7ffff52a8a69b8bf31
Using this module, options of a select2 list box will be loaded/refreshed by ajax based on selection of another select2 list box.
Example use -
new Select2Cascade($('#province'), $('#district'), 'path/to/geocode', {type:"district", parent_id: ''});
Selected value of parent select2 listbox will be set to the parent_id of the data object before ajax call.

Knockout List Item Animation

I've been working with Knockout.js for some time now but only recently I've started to integrate jqueryUI animations for the sake of a better user experience. I'm seeing some issues trying to use the animation bindings on the tr elements inside a table tag. When I use the "visible" binding to hide and show each element it works just fine but when I attempt to animate the showing hiding of each element it only seems to apply to the first row in the table. I've attempted this using various methods. I've attempted using the knockout foreach template 'afterAdd' option as described here:
http://knockoutjs.com/documentation/foreach-binding.html#note_5_postprocessing_or_animating_the_generated_dom_elements
I've also created a custom binding and attempted to use that on each of the table row items with the same results.
Lastly I attempted to use the plugin found here:
http://www.codecoding.com/knockout-plugin-visibility-bindings-with-jqueryui-effects/
And again, it only appears to work on the first element of the table. Now before attempting to rewrite my HTML to use divs and spans rather than the tables I wanted to see if anybody else has seen these sorts of issues with knockout in the past. The relevant chunk of HTML is this:
<table class="tab_table table_a">
<tbody data-bind="foreach:featuredMenuItems,visible:showFeatured">
<tr data-bind="fadeVisible:readyToShow, click:function(){$root.showProductOptions($data);}">
<td class="td_large" data-bind="css:{td_select:itemInCart};"><span class="inCart_delete" data-bind="css:{display_IB:itemInCart},click:removeFromCart,clickBubble:false"><i class="fa fa-times-circle"></i></span><span data-bind="text:name"></span></td>
<td class="td_last" data-bind="css:{td_select:itemInCart},text:lineItemCost"></td>
</tr>
</tbody>
</table>
I would paste the ViewModel code in here as well but it is a rather large view model and the relevant part to this is just a simple "readyToShow" observable set to either true or false. Whenever this table is being shown the "readyToShow" values of each of the objects in the observableArray containing the table items is being set to true over time using a timeout so as to show a cascading effect when the table is shown.
I would really appreciate any help you guys could provide. Thanks!

AngularDart table data binding not working

In a Chrome Packaged app, using angular.dart, in a component html I have the below table which is dispaying paginated contents of an object list; exp. jobs :
<tbody>
<tr id="{{job.jobID}}" ng-repeat="job in jComp.jobs | pagination:jComp.paginator.instance" ng-model="job" ng-click="jComp.selectJob(job.jobID)">
<td>{{job.jobID}}</td>
<td>
{{job.productID}}<br>
{{job.productDescription}}<br>
</td>
<td>{{job.productType}}</td>
<td><img alt="No thumb" ng-src="{{job.thumbFURL}}"/></td>
<td>{{job.status}}</td>
</tr>
</tbody>
then in my component I am showing a popup modal div to ask user to choose an action. When the user clicks to change the job.status, there is a second layer of confirmation modal, and once confirmed in the component I am finding the job from the jComp.jobs List and updating the status. In side the popup modal the status gets updated but on the table it still shows the old status. And then when I paginate to next page and come back it gets updated. Before page switch it stays the same ? I tried calling scope.apply() after updating the jobs list, but it doesn't help. I like to know what is paginator.goNext() or paginator.goPrev() doing that causes the table list to refresh. Not clear about how the two way data binding working in this scenario. ( pagination is done using angular_pagination package )
I tried using :
<td ng-bind="job.status"/>
instead of:
<td>{{job.status}}</td>
and it fixed this issue. I am not sure why double brackets were not registering the object in the list to the change listeners / watchers. As far as I understand two way binding should be working with {{}} but in this case something was breaking it. It might be a bug in double brackets.

Custom Add and Edit Record Dialog in Infragistics Grid

I am working on Infragistics Grid in MVC and want to do some customization in it.
The issue is that data which I am showing is different than the inputs I am taking from the user (the editors in row editing/adding mode). There is additional processing needed to be done before displaying in a grid.
Infragistics grid provides a good mechanism to show the JSON object array which nice UI and events which works fine for me. The problem comes when I want to Edit a particular Row or Add New. For this Infragistics provides its own UI for it. Or in case we want to customize it, it doesn't provide much room to do so. It just allows providing a template for columns like the following:
<script id="rowEditDialogRowTemplate1" type="text/x-jquery-tmpl">
<tr class="tableBackGround">
<td class="labelBackGround"> ${headerText}
</td>
<td data-key='${dataKey}'>
<input />
</td>
</tr>
</script>
But I want to provide an entire template which will have my custom form and form elements.
I want a simple Infragistics Grid which will just show the data. If I click Add New within the grid then it will load my dialog.
If I double-click any row it will again open my dialog where I can edit the things. Later, once I save the data, I'll make a server trip and refresh the grid accordingly.
To summarize
I want to provide my own custom Form for Add and Edit in Infragistics Grid. And I'll take care of reloading the Grid after saving the data.
Reference : Infragistics Grid
Please help me to get this done!
You have found the correct API reference - in the 'options' tab look for the rowEditDialogTemplate option.
The use of the default Row Edit Template (yes, it can be used for adding rows as well) is shown in the official sample.
You can also find out more about it in the help topics: Row Edit Template and Configuring Row Edit Template.
Also, in the Infragistics forums you can find additional info on how to utilize the igGridUpdating feature's API methods (addRow and updateRow for example) with your fully custom form for row adding and editing.

getting the values of tds using jquery

I am using jquery 1.6.4 and I have a table. Initially in the table, a user is presented by only one row and a few columns. I, then, let users add as many rows as they would like using by doing this
$('.add').live('click', function(e){
e.preventDefault();
var $parentRow = $(this).parents('tr');
$parentRow.clone().insertAfter($parentRow);
$parentRow.next().find('input').val('');
$(this).replaceWith('-');
});
I also let them delete the rows on fly doing this
$('.delete').live('click', function(e){
alert("removing");
e.preventDefault();
$(this).parents('tr').remove();
});
However now I want the values that they are entering in these columns to be collected. I am not sure how to collect those values when they hit submit button as in my view source all I see is this
<tr>
<td class="actions">+</td>
<td><input type="text"></input></td>
<td><input type="text"></input></td>
<td><input type="text"></input></td>
<td><textarea rows="1"></textarea></td>
</tr>
In the page source it shows only one row where as in my view I definitely see three rows added. Not sure what am I missing and how to get the values
You don't have ids so it will be difficult to tell what you are actually collecting, but to get the values of the inputs, both static and dynamic, you can use this:
//submit code
$('input[type=submit]').click(function(){
$('table input').each(function(index,item){
//for testing you could just output to a div
//$('#output').append($(this).val());
});
});
From what I can tell, your input fields don't have names, so you're not going to get much when submit is pressed.
Also, you won't see DOM updates in your view source. View source will only show you what the page looked like when it first loaded.
To get a live view of the page, you can either use FireBug, for FireFox, or if you're using Google Chrome, there are developer tools under the "View" menu that you can use to see how the html looks live.

Resources