Как создать статический контент страницы при работе с несколькими фреймами? - PullRequest
0 голосов
/ 12 октября 2018

Я только недавно начал работать над тестированием нового приложения и начал моделировать объекты страницы для указанного приложения.

Я обнаружил, что это приложение использует «фреймы», так как в DOM содержится 2 илибольше тегов HTML-элементов.По умолчанию, похоже, что GEB не может видеть элементы, найденные под вложенным элементом HTML.

Я проверил книгу GEB и увидел, что вы можете использовать метод withFrame, чтобы указать, к какому фрейму принадлежит элемент.когда я делаю это, GEB действительно видит рассматриваемый элемент.

Проблема, с которой я столкнулся, заключается в том, что я не хочу, чтобы люди, которые пишут сценарии (используя объекты моей страницы), беспокоились о том, какой кадрконкретный элемент исходит от.Я хочу знать, есть ли способ указать рамку, к которой принадлежит элемент, из статического содержимого.В противном случае автор сценария должен будет не только знать, что элемент находится вне фрейма, но также должен проверить и посмотреть, к какому фрейму относится данный элемент.

Вот некоторые из вещей, которые я до сих пор пробовал:

SomePage extends Page{
    static content=  {
        myNavigator {withFrame("header", {$(By.xpath("my xpath"))})}
    }
}

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

Я также пробовал это, что также вызывает устаревание элемента:

SomePage extends Page{
    static content=  {
        myNavigator {$(By.xpath("my xpath"))}
    }

    Navigator getMyNavigator(){
        return withFrame("header", {myNavigator})
    }
}

Я понимаю, почему это происходит, после того, как colusre withFrame выполняется, я предполагаю, что любые элементыссылки внутри этого замыкания становятся устаревшими.

По сути, я хочу, чтобы все, что нужно сделать сценаристу, это сказать что-то вроде:

at MyPage
waitFor {myNavigator}.click()

Я хочу избежать необходимости:

at MyPage
withFrame("header", {waitFor {myNavigator}.click()}

Как я могу настроить это на стороне объектов страницы, чтобы получить желаемый результат?(Могут ли модули быть возможной опцией?)

Редактировать: я также пытался определить статическое содержимое с немного другим синтаксисом, но все еще получал ту же ссылку на устаревший элемент:

myNavigator{ withFrame("header") { $(By.xpath("//td/a"))} } 

Edit2: Я также попытался реализовать что-то похожее на этот пост: https://groups.google.com/forum/#!topic/geb-user/uxgcgWgmGYE

мой статический контент теперь выглядит так:

static content = {
    bannerMod {withFrame("banner") {module BannerModule}}
    mainViewMod {withFrame("FrameworkMain") {module MainViewModule}}
    sideMenuMod {withFrame("contents") {module SideMenuModule}}
}

Я переместил все элементы в соответствующие модули, нотеперь, когда я пытаюсь ссылаться на них, я все еще получаю исключение для устаревшей ссылки на элемент.например, он добавляется в эту строку кода:

if(!mainViewMod.table.displayed){

с указанием stale element reference: element is not attached to the page document

1 Ответ

0 голосов
/ 21 октября 2018

Как вы уже заметили, вы получаете StaleElementExcpetions, потому что вы пытаетесь получить доступ к элементам, на которые вы получили ссылку, когда находитесь в контексте фрейма после переключения в контекст корневых документов, то есть выпытаясь получить доступ к этим элементам вне вызова withFrame().

Я вижу два решения вашей проблемы.

Первый - не использовать withFrame(), а управлять контекстом кадра вручную с помощью вызовов driver.switchTo().frame(..).К сожалению, это будет означать, что вы не достигнете цели, заключающейся в том, чтобы не знать, какие элементы и из каких фреймов поступают при использовании объектов страницы.

Другой способ - написать на своей странице метод, который бы закрывали иметь дело с переключением на правильный кадр.Что-то вроде:

class PageWithFrames extends Page {
    public <T> T mainView(@DelegatesTo(value = MainViewPage, strategy = Closure.DELEGATE_FIRST) Closure<T> mainViewAction) {
        withFrame('FrameworkMain', MainViewPage, mainViewAction)
    }
}

class MainViewPage extends Page {
    static content = {
        table { ... }
    }
}

И тогда его можно использовать так:

at PageWithFrames
if (mainView { table.displayed }) {
    ....
}

Обратите внимание, что благодаря аннотации @DelegatesTo IntelliJ будет знать, что вы находитесь на MainViewPage внутриmainView {} позвоните, и вы получите автозаполнение.Просто помните, что что бы вы ни делали, вы не должны возвращать элементы страницы из вызовов mainView {}, потому что вы начнете получать StaleElementException s.

Вы также можете найти "Переключение страниц и фреймов сразу" ручной раздел интересный.

...