Транспортир, повторяющиеся элементы: Failed: ссылка на устаревший элемент - PullRequest
0 голосов
/ 08 мая 2018

У меня есть массив элементов веб-драйвера, я пытаюсь перебрать их, чтобы удалить все, кроме одного с индексом 0. Процессы внутри этой итерации асинхронные.

Я пробовал несколько вещей, но ни одна из них не работает.

Мой текущий подход заключается в использовании цикла for of, но я получаю Failed: stale element reference: element is not attached to the page document.

const els = await this.el.getElements(this.s.tm.button.remove)

for (let el of els) {
      if (els.indexOf(el) >= 1) {
        await this.h.waitForSpinner(2147483647)
        await el.click()
        await EC.isVisible(this.s.tm.deleteModal.container)
        await this.h.waitForSpinner(2147483647)
        await this.el.clickElement(this.s.tm.deleteModal.confirmButton)
      }
    }

Я также пытался использовать:

element.all(by.css('[data-qa="this.s.tm.button.remove"]')).filter((el, i) => {
      return i >= 1;
    }).each(async (el, i) => {
      await el.click()
      await EC.isVisible(this.s.tm.deleteModal.container)
      await this.h.waitForSpinner(50000)
      await this.el.clickElement(this.s.tm.deleteModal.confirmButton)
    });

Но этот второй подход не ожидает асинхронного кода.

Любая помощь будет оценена!

=================== ОБНОВЛЕННОЕ РЕШЕНИЕ =================== 1018 *

Решение для перебора коллекции элементов WebDriver с помощью @yong является правильным.

Однако в моем случае код внутри for loop означает , удаляя один элемент каждый раз, так что есть момент, когда .get(i) пытается получить индекс, предоставленный циклом, который не больше существует на странице. Получение ошибки:

Failed: Index out of bound. Trying to access element at index: 6, but there are only 5 elements that match locator By(css selector, [data-qa=team-members__button-remove]).

Решение - использовать декремент for loop. Это означает, что цикл в обратном направлении els_count всегда будет соответствовать get(i). Обратите внимание, что если els_count === 10, последний индекс будет 9. Поэтому нам нужно сделать els_count - 1.

async deleteAllTeamMembers() {
  await EC.isVisible(await this.el.getFirstElement(this.s.tm.button.invite));
  const els_count = await this.el.getElements(this.s.tm.button.remove).count();

for (let i = els_count - 1; i >= 1; i--) {
  await EC.isVisible(this.el.getElements(this.s.tm.button.remove).get(i))
  await this.el.getElements(this.s.tm.button.remove).get(i).click()
  await EC.isVisible(this.s.tm.deleteModal.confirmButton, 50000)
  await this.el.clickElement(this.s.tm.deleteModal.confirmButton)
  await this.h.waitForSpinner(50000)
}

}

Ответы [ 2 ]

0 голосов
/ 09 мая 2018
const els_cnt = await element.all(by.css('[data-qa="this.s.tm.button.remove"]')).count();

for (let index=1;index<els_cnt;index++) {
    await element.all(by.css('[data-qa="this.s.tm.button.remove"]')).get(index).click();
    await EC.isVisible(this.s.tm.deleteModal.container)
    await this.h.waitForSpinner(50000)
    await this.el.clickElement(this.s.tm.deleteModal.confirmButton)
}
0 голосов
/ 08 мая 2018

Попробуйте сделать это. Удерживайте элементы в объекте, и вам нужно асинхронно обращаться к каждому элементу и выполнять действия, как показано ниже. Не нужно указывать время ожидания

this.searchResults = element.all(by.xpath('<xpath>') // this will hold array of elements

function foo(){
this.searchResults.then(function(runTimeResults){
            for(i=0; i< runTimeResults.length; i++){
                if(i>0){ //click/delete the element if the index > 0
                (function(currentElement){
                    currentElement.click();                 
                    });
                })(runTimeResults[i]);// Need to hold the current ith element in a variable => currentElement
                }
            };
        });
}
...