safary
safary

Reputation: 325

for loop "index was out of range" c# webdriver

I am getting "index out of range" from this loop. But I need to use new elements that loop founds, how do I do that? Please help to fix the problem

int linkCount = driver.FindElements(By.CssSelector("a[href]")).Count;
string[] links = new string[linkCount];

for (int i = 0; i < linkCount; i++)
{
    List<IWebElement> linksToClick = driver.FindElements(By.CssSelector("a[href]")).ToList();
    links[i] = linksToClick[i].GetAttribute("href");
}

Upvotes: 1

Views: 704

Answers (5)

jaredlee.exe
jaredlee.exe

Reputation: 81

int linkCount = driver.FindElements(By.CssSelector("a[href]")).Count;
List<string> links = new List<string>();

for (int i = 0; i < linkCount; i++)
{
    List<IWebElement> linksToClick = driver.FindElements(By.CssSelector("a[href]")).ToList();
    if (linksToClick.Count < i)
        links.Add(linksToClick[i].GetAttribute("href"));
}

This might help with the out of range exception. Doing this allows you to create a list of type: string without having to explicitly define the size of the list

Upvotes: 0

CThakur
CThakur

Reputation: 136

First of all i dont see a point in assigning linkstoclick values inside loop... And Reason for error must be that linksToClick list's length is more than that of linkCount.

Upvotes: 0

Leigh Shepperson
Leigh Shepperson

Reputation: 1053

You can rewrite your code to bypass the for loop:

string[] links = driver.FindElements(By.CssSelector("a[href]")).Select(l => l.GetAttribute("href")).ToArray();

This should also avoid the index out of range problem, and cut down the amount of code you have to write.

Upvotes: 1

Miłosz Wieczorek
Miłosz Wieczorek

Reputation: 591

I think that you could refactor your code:

var linkElements = driver.FindElements(By.CssSelector("a[href]")).ToList();
var links = new List<string>();

foreach (var elem in linkElements)
{
    links.Add(elem.GetAttribute("href"));
}

If that works, you could simplify the query:

var instantLinks = driver.FindElements(By.CssSelector("a[href]"))
                                .Select(e => e.GetAttribute("href"))
                                .ToList();

Upvotes: 1

Noctis
Noctis

Reputation: 11763

the first one gets all of your elements by tag name ...let's assume 5.

in the loop, your driver get's all the elements by css selector, and you might have a different number here. let's say 4.

then, you might be trying to set the fifth element in a four element array. boom.

Easiest fix to debug:

int linkCount = driver.FindElements(By.TagName("a")).Count;
string[] links = new string[linkCount];
// WRITE OUT HOM MANY links you have

for (int i = 0; i < linkCount; i++)
{
    List<IWebElement> linksToClick = driver.FindElements(By.CssSelector("a[href]")).ToList();
    // ASSERT THAT YOU HAVE THE SAME AMOUNT HERE
    If (links.Count != linksToClick.Count)
         // your logic here

    links[i] = linksToClick[i].GetAttribute("href");
}

Upvotes: -1

Related Questions