Расположение элемента селена

Есть ли простой способ найти дочерний элемент из другого элемента (оба этих элемента были найдены с помощью PageFactory)? У нас есть набор контейнеров, в которых содержится много модулей, и я хотел бы убедиться, что они отображаются в соответствующих местах.

API, похоже, имеет только следующий метод:

webElement.findElement(s).(By by);

Есть ли простой способ сделать следующее:

webElement.findElement(s)(WebElement webElement);

или еще лучше:

webElement.contains(WebElement webElement);

person Scott    schedule 04.04.2012    source источник
comment
Я не могу понять, что ты пытаешься сделать. Не могли бы вы привести пример? Из того, что я понял, element.findElement(s)(By by) должно хватить даже для ваших нужд. Что я делаю неправильно?   -  person Petr Janeček    schedule 05.04.2012
comment
Я бы предпочел больше не использовать отражение, чтобы вытащить аннотацию FindBy из полей. У меня есть два элемента, которые уже были инициализированы пользовательской PageFactory. У нас есть много разных модулей, которые можно создавать и добавлять на разные страницы. Я не хочу модифицировать каждый из этих тестов всякий раз, когда страницы изменяются в CMS, поэтому я самостоятельно нахожу эти модули и теперь хочу убедиться, что они существуют в правильных местах на экране (т.е. я хочу чтобы убедиться, что модуль A находится в контейнере A или B, но не в C).   -  person Scott    schedule 05.04.2012


Ответы (1)


Наконец-то я получил то, что тебе нужно. Моим лучшим решением было бы что-то вроде:

public static void assertContains(WebElement outerElem, WebElement innerElem) {
    // get borders of outer element
    Point outerLoc = outerElem.getLocation();
    Dimension outerDim = outerElem.getSize();
    int outerLeftX = outerLoc.getX();
    int outerRightX = outerLeftX + outerDim.getWidth();
    int outerTopY = outerLoc.getY();
    int outerBottomY = outerTopY + outerDim.getHeight();

    // get borders of inner element
    Point innerLoc = innerElem.getLocation();
    Dimension innerDim = innerElem.getSize();
    int innerLeftX = innerLoc.getX();
    int innerRightX = innerLeftX + innerDim.getWidth();
    int innerTopY = innerLoc.getY();
    int innerBottomY = innerTopY + innerDim.getHeight();

    // assures the inner borders don't cross the outer borders
    final String errorMsg = "ughh, some error message";
    final boolean contains = (outerLeftX <= innerLeftX)
            && (innerRightX <= outerRightX)
            && (outerTopY <= innerTopY)
            && (innerBottomY <= outerBottomY);
    assertTrue(errorMsg, contains);
}

... работает, только если ни один из этих контейнеров не перекрывается. Если они это сделают, я бы попробовал немного темной и дикой магии с innerElem.getTag() и getText() и проверил, содержит ли внешний текст внутренний элемент. Один из способов сделать это:

public static void assertContains(WebElement outer, WebElement inner) {
    // e.g. //div[text()='some text in inner element']
    final String findInner = ".//" + inner.getTagName() + "[text()='" + inner.getText() + "']";
    try {
        outerElem.findElement(By.xpath(findInner));
    } catch (NoSuchElementException ignored) {
        fail("Some horrible message! We are all doomed!");
    }
    // passed
}

... или что-то подобное. Возможно, normalize-space() или contains() (или оба) потребуется из-за тегов в тегах в тегах в.. .

И, конечно же, это еще догадки. Первый метод может иметь ложные срабатывания и негативы (но мне он больше нравится, учитывая мои потребности), второй должен иметь только ложные срабатывания. Вы можете комбинировать их или придумать что-то самостоятельно (например, используя Reflection, как вы уже сказали).

Или отправьте сообщение об ошибке.

person Petr Janeček    schedule 04.04.2012
comment
Хотя мне не обязательно нравится этот метод, он дает преимущество в том, что мы должны быть в состоянии определить, отображают ли браузеры HTML аналогично друг другу, однако это также палка о двух концах, так как HTML на самом деле может быть дочерним элементом элемента, но не в его границах, если мы получаем результат из шланга от драйвера из-за проблем с рендерингом. - person Scott; 05.04.2012
comment
Да, я знаю, что это не то, что мы на самом деле хотели бы иметь =/. Кроме того, я отредактировал ответ, чтобы он был более полезным для будущих читателей (кстати, вы сами казались довольно способными). - person Petr Janeček; 05.04.2012
comment
Выглядит хорошо, я, скорее всего, просто буду работать над пользовательским локатором, так как я думаю, что он будет немного чище. Я также собираюсь опубликовать это в репозитории кода Google Selenium в качестве запроса функции. - person Scott; 05.04.2012
comment
Или это. Забавно, я не думал об этом вообще. - person Petr Janeček; 05.04.2012
comment
Если вам интересно, я передал родительский элемент пользовательской ElementLocatorFactory, которую мы создали, и поймал исключения, если они не были найдены в этом конкретном WebElement (и зарегистрировал проблему 3682). - person Scott; 19.04.2012