Получить xpath из WebElementFacade для конкатеннации

На проекте используем Java + Serenity + Cucumber.
В классе каждого объектра страницы имеются, естесственно, элементыи с локаторами. Например:

@FindBy(xpath = “//input[@name=‘filter’ and @id=‘leftFilterValue’]”)
private WebElementFacade searchField;

Допустим, в дальнейшем в определенном методе необходимо использовать xpath указанного элемента с добавлением еще какой-то части xpath к нему. То есть, нужно конкетенировать xpath указанного searchField с, скажем //h3.

Не нашел возможности выдернуть xpath значение в объявленных объектах типа WebElementFacade инструментами serenity. Посоветуйте, плз

Вот js скрипт получения полного xpath для переданного элемента

Summary
    public static string GetAbsoluteXPath(IWebDriver Browser, IWebElement element)
    {
        return (string)((IJavaScriptExecutor)Browser).ExecuteScript(
             "function absoluteXPath(element) {" +
               "var comp, comps = [];" +
                 "var parent = null;" +
                 "var xpath = '';" +
                 "var getPos = function(element) {" +
                 "var position = 1, curNode;" +
                 "if (element.nodeType == Node.ATTRIBUTE_NODE) {" +
                 "return null;" +
                 "}" +
                 "for (curNode = element.previousSibling; curNode; curNode = curNode.previousSibling) {" +
                     "if (curNode.nodeName == element.nodeName) {" +
                         "++position;" +
                     "}" +
                 "}" +
                 "return position;" +
                 "};" +

                 "if (element instanceof Document) {" +
                     "return '/';" +
                 "}" +

                 "for (; element && !(element instanceof Document); element = element.nodeType == Node.ATTRIBUTE_NODE ? element.ownerElement : element.parentNode) {" +
                 "comp = comps[comps.length] = {};" +
                 "switch (element.nodeType) {" +
                 "case Node.TEXT_NODE:" +
                     "comp.name = 'text()';" +
                     "break;" +
                 "case Node.ATTRIBUTE_NODE:" +
                     "comp.name = '@' + element.nodeName;" +
                     "break;" +
                 "case Node.PROCESSING_INSTRUCTION_NODE:" +
                     "comp.name = 'processing-instruction()';" +
                     "break;" +
                 "case Node.COMMENT_NODE:" +
                     "comp.name = 'comment()';" +
                     "break;" +
                 "case Node.ELEMENT_NODE:" +
                     "comp.name = element.nodeName;" +
                     "break;" +
                 "}" +
                 "comp.position = getPos(element);" +
                 "}" +

                 "for (var i = comps.length - 1; i >= 0; i--) {" +
                     "comp = comps[i];" +
                     "xpath += '/' + comp.name.toLowerCase();" +
                     "if (comp.position !== null) {" +
                     "xpath += '[' + comp.position + ']';" +
                     "}" +
                 "}" +
                 "return xpath;" +

             "} return absoluteXPath(arguments[0]);", element);
    }

Скрипт возвращает xpath строкой

ну и это c#, необходимо под джаву поменять типы объектов

Зачем это нужно? Если для того, чтобы искать //h3 внутри searchField, то обращаться к локатору нет необходимости. Серенити и так умеет искать внутри элемента:

WebElementFacade innerText = searchField.findBy("//h3");

Если все-таки нужно хранить локаторы и обращаться к ним, то имхо лучше держать их не в аннотациях а в константах.

1 лайк

то что нужно, спс