XPath: Get previous item, filtering by class - selenium

I have this HTML:
<div class="DivHeaderSizes" data-subgroup="1">
<img style="display:none" class="help-size-img-colorbox" data-subgroup="1_Man" src="Man.gif">
<div class="subgroup-description">Jogging</div>
<div class="help-size-link cboxElement" data-subgroup="1_Man">Tutorial</div>
</div>
<div style="float: left;" class="DivSizeElement">
<table data-size="41" class="SizeElement" style="display: none;">
<tbody>
<tr>
<td class="td-label-size">
<span class="label-size" data-size="41">41</span>
</td>
<td class="td-label-textbox">
<input name="ctl00$CthBody$sizelist$TxtSize_41" type="text" maxlength="4" id="CthBody_sizelist_TxtSize_41" class="txt-Size" data-price="19.50" data-size="41" data-available="0" data-subgroup="1" style="width:30px;">
</td>
</tr>
</tbody>
</table>
</div>
<div style="float: left;" class="DivSizeElement">
<table data-size="42" class="SizeElement" style="display: none;">
<tbody>
<tr>
<td class="td-label-size">
<span class="label-size" data-size="42">42</span>
</td>
<td class="td-label-textbox">
<input name="ctl00$CthBody$sizelist$TxtSize_S" type="text" maxlength="4" id="CthBody_sizelist_TxtSize_S" class="txt-Size" data-price="19.50" data-size="42" data-available="0" data-subgroup="1" style="width:30px;">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Using Selenium with C# and starting from input element with name
ctl00$CthBody$sizelist$TxtSize_41
I want the XPath expression to get the text "Jogging". Thanks.

If the context node is input[#name='ctl00$CthBody$sizelist$TxtSize_41'], then the following XPath will select the div containing "Jogging":
(preceding::div[#class='subgroup-description'])[1]
Or you could use:
ancestor::div[1]/preceding-sibling::div[1]/div[#class='subgroup-description']

Related

Bootstrap table column not same width when using a form input

I am trying to create a bootstrap table with one of the cell having a form input. However, I realised that this input prevents bootstrap from setting the table width to be the same for each column, even when I reduce the length of the input.
Can anyone help with this to adjust the width to be consistent for all columns? Thanks.
<!doctype html>
<head>
<link rel="stylesheet" href="./frameworks/bootstrap.min.css"></link>
<script src="./frameworks/bootstrap.min.js"></script>
<script src="./frameworks/button_plus_minus.js"></script>
<link href="./font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-7">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Time</th>
<th>Location</th>
<th>Item</th>
<th>Value ($)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>Australia</td>
<td>Silver</td>
<td>1500</td>
</tr>
<tr>
<td>2</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>Australia</td>
<td>Gold</td>
<td>
<div class="col-xs-8 input-group">
<span class="input-group-btn">
<button type="button" class="btn qtyminus" data-type="minus" field='quantity'">
<span class="fa fa-minus"></span>
</button>
</span>
<input id="inputvalue2" type="text" name="quantity" class="form-control qty" value="1000" min="1" max="100000"></input>
<span class="input-group-btn">
<button type="button" class="btn qtyplus" data-type="plus" field='quantity'">
<span class="fa fa-plus"></span>
</button>
</span>
</div>
</td>
</tr>
<tr>
<td>3</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>US</td>
<td>Computer</td>
<td>2000</td>
</tr>
<tr>
<td>4</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>Japan</td>
<td>Bags</td>
<td>1000</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
Added a class to the <table> and the <input> tag. By making the text-align center will make your table more subtle and consistent. You should also try using classes for other screen sizes like col-md-6 or col-lg-4 whatever suits you best. But this practice will help you control your UI across different screen sizes. Hope that helps. Let me know if this doesn't work out for you.
<!doctype html>
<head>
<link rel="stylesheet" href="./frameworks/bootstrap.min.css"></link>
<script src="./frameworks/bootstrap.min.js"></script>
<script src="./frameworks/button_plus_minus.js"></script>
<link href="./font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<style>
.txt_cent{
text-align:center;
}
.inp_width{
width:70px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-7">
<table class="table table-striped txt_cent" >
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Time</th>
<th>Location</th>
<th>Item</th>
<th>Value ($)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>Australia</td>
<td>Silver</td>
<td>1500</td>
</tr>
<tr>
<td>2</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>Australia</td>
<td>Gold</td>
<td>
<div class="col-xs-8 input-group">
<span class="input-group-btn">
<button type="button" class="btn qtyminus" data-type="minus" field='quantity'">
<span class="fa fa-minus"></span>
</button>
</span>
<input id="inputvalue2" type="text" name="quantity" class="form-control qty inp_width" value="1000" min="1" max="100000"></input>
<span class="input-group-btn">
<button type="button" class="btn qtyplus" data-type="plus" field='quantity'">
<span class="fa fa-plus"></span>
</button>
</span>
</div>
</td>
</tr>
<tr>
<td>3</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>US</td>
<td>Computer</td>
<td>2000</td>
</tr>
<tr>
<td>4</td>
<td>28 Aug</td>
<td>10:47:21</td>
<td>Japan</td>
<td>Bags</td>
<td>1000</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>

Materialize CSS Remove table head spacing

I making a simple demo where i have few employees information. I am using materialize css table. But i am getting extra space between sr.no and other column names.
here is my code :
<br/>
<div class="row">
<div class="col l8">
<div class="card darken-2">
<div class="card-content">
<span class="card-title">{{tableTitle}}</span>
<br/>
<div class="row">
<div class="input-field col s4">
<input id="empSearch" type="text" placeholder="Search">
</div>
</div>
<br/>
<div class="row">
<div class="col lg7">
<table class="bordered highlight responsive-table">
<thead>
<tr>
<th>Sr.no</th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
<th>Address</th>
<th>Designation</th>
<th>Department</th>
<th>Salary</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of EmployeeData;let i= index">
<td>{{i+1}}</td>
<td>{{item.Name}}</td>
<td>{{item.Age}}</td>
<td>{{item.Gender}}</td>
<td>{{item.Address}}</td>
<td>{{item.Designation}}</td>
<td>{{item.Department}}</td>
<td>{{item.Salary}}</td>
<td>
<i class="material-icons">delete</i>
</td>
<td>
<i class="material-icons">mode_edit</i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
in the <th> you could set width="30px" or whatever your're comfortable with.
The icons, I'd put in one cell, and use text-align: right
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.1/css/materialize.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<table>
<thead>
<tr>
<th width="30px">Sr.no</th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
<th>Address</th>
<th>Designation</th>
<th>Department</th>
<th>Salary</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>{{i+1}}</td>
<td>{{item.Name}}</td>
<td>{{item.Age}}</td>
<td>{{item.Gender}}</td>
<td>{{item.Address}}</td>
<td>{{item.Designation}}</td>
<td>{{item.Department}}</td>
<td>{{item.Salary}}</td>
<td style="text-align: right">
<i class="material-icons">delete</i>
<i class="material-icons">mode_edit</i>
</td>
</tr>
</tbody>
</table>

Not able to check the check box, exception "element not visible"

In an table which can contain more rows, user is searchable using the email id. After searching, selecting the first check box. But selenium is throwing the element not visible exception.
//*[#id='share_user']/tbody/tr1/td1//label
//*[#id='share_user']/tbody/tr1/td1//input
//label[#for='checkbox_416']
last identifier is dynamic. Still getting the element not visible exception.
Table code is mentioned below
<table class="table table-striped table-hover dataTable" id="share_user"
aria-describedby="share_user_info">
<thead>
<tr role="row">
<th class="small-cell sorting" role="columnheader" tabindex="0"
aria-controls="share_user" rowspan="1" colspan="1" style="width: 137px;"
aria-label="Share Profile : activate to sort column ascending">Share Profile </th>
<th class="medium-cell sorting" role="columnheader" tabindex="0"
aria-controls="share_user" rowspan="1" colspan="1" style="width: 523px;"
aria-label="User Details: activate to sort column ascending">User Details</th>
<th class="medium-cell sorting_asc" role="columnheader" tabindex="0"
aria-controls="share_user" rowspan="1" colspan="1" style="width: 366px;"
aria-sort="ascending" aria-label="Access: activate to sort column descending">Access</th>
</tr>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
<tr class="odd">
<td class="">
<div class="checkbox check-default">
<input name="checkUser" id="checkbox_416" value="416" class="shareCheck"
type="checkbox">
<label for="checkbox_416"></label>
</div>
</td>
<td class=" ">
<img src="" class="img-responsive display-inline share-image">
<div class="display-inline">
<p class="share-name">alexx</p>
<p class="muted">
<i class="fa fa-envelope" hidden="true"></i>
<span>alexxm360#gmail.com</span>
</p>
</div>
</td>
<td style="vertical-align: middle;" class=" sorting_1">
<div class="select2-container medium-cell" id="s2id_rolelink416"
style="float:left;">
<a href="javascript:void(0)" onclick="return false;" class="select2-choice"
tabindex="-1">
<span class="select2-chosen">PROFILE ADMIN</span>
<abbr class="select2-search-choice-close"></abbr>
<span class="select2-arrow">
<b></b>
</span>
</a>
<input class="select2-focusser select2-offscreen" id="s2id_autogen11"
type="text">
<div class="select2-drop select2-display-none select2-with-searchbox">
<div class="select2-search">
<input autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false" class="select2-input"
type="text">
</div>
<ul class="select2-results">
</ul>
</div>
</div>
<select name="profileUsers.roleId" id="rolelink416"
class="medium-cell select2-offscreen" style="float:left;" tabindex="-1">
<option value="6">PROFILE ADMIN</option>
<option value="7">PROFILE AGENT</option>
<option value="8">PROFILE VIEWER</option>
<option value="196">profile role</option>
</select>
</td>
</tr>
</tbody>
</table>
providing the screen shots as well.
Try to use explicit wait with Expected Conditions
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement checkbox = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='share_user']/tbody/tr[1]/td[1]//input")));
checkbox.click();
You can use the following expression, I have verified working fine.
driver.findElement(By.xpath("//*[#id='share_user']/tbody/tr[1]/td[1]/div")).click();
Try this
int ele_size=driver.findElements(By.xpath("locator")).size();
driver.findElements(By.xpath("locator")).get(ele_size-1).click();
We might encounter element not visible exception if element matching the locator existed in the DOM but is not currently visible. So we have to take the size of the element in first statement then in next statement we have to take the first element from the list and click on element.
Used this //*[#id='share_user']/tbody/tr[1]/td[1]/div worked

Automating using Selenium

I am trying to find the text from the Select Elements "[New List]". The HTML code behind this is :
<div id="pageBody">
<div class="grid">
<div class="col_12 bgColor column">
<form method="POST" action="pickListEdit.cfm" name="formMain" id="formMain">
<input type="hidden" id="usrAction" name="usrAction" value="NONE"/>
<input type="hidden" id="listtype" name="listtype" value="ACCTS"/>
<input type="hidden" id="listmodified" name="listmodified" value="0"/>
<table cellpadding="0" cellspacing="0" border="0" width="620">
<tbody>
<tr class="alt first last">
<td>
<table cellpadding="0" cellspacing="0" border="0" width="360">
<tbody>
<tr class="alt first">
<td width="150" align="right" class="critH2">
<td height="1" align="left">
<select name="listkey" size="1" onchange="formSubmit('GET');"class="selectfont">
<option value="0">[New List]</option>
</select>
</td>
</tr>
<tr class="alt last">
</tbody>
</table>
</td>
<td width="10"/>
<td width="10"/>
<td valign="top">
</tr>
</tbody>
</table>
<table border="0" cellspacing="0" cellpadding="0" width="600">
</form>
</div>
</div>
</div>
</div>
</body>
The C# code that I am using is :
var AccPic = Driver.Instance.FindElement(By.ClassName("selectfont"));
var selectelement = new SelectElement(AccPic);
selectelement.SelectByText(AP);
The problem is it is unable to find the field name. What I need to do is find the element [New List] and select it. Can someone please help.
Assuming it's the only option tag on the page:
var newList = Driver.Instance.FindElement(By.TagName("option"));
var selectedElement = new SelectElement(newlist);

What can I do to see all the contents of my page when screens are smaller

I am new to bootstrap. What can I do to see all the contents of my page when screens are smaller. My table in Activities panel doesn't adjust with the screen size.I have a div named MiddleDiv where I append 1 or more tables on the fly.
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 col-xs-12">
<div class="panel panel-primary">
<div class="panel-heading">Activities</div>
<div class="panel-body">
<div class="table-responsive" id="MiddleDiv">
<table width="100%" style="margin-bottom:10px" id="Table_1" class="TableBlankClass table">
<tbody>
<tr class="bg-success">
<td style="font-weight:bold" id="ActivityCompany_1" colspan="3">Company(Bill to): TD General Insurance Company</td>
<td style="font-weight:bold" id="ActivityClient_1" colspan="6">Client: Test Adjsuter</td>
</tr>
<tr>
<td colspan="3">
<table width="100%">
<tbody>
<tr>
<td><button class="btn btn-danger btn-xs" id="ActivityDel_1" onclick="DelActivity('Table_1')" type="button">Del</button></td>
<td class="ActivitiesHeading">Activity</td>
<td>
<select onchange="GetRate('Table_1')" id="ActivityTypeDropDown_1" style="width:200px;" class="form-control TableSelectClass">
<option value="- Select One -" selected="">- Select One -</option>
<option value="Accomodation">Accomodation</option>
</select>
</td>
</tr>
</tbody>
</table>
</td>
<td class="ActivitiesHeading">Comments</td>
<td colspan="2" class="ActivitiesHeading"><textarea rows="1" style="width: 275px; height: 35px;" class="form-control" id="ActivityComments_1"></textarea></td>
<td class="ActivitiesHeading">Status<span id="ActivitySpan_1"></span></td>
<td colspan="2" class="ActivitiesHeading">
<select onchange="CalculateActivities(); CreateRemoveReasonButton('Table_1');" id="ActivityStatusDropDown_1" style="width:200px;" class="form-control">
<option value="24859" selected="">Waiting To Process Payer Invoice</option>
</select>
</td>
</tr>
<tr>
<td class="ActivitiesHeading">Rate</td>
<td class="ActivitiesHeading">Qty</td>
<td class="ActivitiesHeading">Discount</td>
<td class="ActivitiesHeading">Discount %</td>
<td class="ActivitiesHeading">Reason For Discount</td>
<td class="ActivitiesHeading">Tax Applicable</td>
<td class="ActivitiesHeading">Taxes</td>
<td class="ActivitiesHeading">SubTotal</td>
<td class="ActivitiesHeading">Gross Total</td>
</tr>
<tr>
<td><input type="text" onblur="if (this.value=='') {this.value = 0;}" value="0" onkeyup="CalculateActivities()" id="ActivityRate_1" class="form-control TableNumericClass"></td>
<td><input type="text" onblur="if (this.value=='' || this.value=='0') {this.value = 1;}" value="1" onkeyup="CalculateActivities()" id="ActivityQty_1" class="form-control TableNumericClass"></td>
<td><input type="text" onblur="if (this.value=='0') {this.value = '';}" value="" onkeyup="CalculateActivities()" id="ActivityDiscount_1" class="form-control TableDiscountClass"></td>
<td><input type="text" onblur="if (this.value=='0') {this.value = '';}" value="" onkeyup="CalculateActivities()" id="ActivityDiscountPercentage_1" class="form-control TableDiscountClass"></td>
<td>
<select id="ReasonForDiscountDropDown_1" class="form-control">
<option value="- Select One -" selected="">- Select One -</option>
<option value="Late Report Delivery">Late Report Delivery</option>
<option value="Incorrect File Management">Incorrect File Management</option>
<option value="Client Satisfaction">Client Satisfaction</option>
<option value="Other - See Service Notes">Other - See Service Notes</option>
</select>
</td>
<td>
<select onchange="CalculateActivities()" id="ActivityTaxApplicable_1" class="form-control">
<option value="Yes" selected="">Yes</option>
<option value="No">No</option>
</select>
</td>
<td><img width="15" height="15" title="<body> <table width="150px" border="0" cellspacing="1" cellpadding="1"> <tr> <td class="ToolTipTableClass">Tax1 :</td> <td class="ToolTipTableClass">0.00</td> </tr> <tr> <td class="ToolTipTableClass">Tax2 :</td> <td class="ToolTipTableClass" >0.00</td> </tr> </table> </body>" src="/files/404048/93171/Info-32.png" id="ActivityTaxesAmount_1" class="TaxesClass" data-original-title="<body> <table width="150px" border="0" cellspacing="1" cellpadding="1"> <tr> <td class="ToolTipTableClass">Tax1 :</td> <td class="ToolTipTableClass"></td> </tr> <tr> <td class="ToolTipTableClass">Tax2 :</td> <td class="ToolTipTableClass" ></td> </tr> </table> </body>"></td>
<td id="ActivitySubTotal_1">100.00</td>
<td id="ActivityGrossTotal_1">100.00</td>
</tr>
<tr>
<td class="ActivitiesHeading">Measure</td>
<td colspan="2" class="ActivitiesHeading">GAP Code</td>
<td colspan="3" class="ActivitiesHeading">Other Description</td>
<td colspan="3" class="ActivitiesHeading"> </td>
</tr>
<tr>
<td>
<select id="ActivityMeasure_1" class="form-control">
<option selected="" value="- Select One -">- Select One -</option>
</select>
</td>
<td colspan="2">
<select id="ActivityGAPCode_1" class="form-control">
<option value="00000" selected=""><-Select One-></option>
</select>
</td>
<td colspan="3"><input type="text" id="ActivityOtherDescription_1" class="form-control"></td>
<td colspan="3">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 col-xs-12">
<div class="panel panel-primary">
<div class="panel-heading">Total</div>
<div class="panel-body">
<div class="table-responsive">
<table width="100%" class="table">
<tbody>
<tr>
<td class="HeadingTD">SubTotal</td>
<td id="AllSubTotal"></td>
<td class="HeadingTD">Discount</td>
<td id="AllDiscount"></td>
<td class="HeadingTD">Tax</td>
<td id="AllTax"></td>
<td class="HeadingTD">Gross Total</td>
<td id="AllGrossTotal"></td>
</tr>
<tr>
<td colspan="2" id="AddItemTD"></td>
<td colspan="2" id="SubmitActivitiesTD"></td>
<td colspan="2" id="VoidInvoiceTD"></td>
<td colspan="2" align="right"><button class="btn btn-primary btn-sm" onclick="window.parent.close()" type="button">Close</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
I can see you are just wrapping traditional HTML tables with some bootstrap classes expecting them to be responsive.
It's a good start but you need to rethink how you construct your tables when you use bootstrap.
Bootstrap uses their "Grid System" http://getbootstrap.com/css/#grid
The grid system doesn't use tables at all. It uses divs with specific classes on them achieve the layout you are looking for. Until you fully use the bootstrap grid system you will not truly see a responsive design.
Take the time to learn the bootstrap grid system.
A bit of a side note and personal opinion: Looking at your form design (which looks great btw) you might not like the result of a responsive design. All of the form fields will end up stacking on top of each other. This form design really only works horizontally. If it were vertically aligned it might get very confusing. If it were me, I might design the form to fit interfaces as small as a tablet but not mobile.