Merge to IList<IWebElement> element into a Dictionary - c#

I'm trying to create a dictionary from a two IWebelement that I obtain from selenium, the first element is the header of a table and the second one is the value of each column. It's possible to do it?
This are my two Ilist:
IList<IWebElement> headersrows = tableheaders.FindElements(By.XPath("tr"));
IList<IWebElement> resultsrows = tableresults.FindElements(By.XPath("tr"));
And I do a for to get all the elements from each of the list:
IList<IWebElement> columnsTable;
foreach (IWebElement row in resultsrows)
{
columnsTable = row.FindElements(By.TagName("td"));
}

IDictionary<IWebElement, IList<IWebElement>> dict = new Dictionary<IWebElement, IList<IWebElement>>();
int index = 0;
foreach (var header in headersRows.SelectMany(r => r.FindElements(By.XPath("th"))))
{
dict.Add(header, resultsRows.Select(r => r.FindElements(By.TagName("td"))[index]).ToList());
index++;
}
This will give you a dictionary where the key is the th element, and the values are a list of td elements containing the values for the column.

Related

Selenium Webdriver can't find table elements

I'm new with selenium, I can not figure out how to find some elements from an HTML page.
I reproduced the page here :
http://www.ladiana.it/test/test.htm
I need to click on this button :
Selection
and after the table appears, to read and write their values :
values
I'm using c# and I tried all possible way, I also tried to list all the elements with the Id
: "targetDemandReductionMW"
IList IWebElement> all = driver2.FindElements(By.Id("targetDemandReductionMW"));
I get a list of 52 void elements.
Here some other code , it doesn't generate any error but didn't work:
IWebElement element_xpath = driver2.FindElement(By.ClassName("tab_buttonSel"));
element_xpath.Click();
IWebElement table = driver2.FindElement(By.Id("drr1OfferAM"));
var rows = table.FindElements(By.TagName("tr"));
int conteggio = 0;
foreach (var row in rows)
{
var rowTds = row.FindElements(By.TagName("td"));
foreach (var td in rowTds)
{
IWebElement a = td.FindElement(By.XPath("//*[#id='targetDemandReductionMW']"));
Console.WriteLine(conteggio++.ToString()+" "+a.GetAttribute("href")+" "+ a.Text);
}
}
Any help?
Thanks
For the button you need to click, you can use:
//div[#id='tabContainer']/div[2]/following::tr/td[text()='DRR1 Offer']
For the xpath for the table records you can use:
//table[#id='drr1OfferPMHead']//td[#id='targetDemandReductionMW']
This returns the 13 rows that you are looking for. You can then do FindElements on this and get a list.
List<String> search = new List<string>();
IReadOnlyList<IWebElement> cells = driver.FindElements(By.Xpath("//table[#id='drr1OfferPMHead']//td[#id='targetDemandReductionMW']"));
foreach (IWebElement cell in cells)
{
search.Add(cell.Text);
}
The cell (in the html) has cellclick event , but if i try with :
foreach (IWebElement cell in cells)
{
search.Add(cell.Text);
if (cell.Text=="300.0")
{
cell.click();
}
}
it come out this error : "OpenQA.Selenium.ElementNotInteractableException: 'element not interactable"

C# add only first column text in a table to a List<string> for assertion

I have this table and I want to verify files have been uploaded successfully
I want to iterate through the first column and add file names to a list to assert against an expected list
This works but I am wondering how I can modify my method to be able to iterate through all columns and rows and I can add any column to the list. Basically make the method more useable and not use it just to verify file names but also to be able to verify other columns if needed
public List<string> ListofFilesUploaded()
{
IWebElement table = WebDriver.Driver.FindElement(By.XPath("//table[#id='files_list']//tbody"));
IList<IWebElement> rows = table.FindElements(By.TagName("tr"));
List<string> fileNames = new List<string>();
foreach (var row in rows)
{
fileNames.Add(row.Text.Split(' ').First());
}
return fileNames;
}
Does anyone have an idea how to enhance this solution or improve this?
I believe instead of returning a list you can return a dictionary of lists with each document tile as key and list of all columns As value.
public Dictionary<string, List<string>> ListofFilesUploaded()
{
IWebElement table = WebDriver.Driver.FindElement(By.XPath("//table[#id='files_list']//tbody"));
IList<IWebElement> rows = table.FindElements(By.TagName("tr"));
Dictionary<string, List<string>> fileNames = new Dictionary<string, List<string>>();
foreach (var row in rows)
{
List<string> Col_value = new List<string>();
IList<IWebElement> cols= row.FindElements(By.TagName("td"));
foreach (var col in cols)
{
Col_value.Add( col.Text);
}
fileNames.Add(row.Get_Attribute(“title”), Col_value);
}
return fileNames;
}
Now you can iterate though dictionary to get list of all files upload and corroding column value for each file. Can see below link for same
What is the best way to iterate over a dictionary?
Instead of iterating over a List of strings for just fileNames, create a List of Files with properties as Name, size, modificationDateTime, numberOfDownloads, isDeleteable etc.
List<Files> files = new List<Files>();
Then you can iterate over each row that is represented by a File from the files list.

Selenium C# Tables - reading each values and adding them and Returning as List<string>

I can able to read the table values BUT Im unable to add the values inside foreach loop and returning them as List<string>.
Please share your approach and Will be great helpful
IWebElement tableElement = driver.FindElement(By.XPath("//div[#id='table']"));
IList<IWebElement> tableRow = tableElement.FindElements(By.TagName("tr"));
IList<IWebElement> rowTD;
foreach (IWebElement row in tableRow)
{
rowTD = row.FindElements(By.TagName("td"));
//add the values in list??
}
return list
After this how can I add the td text values into an List<string>? I want this function to return the list.
I'm guessing that you are trying to return all of the table data elements as a list of strings.
If you want to stick with a similar approach of only getting the text of the td elements, then I would do something like this:
IWebElement tableElement = driver.FindElement(By.XPath("//div[#id='table']"));
IList<IWebElement> tableDataElements = tableElement.FindElements(By.TagName("td"));
var reults = new List<string>();
foreach (IWebElement tableDataElement in tableDataElements)
{
var tableData = tableDataElement.Text;
reults.add(tableData);
}
return reults;
You can combine Michiel's answer with LINQ to do this even more concisely--without a foreach loop at all:
First, add
using System.Linq;
Then, you can replace your entire code block with:
return driver.FindElement(By.XPath("//div[#id='table']"))
.FindElements(By.TagName("td"))
.Select(e => e.Text)
.ToList();

Unable to use int array item in table cell

I am trying to use int array element in tablecell item and it doesn't allow me to add.
Code:
I'm getting datatable column values into array
int[] price = dtPrice.Rows.OfType<DataRow>().Select(n => Convert.ToInt32(n[0])).ToArray();
Then using foreach I am adding the items to the cell text and its not working.
foreach(var item in price)
{
string strValue = e.Row.Cells[item].Text;
}
Below error is what I see. Please provide any suggestions on how this can be handled.

Getting split Items by Index from an IEnumerable list to add on certain ListView ColumnHeaders?

I have an iEnumerable list called Students read from a text file which was split by a linq query using a : delimiter. I am using a for loop, instead of a foreach loop because I want to add the List by Index to ListView SubItems. How would I go about grabbing a particular split Item from an iEnumerable list?
var Students = File.ReadLines("C:\Folder\student_list.txt")
.Select(line => line.Split(':'));
// John:Smith
// Adam:Turner
// Abraham:Richards
for (int i = 0; i < Students.Count(); i++)
{
// Listview already has 3 items, I want to add First and Last name of each
// Item in Students List into ColumnHeader [1] and [2].
// Before when using a foreach loop and no existing Listview Items, I was doing
// foreach (var piece in Students)
// lvStudents.Items.Add(new ListViewItem(new String[] { piece[0], piece[1] }))
// How would I do the same up above, but for each SubItem using a for loop?
}
You can't access IEnumerable by index. You have to use
string[] StudentItems = Students.ElementAt(i);
Another option would be the replacement of the for loop by foreach
foreach (string[] StudentItems in Students)
If you want to access your items by [] and avoid a foreach, you have to use a ToList() or ToArray()
string[][] Students = File.ReadLines(#"C:\Folder\student_list.txt")
.Select(line => line.Split(':'))
.ToArray();
for (int i = 0; i < Students.Count(); i++)
{
string[] StudentItems = Students[i];
}

Categories