Visual Basic C# with Selenium variable in css selector - c#

I am only a week or so into C#, but thanks to forums like this I am able to piece together a bunch of code and get a general understanding. However, I have a problem with using a variable I can't solve.
List<IWebElement> elementList = new List<IWebElement>();
elementList.AddRange(browser.FindElements(By.CssSelector("div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div[class^='CalendarEvent-event-']")));
int t = elementList.Count;
for (int i = 1; i <= t; i++)
{
var item + i = browser.FindElement(By.CssSelector("div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div:nth-child(i)>div>div[class^='CalendarEvent-title']")).GetAttribute("textContent");
}
Problems are "var item + i" and "div:nth-child(i)". The first is automatically creating sequential variables and the second trying to get the nth-child using the variable "i". I can't figure out how to format "i" in either instance.
Any help would be appreciated.
Working Code after edits:
List<IWebElement> elementList = new List<IWebElement>();
elementList.AddRange(browser.FindElements(By.CssSelector("div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div[class^='CalendarEvent-event-']")));
int t = elementList.Count;
List<String> listItems = new List<String>();
for (int i = 1; i <= t; i++)
{
String item = browser.FindElement(By.CssSelector("div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div:nth-child(i)>div>div[class^='CalendarEvent-title']")).GetAttribute("textContent");
listItems.Add(item);
}
Thanks,
Don

You should use a list to store the different items, you have to know the type of GetAttribute. I assume it is String :
List<String> listItems = new List<String>();
for (int i = 1; i <= t; i++)
{
String item = browser.FindElement(By.CssSelector("div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div:nth-child(i)>div>div[class^='CalendarEvent-title']")).GetAttribute("textContent");
listItems.Add(item);
}
then you can access the list items by index listItems[i]
For the second part of the question you have to concatenate the string with the i of the for loop like this:
browser.FindElement(By.CssSelector("div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div:nth-child("+i+")>div>div[class^='CalendarEvent-title']")).GetAttribute("textContent");

You can't do var item + i. Just use the same variable each time, it's inside the loop scope anyway.
To insert the i variable to the locator you can use string interpolation
var item = browser.FindElement(By.CssSelector($"div[class^='CalendarDays-calendarDays-']>div:nth-child(3)>div>div:nth-child({i})>div>div[class^='CalendarEvent-title']")).GetAttribute("textContent");

Related

How can I split a string to store contents in two different arrays in c#?

The string I want to split is an array of strings.
the array contains strings like:
G1,Active
G2,Inactive
G3,Inactive
.
.
G24,Active
Now I want to store the G's in an array, and Active or Inactive in a different array. So far I have tried this which has successfully store all the G's part but I have lost the other part. I used Split fucntion but did not work so I have tried this.
int i = 0;
for(i = 0; i <= grids.Length; i++)
{
string temp = grids[i];
temp = temp.Replace(",", " ");
if (temp.Contains(' '))
{
int index = temp.IndexOf(' ');
grids[i] = temp.Substring(0, index);
}
//System.Console.WriteLine(temp);
}
Please help me how to achieve this goal. I am new to C#.
If I understand the problem correctly - we have an array of strings Eg:
arrayOfStrings[24] =
{
"G1,Active",
"G2,Inactive",
"G3,Active",
...
"G24,Active"
}
Now we want to split each item and store the g part in one array and the status into another.
Working with arrays the solution is to - traverse the arrayOfStrings.
Per each item in the arrayOfStrings we split it by ',' separator.
The Split operation will return another array of two elements the g part and the status - which will be stored respectively into distinct arrays (gArray and statusArray) for later retrieval. Those arrays will have a 1-to-1 relation.
Here is my implementation:
static string[] LoadArray()
{
return new string[]
{
"G1,Active",
"G2,Inactive",
"G3,Active",
"G4,Active",
"G5,Active",
"G6,Inactive",
"G7,Active",
"G8,Active",
"G9,Active",
"G10,Active",
"G11,Inactive",
"G12,Active",
"G13,Active",
"G14,Inactive",
"G15,Active",
"G16,Inactive",
"G17,Active",
"G18,Active",
"G19,Inactive",
"G20,Active",
"G21,Inactive",
"G22,Active",
"G23,Inactive",
"G24,Active"
};
}
static void Main(string[] args)
{
string[] myarrayOfStrings = LoadArray();
string[] gArray = new string[24];
string[] statusArray = new string[24];
int index = 0;
foreach (var item in myarrayOfStrings)
{
var arraySplit = item.Split(',');
gArray[index] = arraySplit[0];
statusArray[index] = arraySplit[1];
index++;
}
for (int i = 0; i < gArray.Length; i++)
{
Console.WriteLine("{0} has status : {1}", gArray[i] , statusArray[i]);
}
Console.ReadLine();
}
seems like you have a list of Gxx,Active my recomendation is first of all you split the string based on the space, which will give you the array previoulsy mentioned doing the next:
string text = "G1,Active G2,Inactive G3,Inactive G24,Active";
string[] splitedGItems = text.Split(" ");
So, now you have an array, and I strongly recommend you to use an object/Tuple/Dictionary depends of what suits you more in the entire scenario. for now i will use Dictionary as it seems to be key-value
Dictionary<string, string> GxListActiveInactive = new Dictionary<string, string>();
foreach(var singleGItems in splitedGItems)
{
string[] definition = singleGItems.Split(",");
GxListActiveInactive.Add(definition[0], definition[1]);
}
What im achiving in this code is create a collection which is key-value, now you have to search the G24 manually doing the next
string G24Value = GxListActiveInactive.FirstOrDefault(a => a.Key == "G24").Value;
just do it :
var splitedArray = YourStringArray.ToDictionary(x=>x.Split(',')[0],x=>x.Split(',')[1]);
var gArray = splitedArray.Keys;
var activeInactiveArray = splitedArray.Values;
I hope it will be useful
You can divide the string using Split; the first part should be the G's, while the second part will be "Active" or "Inactive".
int i;
string[] temp, activity = new string[grids.Length];
for(i = 0; i <= grids.Length; i++)
{
temp = grids[i].Split(',');
grids[i] = temp[0];
activity[i] = temp[1];
}

Add item in list in specific position

I'm trying to find if i can add an item in list in specific position.
Example
string[] tokens= new string[10];
tokens[5]="TestString";
when i'm trying this to list
List<string> mitems = new List<string>();
mitems.Insert(5, "TestString");
I'm getting error list inside a list index out of range.
Is there any relative to this for a list?
Use the Insert(index, item); method.
Have a look at MSDN Insert for more information.
But you will get an error when you're trying to insert an item at an index which is not existing.
You could init your list with 10 empty values like you did with your array but if you use Insert a new entry is created and not an old replaced like with a dictionary. That would mean you would have 11 entries after the first use of Insert
This example code
var items = new List<string>();
items.AddRange(Enumerable.Repeat(string.Empty, 10));
Console.WriteLine(items.Count);
items.Insert(5, "TestString");
Console.WriteLine(items.Count);
gives this output (for better understanding):
10
11
private static void Myfunc()
{
List<string> l = new List<string>();
string opt = "y";
while (opt == "y")
{
Console.WriteLine("Do you want to add in a specific position? (y/n)");
string pos = Console.ReadLine();
if (pos == "y")
{
Console.WriteLine("Which index you want to add?");
int index = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Add items in {0}", index);
l.Insert(index, Console.ReadLine());
}
else
{
Console.WriteLine("Enter to add in a list");
l.Add(Console.ReadLine());
Console.WriteLine("Do you wish to continue? (y/n)");
opt = Console.ReadLine();
}
Console.WriteLine("Do you want to print the list? (y/n)");
string print = Console.ReadLine();
if (print == "y")
{
foreach (var item in l)
{
Console.WriteLine(item);
}
}
}
I wrote this function for you.
Add this function to a console app for better understanding how list works for insert and append
EDIT 1:
I just saw your edit, another way of initializing a list with default values and then insert something in a certain position would be by initializing the list like this :-
List<string> l = Enumerable.Repeat("something blank", 10).ToList();
And then add to an index of your choice
Following adds default values of string at every index from 0-9
string[] tokens= new string[10];
But list is created on heap nothing instantiated. No default assigned values.
List<string> mitems = new List<string>();
If you try following it will fail as there are no values at 0-5
mitems.Insert(5, "TestString");
If you do following it will work
mitems.Insert(0, "TestString");
You can use List<T>.Insert(int, T) method to do that, example:
var tokens = new List<string>();
for (int i = 0; i < 10; i++)
tokens.Add(string.Empty);
tokens.Insert(5, "TestString");
See MSDN
Edit:
If you were just trying to replace the item in index of 5, than the [] will also do the trick as following example:
var tokens = new List<string>(10);
for (int i = 0; i < 10; i++)
tokens.Add(string.Empty);
tokens[5] = "TestString";

c# change the string in a foreach string loop

I'm trying to cycle through strings in a list with a foreach loop, but I don't know how to change the item that's being referenced - How can I change s in the list... e.g. below I want to add "-" to the end of every string, s in myStringList
foreach(string s in myStringList)
{
s = s + "-";
}
I can't do things to s because it's a "foreach iteration variable" - so can I not change it as I cycle through?
Do I have to use an int to count through?
I'm sure there's a simpler way...
You can do this with Linq quite easily:
var newStringList = myStringList
.Select(s => s + "-")
.ToList();
If you really want to modify the existing list, you can use a classic for loop, for example:
for (var i = 0; i < myStringList.Count; i++)
{
myStringList[i] = myStringList[i] + "-";
}
Try this
List<string> listString = new List<string>() { "1","2","3"};
listString=listString.Select(x => x + "-").ToList();

Use LINQ to populate controls from object array

I am just trying to find a better way to populate some RadioButtonList controls. There are a set number of these on the usercontrol.ascx. The code is what I am currently using but I am still not very good with Linq and was wondering if there's a better way to do this.
quizId1 = quiz.Items[0].questionId;
pTag1.InnerText = quiz.Items[0].QuestionText;
foreach (Question q in quiz.Items[0].AnswerChoice)
{
radiobuttonlist1.Items.Add(new ListItem(q.Value, q.answerId));
}
same for radiobuttonlist2 but using Items[1] etc.
quizId2 = quiz.Items[1].questionId;
pTag2.InnerText = quiz.Items[1].QuestionText;
foreach (Question q in quiz.Items[1].AnswerChoice)
{
radiobuttonlist2.Items.Add(new ListItem(q.Value, q.answerId));
}
Sorry, the InnerText is a server side 'P' tag, pTag1, pTag2 etc.
Try this
var listItems = (from x in quiz.Items[0].AnswerChoice
select new ListItem { Text = q.Value, Value = q.answerId }
).ToList<ListItem>();
radiobuttonlist1.DataSource = listItems;
radiobuttonlist1.DataBind();
I suppose you could do something like this:
var listItems = from q in quiz.Items[0].AnswerChoice
select new ListItem(q.Value, q.answerId);
radioButtonlist1.Items.AddRange(listItems.ToArray());
though I'm not really sure if that buys you anything other than experience with LINQ...
I assume you want to use ling to popiulate several controls, not an individual control.
Linq is for querying, not updating. To update you still need either for or foreach loops.
If your RadioButtonList objects are in a collection, you could just loop over them:
var radioList = new [] {radiobuttonlist1, radiobuttonlist2, ...};
for(int i = 0; i < quiz.Items.Length; i++)
{
var quizId = quiz.Items[i].questionId;
radioList[i].InnerText = quiz.Items[i].QuestionText;
radioList[i].Items.AddRange(quiz.Items[i]
.AnswerChoice
.Select(q => => new ListItem(q.Value, q.answerId))
.ToArray()
);
}
or use DataSource as others have suggested:
var radioList = new [] {radiobuttonlist1, radiobuttonlist2, ...};
for(int i = 0; i < quiz.Items.Length; i++)
{
var quizId = quiz.Items[i].questionId;
radioList[i].InnerText = quiz.Items[i].QuestionText;
radioList[i].DataSource = quiz.Items[i].AnswerChoice;
radioList[i].DataTextField = "Value";
radioList[i].DataValueField = "answerId";
}
but there's no Linq way to populate several controls.

Add to array list from listbox selected item does not work properly

I have a program where I am trying to move items from one arrayList to another via a listbox and then print out the info in an XML, but the error I have is when I am adding it often certain times the values would repeat, when there are no repeats.
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
list1.Add(new RandomClass(var1, var2, var3, var4, var5, var6, var7));
foreach (object o in list1)
{
RandomClass m = (RandomClass)o;
selectionBox.Items.Add(m);
}
This is my initialization code.
bool req = true;
if (selectionBox.SelectedItem != null)
{
Count++;
errorLabel.Text = "";
for (int i = 0; i < selectionBox.Items.Count; i++)
{
if (selectionBox.GetSelected(i) == true)
{
RandomClass m = selectionBox.SelectedItem as RandomClass;
if (m.var2 == ((RandomClass)selectionBox.Items[i]).var2)
{
list2.Add(list1[i]);
}
}
}
}
else
{
errorLabel.Text = "Error";
}
Here is where I add to another array list. However as I said often the item would repeat and not be different, how can I resolve this problem?
Try clearing the second list each time you scan and add items from the first list.
list2.Clear();
for (int i = 0; i < selectionBox.Items.Count; i++)
....
I have fixed this problem using a list with my class, and there does not seem to be a problem.
List<RandomClass> list2 = new List<RandomClass>();
And then when adding I just simply put the following in the if statement
list2.Add(m);

Categories