Selenium Webdriver: инициализация фабрики страниц с использованием путей относительно других элементов?

Я пытаюсь написать объект страницы в Selenium Webdriver, используя аннотации @FindBy фабрики страниц. Объект страницы предназначен для боковой панели, а родительский элемент WebElement, содержащий все элементы, с которыми объект страницы должен взаимодействовать, инициализируется следующим образом:

@FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]")
WebElement sidebar;

Затем мне нужен ввод для поиска относительно этого элемента sidebar. Есть ли способ сделать ссылку на элемент sidebar? Я мог скопировать и вставить весь путь в начало:

@FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]//input[@id='search']")

Но я бы предпочел сделать это относительно первого элемента. Возможно ли что-нибудь подобное?

@FindBy (parent = "sidebar", xpath = ".//input[@id='search']")

документация Selenium по аннотации @FindBy немного не хватает ...


person kesslern    schedule 16.06.2014    source источник
comment
Нет, с @FindBy это невозможно.   -  person Nathan Merrill    schedule 17.06.2014


Ответы (3)


Ответ - реализовать ElementLocatorFactory, который позволяет вам предоставлять контекст поиска (то есть драйвер или WebElement).

public class SearchContextElementLocatorFactory
        implements ElementLocatorFactory {

    private final SearchContext context;

    public SearchContextElementLocatorFactory(SearchContext context) {
        this.context = context;
    }

    @Override
    public ElementLocator createLocator(Field field) {
        return new DefaultElementLocator(context, field);
    }
}

Затем при создании экземпляра объекта страницы используйте эту фабрику локаторов.

WebElement parent = driver.findElement(By.xpath("//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]"));
SearchContextElementLocatorFactory elementLocatorFactory = new SearchContextElementLocatorFactory(parent);
PageFactory.initElements(elementLocatorFactory, this);

Теперь ваши @FindBy аннотации будут относиться к parent. Например, чтобы получить главную боковую панель WebElement:

@FindBy(xpath = ".")
WebElement sideBar;
person kesslern    schedule 17.06.2014
comment
Спасибо, очень полезно, но мне интересно, есть ли способ создать экземпляр объекта страницы без поиска родительского элемента (просто установите локатор родительского элемента и создайте экземпляр, когда элемент просматривается, что лучше соответствует шаблону, imo)? - person SirLenz0rlot; 07.10.2015
comment
Ответ выглядит как одноразовая конфигурация для всех FindBys на странице. Есть ли возможность настроить его для любого отдельного FindBy (как в вопросе ›› @ FindBy (parent = sidebar, xpath = .// input [@ id = 'search']) ‹<) - person Robert DROP TABLE STUDENTS; 24.09.2019

Нет, это невозможно. Но вы можете использовать методы получения вместо инициализации на основе аннотаций:

public class SomePage {
    @FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and   child::div[.='Sidebar']]")
    private WebElement sidebar;

    private WebElement getSomeChildElement() {
        return siderbar.findElement(By.id("somechild"));
    }
}
person Lucas Wa    schedule 16.06.2014
comment
Я полагал. Я этим и занимаюсь. - person kesslern; 17.06.2014

Selenium Jutils библиотека сделает все, что вам нужно. Вы можете проверить этот ответ на похожий вопрос.

person Slev Florin    schedule 27.07.2021