Продолжить обсуждение из А как вы проставляете значения полей на формах?:
вероятно вы используете паттерн wrapper или decorator для оборачивания WebElement. Иначе как вы перехватываете обращение к элементу без прокси, AOP и т.п.?
По все видимости да - но что в этом плохого?
нет ничего плохого Это просто одна из реализаций перехвата обращения к 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 и прокси Архитектура тестового фреймворка сильно зависит от особенностей тестируемого приложения.
Если элементы на странице (в подавляющем большинстве) загружаются до того как 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-запрос или нет.
Можно опустить слово “дефолтовый”. Как может влиять специфика приложения на реализацию сабжа? Меня убеждают что может, а я этого понять не могу.
PS: может стоило упомянуть, что я использую позднюю инициализацию
Давайте по фактам:
- У вас своя реализация инициализации элементов
- Вы реализовали свою позднюю инициализацию (вероятно, при первом обращении к методу?)
- Вероятно (внутри реализации у вас свои ожидания элементов)
Вопрос: а зачем вы это все сделали, если специфика приложения никак не влияет?
Почему бы не использовать стандартные реализации, например те, которые есть в PageObject?
Вероятно, потому, что как раз специфика приложения: задержки, ajax, погрузки, применения различных эффектов, таки влияют на работу тестов.
Но, тут я ничего не говорю, если подход работает и не создает проблем – значит он правильный.
Для себя я выбрал другой путь:
- Использую стандартный PageObject, который идет вместе с WebDriver (Support), потому что вполне его хватает и инициализация по умолчанию, там тоже ленивая, что для меня важно.
- Все ожидания у меня явные, но скрыты внутри других методов PageObject
- Ожидалки элементов у меня тоже явные, и свои, на C# выглядит так:
txtName.Wait().SendKeys(“”);
или
txtName.Wait(3000).SendKeys (“);
Если нужно подождать выполнения отдельного длительного запроса (например, сохранение формы), то тоже делаю это явно, но, опять же, все скрыто в методах PageObject’ов.
Причем тут особенности 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() и т.д.