Коллеги, посоветуйте что-нибудь хорошее :)
Дело вот какое. Браузер IE8, приложение построено на совершенно безумном фреймворке, элементы появляются и исчезают без всякого предупреждения и видимой внешней необходимости. :) Пока что мне удавалось это как-то побеждать, но сейчас как-будто в тупике. Есть у меня табличка с текстом. Мне нужно её представить в виде коллекции объектов. Каждый из объектов собирается из строки в этой таблице, ячейка строки - то или иное свойство объекта.
Задача изначально решалась двумя циклами с использованием двух коллекций WebElement (строчки и ячейки внутри каждой строчки), т.е. традиционно. Но пока драйвер ползал внутри одной строчки, ссылка на следующую устаревала, из-за чего пришлось повторять поиск каждой отдельной ячейки по полному xpath (см. ниже метод целиком), Да, xpath получается длинноватый, но что делать, такой роскоши, как статические id в приложении не предусмотрено.
public List<Actor> getActors() { List<Actor> actors = new ArrayList<Actor>(); List<WebElement> rows = driver.findElements(By.xpath("//div[contains(@onscroll,'bcgServicesLG_body') and @class='gridBody']/div[1]/table//tr")); int count = rows.size(); for (int i=1; i<=count; i++) { WebElement elem = driver.findElement(By.xpath("//div[contains(@onscroll,'bcgServicesLG_body') and @class='gridBody']/div[1]/table//tr["+i+"]")); List<WebElement> props = elem.findElements(By.xpath("./td")); int pcount = props.size(); List<String> properties = new ArrayList<String>(); for (int k=1; k<=pcount; k++) { properties.add(driver.findElement(By.xpath("//div[contains(@onscroll,'bcgServicesLG_body') and @class='gridBody']/div[1]/table//tr["+i+"]/td["+k+"]")).getText().trim()); } boolean isOn = properties.get(3).equals("включена"); Actor a = new Actor(properties.get(1), properties.get(2), properties.get(4), properties.get(6), isOn); a.setErrorMessage(properties.get(5)); actors.add(a); }
Да, я знаю, что вот так вот нельзя: "div[1]", но в данном случае никуда не деться. Локаторы тут оптимизации не поддаются.
Я знаю, что IE не очень любит длинные xpath, но он все равно меня удивил.
Вот в этом месте:
properties.add(driver.findElement(By.xpath("//div[contains(@onscroll,'bcgServicesLG_body') and @class='gridBody']/div[1]/table//tr["+i+"]/td["+k+"]")).getText().trim());
то на одной то на другой итерации цикла происходит то самое StaleElementReferenceException. Видать аккурат после того как элемент найден и до того, как мы успели из него текст извлечь.
Выходит, только мы элемент ухватили, идентификатор запомнили, а его уже и след простыл.
Конечно, поскольку это происходит с вероятностью процентов 10-20 для каждого конкретного элемента, то можно отлавливать эксепшн и повторять поиск опять. Глядишь, потихоньку и пробьемся. Но такое решение кажется мне упадническим, и я берегу его на самый крайний случай.
Заранее спасибо за любые идеи.