Check if the value exists in a dropdown - c#

I have a dropdown that contains Subjects.
What I did, I use the code below to get the values on that dropdown.
IList<IWebElement> allOptions = check.Options;
Then I declare a string that will handle all the values I have to verify if these values exist on that dropdown.
string[] subject = "Math", "Science", "History", "Calculus", etc...
I loop them to get how many subjects I have to check if they exist on the dropdown then verify it using Contains.
if (allOptions.Contains(subject[i]))
{
exist = true;
}
However, I am getting an error that cannot convert a string to OpenQA.Selenium.IWebElement.
Anyone has idea how to fix it?
Thank you.

You can use LINQ for this. Basically this code:
if (allOptions.Contains(subject[i]))
{
exist = true;
}
Can be replaced by a single line:
exist = allOptions.Any(x => x.Text == subject[i]);
Basically this code just checks if any element in the allOptions list has Text that matches subject[i]. If true, exist is now true, if false exist is now false.

Indeed, you cannot do that directly. The IWebElement contains a string property named Text, which is what you need to filter on. Like so:
var foundSubjects = allOptions.Where(o => subject.Contains(o.Text));
If you just need to find out if ALL the options are found in the subject array, do:
var optionsAreValid = allOptions.All(o => subject.Contains(o.Text));
Alternatively you could use Any to determine if at least one option exists in the subject array:
var isThereAValidOption = allOptions.All(o => subject.Contains(o.Text));

Try looping through the IList<IWebElement> instead:
int subjectCount = 0;
foreach (IWebElement element in allOptions)
{
if (subject.Contains(element.Text))
{
subjectCount++;
}
}

Use the Text property of the WebElement. it may be work for you

Related

How to remove duplicates from the list in C#

Please help me to fix this issue. My dropdown list looks something like this mentioned below.
Client
Contractor,Contractor,Contractor,Manager
Contractor,Manager
Manager
Operator
Viewer
I want to remove the duplicates and my output should be like :
Client
Contractor
Manager
Operator
Viewer
This is my code mentioned below:
Property:
public List<string> TeamRoleNames => TeamRoleUids.Select(MainRoles.GetRoleName).ToList();
Display Method:
{
result += " ; TeamRoleNames=" + this.TeamRoleNames;
}
GetRole Method:
{
string roleName;
if (RoleNameByUid.TryGetValue(roleUid, out roleName))
{
return roleName;
}
return null;
}
I have tried with Distinct Method mentioned below, But did not work like the output what I wanted!
public List<string> TeamRoleNames => TeamRoleUids.Select(MainRoles.GetRoleName).Distinct().ToList();
How can I fix this? Can anyone help?
Having elements comma separated require you to split them first to have an homogenous collection then do the distinct
// get the comma separated values out as 1 value each
// for that you can use split, remove empty and select many
// which will return as a single level list (flat)
var result = TeamRoleUids.SelectMany(o => o.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)).Distinct().ToList();
Consider converting the list to a set (hashset) since sets as a data structure doesn't allow duplicates.
More about hashsets form official documentation.
So, the solution would be similar to the following:
var hashSet = new HashSet<YourType>(yourList);
example:
var hashSet = new HashSet<string>(TeamRoleUids);
then converting it back toList() will remove duplicates.
If you have already tried Distinct and it hasn't worked, then you could do the following;
Split your string list to a List<string>
List<string> result = TeamRoleNames.Split(',').ToList();
Then when you're adding them to the dropdwon, check to see if the role is already in the dropdown. If so, move on, else add to the dropdown.
So something like
foreach(var role in this.TeamRoleNames)
{
if(!result.contains(role))
result += " ; TeamRoleNames=" + role;
}
You can use SelectMany to flatten a enumeration containing a nested enumeration. Here, we create the nested enumeration by splitting the string at the commas:
string[] input = {
"Client",
"Contractor,Contractor,Contractor,Manager",
"Contractor,Manager",
"Manager",
"Operator",
"Viewer"
};
var roles = input
.SelectMany(r => r.Split(','))
.Distinct()
.OrderBy(r => r)
.ToList();
foreach (string role in roles) {
Console.WriteLine(role);
}
prints
Client
Contractor
Manager
Operator
Viewer

Simple code to get specific item from a list

I have a list of a tags. I want to get an a tag which contains a string.
I used the below code and everything work fine.
string mainLink = "";
List<HtmlNode> dlLink = new List<HtmlNode>();
dlLink = doc.DocumentNode.SelectNodes("//div[#class='links']//a").ToList();
foreach (var item in dlLink) {
if (item.Attributes["href"].Value.Contains("prefile"))
{
mainLink = item.Attributes["href"].Value;
}
}
but I want to write a simple code
var dlLink = doc.DocumentNode.SelectNodes("//div[#class='link']//a").ToList().Where(x => x.Attributes["href"].Value.Contains("prefile")).ToList().ToString();
But it does not work and I get nothing.
Your foreach is setting mainLink string, but your linq chain is using ToString on a List result.
Converting your code, you will have something like this:
mainLink = doc.DocumentNode.SelectNodes("//div[#class='links']//a")
.Where(item => item.Attributes["href"].Value.Contains("prefile"))
.Select(item => item.Attributes["href"].Value)
.Last();
I used Select to get only the href values, and getting the last as your foreach did, maybe you need to validate this last step, use a LastOrDefault, First, etc.
You can also use the Last or First instead of the Where condition:
mainlink = doc.DocumentNode.SelectNodes("//div[#class='links']//a")
.Last(item => item.Attributes["href"].Value.Contains("prefile"))
.Attributes["href"].Value;

address an object by retrieving the ID name of the object from a variable

Good evening,
I am trying to get the following done. I have seen a similar post but it was related with Unity.
Anyway, I am on web forms in asp.net and I have a radiobuttonList with ID="id001"
so on my code behind, I would normally be able to get the selected value by just doing:
string value = id001.SelectedValue
However, in this situation, I don't know the exact ID name, so I have a function that retrieves it. So now I have the variable with the name of the ID. So I want to be able to now, convert the value of that variable in something like this:
string foundid = "id001"
string foundidvalue = id001.SelectedValue
I hope this makes sense.
Thanks in advance for the help.
I am assuming this one is related to your previous question. So, when you found the control, instead of using function to get the fullname, you can do like this:
foreach (Control c in Page.Form.Controls.OfType<RadioButtonList>())
{
if (c.ID.Contains("id"))
{
// string FullID = c.ID.ToString();
var radioButtonList = c as RadioButtonList;
var selectedValue = radioButtonList.SelectedValue;
}
}
You want to use FindControl.
string foundid = "id001";
var foundCtrl = (RadiobuttonList)FindControl(foundid);
var result = foundCtrl.SelectedValue;

Verify all the options of a drop down in selenium c#

I am writing selenium webdriver code in c#. I want to verify all the options of a drop down. I am using the following code. But its giving me an error for 'soc.options.text'. May I know where I am getting wrong?
SelectElement soc = new SelectElement(driver.FindElement(By.Id("soc_id_look")));
string[] drop = { "x----x", "Ra", "Ma", "sa", "ga", "ta" };
string[] actual = soc.Options.Text;
int n = drop.Length;
for (int i = 0; i < n; i++)
{
Console.Write(" " + drop[i]);
Assert.IsTrue(drop[i].Equals(actual[i]));
}
So I guess you are getting an error because soc.Options will return a collection of IWebElement's, and therefore .Text is not accessible.
Regardless of the error you are getting, the for loop can be condensed into a single LINQ statement:
Assert.IsTrue(drop.All(d => actual.Contains(d)));
http://msdn.microsoft.com/en-us/library/bb548541(v=vs.110).aspx
Determines whether all elements of a sequence satisfy a condition.
So it translates into "does every element within the "drop" array exist within the "actual" array? If so, return true, otherwise return false.
Now, to fix the inital error you were getting, you can, again, use LINQ, to translate it into a collection of string's:
IEnumerable<string> actual = soc.Options.Select(i => i.Text);
http://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
Projects each element of a sequence into a new form.
So this would become "take each IWebElement within this collection, get the value of it's .Text property and return that." So we'd end up with a collection of string's.
We put it all together and end up with:
SelectElement soc = new SelectElement(driver.FindElement(By.Id("soc_id_look")));
string[] drop = { "x----x", "Ra", "Ma", "sa", "ga", "ta" };
IEnumerable<string> actual = soc.Options.Select(i => i.Text);
Assert.IsTrue(drop.All(d => actual.Contains(d)));
However, just as a note, if you get errors (whether compiler or runtime) you should post the entire error, along with the entire stack trace (if there is one). It is near impossible to help when someone says "I get an error" and we've got no idea whatsoever on what error it is. Just a friendly tip to help you get the best out of StackOverflow.
I can guess the error you got was probably something along the lines of IEnumerable<IWebElement> does not contain a definition for ".Text".
I think this will work:
IList<IWebElement> options = soc.Options;
Assert.Equals(options.Count, drop.Length);
foreach (IWebElelent option in options)
{
Console.Write(" " + drop[i]);
Assert.IsTrue(drop.Contains(option.Text));
}

Getting number of ITEMS in an array C#

I need to insert a string (from one window(QueryBuilder)) into an array(of another window(Main)).
In the Main i have a method as
public void DisplayCalcQuery(string argFromQueryBuilder)
{
int itemsInUserBuiltQueries = UserBuiltQueries.Count();
UserBuiltQueries[itemsInUserBuiltQueries] = argFromQueryBuilder.ToString();
//displayng the user built query(queries) on the stack panel meant to display it.
foreach (string query in UserBuiltQueries)
{
CheckBox checkQueries = new CheckBox() { Content = query };
stackPanel1.Children.Add(checkQueries);
checkboxes.Add(checkQueries);
}
}
Where UserBuiltQueries is declared as
string[] UserBuiltQueries;
However when from the other window i do
backscreen.DisplayCalcQuery(ttextBox1.Text.ToString()); //where backscreen is the Main
The argument is passed well but i get an error as
{"Value cannot be null.\r\nParameter name: source"}
What did I do wrong ?
These lines are wrong
int itemsInUserBuiltQueries = UserBuiltQueries.Count();
UserBuiltQueries[itemsInUserBuiltQueries] = argFromQueryBuilder.ToString();
Arrays start at index zero and end at index (Count - 1), so, if UserBuiltQueries.Count() returns 10 you could use indexes from 0 to 9. Essentially, using index 10, you are adding a new string outside the end of the array.
However, if your requirements force you to expand the array, it is better and more easy to code if you use a List<string> instead. Adding new elements will be a lot more easier and you could still use the List as an Array for common tasks.
List<string> UserBuiltQueries = new List<string>();
.....
public void DisplayCalcQuery(string argFromQueryBuilder)
{
UserBuiltQueries.Add(argFromQueryBuilder);
//displayng the user built query(queries) on the stack panel meant to display it.
foreach (string query in UserBuiltQueries)
{
CheckBox checkQueries = new CheckBox() { Content = query };
stackPanel1.Children.Add(checkQueries);
checkboxes.Add(checkQueries);
}
}
By the way, you should stop to unnecessarily convert a string to a string. You pass a ttextBox1.Text.ToString() but ttextBox1.Text is already a string. Inside the method the parameter argFromQueryBuilder is already a string and there is no need to convert to a string
Instead of using string[] for UserBuildQueries, use List. When you need it as an array, you can simply say: UserBuildQueries.ToArry()
Rewrite the function to
public void DisplayCalcQuery(string argFromQueryBuilder)
{
UserBuiltQueries.Add(argFromQueryBuilder.ToString());
//displayng the user built query(queries) on the stack panel meant to display it.
foreach (string query in UserBuiltQueries)
{
CheckBox checkQueries = new CheckBox() { Content = query };
stackPanel1.Children.Add(checkQueries);
checkboxes.Add(checkQueries);
}
}
In c# but I think in all programming language indexis start from 0:
so if an array has length or count =1 the index is 0 array[0], array.lenght==1
int itemsInUserBuiltQueries = UserBuiltQueries.Count()-1;
UserBuiltQueries[itemsInUserBuiltQueries] = argFromQueryBuilder.ToString();
And double check that your array is initialized before using it!

Categories

Resources