Прозрачная работа со всплывающими окнами и iFrame

Продолжить обсуждение из А как вы проставляете значения полей на формах?:

вероятно вы используете паттерн wrapper или decorator для оборачивания WebElement. Иначе как вы перехватываете обращение к элементу без прокси, AOP и т.п.?

По все видимости да - но что в этом плохого?

нет ничего плохого :slight_smile: Это просто одна из реализаций перехвата обращения к WebElement.

Но, поскольку вы используете тип-враппер для элемента, то вероятно не используете стандартный механизм webdriver для ожидания появления элемента, когда элементы страницы можно размечать аннотациями вроде этой:

@FindBy (id = "crmGrid")
WebElement clientsTableElement;

Тогда при обращении к этому элементу в коде страницы нет необходимости использовать явное ожидание, WebDriver сам его организует (если инициализация элементов страницы делается с помощью AjaxElementLocatorFactory).

Или вы используете этот механизм?

Не-не-не. На этот механизм я “забил” после первых 10-20 кейсов, он слишком неуклюжий и деревянный. А явных достоинств я в нем не вижу, и мне приятнее видеть что нить типа

WebElement clientsTable = id(“crmGrid”);

или

Table clientsTable = table(“crmGrid”);

[quote=“joemast, post:4, topic:3486”]
Тогда при обращении к этому элементу в коде страницы нет необходимости использовать явное ожидание, WebDriver сам его организует (если инициализация элементов страницы делается с помощью AjaxElementLocatorFactory).
[/quote]Это ж во врапере тоже прикручивается элементарно.

ну вот и выяснили почему вы обошлись без использования AOP и прокси :slight_smile: Архитектура тестового фреймворка сильно зависит от особенностей тестируемого приложения.

Если элементы на странице (в подавляющем большинстве) загружаются до того как document.readyState == “complete” (я не уверен, но похоже как-то так webdriver ожидает загрузку страницы), то и встроенные в PageObject механизмы ожидания не пригодятся. А в редких случаях необходимости можно использовать wait на местном уровне.

А если большинство элементов страницы загружается через ajax, то к каждому элементу прицеплять wait уже не будет так удобно и красиво.

Нужно исходить из особенностей AUT

Не понятно, причем тут аякс и ожидания? Дефолтовый эксплисит вейт легко прикручивается как на уровне WebPage, так и на уровне WebElement.

AUT не простой - аякса хватает.

Да и driver().manage().timeouts().implicitlyWait() никто не отменял.

Причем тут особенности AUT - хоть убейте не пойму.

Все таки, от приложение многое зависит. У меня вот Single Page Application, когда физически все на одной странице, а JavaScript (knockout) уже эмулирует многостраничность.
В такой ситуации, implicit/explicit ожиданий было просто недостаточно. Они просто не работали нормально. Приходилось явно спрашивать у jQuery закончился Ajax-запрос или нет.

1 лайк

Можно опустить слово “дефолтовый”. Как может влиять специфика приложения на реализацию сабжа? Меня убеждают что может, а я этого понять не могу.
PS: может стоило упомянуть, что я использую позднюю инициализацию

Давайте по фактам:

  1. У вас своя реализация инициализации элементов
  2. Вы реализовали свою позднюю инициализацию (вероятно, при первом обращении к методу?)
  3. Вероятно (внутри реализации у вас свои ожидания элементов)

Вопрос: а зачем вы это все сделали, если специфика приложения никак не влияет?

Почему бы не использовать стандартные реализации, например те, которые есть в PageObject?

Вероятно, потому, что как раз специфика приложения: задержки, ajax, погрузки, применения различных эффектов, таки влияют на работу тестов.
Но, тут я ничего не говорю, если подход работает и не создает проблем – значит он правильный.

Для себя я выбрал другой путь:

  • Использую стандартный PageObject, который идет вместе с WebDriver (Support), потому что вполне его хватает и инициализация по умолчанию, там тоже ленивая, что для меня важно.
  • Все ожидания у меня явные, но скрыты внутри других методов PageObject
  • Ожидалки элементов у меня тоже явные, и свои, на C# выглядит так:
    txtName.Wait().SendKeys(“”);
    или
    txtName.Wait(3000).SendKeys (“);

Если нужно подождать выполнения отдельного длительного запроса (например, сохранение формы), то тоже делаю это явно, но, опять же, все скрыто в методах PageObject’ов.

1 лайк

Причем тут особенности AUT - хоть убейте не пойму

не для каждого приложения оправдано введение такого богатого на функционал слоя PageElement как у вас. Для кого-то будет достаточно (более оправдано использование) стандартных механизмов, предлагаемых из коробки.

К примеру, использование слоя PageElement оправдано в ситуации, когда эти elements имеют одинаковую верстку на всех страницах. А если в приложении каждая (ну или почти каждая) страница неповторима и одинаковые с виду элементы имеют разную верстку, то в классах PageElement-слоя можно будет запросто запутаться.

Поэтому и нет у нас автотестеров единого стандарта и приходится выбирать те подходы, которые лучше сработают для данного конкретного AUT

P.S. благодаря нашей дискуссии я серьезно задумался над тем, чтобы использовать подобный вашему PageElement-слой на одном из своих проектов, где стандартизация верстки элементов страниц достаточно высокая

Много было причин. Мозолили глаза повторяющиеся локаторы, помимо @FindBy приходилось использовать findElement, хотелось простой типизации элементов, простой декомпозиции страницы/элемента, читабельных логов, расширенного интерфейса WebElement (со своими ассертами, доп. экшенами) и т.д. Возможно это и реализуется в рамках PageFactory через кастомные фабрики, прокси, рефлекшены, но это сразу “поднимает планку” для ньюкамеров, у которых зачастую и базовые знания ООП отсутствуют, не говоря уже про патерны.

Так что специфика приложения тут точно никак не влияла на этот выбор. Сначала это обкатывалось в приложении на GWT (SCLocator’ы, здоровенные xpath’ы, и прочие “вкусности” в виде js затычек), потом допилилось и легко “легло” на другой проект “долгожитель”, в котором наравне с “классическим” html используются и современные библиотеки для UI.

[quote=“joemast, post:11, topic:3486”]
Для кого-то будет достаточно (более оправдано использование) стандартных механизмов, предлагаемых из коробки.
[/quote]Сомневаюсь что коробочную версию можно применять без дополнительной “обработкой напильником”, ну разве что на сайтах-визитках. Может я просто “не умею ее готовить” - хз, но когда появлялись “хотелки”, простой и очевидной возможности их реализации в PageFactory я не видел, что и подтверждает данный топик.

[quote=“joemast, post:11, topic:3486”]
А если в приложении каждая (ну или почти каждая) страница неповторима и одинаковые с виду элементы имеют разную верстку, то в классах PageElement-слоя можно будет запросто запутаться.
[/quote]Нет нужды выделять уникальные UI контролы в отдельный класс, вполне хватает “базового”. Я создаю новый класс, когда копи-паст становится очевиден.
Да я б и не сказал, что это “жирный” слой - три класса с сумарным кол-вом строк около тысячи, но это со всякими “плюшками”, типа contextClick(), dragAndDrop(), waitForElementInvisibility(), verifyIsDisplayed() и т.д.