Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public void assertThat(ExpectedCondition condition){
- new WebDriverWait(getWebDriver(), 15).until(condition);
- }
- public WebElement $(By locator){
- assertThat(ExpectedConditions.visibilityOfElementLocated(locator));
- return new WebDriverWait(getWebDriver(), 15).until(visibilityOfElementLocated(locator));
- }
- получается - мы в методе $ - сначала дождались видимости элемента
- и потом снова делаем ждущую проверку видимости
- это лишнее
- если реализовать строки 140-145 прошлого ревью
- то получим
- public WebElement $(By locator){
- assertThat(ExpectedConditions.visibilityOfElementLocated(locator));
- return getWebDriver().findElement(locator);
- }
- в первой строке = дождались элемента
- в второй строке - уже просто ищем его и возвращаем
- тут мы так можем поступить - т к в предыдущей строке мы дождались его появления
- ====
- строки 97-116 прошлого ревью - еще надо реализовать
- собственно - ты и у себя эти куски оставила)
- значит что-то не получилось...
- буду читать твой слек
- ====
- public void setValue(By elementLocator, String value){
- $(elementLocator).clear();
- $(elementLocator).sendKeys(value);
- }
- public void setValue(String selector, String value){
- $(By.cssSelector(selector)).clear();
- $(By.cssSelector(selector)).sendKeys(value);
- }
- код можно сделать более DRY
- в методе setValue(String selector, String value)
- переиспользовать setValue(By elementLocator, String value)
- кстати - лучше имя cssSelector, а не selector - будет точнее
- =====
- public static ExpectedCondition<Boolean> listNthElementHasText(final List<WebElement> elements, final int index, final String expectedText) {
- return new ExpectedCondition<Boolean>() {
- private String elementText;
- public Boolean apply(WebDriver driver) {
- try {
- elementText = elements.get(index).getText();
- return elementText.contains(expectedText);
- } catch (Exception e) {
- return false;
- }
- }
- // когда мы получаем elements.get(index) для индекса за границами списка
- // вызывается исключение ListOutOfBoundsException
- // и далее - проверка не выполняется
- // а нам - стоит и дальше ждать
- // возможно через время нужный нам элемент в списке уже будет
- // т е нам надо обрабатывать ситуацию с возникновением такого исключения
- //
- public String toString() {
- return String.format("\ntext in %s\n element of the elements list has to be: %s\n while actual text is: %s\n", index, expectedText, elementText);
- }
- };
- }
- я намекала тебе на использование try-catch и обработке возникновения исключения ListOutOfBoundsException
- ок - сейчас подскажу больше
- обычно эти подсказки выдаем уже после того как версию с применением try-catch реализовали
- но с нашим рваным графиком думаю правильнее продвинуться дальше
- https://docs.google.com/document/d/1BiYTLdypDfucSqiY9isv1HCKKQIxelzqYrN-3Ku1RWM/edit?usp=sharing
- /*
- почитай и примени это для кондишенов
- делай это - после того, как получишь отлаженную и проверенную версию (я писала - как проверять кондишены)
- если тебе будет проще - оперируй не типом Function<? super WebDriver, V> (это тип предка ExpectedCondition)
- а ExpectedCondition<V>
- поскольку кетчер бует применяться к потомкам ExpectedCondition - это будет ОК
- если захочешь поразбираться с дженериками
- про дженерики в общем(русский)
- http://www.quizful.net/post/java-generics-tutorial
- http://www.tutorialspoint.com/java/java_generics.htm
- http://developer.alexanderklimov.ru/android/java/generic.php
- конвеншенcы http://stackoverflow.com/questions/2900881/generic-type-parameter-naming-convention-for-java-with-multiple-chars
- https://docs.oracle.com/javase/tutorial/java/generics/types.html
- уроки
- http://docs.oracle.com/javase/tutorial/extra/generics/index.html
- очень приличный faq (есть pdf, и есть кое-что еще, помимо дженериков)
- http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
- ----------------------------------------------------------
- для понимания кетчера (Catcher)
- http://grepcode.com/file/repo1.maven.org/maven2/com.google.guava/guava/r06/com/google/common/base/Function.java
- http://www.programcreek.com/java-api-examples/com.google.common.base.Function
- https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html
- http://stackoverflow.com/questions/3847162/java-generics-super-keyword
- http://stackoverflow.com/questions/2800369/bounding-generics-with-super-keyword
- http://stackoverflow.com/questions/1910892/what-is-the-difference-between-super-and-extends-in-java-generics
- */
- ====
- public void assertMails(String headerText) {
- assertThat(CustomConditions.textsOf(mailsList, список expectedTexts));// как его получить? в каждом запуске тестов переменная subject хранит только одно значение
- }
- по поводу того как получить список
- вспомни что такое varargs parameter
- http://www.linkex.ru/java/varargs.php
- если у нас есть метод
- method(String... texts)
- то мы можем вызвать метод так
- method("text1")
- и так
- method("text1", "text2")
- если у нас будет метод
- public void assertMails(String... headerTexts)
- и кондишен
- textsOf(final List<WebElement> elements, final String... expectedTexts)
- то метод assertMails(String... headerTexts) - получится универсальным
- мы сможем его вызвать вот так - assertMails(subject1)
- нам собственно именно такой вариант и нужен
- и вот так - assertMails(subject1, subject2, subject3) - если бы нам надо было проверить
- что писем три
- и что тексты в заголовках писем такие-то
- =====
- public static ExpectedCondition<Boolean> textsOf(final List<WebElement> elements, final List<String> expectedTexts) {
- /*
- если тебе передадут не final List<String> expectedTexts
- а final String... expectedTexts
- то ты сможешь работать с expectedTexts как с обычным массивом
- см ссылку выше по varargs параметры
- */
- return new ExpectedCondition<Boolean>() {
- public Boolean apply(WebDriver driver) {
- if (elements.size() != expectedTexts.size()) {
- return false;
- }
- /*
- верно - мы должны сравнить к-во вебэлементов
- с к-вом переданных текстов
- только вот что...
- у нас elements - при каждом обращении к нему - переискивается)
- и тут - вначале кода метода apply -
- у нас может быть один размер списка
- а далее по коду - уже другой)
- ну и не только размер
- сами элементы тоже
- то что я предлагаю - конечно не панацея
- но код проще понять - и читая его - и при случае наблюдая в отладке
- я предлагаю - собрать в список actualTexts - все тексты элементов
- обойдя в цикле elements
- и далее по коду метода apply - уже оперировать сравнением
- actualTexts и expectedTexts
- эти вещи - не будут меняться в процессе)
- в принципе - соглашусь
- и во время первого обхода списка - список может ментяться
- и в actualTexts мы можем собрать не
- некую картинку в точке времени - а все же что-то в динамике
- из-за вот этого переискивания
- но вероятность этого гораздо ниже
- чем если мы на протяжении всего apply будем работать с elements
- и кроме того - нам полезно вывести в toString - значения
- actualTexts и expectedTexts
- в стиле
- для списка такого-то
- ждали того-то
- ожидаемые значения = такие-то
- фактические = такие-то
- при таком коде в toString
- если проверка ондишена упадет
- все будет понятно
- так что работа с actualTexts нам пригодится сразу для двух целей
- не знаю - увидела ли ты это сама - когда отлаживала код
- но вот есть такая тонкость
- если работаешь с @FindBy элементами/списками
- в методе apply кондишена - лучше получить то что будешь сравнивать
- и потом сравнивать уже ранее полученное
- потому что в рамках одного метода если ты получаешь
- с твоей точки зрения что-то одинаковое
- например - размер коллекции
- или такой-то элемент
- или какие-то свойства элемента
- то ты можешь получить разные значения
- и можно довольно долго ходить кругами и не понимать происходящего
- потому - лучше взять за правило
- сначала получили то что будем сравнивать
- и далее уже это сравниваем
- и с нашим переискивающимся списком/элементом - более не работаем
- я считаю это вторым крупным недостатком в работе с FindBy-аннотированными элементами
- */
- for (int i = 0; i < expectedTexts.size(); i++) {
- String elementText = elements.get(i).getText();
- String expectedText = expectedTexts.get(i);
- if (elementText.contains(expectedText)) {
- return false;
- }
- }
- return true;
- }
- посмотри на кусок кода
- из-за неверного форматирования он на первый взгляд кажется не правильным)
- последняя фигурная скобка - относится не к for
- а ко всему методу
- а на первый взгляд этого не видно
- не забывай о форматировании
- public String toString() {
- return String.format("\nthere is no such text in elements list\n");
- }
- выше я писала про то что лучше отразить в toString
- учти это
- };
- }
- =====
- By.xpath("//*[text()='COMPOSE']")
- довольно полезно в ConciseaAPI реализовать byText
- ведь мы не раз элементы ищем по тексту
- можно вот с такой реализацией - как тут
- если интересно - загляни в селениде
- там применяется более сложное xPath выражение
- но оно и больше всякого учитывает
- может пригодиться в проектах написанных на чистом селениуме
- вот само выражение
- ".//*/text()[normalize-space(.) = " + Quotes.escape(elementText) + "]/parent::*"
- вот ссылка на источник
- https://github.com/codeborne/selenide/blob/master/src/main/java/com/codeborne/selenide/Selectors.java
- =====
- $(By.cssSelector("div.asf")).click();
- насколько я помню - ок работает и вариант ".asf"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement