Selenium 2 предоставляет достаточно много локаторов для поиска элементов. Но иногда возникает необходимость поиска элементов по своим параметрам, например, поиск элемента по значению атрибута. Есть несколько вариантов решения такой задачи.
Вариант 1. Можно написать собственные методы сортировки результатов, полученных поиском элементов по стандартным локаторам. Но это самое медленное и нерациональное решение, которое можно использовать.
Вариант 2. Можно использовать XPath для поиска элементов по заданным параметрам, например, значениям атрибутов.
driver.findElements(By.xpath(".//*[@value='register']"));
Вариант 3. Можно создать собственный механизм поиска элементов. Такое решение сделает код более компактным. Для того, чтобы это осуществить, нужно унаследоваться от класса By и переопределить его abstract метод findElements
. При необходимости можно также переопределить метод findElement
.
package examples.selenium; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.SearchContext; import org.openqa.selenium.WebElement; public class ByAttribute extends By { private String attr; private String value; public ByAttribute(String attrName, String value) { super(); this.attr = attrName; this.value = value; } @Override public List<WebElement> findElements(SearchContext context) { return context.findElements( By.xpath(".//*[@" + attr + "='" + value + "']") ); } /** * @param value The exact value to match against * @return a By which locates elements * by the value of the "href" attribute */ public static By href(String value) { if (null == value) { throw new IllegalArgumentException( "Cannot find elements when href is null."); } return new ByAttribute("href", value); } /** * @param value The exact value to match against * @return a By which locates elements * by the value of the "title" attribute */ public static By title(String value) { if (null == value) { throw new IllegalArgumentException( "Cannot find elements when title is null."); } return new ByAttribute("title", value); } @Override public String toString() { return "ByAttribute." + attr + ": " + value; } }
Метод findElements
переопределен для поиска элементов по значению атрибута с помощью XPath. Для примера реализованы также два статических (!необязательных) метода href(String value)
и title(String value)
. Использовать класс ByAttribute
можно двумя способами — через статические методы и непосредственно вызывая конструктор ByAttribute
:
driver.findElements(ByAttribute.href="#"); By passwordLocator = new ByAttribute("type","password"); driver.findElement(passwordLocator);
Использование статических методов значительно сокращает код и предотвращает ввод неверных имен атрибутов.
При переопределении метода findElements
можно использовать любой способ для поиска элементов, например, javascript:
@Override public List<WebElement> findElements(SearchContext context) { return (List<WebElement>) ((JavascriptExecutor) context) .executeScript("return $('" + jQuerySel+ "');"); }