Как удалить и сбросить коллекцию для каждого цикла в Java? - PullRequest
0 голосов
/ 15 октября 2019

Selenium: 3.141 в Java

Проблема: Как сбросить сбор в цикле for-each?

WebElement columnid = driver.findElement(By.id("id")); 
List<WebElement> getTaskName = columnid.findElements(By.xpath("//*[contains(@class,'card-title')]")); //gets the list of first 20 elements i.e., 1-20
for(Iterator<WebElement> ite = getTaskName.iterator(); ite.hasNext();)
{
    WebElement el = ite.next();
    JavascriptExecutor jse = (JavascriptExecutor) driver; 
    jse.executeScript("arguments[0].scrollIntoView();",el); //scroll-down one element
    ite.remove(); //have added remove and modified for-each loop with collection to iterator. it doesn't throw concurrentmodifiedexception. 
    getTaskName = columnid.findElements(By.xpath("//*[contains(@class,'card-title')]")); //this gets the list of next 20 elements i.e., 2-21
}

Ожидаемый результат: Я хочу reset getTaskName с элементами 2-21 и повторите каждый элемент.

Фактический результат: getTaskName всегда установлен на 1-20 и повторяется с 1-20 и завершается.

Пожалуйста, дайте мне знать, если что-то отсутствует или неверно изприведенный выше пример кода. Спасибо.

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

Ваш код не работает, потому что первое выражение в операторе for (Iterator<WebElement> ite = getTaskName.iterator()) вычисляется только один раз: до начала первой итерации.

Таким образом, getTaskName = columnid.findElements(...) фактически переназначает getTaskName нановый List, но ваш цикл for все еще выполняет итератор, который вы получили в первый раз. Этот итератор привязан к экземпляру List, из которого он был получен, и не будет автоматически переключать списки, если вы переназначите getTaskName.

Если вы хотите сохранить цикл, вынеобходимо преобразовать его в цикл while и переназначить сам итератор для нового экземпляра итератора, например:

WebElement columnid = driver.findElement(By.id("id")); 
List<WebElement> getTaskName = columnid.findElements(By.xpath("//*[contains(@class,'card-title')]")); //gets the list of first 20 elements i.e., 1-20
Iterator<WebElement> ite = getTaskName.iterator();
while(ite.hasNext())
{
    WebElement el = ite.next();
    JavascriptExecutor jse = (JavascriptExecutor) driver; 
    jse.executeScript("arguments[0].scrollIntoView();",el); //scroll-down one element
    ite.remove(); //have added remove and modified for-each loop with collection to iterator. it doesn't throw concurrentmodifiedexception. 
    getTaskName = columnid.findElements(By.xpath("//*[contains(@class,'card-title')]")); //this gets the list of next 20 elements i.e., 2-21
    ite = getTaskName.iterator();
}

Обратите внимание, что это кажется мне не очень чистым. Использование итератора для получения первого элемента кажется совершенно ненужным. Вы могли бы сделать это вместо этого:

WebElement columnid = driver.findElement(By.id("id")); 
List<WebElement> getTaskName = columnid.findElements(By.xpath("//*[contains(@class,'card-title')]")); //gets the list of first 20 elements i.e., 1-20
while(!getTaskName.isEmpty())
{
    WebElement el = getTaskName.get(0);
    JavascriptExecutor jse = (JavascriptExecutor) driver; 
    jse.executeScript("arguments[0].scrollIntoView();",el); //scroll-down one element
    getTaskName = columnid.findElements(By.xpath("//*[contains(@class,'card-title')]")); //this gets the list of next 20 elements i.e., 2-21
}

В идеале, вам, вероятно, следует настроить свой запрос XPath, чтобы просто вернуть первый элемент в списке.


В качестве отдельного вопроса, я 'Я не думаю, что то, что вы пытаетесь сделать, будет работать. Насколько я помню из своего опыта работы с Selenium, удаление элемента из List, возвращаемого findElements(), НЕ приводит к удалению этого элемента из DOM страницы. Таким образом, запрос columnid.findElements() с тем же запросом XPath всегда будет возвращать точно такой же список WebElement. Поэтому, если какой-либо другой сценарий на веб-странице автоматически не удалит первый элемент DOM в списке, когда он прокручивается в поле зрения, ваш цикл всегда будет зависать на первом элементе.

0 голосов
/ 15 октября 2019

Не уверен, что это помогает, но однажды у меня была похожая проблема, и я исправил ее с помощью итерации в обратном направлении.

Список заполнен числами от 0 до 4. Это не удаляет каждый элемент списка:

for (int i = 0; i < arr.size (); i++) {
  arr.remove (i);
}

output = [1, 3]

Но это прекрасно работает:

for (int i = arr.size () - 1; i >= 0; i--) {
  arr.remove (i);
}

output = []

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...