WebDriver/PageObject/FindBy: как указать xpath с динамическим значением?
Я пытаюсь использовать шаблон Page Object в Java и у меня возникли проблемы с @FindBy / XPath.
Ранее я использовал следующую конструкцию в Groovy:
driver.findElement(By.xpath("//td[contains(text(),'$SystemName')]")).click()
Here, SystemName is a parameter that can be different.
Теперь я хочу сделать то же самое, но в соответствии с парадигмой Page Object в Java:
public class ManagedSystems {
private WebDriver driver;
@FindBy(id="menu_NewSystem")
private WebElement menuNewSystem;
@FindBy (xpath = "//td[contains(text(),'$SystemName')]") // ??? How to use SystemName from deleteSystem method (below)?
private WebElement plantSystemName;
....
public SystemHomePage deleteSystem (String systemName) {
plantSystemName.click();
}
}
В моем тесте я вызываю deleteSystem:
SystemHomePage.deleteSystem("Firestone");
Вопрос: Как связать нотацию @FindBy для PlantSystemName и SystemName, указанные для deleteSystem?
Спасибо енот
4 ответа
Я использовал другой обходной путь для этого, который позволит нам использовать динамический xpath даже с фабрикой страниц.
Решение: Добавьте xpath любого родительского элемента, который является статическим, и укажите дочерний элемент с динамическим путем. В вашем случае, //td[содержит (text(),'$SystemName'), родительский элемент td может быть 'tr' или 'table'. Если таблица статическая, используйте код ниже:
@FindBy(xpath = "<..table xpath>")
public WebElement parentElement;
public WebElement getDynamicEmement(String SystemName){
parentElement.findElement(By.xpath("//tr/td[contains(text(),'"+SystemName+"')]"))
}
Теперь в вашем скрипте сначала получите доступ к таблице (чтобы ее ссылка загружалась в память), а затем вызовите метод getDynamicElement.
waitForElement(parentElement)
getDynamicElement("System-A")
Вы не можете сделать это, аннотации являются постоянными значениями, хранящимися в файле класса. Вы не можете вычислить их во время выполнения.
См. Можно ли определять переменные аннотации во время выполнения?
Благодаря Ардеско и Робби, я пришел к следующему решению:
private String RequiredSystemNameXpath = "//td[contains(text(),'xxxxx')]";
private WebElement prepareWebElementWithDynamicXpath (String xpathValue, String substitutionValue ) {
return driver.findElement(By.xpath(xpathValue.replace("xxxxx", substitutionValue)));
}
public void deleteSystem (String systemName) {
WebElement RequiredSystemName = prepareWebElementWithDynamicXpath(RequiredSystemNameXpath, systemName);
RequiredSystemName.click();
}
Вы используете фабрику объектов страницы вместо того, чтобы просто следовать шаблону объекта страницы.
Вы можете создавать объекты страницы как простые классы с идентификаторами, хранящимися как частные переменные, и методами, которые предоставляют элементам доступ к этим переменным, и вы по-прежнему придерживаетесь шаблона объекта страницы.
проверить это; http://relevantcodes.com/pageobjects-and-pagefactory-design-patterns-in-selenium/
Если ваши идентификаторы являются просто переменными, то вы можете использовать любые манипуляции, которые вы хотите