java.lang.NullPointerException при явном ожидании

Я пытаюсь перебрать и нажать несколько кнопок на веб-странице. Мой код сначала проверяет количество элементов на странице, затем просматривает и щелкает каждый из них.

Это сработало для первого цикла, но потом я получил Element Not Found исключение во втором цикле. Это происходит потому, что при нажатии кнопки элемент исчезает со страницы, а DOM изменяется. Затем я прочитал, что явное ожидание заставит Selenium переполнить DOM. Поэтому я добавил явное ожидание.

Но теперь я получаю java.lang.NullPointerException на самой первой петле на wait.Until линия.

Водитель RemoteWebDriver если это имеет какое-либо значение.

var elements = new List<IWebElement>();
driver.Manage().Timeouts().ImplicitWait=TimeSpan.FromSeconds(0);
elements.AddRange(driver.FindElements(By.XPath("//button[contains(@data-cancelref,'outgoing_requests')]")));

if(!elements.Any()) {
    return;
}

int loop = elements.Count-1;
for(int i = 0; i<loop; i++) {
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//button[contains(@data-cancelref,'outgoing_requests')]")));
    var button = driver.FindElement(By.XPath("//button[contains(@data-cancelref,'outgoing_requests')]"));
    button.Click();
    Thread.Sleep(rnd.Next(2000, 4000));
}

driver.Manage().Timeouts().ImplicitWait=TimeSpan.FromSeconds(60);

Трассировки стека:

at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebElement.get_Displayed()
at OpenQA.Selenium.Support.UI.ExpectedConditions.<>c__DisplayClass7_0.<ElementIsVisible>b__0(IWebDriver driver)
at OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition)
at _Common.FDriver.Clean(IWebDriver driver, String prox, Int32 timeout, Boolean& success) in C:\_Common\FDriver.cs:line 727

Строка 727 является заявлением For

1 ответ

Я думаю, что вы делаете это более сложным, чем это должно быть. Из того, что вы заявили, каждый раз, когда вы нажимаете кнопку, она исчезает со страницы. Из-за этого вам не нужно (и не нужно) перебирать элементы со счетчиком, потому что в каждом цикле коллекция уменьшается.

Это логика:

  1. Вы очищаете страницу, чтобы получить текущую коллекцию кнопок
  2. Вы нажимаете первую кнопку

Вы повторяете эти шаги, пока не останется больше кнопок.

IReadOnlyCollection<IWebElement> elements = GetElements();
while (elements.Any())
{
    elements.ElementAt(0).Click();
    elements = GetElements();
}

Я поместил код, чтобы получить элементы в отдельной функции. Вы не должны, но я думаю, что это делает код немного чище.

public IReadOnlyCollection<IWebElement> GetElements()
{
    return new WebDriverWait(Driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.XPath("//button[contains(@data-cancelref,'outgoing_requests')]")));
}
Другие вопросы по тегам