Krazy Dev Krazy Dev - 3 months ago 10
C# Question

Function keeps throwing index out of range exception

I have a function that will get a IWebElement from a list based on the index that is passed.

Here is the property -

public IList<IWebElement> ExistingDrafts { get { return Driver.FindElements(By.ClassName("broadcast-list-item")); } }


Here is the function-

public void DeleteDraft(int index = 0) {

if(ExistingDrafts.Count > 0) {
ExistingDrafts[index].Click();
}

IWebElement discardButton = Driver.FindElement(By.XPath("/html/body/div[2]/div/div[1]/div[2]/div/div[2]/form/div[7]")).FindElements(By.ClassName("form-control"))[0];
Wait.Until(w => discardButton != null);

discardButton.Click();
}


Here is how it is being used in my test-

[Fact]
public void DeleteTheDraft() {

BroadcastPage.DraftsHyperLink.Click();
//delete first draft
string firstDraftSubj = BroadcastPage.ExistingDrafts[0].Text;
System.Threading.Thread.Sleep(6000);
BroadcastPage.DeleteDraft(0);

string newfirstDraftSubj = BroadcastPage.GetNewestDraftSubject();
BroadcastPage.Wait.Until(w => newfirstDraftSubj != null);

Assert.True(firstDraftSubj != newfirstDraftSubj, "Draft was not deleted");
}


When I debug through my test, it passes. However if I run the test, it throws the exception. I'm not sure what's going on.

Answer

This happens because not all the elements are loaded on the page. Basically public IList<IWebElement> ExistingDrafts { get { return Driver.FindElements(By.ClassName("broadcast-list-item")); } } will get only some elements (seeing that you check that Count > 0).

Your best way at this is to have a wait in place that will wait for all the elements to be present and this can be achieved by using:

public By ExistingDraftBy
{
    get {return By.ClassName("broadcast-list-item");}
}

WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 2, 0));
wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(ExistingDraftBy));

And to be more on the safe side, modify your if statement to also check for the index to be less than then count:

if(ExistingDrafts.Count > 0 && index < ExistingDrafts.Count) 
{
    ExistingDrafts[index].Click();
}
Comments