Проблема (Вопрос) заключается в том, что создав объект, он его не запоминает и постоянно ищет его по указанному пути.
К примеру:
SelenideElement row = tableList.$(byText(ip)).parent();
После вызова в UI редактирования для этого элемента - там меняется само поле, по которому происходит поиск.
row.$(“button”).click() - отработал, текстове поле стало input.
row.$(“input[name=‘ip’]”).setValue() - уже не выполняется, так как объект не находится по тексту byText(ip) из-за того, что этого текста уже нет.
HTML пример
До нажатия Редактирования
<tbody>
<tr> # сохраняет этот объект в объект row
<td data-test="ip">${ip}</td>
<td>
<button>Edit</button>
</td>
</tr>
</tbody>
После нажатия
<tbody>
<tr> # сохраняет этот объект в объект row
<td>
<input type="text" name="ip" value="${ip}" placeholder="">
</td>
<td>
<button>Edit</button>
</td>
</tr>
</tbody>
Вот и как так сделать, что бы работать с найденным родителем? Решил свой вопрос через нахождение его напрямую (при создании он всегда находится на первом месте), но что если нужно искать не конкретно его.
да, это самое логично, но к сожалению с этим какие-то проблемы ( React + web-kit - это самописная библиотека элементов).
Проблема тут даже вот в чём, я переписал через WebElement - и поиск через xpath - работает как надо, сделал аналогично на SelenideElement - при повторном обращении к строке, которую уже нашёл и совершил действие, - теряет элемент из-за того, что поле, по которому элемент был найден изменилось. Вот тут как-то проблемно, на мой взгляд.
Стало интересно и уже второй час переписываю код туда-сюда
// tableList - приватный аттрибут класса, который определяется при инициализации страницы для объекта tbody
public IPTablePage changeFirstRuleInTable(String text, IPTableRule rule) {
WebElement row = tableList.findElement(By.xpath("//text()[contains(.,'"+text+"')]/../..")); // - работает, находит и продолжает работать с элементом после изменения
// SelenideElement row = tableList.find(By.xpath("//text()[contains(.,'"+text+"')]/../..")); - не работает, теряет элемент после изменения
// WebElement row = tableList.$(By.xpath("//text()[contains(.,'"+text+"')]/../..")); // - не работает, теряет элемент после изменения
// WebElement row = tableList.$(byText(text)).parent(); // - не работает, теряет элемент
updateRule(row, rule);
return clickSaveButton(row);
}
private IPTablePage clickEditButton(WebElement row){
logger.info("Click edit button");
row.findElement(byText("Edit")).click();
return this;
}
private void updateRule(WebElement row, IPTableRule newRule){
clickEditButton(row);
row.findElement(By.cssSelector("input[name='addr']")).clear(); // теряет элемент на этой строке, пытаясь повторно найти row
row.findElement(By.cssSelector("input[name='addr']")).sendKeys(newRule.ip);
row.findElement(By.cssSelector("input[name='added_by_cause']")).clear();
row.findElement(By.cssSelector("input[name='added_by_cause']")).sendKeys(newRule.reason);
row.findElement(By.cssSelector("input[placeholder='Expired Date']")).clear();
row.findElement(By.cssSelector("input[placeholder='Expired Date']")).sendKeys(formatter.format(newRule.expiredDate));
row.findElement(By.cssSelector("[data-test='ip-edit-type'] span.sc-input__control")).click();
selectValueFromDropDownListForEdit(newRule.listType.toString());
row.findElement(By.cssSelector("[data-test='ip-edit-section'] span.sc-input__control")).click();
selectValueFromDropDownListForEdit(newRule.actionType.toString());
}
В общем, скорее всего это связано с обновлением элемента, что бы избежать StaleElementReferenceException или что-то в этом роде. А так как он не знает какой кусок DOM есть наш объект, он его повторно ищет. Интересен момент, что WebElement с findElement вполне себе справляются с этой задачей =(
Если я правильно понял, то в примере Андрея, ситуация повторится, когда в этой строке я поменяю ip => data-ip аттрибут тоже изменится и начнётся хаос.