julia_v_iluhina

Untitled

Oct 28th, 2016
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.13 KB | None | 0 0
  1. public class SmartFilteredByConditionCollection extends AbstractSmartCollection {
  2. ...
  3.  
  4.     @Override
  5.     public List<WebElement> getWrappedEntity() {
  6.         List<WebElement> innerCollection = new ArrayList<>();
  7.  
  8.         for (SmartElement smartElement:collection) {
  9.             if (smartElement.is(condition)) {
  10.                 innerCollection.add(smartElement);
  11.             }
  12.         }
  13.         return innerCollection;
  14.     }
  15. /*
  16.     ну да метод красивый
  17.     почти)
  18.  
  19.         убери лишние комментарии
  20.  
  21.         не согласна я с термином innerCollection )
  22.         корректнее - filteredCollection
  23.  
  24.         а главное - в список правильнее помещать именно вебэлемент
  25.         а не завернутый в смартэлемент
  26.         не innerCollection.add(smartElement);
  27.         в innerCollection.add(smartElement.getWrappedEntity());
  28.  
  29.         нам ведь в getWrappedEntity() - надо кончательно от смарт-сущностей
  30.         перейти к вебэлементам или их спискам
  31.  
  32.     за нашей красотой
  33.     на самом деле кроются потери времени)
  34.  
  35.         что по факту мы делаем
  36.  
  37.                 сначала - заворачиваем каждый вебэлемент списка коллекции
  38.                 (чтобы воспользоваться итератором для нашей коллекции)
  39.                 а потом - на каждом шаге - разворачиваем (получаем wrappedElement = element.getWrappedEntity())
  40.  
  41.                 т е - делаем таки кучу не нужной работы
  42.                 хоть код и красивый, конечно...
  43.  
  44.             правильнее - для оптимизации реально выполняемых действий -
  45.             отказаться от идеи обхода коллекции таким образом
  46.                 for (SmartElement smartElement:collection)
  47.  
  48.             а реализовать вот так
  49.                 получить список вебэлементов collection.getWrappedEntity()
  50.                 обойти полученный список вебэлементов в цикле
  51.                 и применять к вебэлементу - метод check
  52.                 правда, для этого объявление метода check придется вынести на уровень интерфейса Condition
  53.  
  54.                 сэкономим на заворачиваниях-разворачиваниях)
  55.     поправь и в SmartCollectionFoundByConditionElement
  56. */
  57. *******************************
  58. public interface Condition<T> {
  59.     T apply(SmartEntity<T> entity);
  60.  
  61.     boolean check(T wrappedEntity);
  62. }
  63.  
  64. /*
  65.     делаем красиво)
  66.  
  67.     сейчас в этом интерфейсе - объявлены методы
  68.         служащие как для принятия решения - прошли-не прошли
  69.         так и для получения результата ожидания
  70.  
  71.     нарушаем Single Responsibility Principle )
  72.  
  73.     реализуй интерфейс Matcher <T> с объявленным методом boolean check(T wrappedEntity);
  74.  
  75.     а в Condition <T> - останется apply
  76.     Condition <T> - отнаследуй от Matcher <T>
  77.  
  78.     и реализацию is стоит поправить - с check она будет нагляднее
  79. */
  80. ************************************
  81. /*
  82.     еще немного challenge )
  83.  
  84.     в интерфейсе SmartElement
  85.         объяви методы
  86.     SmartCollection findAll(By innerLocator);
  87.     SmartCollection findAll(String innerCssSelector);
  88.  
  89.     и реализуй их в AbstractLazyElement
  90.  
  91.     этот метод позволит у элемента  - по селектору или локатору - получить коллекцию внутренних элементов
  92.  
  93.     отладиться можно - используя
  94.     SmartCollection tasks = $("#todo-list").findAll("li");
  95.     или
  96.     SmartCollectionLazyCollection emails = $("[role='main']").findAll(".zA");
  97.  
  98.     Иногда такой метод findAll будет очень полезным
  99.  
  100.     принципы - те же
  101.     как ты до этого реализовывала методы get, find, filter ...
  102.  
  103.     так сказать - для закрепления результатов)
  104. */
  105. **************************************
  106. public class Text extends ElementCondition {
  107.  
  108.     protected String expectedText;
  109.     protected String actualText;
  110. /*
  111.     насчет использования модификатора доступа protected
  112.  
  113.         есть такая точка зрения, что использовать protected - это самообман
  114.         т к в рамках потомков можно для отнаследованного protected-метода
  115.         этот метод сделать публичным
  116.  
  117.         когда мы использовали protected, мы хотели, чтобы что-то было с возможностью наследования
  118.         и не хотели его внешнего использования.
  119.         а кто-то отнаследовался от нашего класса и объявил это как public
  120.         и вот то, что мы прятали внутри класса - уже "торчит" наружу
  121.  
  122.         есть good practice - избегать применения protected
  123.         то, что мы что-то объявим внутри класса-кондишена как public
  124.         не будет нам особо мешать при работе с нашим фреймворком
  125.         т к в итоге - используем для кондишена тип интерфейс,
  126.         и это позволит не светить нашими публичными переменными/методами
  127.         когда будем юзать фреймворк
  128.  
  129.         идеально про протектед-методы
  130.             http://programmers.stackexchange.com/questions/162643/why-is-clean-code-suggesting-avoiding-protected-variables
  131.             http://joxi.ru/52akqzoUGnqYGr
  132.  
  133.             http://stackoverflow.com/questions/3631176/why-are-many-developers-opposed-to-using-the-protected-modifier-in-oop
  134.             http://stackoverflow.com/questions/37011/should-you-ever-use-protected-member-variables
  135.             http://stackoverflow.com/questions/4913025/reasons-to-use-private-instead-of-protected-for-fields-and-methods
  136.  
  137.             http://www.javalobby.org/java/forums/t77911.html
  138.  
  139.     Просмотри весь проект, перейди на использование public
  140. */
  141. ***************************
  142. public interface Condition<V> {
  143.  
  144.     V apply(SmartEntity<V> smartEntity);
  145.  
  146. }
  147. /*
  148.     просмотри конвеншенсы и подправь
  149.     тут для дженерик-типа - вместо <V> - надо бы <T> использовать
  150.     остальные классы просмотри
  151.     http://stackoverflow.com/questions/2900881/generic-type-parameter-naming-convention-for-java-with-multiple-chars
  152.     https://docs.oracle.com/javase/tutorial/java/generics/types.html
  153. */
  154. ******************************
  155. public abstract class ElementConditions {
  156.  
  157.     public static Condition<WebElement> visible() {
  158.         return new Visible();
  159.     }
  160. /*
  161.     по идее - можно было еще короче)
  162. */
  163. public static Condition<WebElement> visible = new Visible();
  164.  
  165. /*
  166.     т е - реализовывать не метод, а статическую переменную
  167.     вроде бы - лаконичнее, что хорошо
  168.  
  169.     но - не так уж и хорошо)
  170.  
  171.     Тут есть такая тонкость)
  172.  
  173.     мы создали статические переменные = объект-кондишен
  174.  
  175.     и используем их в проекте, который поддерживает параллелизацию
  176.  
  177.     если мы в параллельных тестах будем использовать ОДИН объект-кондишен ОДНОВРЕМЕННО
  178.     могут возникать странные ошибки
  179.  
  180.     чтобы избежать этого
  181.     вместо переменных стоит использовать методы
  182.     тогда для каждого вызова кондишена мы будем использовать свой объект
  183.     и таких проблем не будет
  184.  
  185.     наш текущий вариант с методом - грамотнее)
  186. */
  187. ***********************************************
  188.  public static Condition<List<WebElement>> listNthElementHasText(int index, String text) {
  189.         return new ListNthElementHasText(index, text);
  190.  }
  191. /*
  192.     нам такое сложное теперь и не нужно
  193.     мы вполне можем и так делать
  194.     $$(...).get(...).shouldHave(...)
  195.  
  196.     убираем гибрида ужа с ежом)
  197.     и тут, и сам класс ListNthElementHasText
  198. */
  199. *********************************
  200. public class Present extends ElementCondition {
  201.  
  202.     boolean isPresent;
  203. /*
  204.     просмотри классы
  205.     я бы все же была более конкретной
  206.     и явно указывала модификатор доступа (access modifier)
  207. */
  208. *********************************************
  209. public abstract class ElementCondition extends AbstractCondition<WebElement> {
  210.  
  211. }
  212. /*
  213.     кажется, уже єто обсуждали
  214.     по большому счету - класс реализован только ради его наследников
  215.  
  216.     если наводим японский минимализм - можно и прибить
  217.     а наследников єтого класса - наследовать от AbstractCondition<WebElement>
  218.  
  219.     не настаиваю
  220. */
  221. ***********************
  222. public class SizeOf extends CollectionCondition {
  223.  
  224.     ...
  225.     protected int actualSize = 0;
  226. /*
  227.     вполне можно было и не инициализировать
  228.     http://stackoverflow.com/questions/19131336/java-default-values-and-initialization
  229. */
  230. *************************
  231. public class Empty extends SizeOf {
  232. /*
  233.     вообще не стоило реаизовывать
  234.     на уровне CollectionConditions
  235.     в методе empty() - используй кондишен SizeOf
  236.  
  237.     кстати имя SizeOf - подправь на Size
  238.  
  239.     раньше - когда первым параметром кондишена был локатор - оно было разумно
  240.     SizeOf(locator
  241.     TextOf(locator...
  242.  
  243.     Of - сейчас оно потеряло актуальность
  244.     просмотри кондишены
  245. */
  246. ***********************************
  247.  public void pressEnter() {
  248.  public void pressEscape() {
  249.  public void pressTab() {
  250.  
  251.  /*
  252.     спокойно можно переиспользовать this.sendKeys
  253.  
  254.     с setValue - так лучше не делать
  255.     думаю - и сам понимаешь почему)
  256.  */
  257. **************************
  258.     public void sendKeys(final String text) {
  259. /*
  260.     не поняла - зачем такой метод
  261.     наверное - подзастрял со старых версий
  262. */
  263. **********************************
  264.     public String toString() {
  265.         return "element from parentCollection = "  + parentCollection + "found by condition = " + condition;
  266.     }
  267. /*
  268.     тут лучше бы про кондишен писать - только его класс
  269.     toString() кондишена тут будет не уместен
  270.  
  271.     parentCollection.toString() + " find(" + condition.getClass().getSimpleName() + ")" ?
  272. */
  273. ****************************************
  274.  public String toString() {
  275.         return "element from parentCollection = " + parentCollection + ", index = " + index;
  276.  }
  277. /*
  278.     parentCollection.toString() + "[" + index + "]" ?
  279. */
  280. **************************
  281. public class SmartElementInnerElement extends AbstractSmartElement {
  282.  
  283.     SmartElement element;
  284.     /*
  285.         именуй родительские смарт-сущности в некой одной логике
  286.     */
  287.     By cssSelector;
  288.     /*
  289.         значение типа By - это не cssSelector
  290.         это локатор
  291.         это может быть и By.xPath(..), Bi.id(...), By.partialLinkText(...)
  292.         ну и By.cssSelector )
  293.  
  294.         и тут переименуй
  295.         и в toString подправь
  296.         и соответствующий метод - где создаешь такой смарт-єлемент - проверь
  297.     */
  298. **************************
Advertisement
Add Comment
Please, Sign In to add comment