Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- *******************************
- if (element.is(condition) == true)
- /*
- такой код равносилен
- if (element.is(condition))
- мной приведенный вариант красивее)
- меньше действий )
- да/нет с да не сравниваем
- сразу оперируем да/нет - которое уже получили
- */
- **********************************
- public WebElement getWrappedEntity() {
- if (fetchWrappedEntity() == null) {
- throw new ElementNotFoundException();
- }
- return fetchWrappedEntity();
- }
- /*
- не надо дважды получать fetchWrappedEntity()
- один раз получили, сохранили в переменную
- и если все ок - ее же и вернули
- что касается исключения - хорошо бы в конструктор исключения слова какие-то передать
- что же за элемент му не нашли
- лучше чем вариант с toString этого же объекта(лейзи-элемента) - у нас нету
- для этого придется реализовать конструктор для ElementNotFoundException
- с одним параметром String message
- в котором вызови аналогичный конструктор предка
- http://developer.alexanderklimov.ru/android/java/extends.php
- http://metanit.com/java/tutorial/3.5.php
- https://docs.oracle.com/javase/tutorial/java/IandI/super.html
- */
- ***************************************
- public class LazyCollectionFindElement extends AbstractLazyElement {
- ...
- @Override
- public WebElement fetchWrappedEntity() {
- ...
- return null;
- }
- /*
- мы своими руками - null не возвращаем
- сразу бросаем исключение - не нашли элемента
- ElementNotFoundException - и тут подойдет
- то же самое - в конструктор исклюсения передавай toString
- да, можно возразить - что на следующем шаге мі и так проверим на нулл и бросим исключение
- Будем последовательны) сами никаких нуллов не вернем нигде
- так проще - меньше помнить придется - что где и как реализовано
- */
- **********************************
- public class LazyCollectionFindElement extends AbstractLazyElement {
- /*
- корректнее назвать такой класс LazyCollectionFoundByConditionElement
- ну или LazyCollectionFoundElement
- */
- ***********************************
- public class LazyCollectionNthElement extends AbstractLazyElement {
- ....
- public WebElement fetchWrappedEntity() {
- WebElement element = null;
- try {
- element = parentCollection.getWrappedEntity().get(index);
- if (element != null) {
- return element;
- }
- /*
- я не это имела в виду в прошлом ревью
- тут - внутри try-catch
- просто возвращай parentCollection.getWrappedEntity().get(index);
- дополнительного сравнения на нулл не надо
- мы явно - нулл не возвращаем (тут же мы нигде не написали - return null)
- а сравнение на нулл - есть в getWrappedEntity
- не надо лишнего кода
- наша цель - не писать вот так - return null
- и в ключевых местах - встроить проверки на нулл
- но только там
- собственно, использование вот такой схемы - вместо возврата нуллов кидать исключения
- как раз и нужно - чтоб избежать кучи if (... != null)
- в различных частях кода
- */
- } catch (LazyСollectionIndexOutOfBoundsException e) {
- /*
- тут - лови IndexOutOfBoundsException - т к именно такое исключение может возникнуть
- если в get(index) - индекс выходит за границы коллекции
- и если словится - вместо такого исключения - кидай LazyСollectionIndexOutOfBoundsException
- кстати - обрати внимание - LazyСolleсtionIndexOutOfBoundsException - подчеркивается кусок имени
- зеленой волнистой линией, где-то русские буквы есть )
- цель - свести все исключения к потомкам WebDriverException
- */
- }
- return element;
- /*
- как ты понимаешь - нам не понадобится ни этой строки
- ни переменной element
- */
- }
- *************************************
- public class LazyWebDriverElement extends AbstractLazyElement {
- public LazyWebDriverElement(AbstractLazyElement abstractLazyElement, By innerLocator) {
- super();
- }
- /*
- вот это не ясно для чего )
- для чего?
- */
- ***************************************
- public class LazyCollectionFilteredByCondition extends AbstractLazyCollection
- /*
- т к фильтровать можно лишь коллекции
- тут можно сэкономить на имени класса
- LazyFilteredCollection
- LazyFilteredByConditionCollection
- а если не экономить - то по нашей схеме
- LazyCollectionFilteredByConditionCollection
- */
- ******************************************
- public V apply(LazyEntity<V> entity) {
- ...
- if (check(wrappedEntity)== true) {
- /*
- достаточно if (check(wrappedEntity))
- */
- throw new WebDriverAssertionException();
- /*
- тут тоже в конструктор исключения - передавай toString самого кондишена
- и для этого исключения придется реализовать конструктор с параметром String message
- */
- }
- *************************************
- public T until(Condition <T> condition, long timeout) {
- Throwable lastError = null;
- long startTime = System.currentTimeMillis();
- do {
- try {
- T result = condition.apply(entity);
- if (result != null) {
- return result;
- }
- /*
- и тут код упростится
- apply нам не вернет null
- он или что-то хорошее вернет
- или бросит WebDriverAssertionException
- потому можно сразу писать
- return condition.apply(entity);
- */
- } catch (WebDriverException | IndexOutOfBoundsException e) {
- /*
- а тут - уже не надо ловить IndexOutOfBoundsException
- мы еще на этапе fetchWrappedEntity() в LazyCollectionNthElement это решили
- теперь нас интересуют только потомки WebDriverException
- */
- lastError = e;
- }
- sleep(Configuration.pollingInterval);
- } while (System.currentTimeMillis() - startTime < timeout);
- throw new TimeoutException(String.format("failed while waiting %d milliseconds to assert %s", timeout, condition.toString()), lastError);
- }
- ******************************************
- public boolean is(Condition<WebElement> condition) {
- try {
- WebElement result = condition.apply(this);
- if (result != null) {
- return true;
- }
- /*
- и тут упрощай
- просто -
- condition.apply(this);
- return true;
- если будет выполняться следующая строка после condition.apply(this);
- значит - исключения не возникло
- и значение condition.apply(this) - не равно нуллу
- */
- } catch (WebDriverException | IndexOutOfBoundsException e) {
- /*
- тут тоже лови только WebDriverException
- */
- return false;
- /*
- этого можешь не писать
- */
- }
- return false;
- /*
- потому что есть эта строка
- */
- }
- ******************************
- public class BaseTest {
- @Before
- public void setUp() {
- setDriver(new FirefoxDriver());
- }
- @After
- public void tearDown() {
- getDriver().quit();
- }
- }
- /*
- если сейчас е используешь параллельный запуск - так тогда разумнее
- в BeforeClass & AfterClass создавать и закрывать вебдрайвер
- обрати внимание - таймаут ты в потомках настраивала в BeforeClass методе
- тут желательно все соответственно делать
- */
- *********************************************
- @Override
- public LazyElement doubleClick() {
- waitFor(this).until(visible());
- actions().doubleClick(this).perform();
- return this;
- }
- @Override
- public LazyElement hover() {
- waitFor(this).until(visible());
- actions().moveToElement(this).perform();
- return this;
- }
- /*
- а чего в этих методах
- actions().moveToElement(this).perform();
- а не
- actions().moveToElement(getWrappedEntity()).perform();
- ?
- нам нужно оперировать уже вебэлементом
- когда дело доходит до конкретного действия
- */
- ****************************************
- public class CssClass extends AbstractCondition<WebElement> {
- ...
- @Override
- public boolean check(WebElement element) {
- attribute = element.getAttribute("class");
- return (attribute.equals(cssClass));
- }
- /*
- еще одна ошибка нашлась
- вспомни прошлые работы - как был реализован кондишен - работающий с классами
- мы получали значение атрибута class
- там содержатся классы, перечисленные через пробел
- мы эту строку разбивали на слова
- и если один из классов равен оюидаемому - да
- проверка прошла
- просто сравнивать на равенство - не получится
- у элемента может быть несколько классов
- вот тут - уже все тест-методы должны работать)
- если так - идем дальше
- */
- ********************************************************
- @Override
- public WebElement fetchWrappedEntity() {
- for (LazyElement element : parentCollection) {
- if (element.is(condition)) {
- return element.getWrappedEntity();
- }
- }
- throw new ElementNotFoundException(toString());
- }
- /*
- ну да, код конечно красивый)
- и что по факту мы делаем
- сначала - заворачиваем каждый вебэлемент списка коллекции
- (чтобы воспользоваться итератором для нашей коллекции)
- а потом - на каждом шаге - разворачиваем (получаем wrappedElement = element.getWrappedEntity())
- т е - делаем таки кучу не нужной работы
- хоть код и красивый, конечно...
- правильнее - для оптимизации реально выполняемых действий -
- отказаться от идеи обхода коллекции таким образом
- for (LazyElement element : parentCollection)
- а реализовать вот так
- получить список вебэлементов parentCollection.getWrappedEntity()
- обойти полученный список вебэлементов в цикле
- и применять к вебэлементу - метод check
- правда, для этого объявление метода check придется вынести на уровень интерфейса Condition
- сэкономим на заворачиваниях-разворачиваниях)
- */
- *********************************
- public interface Condition<T> {
- T apply(LazyEntity<T> entity);
- boolean check(T wrappedEntity);
- }
- /*
- делаем красиво)
- сейчас в этом интерфейсе - объявлены методы
- служащие как для принятия решения - прошли-не прошли
- так и для получения результата ожидания
- нарушаем Single Responsibility Principle )
- реализуй интерфейс Matcher <T> с объявленным методом boolean check(T wrappedEntity);
- а в Condition <T> - останется apply
- Condition <T> - отнаследуй от Matcher <T>
- */
- ************************************
- /*
- а теперь и метод is можно реализовать чуть красивее - с использованием check кондишена
- */
- ********************************************
- /*
- еще немного challenge )
- в интерфейсе LazyElement
- объяви методы
- LazyCollection findAll(By innerLocator);
- LazyCollection findAll(String innerCssSelector);
- и реализуй их в AbstractLazyElement
- этот метод позволит у элемента - по селектору или локатору - получить коллекцию внутренних элементов
- отладиться можно - используя
- LazyCollection tasks = $("#todo-list").findAll("li");
- или
- LazyCollectionLazyCollection emails = $("[role='main']").findAll(".zA");
- Иногда такой метод findAll будет очень полезным
- принципы - те же
- как ты до этого реализовывала методы get, find, filter ...
- так сказать - для закрепления результатов)
- */
- ********************************************
- /*
- насчет использования модификатора доступа protected
- есть такая точка зрения, что использовать protected - это самообман
- т к в рамках потомков можно для отнаследованного protected-метода
- этот метод сделать публичным
- когда мы использовали protected, мы хотели, чтобы что-то было с возможностью наследования
- и не хотели его внешнего использования.
- а кто-то отнаследовался от нашего класса и объявил это как public
- и вот то, что мы прятали внутри класса - уже "торчит" наружу
- есть good practice - избегать применения protected
- то, что мы что-то объявим внутри класса-кондишена как public
- не будет нам особо мешать при работе с нашим фреймворком
- т к в итоге - используем для кондишена тип интерфейс,
- и это позволит не светить нашими публичными переменными/методами
- когда будем юзать фреймворк
- идеально про протектед-методы
- http://programmers.stackexchange.com/questions/162643/why-is-clean-code-suggesting-avoiding-protected-variables
- http://joxi.ru/52akqzoUGnqYGr
- http://stackoverflow.com/questions/3631176/why-are-many-developers-opposed-to-using-the-protected-modifier-in-oop
- http://stackoverflow.com/questions/37011/should-you-ever-use-protected-member-variables
- http://stackoverflow.com/questions/4913025/reasons-to-use-private-instead-of-protected-for-fields-and-methods
- http://www.javalobby.org/java/forums/t77911.html
- Просмотри весь проект, перейди на использование public
- */
Advertisement
Add Comment
Please, Sign In to add comment