Q:

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.

A:

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();
}

