julia_v_iluhina

Untitled

Dec 15th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.00 KB | None | 0 0
  1. public abstract interface Condition<V>
  2. /*
  3.     И этот интерфейс - расположи в пекедже conditions
  4. */
  5. ***********************************
  6.     public V apply(By locator){
  7.         this.locator = locator;
  8.         V essence = getEssence();
  9.         return essence;
  10.     }
  11. /*
  12.     про термин essense
  13.     мне кажется более уместным  - entity
  14.     https://wikidiff.com/essence/entity
  15.  
  16.     нам нужно не только получить сущность
  17.     но еще и проверить ее
  18.     и по результтам проверки -
  19.         либо сущность вернуть
  20.         либо нулл
  21.  
  22.     а для проверки - нужен еще один метод
  23.     check - собственно проверка
  24.     этот метод - на уровне абстрактного класса объяви обстрактным
  25.     и используй в реализации apply (на уровне абстрактного класса
  26.  
  27.     а уже как дело дойдет до реализации конкретных кондишенов - там и реализуешь check
  28.     а apply - уже не будешь - ведь тут все будет реализовано
  29.  
  30.     что метод check должен делать - отвечать на вопрос - прошла проверка для нашей сущности или не прошла
  31.     т е - возвращать от на должен - boolean
  32.     а принимать в качестве параметра - сущность
  33. */
  34. **************************************
  35. public abstract class CollectionCondition extends AbstractCondition<List<WebElement>> {
  36.  
  37.     public List<WebElement> getEssence(){
  38. /*
  39.     с реализацией этого метода - согласна
  40. */
  41.  
  42.     public String identity() {
  43. /*
  44.     а вот тут - все значительно проще
  45.     нам нужна просто строка
  46.     for element
  47.     или
  48.     for elements
  49.  
  50.     для всех кондишенов-наследников CollectionCondition - это for elements
  51.     а то и for collection - чтоб сразу бросилось в глаза - что речь не про один элемент
  52.  
  53.     похожая ситуация - с классом ElementCondition
  54.  
  55.     у нас же какая конечная цель = получить фразу
  56.       __имя кондишена__ +
  57.                   for ____element/elements___ found by: ___locator___
  58.                   expected ___expected result description_____
  59.                   actual ____actual result description_____
  60.  
  61.     ты уже что-то похожее на уровне AbstractCondition - в toString - собираешь
  62.  
  63.     надо бы проверить это (это по финишу обязательно сделай, о уже по финишу)
  64.  
  65.         а для этого - нужно выполнить ждущую проверку
  66.         которая заведомо должна упасть
  67.         и в тексте описания ошибки - мы как раз эту фразу и должны увидеть
  68.         и она должна будет помочь разобраться - что не так сработало
  69.         вот тут уже - глядя на фразу - как раз и доравняешь это сообщение
  70.  
  71.         также обязательно - проверить работу ждущей проверки - на ситуации
  72.         которая должна заведомо пройти проверку
  73.         и это тоже должно подтвердиться экспериментом
  74.  
  75.         это - обязательные шаги в  разработке кондишенов и своих механизмов ждущей проверки
  76.         т к - если на этом уровне создать неверно работающую систему - то остальные старания - будут в общем-то бесполезны
  77. */
  78. ********************************************
  79. public class NthElementHasText extends ElementConditions{
  80.  
  81.      public WebElement apply(By locator) {
  82.  
  83.      public String toString() {
  84.   /*
  85.         мы специально реализовывали эти методы в абстрактном предке
  86.         чтоб тут - уже не использовать их
  87.         чтоб тут - логика кондишенов была проще
  88.  
  89.         тут - будем реализовывать те методы
  90.         которые на уровне абстрактного класса - объявлены как абстрактные
  91.  
  92.         структура и логика методов - apply и toString - для всех кондишенов одна
  93.         именно потому мы и смогли вынести это все на уровень абстрактного класса
  94.         и тут, в реализации конкретного кондишена - мы лишь уточняем - реализуем методы,
  95.         объявленные абстрактными в предке
  96.  
  97.         а сам скелет в apply и toString - един для всех кондишенов
  98.         потому это достаточно реализовать единожды, на уровне предка
  99.   */
  100. }
  101. ****************************************************
  102.    public class NthElementHasText extends ElementConditions{
  103.     ....
  104.     public By locatorForString;
  105.     /*
  106.         на уровне предка - у нас уже хранится локатор
  107.         да нам он и не нужен тут
  108.  
  109.         если тут мы будем реализовывать метод check
  110.         параметром которого уже будет - вебэлемент/или спиок вебэлементов (в зависимости от типа кондишшена)
  111.         то тут уже нам точно не понадобится работать с локатором
  112.     */
  113.  
  114.     ...
  115.     String expectedtext;
  116.     /*
  117.         не забывай про правила CamelCase
  118.         https://google.github.io/styleguide/javaguide.html#s5.3-camel-case
  119.     */
  120. ***************************
  121.         if (actualText.contains(expectedtext)) {
  122.             return element;
  123.         }
  124.         return null;
  125. /*
  126.     вот такие вещи - удобно реализовать используя ternary operator (гугли)
  127.  
  128.     return (condition) ? resultIfTrue : resultIfFalse
  129. */
  130. **********************************************
  131.         for(String text:expectedTexts) {
  132.             this.expectedTexts.add(text);
  133.         }
  134. /*
  135.     можно применить Arrays.asList
  136.  
  137.     https://www.tutorialspoint.com/java/util/arrays_aslist.htm
  138.     http://ru.stackoverflow.com/questions/488383/%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BD%D1%83%D0%B6%D0%B5%D0%BD-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-arrays-aslist
  139. */
  140. **************************************************
  141. http://joxi.ru/52akqzoU4GDQdr
  142. /*
  143.     чтоб было легче разобраться - внутри пекеджа conditions
  144.     создай 2 пекеджа -
  145.         element
  146.         collection
  147.     и разложи классы
  148.  
  149.     в корне у conditions - останутся только общие вещи
  150. */
  151. *******************************************
  152. public static Texts texts(String... text)
  153. /*
  154.     имя параметра - не текст - а текстЫ
  155. */
  156. **********************************************
  157. public class ElementConditions {
  158.     public static VisibilityOfElement visible() {
  159.  
  160.     public static NthElementHasText nthElementHasText(int index, String text) {
  161. /*
  162.     все такие методы - будут возвращать значениетипа интерфейс (приводила в прошлом ревью линки на тему интерыейсов-абстрактных классов - потомков)
  163.     да, внутри метода - создаем объект такого-то класса
  164.  
  165.     но т к этот класс - имплементирует интерфейс Condition<...что-то конкретное уже...>
  166.     то в качестве типа результата -  используй Condition<...что-то конкретное уже...>
  167.  
  168.     правда, кондишен nthElementHasText придется реализовать не как ElementCondition
  169.     а как CollectionCondition
  170.     позже мы от него избавимся
  171.     а пока - пусть apply возвращает список, а не элемент
  172.     нам безразлично - что apply вернет - мы ведь не используем его результат
  173.     а вот работаем мы  - со списокм вебэлемента
  174.     потому объявляй и реализуй как CollectionCondition
  175.     ну и метод тогда будет - в CollectionConditions
  176.  
  177.     для кондишена про видимость элемента - visible() - хорошее имя
  178.     тога и класс VisibilityOfElement - аналогично назови
  179.  
  180. */
  181. *******************************************************************
  182. public class CustomConditions {
  183. /*
  184.     а этот класс зачем нужен?
  185.  
  186.     ведь у нас уже есть CollectionConditions и ElementConditions
  187. */
  188. **********************************************
  189. assertThat(elementLocator, visibilityOfElement());
  190. /*
  191.     вот тут как раз и видно будет - почему имя visible() - лучше
  192.     сравни
  193.     assertThat(elementLocator, visibilityOfElement());
  194.     и
  195.     assertThat(elementLocator, visible());
  196.  
  197.     согласись - второй вариант легче читать, фраза короче и проще понимается
  198. */
  199. ***************************************************
  200.  
  201.  public static <V> V waitUntil(By locator, Condition<V> condition, long timeout) {
  202.  ...
  203.         Throwable error = null;
  204.         while(endTime > System.currentTimeMillis()) {
  205.             try {
  206.                 ....
  207.             } catch(StaleElementReferenceException | ElementNotVisibleException | IndexOutOfBoundsException e) {
  208.                 error = e;
  209.             }
  210.             sleep(waitTimeout);
  211.         }
  212.         throw new TimeoutException(String.format("Failed while waiting ['%s'] seconds to assert ['%s']", timeout / 1000, condition.toString()));
  213.         /*
  214.             ты в переменной error сохранил ошибку
  215.             это ок
  216.  
  217.             и теперь - передай ее как второй параметр в конструктор исключения TimeoutException
  218.             (посмотри сигнатуру такого конструктора - как называются параметры - зажми ctrl + наведи курсор мыши)
  219.  
  220.             передавать ошибку вторым парамтром нужно - чтоб сообщение об ошибке выглядело так
  221.  
  222.             имя возникшего кондишена + его сообщение
  223.  
  224.             а далее - caused by  - описание
  225.         */
  226.     }
  227. /*
  228.     хорошая идея - реализовать умное ожидание в отдельном классе
  229.     с точки зрения Single Responsibility - так будет лучше
  230.  
  231.     наглядно этот класс назвать WaitFor
  232.     а статический метод-умный ожидатель выполнения кондишена - until
  233.     и в коде мы будем писать waitFor(byCss(...)).until(visible())
  234.     получится очень наглядная и понятная фраза
  235.  
  236.     в том же классе - расположи и метод sleep
  237.     а его сделай - private
  238.     т к sleep будет нужен только для реализации ждущей проверки
  239.  
  240.     чтобы так писать - waitFor(byCss(...)).until(visible())
  241.         реализуй конструктор с параметром By locator
  242.  
  243.         реализуй статический метод waitFor с параметром By locator
  244.         возвращающий - новый объект класса WaitFor
  245.  
  246.         реализуй метод until(...)
  247.     получишь
  248.        waitFor(byCss(...)). - создали объект типа WaitFor
  249.           until(visible()) - вызвали у него метод until
  250.  
  251.     конечно, until-у передаай как кондишен, так и таймаут
  252.     уже второй вариант  until-а - без таймаута (также как и раньше - такой берет таймаут по умолчанию
  253. */
Add Comment
Please, Sign In to add comment