Я работаю с GEB и селеном уже некоторое время, и много раз я столкнулся с ужасным исключением элементарного элемента, потому что одна из страниц, которую я должен тестировать, динамически загружается, тем самым вызывая устаревшие исключение элемента.Как я могу переписать этот метод, чтобы дать мне точное xpath или локатор? (Избегая исключения устаревших элементов)
Я пришел очень близко к созданию уловов всего решения для исключения устаревшего элемента, но, увы, недостаточно близко, поэтому мне нужна помощь.
Моим решением было переопределить класс NonEmptyNavigator, который поставляется с GEB. Я собираюсь показать мой метод нажмите() в качестве примера:
class NonEmptyNavigator extends geb.navigator.NonEmptyNavigator {
def NonEmptyNavigator() {
super()
}
NonEmptyNavigator(Browser browser, Collection<? extends WebElement> contextElements) {
super(browser, contextElements)
}
//overridden click method (all of the methods are overridden though
Navigator click(count = 0){
if (count >= 60) {
return super.click()
}
else{
try{
return super.click()
}
catch (StaleElementReferenceException s) {
def oData = this.toString()
def matcher = Pattern.compile("-> ([^:]+): (.*)]").matcher(oData) //Parses out the xPath
matcher.find() //Again more Parsing
def newXpath = matcher.group(2) //final Parsing step
newNav = browser.$(By.xpath(newXpath)) //create a new NonEmptyNavigator from the Stale Navigator's xpath
return newNav.click(count + 1) //attempt to click the new Navigator
}
}
}
}
Теперь вы можете подумать, «Ого, это действительно хорошее решение» (и это), но бывают случаи, когда это не работает , и я не уверен, как победить. Позвольте мне привести пример.
Если я что-то вроде этого (упрощенный для удобства чтения):
class SomePage extends Page{
static content = {
table(required: false) {$(By.xpath("//table/tbody"))}
}
//assume this method gets called in a test script
def someMethod(){
table.click() //assume this throws a StaleElementException
}
}
REFERENCING мой перекрытый метод выше, oData.toString() заканчивает тем, что-то вроде: «[[[ChromeDriver: хром на XP (2cd0a7132456fa2c71d1f798ef32c234)] -> xpath: // table/tbody]] "
как вы можете видеть. Я могу извлечь xpath и создать новый объект навигатора, который является большим.
Где я столкнуться с проблемами, когда приходится сталкиваться с ситуацией, как это:
class SomePage extends Page{
static content = {
table(required: false) {$(By.xpath("//table/tbody"))}
}
//assume this method gets called in a test script
def someMethod(){
table.children().getAt(1).children().getAt(2).click() //assume this throws a StaleElementException
}
}
При выполнении щелчка() бросает несвежий элемент, oData.toString() появляется как это: «[[[ [[ChromeDriver: chrome on XP (2cd0a7132456fa2c71d1f798ef32c234)] -> xpath: // table/tbody]] -> xpath: child :: *]] -> xpath: child :: *]] "
Как вы можете см. информацию о том, что в настоящее время я пытаюсь получить доступ к дочернему узлу дочернего узла, но у меня больше нет ссылки, мне нужно переопределить этот конкретный элемент. У меня нет индекса конкретного ребенка (или детей), который я хочу.
Мне интересно, есть ли способ получить эту информацию, учитывая мои текущие рамки. Я также был бы открыт для других идей и предложений.
В целом я стараюсь создать уловить все решения для исключения StaleElementException. Я думаю, что я довольно близко и нуждаюсь в небольшом подталкивании, чтобы преодолеть последний горб.
Знаете ли вы, что означает 'StaleElementReferenceException'? Я думаю, вы не должны пытаться бороться с этим безликим врагом во всем мире :), но попытайтесь исправить эти строки вашего кода, где вы можете использовать ссылку на элементы, которые больше не привязаны к 'DOM' – Andersson
@Ansersson I new Я бы получил ответ как это :), и да, я хорошо разбираюсь в том, что означает StaleElementReferenceException. Как я отметил в своем описании, страница, которую я тестирую, обновляется динамически. В некоторых случаях он может обновляться более одного раза в секунду, даже если все элементы остаются в соответствующих местах. Вот почему мне нужно решение, которое мне нужно. Я знаю, что я мог бы попытаться поймать снова и снова на скрипте верхнего уровня, но это кажется беспорядочным для меня, я хочу написать что-то более надежное. – switch201
Я собираюсь советовать против «поймать все решения». Вы пробовали предложение waitFor от Geb? Разве это не устранит ваши проблемы более элегантно? –