0

I'm new to the site and to WebDriver.

I am trying to work with a dynamic data table - HTML below

<div id="enquiry-header-grid-SalesTransactionEnquiry-enquiry-header-grid-wrapper" class="enquiry-kendo-grid-wrapper k-grid k-widget" data-role="grid" style="height: 456px;">
 <div class="k-grid-content k-auto-scrollable" style="height: 428px;">
  <table role="grid" tabindex="0" data-role="selectable" class="k-selectable" style="touch-action: none;">
   <colgroup><col style="width:120px"><col style="width:120px"><col style="width:100px"><col style="width:60px"><col style="width:100px"><col style="width:105px"><col style="width:100px"><col style="width:120px"><col style="width:120px"><col style="width:100px"><col style="width:200px"><col style="width:120px"><col style="width:120px"><col style="width:60px"><col style="width:100px"><col style="width:100px"><col style="width:100px"><col style="width:100px"><col style="width:100px"><col style="width:120px"><col style="width:60px"><col style="width:100px"><col style="width:100px">    </colgroup>
   <tbody role="rowgroup">
    <tr data-uid="23f8ebd0-2c90-4728-9430-71376f2d10e3" role="row" class="k-state-selected" aria-selected="true">
     <td class="col-align-left" role="gridcell"><a href="#" class="cell-popover" data-col-type="popover" data-col-name="ST_COPYCUST">MUFC</a></td>
     <td class="col-align-left" role="gridcell">Manchester United</td>
     <td class="col-align-right" role="gridcell">23/10/2017</td>
     <td class="col-align-right" role="gridcell">1</td>
     <td class="col-align-left" role="gridcell">Invoice</td>
     <td class="col-align-left" role="gridcell">1000</td>
     <td class="col-align-center" role="gridcell"><input type="checkbox" disabled="disabled"></td>
     <td class="col-align-right" role="gridcell">5.00</td>
     <td class="col-align-right" role="gridcell">1.00</td>
     <td class="col-align-left" role="gridcell">SA</td>
     <td class="col-align-left" role="gridcell"></td>
     <td class="col-align-right" role="gridcell">6.00</td>
     <td class="col-align-left" role="gridcell">0.00</td>
     <td class="col-align-center" role="gridcell"><input type="checkbox" disabled="disabled"></td>
     <td class="col-align-left" role="gridcell">2017</td>
     <td class="col-align-left" role="gridcell">1</td>
     <td class="col-align-right" role="gridcell">23/10/2017</td>
     <td class="col-align-right" role="gridcell">23/10/2017</td>
     <td class="col-align-left" role="gridcell"></td>
     <td class="col-align-left" role="gridcell">0.00</td>
     <td class="col-align-center" role="gridcell"><input type="checkbox" disabled="disabled"></td>
     <td class="col-align-left" role="gridcell"></td><td class="col-align-left" role="gridcell"></td>
    </tr>
    <tr class="k-alt" data-uid="5a1d2279-5588-4c41-ab22-ce5361192a4c" role="row">
     <td class="col-align-left" role="gridcell"><a href="#" class="cell-popover" data-col-type="popover" data-col-name="ST_COPYCUST">MUFC</a></td>

What I am trying to do is identify the row number based on the cell

<td class="col-align-left" role="gridcell">1000</td>

This column is always a unique value so is the ideal identifier for the row, so once I have the rowid I can then verify the values for all columns in the row.

From the research I have done myself I have got as far as below,

IWebElement elemTable = driver.FindElement(By.XPath("//div[@id='enquiry-header-grid-SalesTransactionEnquiry-enquiry-header-grid-wrapper']//table[1]"));
List<IWebElement> lstTrElem = new List<IWebElement>(elemTable.FindElements(By.TagName("tr")));
foreach (var elemTr in lstTrElem)
{ 
    List<IWebElement> lstTdElem = new List<IWebElement>(elemTr.FindElements(By.TagName("td")));
    foreach (var elemTd in lstTdElem)
    {
        IWebElement customer = elemTable.FindElement(By.XPath("//tr/td[contains(text(), '1000')]"));
        ...

Firstly I'm not confident that what I have is correct in terms of traversing all rows and columns for the table?

Then I'm struggling with how to proceed with getting the rowid to use to verify the other td's?

Am I using the right approach, and how do I move forward?

UPDATE

Thanks to Kate Paulk's answer below i have progressed slightly but am not hitting another roadblock I could do with some help on if possible.

 IWebElement elemTable = driver.FindElement(By.Id("enquiry-header-grid-SalesTransactionEnquiry-enquiry-header-grid-wrapper")).FindElement(By.TagName("table"));
 List<IWebElement> lstTrElem = new List<IWebElement>(elemTable.FindElements(By.TagName("tr")));
 IWebElement row = lstTrElem.Where(item => item.Text.Contains( "1000" )).FirstOrDefault();
 string rowid = row.GetAttribute("data-uid");  

So this is now throwing the error,

Result Message: System.NullReferenceException : Object reference not set to an instance of an object.

Against the line

string rowid = row.GetAttribute("data-uid");  

I think this is due to,

IWebElement row = lstTrElem.Where(item => item.Text.Contains( "1000" )).FirstOrDefault();

Again any help would be great, thanks in advance??

2
  • It means that either lstTrElem is empty, or there is no element with text 1000, so row = null; I suggest you use VS debugger (it is really important to learn!) and check values that those lists are holding.
    – George
    Commented Mar 14, 2018 at 17:53
  • Great advice - debugged the test and found that as i was using TagName "Table" my LstTrElem was populated with the header row only hence not finding the required text!!! Used tbody instead and hey presto!!!
    – Luke
    Commented Mar 15, 2018 at 8:14

1 Answer 1

0

You're on the right track, but you're making things too complicated.

Based on the structure of the HTML you're working with, I would consider this:

  • If the table is the only table in the div, I would find it by Id then by tag - something like: IWebElement elemTable = driver.FindElement(By.Id("enquiry-header-grid-SalesTransactionEnquiry-enquiry-header-grid-wrapper")).FindElement(By.TagName("table"));
  • If it isn't, using Xpath should be fine as long as it's getting the correct table element. I'd suggest logging the value of elemTable.InnerText to make sure you have the element you expect.

Next, since you first want to identify the row, then validate each column in that row, I'd do something like this (code may not be entirely correct - I'm not using an IDE to build this):

include System.Linq; // You will need this for the much simpler find functionality - I'd recommend learning Linq syntax.

// the rest of your code

  List<IWebElement> lstTrElem = new List<IWebElement>   (elemTable.FindElements(By.TagName("tr")));
  // instead of iterating over the rows, use the Linq where syntax to find what you want
  IWebElement row = lstTrElem.Where(item -> item.Text.Contains(" 1000 ")); 
  // You may need to tweak what your contains call uses - typically getting the text of an element with child elements will have white space between the elements. 

 // once you have the row, you can start your validations
 string rowid = row.GetAttribute("data-uid");
 List<IWebElement> cells = row.FindElements(By.TagName("td"));

 // Now you can iterate over the cells and check the Text property of each against your reference values

https://www.tutorialspoint.com/linq/index.htm (found with a quick web search) has a decent tutorial on how Linq works - if you're working C#, Linq is invaluable for finding data in collections.

3
  • Thank you very much for the response i will certainly look into Linq as this seems like a great way of achieving what I'm looking for - one further question - attempting to use your code I'm getting the error the name 'item' does not exist in the current context - i have added it as a private object -- is this the right approach??
    – Luke
    Commented Mar 14, 2018 at 13:22
  • @Luke - the syntax for Linq queries can be a bit tricky. In my sample, item is a scratch variable used to represent the list of rows - it's possible that your version of C# and Linq will insist on using something like l instead. intertech.com/Blog/… has a decent guide to how these work.
    – Kate Paulk
    Commented Mar 15, 2018 at 11:23
  • Got it working now thanks to yours and @George 's advice, although its definitely something else for me to look into - thanks again!
    – Luke
    Commented Mar 15, 2018 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.