julia_v_iluhina

Untitled

Jan 19th, 2017
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.01 KB | None | 0 0
  1.       public static ExpectedCondition<List<WebElement>> listNthElementHasText(final By elementsLocator, final int index, final String text) {
  2.         if (text.isEmpty() || index < 0) {
  3.             throw new IllegalArgumentException("Expected text shoul be not empty \nIndex should be >= 0");
  4.         }
  5. /*
  6.     should
  7.     поправь слово
  8. */
  9. ***************************************
  10. //сравни форматирование
  11.  
  12.     public static ExpectedCondition<List<WebElement>> exactTextsOf(final By elementsLocator, final String... texts) {
  13.         if (texts.length == 0) {
  14.             throw new IllegalArgumentException("Array of expected texts is empty.");
  15.         }
  16.  
  17.         return elementExceptionsCatcher(new ExpectedCondition<List<WebElement>>() {
  18.             List<String> actualTexts;
  19.  
  20.             public List<WebElement> apply(WebDriver driver) {
  21.                 List<WebElement> elements = driver.findElements(elementsLocator);
  22.  
  23.                 actualTexts = getTexts(elements);
  24.                 if (actualTexts.size() != texts.length) {
  25.                     return null;
  26.                 }
  27.                 for (int i = 0; i < texts.length; i++) {
  28.  
  29.                     if (!actualTexts.get(i).equals(texts[i])) {
  30.                         return null;
  31.                     }
  32.                 }
  33.                 return elements;
  34.             }
  35.  
  36.             public String toString() {
  37.                 return "texts of list located" + elementsLocator + "\n should equals :      " + Arrays.toString(texts) + "\n actual texts are    " + actualTexts;
  38.             }
  39.         });
  40.     }
  41.  
  42. // и вот так
  43.     public static ExpectedCondition<List<WebElement>> exactTextsOf(final By elementsLocator, final String... texts) {
  44.         if (texts.length == 0) {
  45.             throw new IllegalArgumentException("Array of expected texts is empty.");
  46.         }
  47.  
  48.         return elementExceptionsCatcher(new ExpectedCondition<List<WebElement>>() {
  49.             List<String> actualTexts;
  50.  
  51.             public List<WebElement> apply(WebDriver driver) {
  52.                 List<WebElement> elements = driver.findElements(elementsLocator);
  53.                 actualTexts = getTexts(elements);
  54.  
  55.                 if (actualTexts.size() != texts.length) {
  56.                     return null;
  57.                 }
  58.  
  59.                 for (int i = 0; i < texts.length; i++) {
  60.                     if (!actualTexts.get(i).equals(texts[i])) {
  61.                         return null;
  62.                     }
  63.                 }
  64.  
  65.                 return elements;
  66.             }
  67.  
  68.             public String toString() {
  69.                 return "texts of list located" + elementsLocator + "\n should equals :      " + Arrays.toString(texts) + "\n actual texts are    " + actualTexts;
  70.             }
  71.         });
  72.     }
  73. //пропуски строк - тоже могут помогать или мешать воспринимать код
  74. //используй их )
  75. //каждый блок = своя законченная мысль
  76. //блоки - разделяй пропусками строк, а внутри блока - не делай их
  77. //примени этот подход ко всему своему коду
  78. //пропускать более одной строки - смысла нету
  79. ********************************************************************************************************
  80. //у кондишена elementWithCssClass - код рабочий, но имеет ряд недостатков, которые делают код неоптимальным
  81. //ошибки в коде есть, но они не приведут к неверной работе, к неэффективной - приведут
  82. //сравни apply - реализованный и который я предлагаю
  83. //реализованный сейчас
  84.             public WebElement apply(WebDriver driver) {
  85.                 List<WebElement> elements = driver.findElements(elementsLocator);
  86.                 for (WebElement element : elements) {
  87.                     actualClasses.add(element.getAttribute("class"));
  88.  
  89.                     for (int i = 0; i < actualClasses.size(); i++) {
  90.                         String actualClass = actualClasses.get(i);
  91.                         String[] actualCssClasses = actualClass.split("\\s");
  92.  
  93.                         for (int j = 0; j < actualCssClasses.length; j++) {
  94.                             if (cssClass.equals(actualCssClasses[j])) {
  95.                                 return elements.get(i);
  96.                             }
  97.                         }
  98.                     }
  99.                     return null;
  100.                 }
  101.                 return null;
  102.             }
  103. //и вот такой вариант
  104.     public static ExpectedCondition<WebElement> elementWithCssClass(final By elementsLocator, final String cssClass) {
  105.         return elementExceptionsCatcher(new ExpectedCondition<WebElement>() {
  106.             List<String> actualClasses;
  107.  
  108.             public WebElement apply(WebDriver driver) {
  109.                 List<WebElement> elements = driver.findElements(elementsLocator);
  110.                 for (WebElement element : elements) {
  111.                     actualClasses.add(element.getAttribute("class"));
  112.                 }
  113.  
  114.                 for (int i = 0; i < actualClasses.size(); i++) {
  115.                     String actualClass = actualClasses.get(i);
  116.                     String[] actualCssClasses = actualClass.split("\\s");
  117.  
  118.                     for (int j = 0; j < actualCssClasses.length; j++) {
  119.                         if (cssClass.equals(actualCssClasses[j])) {
  120.                             return elements.get(i);
  121.                         }
  122.                     }
  123.                 }
  124.                 return null;
  125.             }
  126.  
  127.             public String toString() {
  128.                 return String.format("\nList of elements located:", elementsLocator, "%s\n should contain element with css class: %s\n", cssClass, "while actual classes are", actualClasses);
  129.             }
  130.         });
  131.     }
  132. //сначала - собрали actualClasses
  133. //потом - их обходим
  134. //а сейчас - на каждом шаге сборки actualClasses - мы их все обходим
  135. //подумай сколько обходов будет, если нужный нам элемент - например пятый в списке
  136. **************************************************************************************************
  137.  
  138. public class ToDoMvcPage {
  139.  
  140.  
  141.     static By tasks = byCss("#todo-list>li");
  142.  
  143.     public static void clearCompleted() {
  144. /*
  145.     вспомни первую работу на курсе по пейджам-модулям
  146.  
  147.     там мы для пейджей-модулей - не использовали Page в имени класса пейджа
  148.  
  149.         Пейджи-модули и их нейминг
  150.         Пейдж-модули удобно называть без слова Page в конце
  151.             потому что если ты будешь использовать несколько пейдж-модулей в одном тесте
  152.  
  153.             то желательно обращаться к их методам через имя класса пейдж-модуля
  154.             чтобы видеть где с каким пейджом идет работа
  155.  
  156.             и когда ты будешь писать
  157.                 TodoMVCPage.givenAtAll()
  158.             то это явно не так прикольно как
  159.                 TodoMVC.givenAtAll()
  160.  
  161.             правда?
  162.  
  163.                 (так обращаться - важно, когда есть несколько пейджей,
  164.                 а если он один - то можно без ущерба для точности -
  165.                 заимпортить статически все методы и при вызове - не указывать им класса пейдж-модуля)
  166.  
  167.  
  168.             вот это Page в конце - это дань общим conventions (или общепринятым предпочтениям)
  169.             при именовании классов в мире ООП
  170.  
  171.             ми же тут юзаем подход "Модульного Программирования", потому тут этого "лишнего слова"
  172.             не нужно
  173.  
  174.             А то, что это все же пейдж - скажет нам имя пекеджа - pages
  175.  
  176. */
  177. *******************************************
  178.     static By tasks = byCss("#todo-list>li");
  179.  
  180.     public static void clearCompleted() {
  181.         $(byCss("#clear-completed")).click();
  182.     }
  183.  
  184.     public static By addTask = By.cssSelector("#new-todo");
  185.  
  186. /*
  187.     технически - порядок методов и полей в классе - может быть любым
  188.     но проще работать с кодом - когда поля - объявлены рядом
  189. */
  190. ***********************************
  191. $(byCss("#toggle-all"))
  192. /*
  193.     можно реализовать метод $, принимающий в качестве параметра  css селектор
  194.     тогда тут код упростится до $("#toggle-all")
  195. */
  196. ******************************************
  197.   public static void delete(String taskText) {
  198.         hover($(elementWithText(tasks, taskText)));
  199.         $(byCss(".destroy")).click();
  200.   }
  201. /*
  202.     нам нужна не первая попавшаяся кнопка .destroy
  203.     а кнопка у таски с таким-то текстом
  204.  
  205.     мы это уже обсуждали)
  206.     в методе toggle - ты реализовал верно
  207. */
  208. **********************************************
  209.     public static void toggle(String taskText) {
  210.         $(elementWithText(tasks, taskText)).findElement(byCss(".toggle")).click();
  211.     }
  212. /*
  213.     а в тексте самого задания - предлагалось организовать методы
  214.     $(ExpectedCondition<WebElement> conditionToWaitParentElement, By innerElementLocator)
  215.     и
  216.     $(ExpectedCondition<WebElement> conditionToWaitParentElement, String innerElementCssSelector)
  217.  
  218.     чтобы вместо
  219.     $(elementWithText(tasks, taskText)).findElement(byCss(".toggle"))
  220.     использовать
  221.     $(elementWithText(tasks, taskText), ".toggle")
  222.  
  223.     по сути - в таком методе $
  224.     мы именно это и будем делать - что ты реализовал
  225.     сначала - получим родительский элемент - через использование переданного кондишена в ожидании
  226.     затем - у родительского элемента получим его подчиненный элемент и его вернем
  227.  
  228.     т к такой код будет нужен несколько раз - разумно реализовать и использовать такие методы
  229. */
  230. ***************************************************************
  231.  public static WebElement startEdit(String oldTaskText, String newTaskText) {
  232.         doubleClick($(elementWithText(tasks, oldTaskText)));
  233.         //к даблклику - вопросов нет
  234.         $(elementWithCssClass(tasks, "editing"));
  235.         //мы получили редактируемую таску, но ничего с ней не сделали, просто получили
  236.         setValue($(byCss("edit")), newTaskText);
  237.         //а тут - работаем с первым найденным элементом $(byCss("edit")
  238.         //кстати - посмотри на селенидовский код
  239.         //какой мы селектор использовали для элемента
  240.         //ты ошибся в селекторе тоже
  241.         //получи такой элемент - у таски в режиме редактирования
  242.         //и именно его и нужно будет вернуть
  243.         //опять отсылаю к селенидовскому коду
  244.         return $(elementWithText(tasks, "editing"));
  245.     }
  246. ************************************************************
  247.     public static void assertVisibleTasksEmpty(int expectedSize) {
  248.         assertThat(sizeOfVisible(tasks, expectedSize));
  249.     }
  250. /*
  251.     я могу вызвать так проверку - assertVisibleTasksEmpty(5)
  252.  
  253.     как тебе?
  254.  
  255.     мне кажется - этот метод надо вот так вызывать - assertVisibleTasksEmpty()
  256.  
  257.     ведь пусто = размер равен нулю и только нулю, тут нет вариантов)
  258. */
  259. ******************************
  260.     public void clearData() {
  261.         ((JavascriptExecutor)getDriver()).executeScript("localStorage.clear()");
  262.     }
  263. /*
  264.     Реализуй в ConciseAPI - метод executeJavaScript
  265.     чтоб ему в качестве значения параметра - передали строку - JavaScript команду
  266.     а тут метод - будешь использовать
  267. */
  268. ******************************************
  269. private JavascriptExecutor js;
  270. /*
  271.     зачем такая переменная?
  272. */
  273. ***********************
  274.     @Before
  275.     public void setTimeout() {
  276.         Configuration.timeout = 30;
  277.     }
  278. /*
  279.     вроде для todoMvc - хватало 4 секундного таймаута)
  280.     зачем такой большой?
  281.  
  282.     и еще - согласно задания - нужно было использовать версию задания Smoke: E2E + F (там где был е2е и несколько фиче-тестов
  283.     это критично подправить
  284. */
  285. **************************************
  286.     public static WebElement $(By elementLocator) {
  287.         return assertThat(visibilityOfElementLocated(elementLocator));
  288.     }
  289.  
  290.     public static WebElement $(ExpectedCondition<WebElement> conditionToWaitElement) {
  291.         return assertThat(conditionToWaitElement);
  292.     }
  293. /*
  294.     теперь в методе $(By elementLocator)
  295.     можно использовать вызов $(ExpectedCondition<WebElement> conditionToWaitElement)
  296.     return $(visibilityOfElementLocated(elementLocator));
  297. */
  298. ***************************************
  299.     public static void setValue(WebElement element, String task) {
  300.         Actions actions = new Actions(getDriver());
  301.         element.clear();
  302.         element.sendKeys(task);
  303.     }
  304. /*
  305.     зачем тут Actions actions = new Actions(getDriver());?
  306. */
  307. *********************************
  308.     public static void hover(WebElement element) {
  309.         Actions action = new Actions(getDriver());
  310.         action.moveToElement(element).perform();
  311.     }
  312. /*
  313.     все же корректнее - не action, а actions
  314.     мы же создаем объект типа Actions
  315.  
  316.     кстати, можно реализовать метод actions()
  317.     и его переиспользовать
  318. */
Advertisement
Add Comment
Please, Sign In to add comment