Unable to locate input element under div in Selenium - c#

I am trying to located input element "mpcname" in js file which is under div and table elements.
The code I have written to locate the element is as follows but is not detecting the Input element with the name mpcName in it.
Driver.FindElement(By.XPath(".//input[contains(.,'mpcName')]"));
The HTML code looks like below.
<div enable-tooltips="" class="ng-scope">
<form name="InstanceDetailForm" ng-submit="doApply()" novalidate="" class="ng-pristine ng-invalid ng-invalid-required ng-valid-unnamed ng-valid-maxlength ng-valid-not-integer">
<table class="table-condensed" style="width: 100%;">
<tbody><tr>
<td></td>
</tr>
<tr>
<td>
<table style="width: 100%;">
<tbody><tr>
<td class="pull-left">
<h4 class="ng-binding">Controller Configuration<b ng-show="InstanceIsDirty()" class="ng-hide"> *</b></h4>
</td>
<td class="pull-right">
<button id="btnApply" type="submit" class="btn btn-primary" data-toggle="tooltip" data-placement="bottom" title="Save an APC instance">
<span class="glyphicon glyphicon-save"></span> Apply
</button>
<button id="btnExportConfig" type="button" class="btn btn-primary" ng-click="goToInstanceList()" data-toggle="tooltip" data-placement="bottom" title="Cancel save and redirect to APC instance list page.">
<span class="glyphicon glyphicon-remove"></span> Cancel
</button>
</td>
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td>
<table style="width: 100%" class="table-condensed table-striped table-bordered">
<tbody><tr>
<td>Name</td>
<td>
**<input id="mpcname" name="mpcname" ng-model="mpcname" value="" ng-required="true" is-named="" size="50" autocomplete="off" ng-disabled="!allowEditInstanceName(mpcname,state)" class="ng-pristine ng-empty ng-invalid ng-invalid-required ng-valid-unnamed ng-touched" required="required" type="text">**

With xpath ".//input[contains(.,'mpcName')]" you are actually looking for an <input> element with text mpcName. mpcName is actually the id (and name and ng-model) attribute. You can use
Driver.FindElement(By.Id("mpcName"));
Or
Driver.FindElement(By.Name("mpcName"));

following code may be helpful
Driver.FindElement(By.XPath(".//input[contains(#id,'mpc')]");
Driver.FindElement(By.XPath(".//input[contains(#class,'ng-pris')]");

Related

Unable to locate element inside a table using xpath with selenium

I want to click on a button inside my table each row has a update button I want to click on a specfic button inside my table.
Here is a what my table looks like:
<table _ngcontent-vhp-c82="" datatable="" id="dtOptionsComments" class="display table table-striped table-bordered dt-responsive dataTable dtr-inline" aria-describedby="dtOptionsComments_info" style="width: 100%;" width="100%">
<thead _ngcontent-vhp-c82="">
<tr _ngcontent-vhp-c82="">
<th _ngcontent-vhp-c82="" class="no-marking sorting_disabled" rowspan="1" colspan="1" style="width: 50.4px;" aria-label=""></th>
<th _ngcontent-vhp-c82="" class="sorting sorting_asc" tabindex="0" aria-controls="dtOptionsComments" rowspan="1" colspan="1" style="width: 1109.4px;" aria-label="Comment.Comment Shipping.ShippingDatatable.aria.sortDescending" aria-sort="ascending">Comentario Shipping.Shipping</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td class="no-marking dtr-control">
<a href="javascript:void(0);">
<span data-toggle="modal" data-target="#update-modal" update-comment-text="6 MESES DE GARANTIA" update-comment-id="5" class="material-icons md-18 clickable"> edit </span>
</a>
<a href="javascript:void(0);">
<span data-toggle="modal" data-target="#delete-modal" delete-comment-id="5" class="material-icons clickable">delete</span>
</a>
</td>
<td class="sorting_1">6 MESES DE GARANTIA</td>
</tr>
<!-- MORE ROWS!!! -->
</tbody>
<tfoot _ngcontent-vhp-c82="">
<tr _ngcontent-vhp-c82="">
<td _ngcontent-vhp-c82="" class="no-marking" rowspan="1" colspan="1">
<a _ngcontent-vhp-c82="" href="javascript:void(0);">
<span _ngcontent-vhp-c82="" class="material-icons clickable"> add_box </span>
</a>
</td>
<td _ngcontent-vhp-c82="" rowspan="1" colspan="1">
<input _ngcontent-vhp-c82="" formcontrolname="addComment" type="text" id="addComment" name="addComment" class="form-control ng-untouched ng-pristine ng-invalid">
<!---->
</td>
</tr>
</tfoot>
</table>
Here is my code trials:
IWebElement btnUpdate = _driver.FindElement(By.XPath("//*[update-comment-id='" + commentAction.GetLastQuoteInsertId().ToString() + "']"));
btnUpdate.Click();
I have validated that the function GetLastQuoteInsertId returns the proper value
Why is my xPath selector wrong how can I fix it thank you for your help.
You were almost there. While considering a xpath the attribute_name should be always preceded by a # sign.
Additionally to make the xpath more canonical as the element is a <span> element you can mention //span to start the xpath.
Effectively, your line of code will be:
IWebElement btnUpdate = _driver.FindElement(By.XPath("//span[#update-comment-id='" + commentAction.GetLastQuoteInsertId().ToString() + "']"));
btnUpdate.Click();

C# Selenium Select all column elements if two conditions are met (Multiple Conditions)

I'm trying to retrieve all elements from a html table td, however when I try to find elements by xpath with multiple conditions it fails retrieving 0 elements, there is no problem getting all values with a single condition. So far my issue is probably in the order of the html elements.
This is the search by a single condition using xpath which works fine:
"//input[#class='managebtn'][#value='repost']"
This is what I am trying to achieve without desired result:
"//td[contains(text(),'manage')]/div[#class='regular']/form[#class='manage']/input[#class='managebtn'][#value='repost']"
The following html table is the one I am trying to read"
<tbody aria-live="polite" aria-relevant="all">
<tr class="posting-row odd ui-state-default" role="row">
<td class="status expired">
<small class="gc" style="background:">
Expired </small>
</td>
<td class="buttons expired"></td>
</tr>
<tr class="posting-row even ui-widget-content" role="row">
<td class="status deleted">
<small class="gc" style="background:">
Deleted </small>
</td>
<td class="buttons deleted">
<div class="regular">
<form action="https://" method="GET" class="manage display">
<input type="hidden" name="action" value="display">
<input type="submit" name="go" value="display" class="managebtn">
</form>
<form action="https://" method="GET" class="manage ">
<input type="hidden" name="action" value="repost">
<input type="submit" name="go" value="repost" class="managebtn">
</form>
</div>
</td>
</tr>
<tr class="posting-row odd ui-state-default" role="row">
<td class="status deleted">
<small class="gc" style="background:">
Deleted </small>
</td>
<td class="buttons deleted">
<div class="regular">
<form action="https://" method="GET" class="manage display">
<input type="hidden" name="action" value="display">
<input type="submit" name="go" value="display" class="managebtn">
</form>
<form action="https://" method="GET" class="manage ">
<input type="hidden" name="action" value="repost">
<input type="submit" name="go" value="repost" class="managebtn">
</form>
</div>
</td>
</tr>
<tr class="posting-row even ui-widget-content" role="row">
<td class="status deleted">
<small class="gc" style="background:">
Deleted </small>
</td>
<td class="buttons deleted">
<div class="regular">
<form action="https://" method="GET" class="manage display">
<input type="hidden" name="action" value="display">
<input type="submit" name="go" value="display" class="managebtn">
</form>
<form action="https://" method="GET" class="manage ">
<input type="hidden" name="action" value="repost">
<input type="submit" name="go" value="repost" class="managebtn">
</form>
</div>
</td>
</tr>
I only want to retrieve all values from second column (value='repost')only when the first column has the value Expired.
Looks like since this table has multiple elements inside the columns, maybe there something I am overlooking.
Since the columns have th like this:
<th data-column="0" class="tablesorter-header tablesorter-headerUnSorted ui-widget-header ui-corner-all ui-state-default" tabindex="0" scope="col" role="columnheader" aria-disabled="false" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="status: No sort applied, activate to apply an ascending sort">
<div class="tablesorter-wrapper" style="position:relative;height:100%;width:100%">
<div class="tablesorter-header-inner">
status <i class="tablesorter-icon ui-icon ui-icon-carat-2-n-s"></i>
</div>
</div>
</th>
<th class="sorter-false tablesorter-header tablesorter-headerUnSorted ui-widget-header ui-corner-all ui-state-default" data-column="1" scope="col" role="columnheader" aria-disabled="true" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="manage: No sort applied, sorting is disabled">
<div class="tablesorter-wrapper" style="position:relative;height:100%;width:100%">
<div class="tablesorter-header-inner">
manage <i class="tablesorter-icon ui-icon"></i>
</div>
</div>
</th>
I do't know if it is possible to have a line of code like this one in order to get the values I need:
driver.findElement(By.xpath("//th[#class='sorter-false tablesorter-header tablesorter-headerUnSorted ui-widget-header ui-corner-all ui-state-default' and #text()='manage']"));
This is how the table looks like:
To identify the elements with value attribute as repost within the items with status as Expired you have to induce WebDriverWait for the VisibilityOfAllElementsLocatedBy() and you can use the following xpath based Locator Strategy:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.XPath("//tr[contains(#class, 'posting-row')][./td[#class='status expired']]//td[#class='buttons expired']//input[#class='managebtn' and #value='repost']")));
With SeleniumExtras.WaitHelpers you can use:
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.XPath("//tr[contains(#class, 'posting-row')][./td[#class='status expired']]//td[#class='buttons expired']//input[#class='managebtn' and #value='repost']")));

I need help to implement XPath

I have the following email from amazon that is from temp-mail.org
Basically amazon has sent me a verification code after i signed up with an email from temp-mail.org. I would like to use XPath to scrape/extract that Verification code and ignore everything else in the email and save it as a variable.
Here is the source for the email:
<div class="col-md-7 col-md-offset-0 col-sm-10 col-sm-offset-2 col-xs-12 ord2">
<div class="content main" style="opacity: 100;">
<div class="mailView" style="display: block">
<div class="pm-ctrl clearfix">
<ul class="reset lcol">
<li class="lcol">
<span class="glyphicon glyphicon-chevron-left"></span> Back to list
</li>
</ul>
<ul class="reset rcol">
<li class="lcol">
<span class="glyphicon glyphicon-download-alt"></span> Download
</li>
<li class="lcol">
<span class="glyphicon glyphicon-remove"></span> Delete
</li>
<li class="lcol">
<span class="glyphicon glyphicon-wrench"></span> Source
</li>
</ul>
</div>
<div class="pm-info">
<h4 class="pm-subject">Amazon password assistance</h4>
<ul class="reset">
<li><span class="glyphicon glyphicon-user grey"></span> From: "Amazon.co.uk" <account-update#amazon.co.uk></li>
<li><span class="glyphicon glyphicon-time grey"></span> Date: 12-01-2019 11:19:27</li>
</ul>
</div>
<div class="pm-text">
<div data-x-div-type="html" xmlns="http://www.w3.org/1999/xhtml">
<div data-x-div-type="body">
<img width="1" height="1" src="https://www.amazon.co.uk/gp/r.html?C=4XBRCDY40J48&M=urn:rtn:msg:20190112112940370f133b15924642ae9c1749c160p0eu&R=3SXE68KQSKHXF&T=O&U=https%3A%2F%2Fimages-eu.ssl-images-amazon.com%2Fimages%2FG%2F01%2Fnav%2Ftransp.gif&H=MSPPWISARSEXNQ35VMWJXUZ01L4A&ref_=pe_1764051_62581901_opens">
<table
align="center" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="250">
<img src="https://images-na.ssl-images-amazon.com/images/G/01/x-locale/cs/te/logo._CB152417367_.png"></td>
<td width="250" valign="top" align="right">
<p>Password assistance</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>
<p>To verify your identity, please use the following code:</p>
<p>451429</p>
</td>
</tr>
<tr>
<td>
<p>Amazon takes your account security very seriously. Amazon will never email you and ask you to disclose or verify your Amazon password, credit card or banking account number. If you receive a suspicious email with a link to
update your account information, do not click on the link—instead, report the email to Amazon for investigation.
</p>
</td>
</tr>
<tr>
<td>
<p>We hope to see you again soon.
</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table><img width="1" height="1" src="https://www.amazon.co.uk/gp/r.html?C=4XBRCDY40J48&M=urn:rtn:msg:20190112112940370f133b15924642ae9c1749c160p0eu&R=HE8PCAHPJVPN&T=E&U=https%3A%2F%2Fimages-eu.ssl-images-amazon.com%2Fimages%2FG%2F01%2Fnav%2Ftransp.gif&H=NJAGFLUUE0Y1VUAJCA4S9MABYVAA&ref_=pe_1764051_62581901_open">
</div>
</div>
</div>
</div>
As you can see, the code is
<p>451429</p>
Now how would i go about using XPath, or anything else (I have an open mind), to save that specific Code which will change everytime i run the program, to a variable called "verifyCode" or whatever variable name you please. Thank you!
Using inspect element, i have found the XPath which is:
//*[#cellspacing='0']/tbody/tr/td/table/tbody/tr[2]/td/p[2]
but when i use
var codeverify = driver.FindElement(By.XPath("//[#cellspacing='0']/tbody/tr/td/table/tbody/tr[2]/td/p[2]/text()"));
it tells me XPath is invalid
You can use HtmlAgilityPack nugget package and use below code. Input.html is the HTML which you mentioned in your question.
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(File.ReadAllText("Input.html"));
var element = htmlDoc.DocumentNode.Descendants()
.Where(x => x.InnerText == "To verify your identity, please use the following code:")
.ToList()
.FirstOrDefault();
while (element.NextSibling.Name != "p")
element = element.NextSibling;
var code= element.NextSibling.InnerText;

How to save data from more than 3 html <input> </>

Hello I have a form with several html/input tags. Like so:
<form class="form-group">
<div class="body table-responsive">
<table class="table m-b-0">
<thead>
<tr>
<th>Name</th>
<th>age</th>
<th>phone number</th>
<th>ID</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.name</td>
<td>
<input type="text" name="" id="" value=""
class="bordered">
</td>
<td>
<input type="text" name="" id="" value=""
class="bordered">
</td>
<td>
<input type="text" name="" id="" value=""
class="bordered">
</td>
</tr>
}
</tbody>
</table>
</div>
</form>
I havent named or id them yet , since I know there is a way to fill all inputs and save them all at the same time when a submit or button is pressed, I just dont know how.
Do I need to add something a tag or attribute on the in order to be able to save all inputs at the same time when the is pressed?
You have to assign names to each input and add place a submit button. When you click submit, user input will be sent to the server with the given method.
<form method="post" class="form-group">
<div class="body table-responsive">
<table class="table m-b-0">
<thead>
<tr>
<th>Name</th>
<th>age</th>
<th>phone number</th>
<th>ID</th>
</tr>
</thead>
<tbody>
#{
var i = 0;
foreach (var item in Model) {
<tr>
<td>#item.name</td>
<td>
<input type="text" name="input1_#i" id="" value=""
class="bordered">
</td>
<td>
<input type="text" name="input2_#i" id="" value=""
class="bordered">
</td>
<td>
<input type="text" name="input3_#i" id="" value=""
class="bordered">
</td>
</tr>
}
}
</tbody>
</table>
</div>
<button type="submit">Submit</button>
</form>
Or you can listen to the submit event and handle it yourself.
$('form').submit(function(e) {
e.preventDefault();
// you can get the input data from 'this' (form element)
// here comes your validation and server call
});

Label and TextBox value on button click as alert

I need little help.
On button click I need values from the labels and txtBox'es shown in form of alert on the screen.
It should look like this:
Label0(value) txtBoxOpis0(value)
Label1(value) txtBoxOpis1(value) ....
The table has many more filed's, I copy'ed in this example only two rows.
<table id="MainContent_gvKarakteristike" style="color:#333333;border-collapse:collapse;" cellspacing="0" cellpadding="4">
<tbody><tr style="color:White;background-color:#507CD1;font-weight:bold;">
<th scope="col">Karakteristike</th><th scope="col"> </th><th scope="col">Opis</th>
</tr><tr style="background-color:#EFF3FB;">
<td>
<span id="MainContent_gvKarakteristike_Karakteristike_0" mycustomattr="foo" margin-left="100px" style="display:inline-block;font-family:Georgia;height:30px;width:150px;">GRP Total_Thickness</span>
</td><td>
<span id="MainContent_gvKarakteristike_Label_0" class="IDKarakteristike" margin-left="100px" style="display:inline-block;font-family:Georgia;height:30px;width:150px;">1</span>
</td><td>
<input name="ctl00$MainContent$gvKarakteristike$ctl02$txtBoxOpis" id="MainContent_gvKarakteristike_txtBoxOpis_0" margin-left="100px" style="font-family:Georgia;height:28px;width:130px;" type="text">
</td>
</tr><tr style="background-color:White;">
<td>
<span id="MainContent_gvKarakteristike_Karakteristike_1" mycustomattr="foo" margin-left="100px" style="display:inline-block;font-family:Georgia;height:30px;width:150px;">GRP Wear Layer thickness</span>
</td><td>
<span id="MainContent_gvKarakteristike_Label_1" class="IDKarakteristike" margin-left="100px" style="display:inline-block;font-family:Georgia;height:30px;width:150px;">2</span>
</td><td>
<input name="ctl00$MainContent$gvKarakteristike$ctl03$txtBoxOpis" id="MainContent_gvKarakteristike_txtBoxOpis_1" margin-left="100px" style="font-family:Georgia;height:28px;width:130px;" type="text">
</td>
</tr><tr style="background-color:#EFF3FB;">
<td>
Here's the button
<input name="ctl00$MainContent$btnButton" value="Save" onclick="return false;" id="MainContent_btnButton" autopostback="false" type="submit">
Thanks in advance !
You Can Do something like this
$('#MainContent_btnButton').click(function () {
alert(
'Label0('+
$("#MainContent_gvKarakteristike_Label_1").text()+
')\n(txtBoxOpis0'+
$("#MainContent_gvKarakteristike_txtBoxOpis_1").text()+
')'
);
});

Categories

Resources