Handle with tables in selenium C# - c#

I a trying to handle with tables in selenium C#.
I have a table which has a few rows and a few columns.
Each row has column with name and buttons.
I want to click "Open" button, where the name in the row is, for example "Name1".
But i can't find even the td's in the table.
Here's what i was trying to do:
public void SelectNameAndClick(string name)
{
IWebElement tableElement = driver.FindElement(By.XPath("//table[#id='TableMp']"));
IList<IWebElement> tableRow = tableElement.FindElements(By.TagName("tr"));
IList<IWebElement> rowTD;
foreach (IWebElement row in tableRow)
{
if (row.Text.Equals(name));
rowTD = row.FindElements(By.TagName("td"));
I attached screen shot of the table: here
<table class="table table-condensed table-hover" id="TableMp" style="" data-bind="visible: opAGents().length > 0">
<tbody data-bind="foreach: opAGents">
<tr>
<td>
<span agentid="OPAgents/4b2f885101f740fdb72c5874596577ac" data-original-title="4b2f885101f740fdb72c5874596577ac">4b2f885101f740fdb72c5874596577ac</span>
</td>
<td class="vert-align">
<span >Jun 23, 2020 9:07 PM</span>
</td>
<td class="vert-align">
<span data-original-title="4b2f885101f740fdb72c5874596577ac">4b2f...</span>
<button class="btn btn-default btn-aligned-left" title="" data-original-title="Copy token"></i></button>
</td>
<td>
<span class="agent-led agent-active" data-original-title="Connected"></span>
</td>
<td class="vert-align hidden-xs">
<button data-bind="class="btn-aligned-left quick-action btn btn-sm btn-primary">
<span class="no-pointer-events">
<span>Open</span>
</span>
</button>
</td>
<td class="vert-align">
<button class="btn btn-default btn-aligned-left" ></i></button>
</td>
</tr>
<tr>
<td class="vert-align">
<span agentid="OPAgents/46414e7df0234d01aa6df6df7c195d17" data-original-title="">Name1</span>
</td>
<td class="vert-align">
<span >Jul 23, 2020 10:17 AM</span>
</td>
<td class="vert-align" style="white-space:nowrap">
<span data-original-title="46414e7df0234d01aa6df6df7c195d17">4641...</span>
<button class="btn btn-default btn-aligned-left"><i class="fa fa-files-o" data-bind="attr:{ 'data-original-title': 'Copy token' }, toolTip: { hideOnMobile: true }" title="" data-original-title="Copy token"></i></button>
</td>
<td>
<span class="agent-led agent-active" data-original-title="Connected"></span>
</td>
<td class="vert-align hidden-xs">
<button class="btn-aligned-left quick-action btn btn-sm btn-primary">
<span class="no-pointer-events">
<span>Open</span>
</span>
</button>
</td>

This should work for you:
public void SelectNameAndClick(string name)
{
// Selecting your table element.
IWebElement table = driver.FindElement(By.XPath("//table[#id='TableMp']"));
// Select the row where name of the agent equals to the name we're searching for.
IWebElement row = table
.FindElements(By.TagName("tr"))
.FirstOrDefault(element =>
element.FindElements(
By.XPath($"//span[#agentid and text()='{name}']")).Count > 0);
// If there is no such row, do nothing.
if (row == null)
return;
// Find the button with the 'Open' text somewhere within it and click the button.
IWebElement button = row.FindElement(By.XPath("//button//*[text()='Open']"));
button.Click();
}

Related

C# selenium find an element by text then click on checkbox

I want to search for example (UK) then click on checkbox that is in the same row
HTML (but tr can increase or decrease)
<tr class="ng-scope table-row-style">
<td class="ng-binding">US</td>
<td class="ng-binding">United States</td>
<td class="btn-td" style="padding: 0;">
<input type="checkbox" class="ng-pristine ng-untouched ng-valid ng-empty">
</td>
</tr>
<tr class="ng-scope table-row-style">
<td class="ng-binding">UK</td>
<td class="ng-binding">United Kingdom</td>
<td class="btn-td" style="padding: 0;">
<input type="checkbox" class="ng-pristine ng-untouched ng-valid ng-empty">
</td>
</tr>
<tr class="ng-scope table-row-style">
<td class="ng-binding">IN</td>
<td class="ng-binding">India</td>
<td class="btn-td" style="padding: 0;">
<input type="checkbox" class="ng-pristine ng-untouched ng-valid ng-empty">
</td>
</tr>
solved by
IList<IWebElement> tableRow = tableElement.FindElements(By.TagName("tr"));
IList<IWebElement> rowTD;
if (tableRow.Count > 0)
{
foreach (IWebElement row in tableRow)
{
rowTD = row.FindElements(By.TagName("td"));
if (rowTD[0].Text.Equals("UK"))
rowTD[2].Click();
}
}
You can find the parent tr element based on child td containing the desired text and then find the child input element as following:
//tr[.//td[contains(.,'UK')]]//input
The entire Selenium command finding and clicking this element could be
driver.FindElement(By.XPath("//tr[.//td[contains(.,'UK')]]//input")).Click();

Want to display a value of a loop outside of the loop as a heading in Razor pages

I want to display #s.CARDNAME that is used in the for each loop inside the else statement outside the loop as a heading:
<div><h4 style="text-align:center; margin-bottom:20px;">WELCOME <span id="UserName">#ViewData["0"]</span> </h4> </div>
Razor Page Code
<div class="container">
<div><h4 style="text-align:center; margin-bottom:20px;">WELCOME <span id="UserName">#ViewData["0"]</span> </h4> </div>
#if ((Convert.ToInt32(ViewData["hascard"])) == 2)
{
<h1>#ViewData["message"]</h1>
}
else
{
<div class="Debit-Card-Boxes">
#foreach (var s in ViewData["card"] as IEnumerable<DebitCardListingResponeDTOCardInfo>)
{
<div class="Debit-Card">
<div class="credit-card">
<img class="Abl-Logo" src="~/images/ABL-Logo.webp" />
<div class="chip"><img src="~/images/chip-logo-black-and-white.png" alt="chip"></div>
<div class="numbers">#s.ACCOUNTNUMBER</div>
<div class="name-and-expiry">
<span>#s.CARDNAME</span>
<span>#s.CARDEXPIRYDATE</span>
</div>
</div>
<a class="activatebtn" href="#modal">Activate</a>
<div class="modal" id="modal" tabindex="1">
<div class="modal__content">
×
<h1 id="genotpheading">OTP Generation</h1>
<table border="0" cellpadding="3" cellspacing="0">
<tr>
<td>
Pin:
</td>
<td>
<input type="password" id="txtPin" />
</td>
</tr>
<tr>
<td>
Confirm Pin:
</td>
<td>
<input type="password" id="txtConfirmPin" />
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="button" id="btnSubmit" value="Submit" />
</td>
</tr>
</table>
</div>
</div>
</div>
}
</div>
}
I suppose #s.CARDNAME is the same for all records, right? if that is not the case you will have to decide which cardname to use since there are many. Anyway if they are the same and you can't change your DTO to separate this property from an IEnumerable.
You can simply cast your viewdata item to IEnumrable and show the first(or last) item's cardname like
<h1>Your Card: #(((IEnumerable<DebitCardListingResponeDTOCardInfo>)ViewData["card"]).First().CARDNAME)</h1>
also, review this dotnetfiddle for a working example
P.S: You can also .Last() simply use any function of LINQ including ElementAt as you wish
Try to use the following code:
<div><h4 style="text-align:center; margin-bottom:20px;">WELCOME <span id="UserName">#(((List<Index3Model>) ViewData["card"])[0].CARDNAME)</span> </h4> </div>

How to delete a value

I want to display the name of the value before deleting it.
Have no idea how to data bind in angular.
1.Angular html.
<div *ngIf="pnlItemType" class="col-12">
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<th scope="col">Item Type Name</th>
<th scope="col" colspan="2"></th>
</thead>
<tbody class="bg-white">
<tr *ngFor="let itemType of itemTypes">
<td class="valign-middle">{{itemType.ItemTypeName}}</td>
<td class="w-80 text-center">
<button type="button" class="btn btn-outline-primary"
title="Edit" (click)="editItemType(itemType)"><i class="fas fa-
pen"></i></button>
</td>
<td class="w-80 text-center">
<button type="button" class="btn btn-outline-
secondary" title="Delete" (click)="deleteItemType()"> <i
class="far fa-trash-alt"></i></button>
</td>
</tr>
</tbody>
</table>
/div>
2.Modal view of delete box.
<ng-template #mdlDeleteItemType>
<div class="modal-header">
<h4 class="modal-title"> Confirm to delete this item</h4>
<button type="button" class="close" aria-label="Close" (click) =
"hideModal();">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<span> Are you sure you want to delete this item? </span>
<b>{{itemType?.ItemTypeName}}</b>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary">
Delete</button>
<button type="button" class="btn btn-outline-secondary mg-rt-10"
(click)="hideModal()">Cancel</button>
</div>
</ng-template>
3.codebehind tsfile.
deleteItemType(){
this.hideModal();
this.openLargeModal(this.mdlDeleteItemType);
}
I would like to show the name of the item to be deleted in bold.
deleteItemType(itemType){
this.mdlDeleteItemType = itemType;
this.hideModal();
//Just Open Modal after it
}
And your HTML
(click)="deleteItemType(itemType)"

Click handler on table using Knockout

C#/MVC/Knockout
I'm playing around with knockout and I can't seem to get a click handler to work on the name column. However, I can add in an image and assign a click handler to it. It seems to be an issue if the column is being assigned a databind.
This is an example:
<tbody data-bind="foreach: CurrentFeeds" class="table-news-body">
<tr class="panel-danger">
<td id="AllFeeds" data-bind="text: RSSName, click: $parent.showfeed" class="h3"></td>
<td>
<a href="#" data-bind="click: $parent.showFeed"class="btn btn-white btn-sm">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
</a>
</td>
#if (bIsEditor)
{
<td>
<button data-bind='click: $.deleteFeed' class="btn btn-primary btn-xs">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
Remove
</button>
</td>
}
</tr>
</tbody>
If I change the allfeeds line to this:
<td id="AllFeeds" data-bind="text: RSSName, click: $parent.showfeed" class="h3"></td>
I don't get an error message but I can't click on that column.
However, if I add in this code:
<td>
<a href="#" data-bind="click: $parent.showFeed"class="btn btn-white btn-sm">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
</a>
</td>
I can click on the icon that's created for it.
Whats going on?

Razor Ajax.BeginForm() creating a table with update form on each row. First Row missing <form> subsequent rows OK

I am creating a table of items in a basket, using the following in razor to create an update quantity form in each row, however the first row has all the contents of the using but not the form tag, all subsequent rows work ok (ie. have correct form tags):
#foreach (var item in #Model.SummaryList)
{
<tr id="basket_row_#(item.ProductCode)">
<td>
<img height="25" class="" src="#Html.DisplayFor(modelItem => item.ProdImage)" alt="#Html.DisplayFor(modelItem => item.ProductDesc)">
</td>
<td>
#Html.DisplayFor(modelItem => item.ProductCode)
</td>
<td>
#if (item.ProductCode != "DL")
{
using (Ajax.BeginForm("asyncUpdateCheckoutBasket", "Online", null, new AjaxOptions { UpdateTargetId = "SubTotal_" + item.ProductCode }, new { id = "updFrm_" + item.ProductCode }))
{
<div class="form-group">
<div class="input-group input-group-xs">
#Html.TextBox("newQty", item.Qty, new { id = "newQty_" + item.ProductCode, #class = "form-control", value = item.Qty })
<span class="input-group-btn ">
<button type="submit" value="Update" class="btn btn-success" id="add_btn_#(item.ProductCode)"><span class="glyphicon glyphicon-refresh"></span></button>
</span>
</div>
</div>
<input type="hidden" name="pCode" value="#item.ProductCode" />
}
}
</td>
<td id="SubTotal_#(item.ProductCode)">
#Html.DisplayFor(modelItem => item.SubTotal)
</td>
<td>
<a class="text-primary" title="DELETE: Delete item: #item.ProductCode" href="#(Url.Action("RemoveFromBasket", new { controller = "Online", area = "", pCode = item.ProductCode }))">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
}
Example of output:
<tr id="basket_row_KF00880">
<td>
<img height="25" title="Q-CONNECT WHITEBOARD MARKER ASTD PK10" alt="Q-CONNECT WHITEBOARD MARKER ASTD PK10" src="https://online.calidore.com/BtoC/Images/KF00880.jpg">
</td>
<td>
KF00880
</td>
<td>
<div class="form-group">
<div class="input-group input-group-xs">
<input name="newQty" class="form-control" id="newQty_KF00880" type="text" value="1">
<span class="input-group-btn ">
<button class="btn btn-success" id="add_btn_KF00880" type="submit" value="Update"><span class="glyphicon glyphicon-refresh"></span></button>
</span>
</div>
</div>
<input name="pCode" type="hidden" value="KF00880">
</td>
<td id="SubTotal_KF00880">
£8.21
</td>
<td>
<a title="DELETE: Delete item: KF00880" class="text-primary" href="/RemoveFromBasket?pCode=KF00880">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
<tr id="basket_row_KF00255">
<td>
<img height="25" title="Q-CONNECT DVD-R CAKEBOX PK25" alt="Q-CONNECT DVD-R CAKEBOX PK25" src="https://online.calidore.com/BtoC/Images/KF00255.jpg">
</td>
<td>
KF00255
</td>
<td>
<form id="updFrm_KF00255" action="/asyncUpdateCheckoutBasket" method="post" data-ajax-update="#SubTotal_KF00255" data-ajax-mode="replace" data-ajax="true">
<div class="form-group">
<div class="input-group input-group-xs">
<input name="newQty" class="form-control" id="newQty_KF00255" type="text" value="1">
<span class="input-group-btn ">
<button class="btn btn-success" id="add_btn_KF00255" type="submit" value="Update"><span class="glyphicon glyphicon-refresh"></span></button>
</span>
</div>
</div>
<input name="pCode" type="hidden" value="KF00255">
</form>
</td>
<td id="SubTotal_KF00255">17.98</td>
<td>
<a title="DELETE: Delete item: KF00255" class="text-primary" href="/RemoveFromBasket?pCode=KF00255">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>

Categories