How to Click on checkboxes one by one in Groovy/Geb? - html

I was working on an automation script using Groovy/Geb and the HTML code looks like the tags below:
<table class="backgrid">
<thead>
<tr>
<th class="select-all-header-cell">
<input tabindex="-1" type="checkbox">
</th>
<th>
<a>
List Item<b class="sort-caret"></b>
</a>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="select-row-cell">
<input tabindex="-1" type="checkbox">
</td><td class="string-cell">CAD</td>
</tr>
<tr>
<td class="select-row-cell">
<input tabindex="-1" type="checkbox">
</td>
<td class="string-cell">
USD
</td>
</tr>
<tr>
<td class="select-row-cell">
<input tabindex="-1" type="checkbox">
</td>
<td class="string-cell">.
GBP
</td>
</tr>
<tr>
<td class="select-row-cell">
<input tabindex="-1" type="checkbox">
</td>
<td class="string-cell">
KPW
</td>
</tr>
</tbody>
</table>
I need to click on the checkboxes inside the one by one and then move to the next stage of the automation. But I am stuck here. I know for clicking checkboxes I should work with interact {} but I can't find any sample example for this kind of stuff. Any kind of hints or suggestions would be a great help for me!

You don't need to use interact {} to achieve it - there is a much easier way using click().
To click the checkbox in header you can use:
$("table.backgrid thead input").click()
To click on the currency checkboxes use:
def checkboxes = $("table.backgrid tbody input")
checkboxes[0].click() //CAD
checkboxes[2].click() //GBP

Quoting the docs
[...] Calling value(value) will set the current value of all elements in the Navigator. The argument can be of any type and will be coerced to a String if necessary. The exceptions are that when setting a checkbox value the method expects a boolean...
So, I didn't try this myself, but I think that if you can change your html to something like this (note that I added a name attribute to the element)
[...]
<td class="select-row-cell">
<input tabindex="-1" type="checkbox" name="GBP">
</td>
<td class="string-cell">.
GBP
</td>
[...]
Then the next code should do the trick:
$("checkbox", name: "GBP").value(true) //Should set the checkbox to 'checked'

Related

Current input value does not get passed to event handler in AngularJS

<tr ng-repeat="item in groups">
<td hidden><input type="hidden" value="{{item.id_group}}" /></td>
<td><input type="text" value="{{item.description}}" class="form-control" /></td>
<td>
Edit |
Delete
</td>
</tr>
So this code was supposed to show values in a table and when the user changes anything in the description and click on Edit, it should POST the new value to the server. Instead it's posting the old value, I need some help please to identify why this is happening.
Try using Ng-model
<tr ng-repeat="item in groups track by $index">
<td hidden><input type="hidden" ng-model="groups[$index].id_group" /></td>
<td><input type="text" ng-model="groups[$index].description" class="form-control" /></td>
<td>
Edit |
Delete
</td>
</tr>

Pre-filling search query's. POST Http

I'm trying to understand how to use query strings in URL's and trying to make some shortcuts to make my job easier. From what I've been reading here and there there are ways to pre-program a website using query parameters. I went to the website I'm interested and pulled the "search form" part that I would like to pre-fill (this is a database search, I would like to have a direct link that just pre-populates and just shows the results of the search instead of me filling it each time I look for new data).
This is from the website's "inspect source". the part of it:
<form id="partInquiry" name="partInquiry" action="PartInquiryForEdit.htm" method="post">
<table style="width: 40%">
<tr>
<td colspan="2" align="left"></td>
</tr>
<tr class="ez1">
<td class="label">Search By:
</td>
<td class="input"><select id="searchby" name="search">
<option value="part_number">Part Number</option><option value="part_description">Part Description</option><option value="rdo_gpl">RDO/GPL</option><option value="rdo_productCd">RDO/Product Code</option>
</select></td>
</tr>
<tr class="ez1">
<td class="label">Match By:
</td>
<td class="input"><select id="matchby" name="match">
<option value="matches">Exactly Matches</option><option value="contains">Contains</option><option value="startsWith">Starts With</option><option value="endsWith">Ends With</option>
</select></td>
</tr>
<tr class="ez1">
<td class="label">Search For:
</td>
<td class="input"><input id="searchfor" name="searchString" type="text" value="" maxlength="750"/> </td>
</tr>
<tr class="ez1">
<td colspan="2"><input type="submit" onclick="clearSession();"
value="Submit"
class="Button" /> <input type="submit"
value="Cancel"
class="Button" /></td>
</tr>
</table>
<BR>
<BR>
<table>
<tr>
<td><label class="errorBox" id="errorBox"></label>
<table>
<tr>
<td></td>
</tr>
</table>
<table>
<tr>
<td></td>
</tr>
</table> <input type="hidden" id="rowsToAdd" name="rowsToAdd" /> <input
type="hidden" id="rowsToRemove" name="rowsToRemove" /> <input
type="hidden" id="rowsToSubmit" name="rowsToSubmit" /> <input
type="hidden" id="isExport" name="isExport" />
<table>
<tr>
<td></td>
</tr>
</table> </td>
<td></td>
</tr>
</table>
<BR>
<BR>
</form>
I tried the following to no avail and I dont know how else to do it:
?search=part_description&searchby=part_description&matchby=contains&match=contains&searchfor=MYSEARCHSTRING&searchString=MYSEARCHSTRING&Submit
?search=part_description&match=matches&searchString=MYSEARCHSTRING&Submit&submit
?searchby=part_description&matchby=matches&searchfor=MYSEARCHSTRING
I'm not sure I'm understanding how to do this or if maybe there's somewhere in the code where It disables this (and how would I find it?). As shown, I tried using the "names" but nothing, I also tried using the "id"s but nothign either. Also I dont know how to actually "submit" the search since the submit button has no id or name. only an "onclick" and a "value".
Pre-populating a form via the query string is something that the website must explicitly support, it's not a general feature. The website must be coded to accept values on the query string and then return the appropriate HTML to pre-select those values.
If the website does not support this, then what you can do as an alternative is create a bookmarklet that populates the fields you want. For example:
javascript:var id=document.getElementById.bind(document);id('searchby').value='part_description';id('matchby').value='matches';id('searchfor')='MYSEARCHSTRING';void 0;
After you've loaded the site, you can click the bookmark to pre-fill the form.

How can i display Array values in a single text box using Angular Js?

I'm displaying list of values fetched from DB. One of its attributes is array. I handled it using table as below,
<tr>
<td>{{movId}}</td>
<td>{{movtitle}}</td>
<td>
<ul>
<li ng-repeat="mem in mov.cast>{{mem}}</li>
</ul>
</td>
</tr>
But i've changed it to display in text box instead of table so that i can edit as below,
<input type="text" ng-value="movId">
<input type="text" ng-value="movtitle">
I don't know how to display array attribute ("Cast") in text box
How to attain this...Hope it is possible...if not any alter way to handle it??
You can use ng-model:
<input type="text" ng-value="movie.movTitle" ng-model="movie.movTitle"/>
I don't know how your data is structured exactly, but you could do it like this:
$scope.movies = [
{
movId:1234,
movTitle:'gone with the wind',
cast:[
'bill',
'ben',
'bart'
]
}
]
HTML:
<table ng-repeat="movie in movies">
<tr>
<td>
<input type="text" ng-value="movId" ng-model="movie.movId"/>
</td>
<td>
<input type="text" ng-value="movie.movTitle" ng-model="movie.movTitle"/>
</td>
</tr>
<tr>
<td ng-repeat="item in movie.cast">
<input type="text" ng-value="item" ng-model="item"/>
</td>
</tr>
</table>
Demo

Why can't I submit my form with WWW::Mechanize::Firefox in Perl?

I have an HTML this is part of the form I'm working on
<form action="/goform/FormUpdateVAP" autocomplete="off" name="myform" id="formid" method="POST">
<table>
<tbody>
<tr>
<td align="right"><span class="label">Name:</span></td>
<td><input id="essid" name="essid" value="X" type="text"></td>
</tr>
<tr>
<td align="right"><input id="broadcast_essid" name="broadcast_essid" value="any" checked="" type="checkbox"></td>
<td><span class="label">Broadcast name:</span></td>
</tr>
</tbody>
</table>
<!-- BEGIN RIGHT COLUMN -->
<table>
<tbody><tr>
<td>
<input name="authentication" id="authentication" value="any" onclick="Update();" type="checkbox"><span class="label"><b>authentication</b></span>
</td>
<td>
<input onclick="Update();" name="wp" id="wp" value="any" type="checkbox"><span class="label"><b>Wp</b></span>
<select id="8021x_mode" name="8021x_mode" onchange="Update();"><option value="wpa">WPA</option>
<option value="wep">WEP</option>
</select>
</td>
</tr>
<tr>
<td height="26">
<input onclick="Update();" name="w_p" id="w_p" value="any" type="checkbox"><span class="label"><b>Wp</b></span>
<select id="8021x_mode" name="8021x_mode" onchange="Update();"><option value="wpa">WPA</option>
<option value="wep">WEP</option>
</select>
</td>
</tr>
<tr>
<td>
<input id="cancel" name="cancel" value="Cancel" onclick="window.location.href = '/fg/list.asp';" type="button">
</td>
<td>
<input id="add-2" name="add" value="Save" type="submit">
</td>
</tr>
</tbody>
</table>
I'm trying to submit it filling the Name and the Broadcast name. And checking the 8021x_mode and the wp checkboxes. If I tick 8021x_mode and set the fields the form submits just fine. But when I try ticking wp it doesn't submit. I got no error messages.
Here's my code so far:
use WWW::Mechanize::Firefox;
use Crypt::SSLeay;
use URI::Fetch;
use HTML::TagParser;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; #not verifying certificate
my $url = 'https://';
$url = $url.#ARGV[0];
my $mech = WWW::Mechanize::Firefox->new;
$mech->get($url);
$mech->form_id('formid');
$mech->tick( '8021x_mode','any');
$mech->tick( 'wp','any'); --after I add this the form doesn't submit
my $name = #ARGV[1];
$mech->set_fields(
'vap_name' => $name,
'essid' => $name,
);
$mech->click_button( id => 'add-2' );
$mech->reload();
add-2 is the submit button. Any idea why is not working? If you need more information please let me now. Any help will be highly appreciated.
The problem is that the html doesn't contains the choice any for 8021x_mode.
I get this error :
No elements found for Checkbox with name '8021x_mode' and value 'any'
at test.pl line 24.
To check the form, I recommend you the mech-dump utility (installed with WWW::Mechanize)
$ mech-dump --forms http://domain.tld/path_to_forms
POST /goform/FormUpdateVAP [myform]
essid=X (text)
broadcast_essid=<UNDEF> (checkbox) [*<UNDEF>/off|any]
authentication=<UNDEF> (checkbox) [*<UNDEF>/off|any/authentication]
wp=<UNDEF> (checkbox) [*<UNDEF>/off|any/Wp]
8021x_mode=wpa (option) [*wpa/WPA|wep/WEP]
w_p=<UNDEF> (checkbox) [*<UNDEF>/off|any/Wp]
8021x_mode=wpa (option) [*wpa/WPA|wep/WEP]
cancel=Cancel (button)
add=Save (submit)
As you can see, there's no any choice...
Maybe the javascript there is doing some things that we don't know.
A workaround is to use LiveHttpHeaders Firefox addon to catch the forms POSTed to /goform/FormUpdateVAP and then instead of ticking, do a POST request with WWW::Mechanize.

html - in order of elements - not by the order of writnig

In the following fiddler why do I see the "BBBB" before the "AAAA"? I expected the order to be according the <tr>.
<table style="text-align:left;">
<tr>
<td class="field">
<label for="...">...</label> <br/>
<myattributes>
<tr>
<td>
<li>
...AAAA
</li>
</td>
</tr>
</myattributes>
<label>
<input data-autocomplete-source="..." />
BBBB
</label>
</td>
</tr>
</table>
​
Your markup is messed up.
The nested <tr> closes the previous table row and add a new one.
By ending the row with </tr> you are currently not in a table line anymore.
When elements o the markup put between table rows, they are moved above the table in the DOM. That's way you see the "BBBB" first.