Регистрация и забытый пароль с временными ящиками почты

BBrbB4i.img

Решил написать небольшую заметку по поводу простого способа проверить регистрацию и восстановление пароля через почту. Как известно в большинстве сервисов регистрация идет через электронную почту, аккаунт привязывается к ней, восстановление пароля идет через отправку письма на нее же. Я встречал в сети описания как можно разворачивать собственный почтовый сервер и отправлять письма туда и другие, не самые простые способы. Они порой обусловлены недоступностью сети интернет и другими факторами и имеют право на жизнь. Я же предлагаю простой способ, который доступен, если выход в интернет все же есть — сервисы временной почты, с простым API.

Сами понимаете, что использовать реальные почтовые адреса, куда вам приходят уведомления о новых семинарах по тестированию и предложения от рекрутеров, не самый лучший выход (хотя я встречал и такое), по сути нам нужен временный почтовый адрес, желательно с возможностью создавать его в ходе выполнения тестов.

В итоге ищем бесплатные сервисы, предоставляющие не только почту, но и API для нее. Платные я сразу же не рассматривал и в итоге нашел сходу post-shift.ru, а также Guerilla Mail. В обоих случаях мы имеем очень простое API (только GET запросы, с параметрами в адресной строке), позволяющее создать новый почтовый ящик, проверять список писем, получать текст письма (для того чтобы получить вожделенную ссылку для подтверждения регистрации или восстановления пароля).

Особенности post-shift:

— создает обычный ящик на 10 минут, можно продлить время, если оно уже не истекло

— можно создать ящик с заданным именем на 1 час

— позволяет получать ответы как в виде json так и простым текстом

— можно очистить ящик, но нельзя удалить конкретное письмо

Особенности guerilla mail:

— позволяет создать новый ящик и не удаляет его, то есть сохранив токен, можно обращаться к нему и потом

— все ответы приходят только в формате json

— позволяет удалять письма из ящика, но нет возможности очистить ящик сразу

— позволяет задать имя для ящика, то есть текст который идет до знака @

— в тексте письма удаляет iframe, javascript код, апплеты

Таким образом можно воспользоваться любым сервисом, скажем создать новый почтовый ящик и зарегистрировать на него нового пользователя, проверить список писем в ящике и при необходимости использовать пришедшую ссылку подтверждения регистрации, в одном из следующих тестов можно проверить восстановление пароля на этот же ящик.

Лично мне понравились оба сервиса, у них есть различия из которых и можно исходить делая выбор

Для своего удобства накидал небольшие модули для использования API этих сервисов, правда на языке Python – так и быстрее и код короче, чем на Java. Можно посмотреть вот тут

Software-Testing.Ru

Реклама

Сравниваем скорости поиска элементов

cross

Я уже не раз писал, как и многие до меня, что несмотря на распространенное мнение поиск с помощью XPATH  не медленнее поиска с помощью CSS локаторов. Выдалась свободная минутка и решил потестить немного скорость поиска элемента с помощью разных локаторов и в разных браузерах: Chrome, Firefox, InternetExplorer. Естественно, замеры относительны и воспроизводимы с теми же цифрами только на моей машине, однако есть интересные тенденции.

В Python есть удобная утилита timeit в стандартной библиотеке, к сожалению не смог найти что-то похожее на Java, поэтому просто накидал метод который 100 раз подряд находит элемент по заданному  локатору и выдает среднее затраченное время.

Поиск проводил на странице https://google.ru  и по идее искал я один и тот же элемент, просто задавал различные локаторы для него. Время в миллисекундах.

Браузер

XPATH

CSS

ID

CLASS

NAME

‘//form[@class=’tsf’]’

‘form.tsf’

‘tsf’

‘tsf’

‘f’

Chrome 6-7 6-7 7 6 6-7
Firefox 3-5 4-5 3-5 3-4 3-4
IE 50 (!) 78(!!) 77-80 77-79 76-79

Я конечно знал, что Chrome быстрый, в последнее время я работаю только с ним, но не ожидал, что Internet Explorer будет настолько медленнее, искренне сочувствую тем, кому приходится тестировать УИ на нем!

Второй неожиданностью стало то, что Firefox пусть и немного, но побыстрее Chrome.

Плюс достаточно интересная вещь, что поиск через XPATH в IE вполовину быстрее всех остальных видов поиска, то есть тем бедолагам, что вынуждены его использовать, рекомендую все локаторы переписать на XPATH.

Естественно, замеры я проводил не один раз и в разном порядке, как 1  локатор за сессию, так и все подряд.

Не успокоившись на этом, запустил консоль Python, который сейчас активно осваиваю, и воспользовался утилитой timeit, которая выдает среднее время за указанное количество повторов функции. Локаторы и сайт естественно остались теми же. Цифры были уже другие, но закономерности сохранились, а именно: Firefox немного быстрее Chrome, Internet Explorer на порядок медленнее обоих браузеров, но при этом поиск по XPATH у него работает гораздо бодрее всех остальных.

Итак, выводы:

1) поиск по XPATH не быстрее CSS, а для браузера Internet Explorer даже наоборот, есть смысл все локаторы писать только на XPATH!

2) Chrome не самый быстрый браузер, пусть и совсем чуть-чуть, но Firefox ищет побыстрее, видимо обновления пошли на пользу Лисе

3) Internet Explorer must die!

4) поиск по id или class имеет только преимущество в удобстве написания локатора, если есть уникальные id или имя класса. Вопреки некоторым встреченным в интернете рассказам, поиск по id или class не быстрее остальных видов поиска

Вот тут пожно почитать про xpath, а вот тут про css!

Software-Testing.Ru

 

 

 

 

Еще немного о WebDriver

item1313068_600px

Решил добавить еще немного информации, о которой не все, как мне кажется, знают и не на всяком курсе рассказывают. Кому-то может показаться любопытным:

securityservСуществует 2 способа паузы, реализуемой через Thread.sleep() непосредственно в библиотеке вебдрайвера. Кроме описанного вот тут, есть еще интерфейс Sleeper, правда все его удобство кончается на возможности задания точного периода ожидания, от необходимости обрабатывать InterruptedException вы не избавлены!

Sleeper.SYSTEM_SLEEPER.sleep(new Duration(3,TimeUnit.SECONDS));

Это чисто для ознакомления, надеюсь вы не будете это использовать в коде тестов для ожидания элементов. Лично мне не ясно для чего такое дублирование кода в библиотеке и почему в Actions при вызове pause() не вызывать Sleeper.

securityservЕсть специальный класс для безопасного использования вебдрайвера в многопоточном тестировании, который рекомендуется для любого многопоточного использования.

webDriver = ThreadGuard.protect(webDriver);

На данный момент могу лишь сказать, что не заметил разницы в скорости выполнения тестов, в сравнении с простым драйвером, потому можно рекомендовать для использования.

Внимание! Этот класс не решит проблем кривой архитектуры при многопоточности или совместного использования ресурсов, он лишь бросает исключение при любой попытке обращения к драйверу из других потоков.

То есть, это скорее способ дополнительно гарантировать себе, что драйвер используется безопасно, как только видите исключение в стиле

Exception in thread "Thread-0" org.openqa.selenium.WebDriverException: 
Thread safety error; this instance of WebDriver was constructed on thread main (id 1) and is being accessed by thread Thread-0 (id 67)
This is not permitted and *will* cause undefined behaviour

нужно принимать меры.

securityservВ библиотеке WebDriver есть свой класс для работы с файлами и директориями FileHandler. Его возможности вы можете посмотреть в документации, а я приведу лишь один пример. Скажем для создания скриншота в основном используют класс из google-guava или apache-commons, но это можно сделать и так, не используя сторонних библиотек

public void make(String fileName) {
  File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE)
     try {
       new FileHandler().copy(scrFile, new File(fileName));
     } catch (IOException e) {
        //логируем и т.д.
     }
}

securityservКроме всем известных способов задания метода поиска By, есть и методы работающие сразу с набором элементов — ByAll и ByChained.

Применяя класс ByAll, мы собираем все элементы, которые соответствуют указанным локаторам. Внимание, будут найдены все элементы, удовлетворяющие каждому из локаторов, а не им всем. Это может быть удобно, если нам нужен список различных элементов: к примеру(ну так случилось!) у вас на странице много кнопок, но локаторы у них разные. С помощью этого класса, можно получить список всех кнопок, перечислив все локаторы.

driver.findElements(new ByAll(By.id("a"), By.id("b")));

— вернет список элементов, в котором будут все, соответствующие локатору id=’a’, а кроме того все, соответствующие локатору id=’b’. То есть это аналогично результату, если бы мы нашли список элементов id=’a’, нашли список id=’b’ и смержили два списка в один.

Второй класс ByChained действует по-другому – он возвращает все элементы последнего локатора, которые при этом расположены внутри элементов с начальными локаторами, то есть являются их потомками. Может быть полезен, если нужны потомки какого-то класса, скажем элементы выпадающего списка.

driver.findElements(new ByChained(By.id("a"), By.id("b")));

— вернет список элементов с локатором id=’b’ (!), которые при этом потомки (вложены) в элемент(ы) с локатором id=’a’.

Если в первом варианте (ByAll) мы можем спокойно перепутать локаторы местами – все равно вернет все элементы, то во втором случае (ByChained) нужно быть точным в порядке локаторов, иначе вернется пустой список.

securityservЛюбителю ОС Windows будет интересно узнать, что в библиотеке есть класс с многозначительным названием WindowsUtils. Как и большинство (все?) утилитных классов он содержит статичные методы, нет необходимости создавать объект класса. Умеет он не так уж много, из полезного можно определить является ли текущая ОС действительно виндой

WindowsUtils.thisIsWindows();  // возвращает true рабам Микрософт :-)

И если работаем именно в Окнах, то можно, к примеру, убить процесс по его имени или id. Думаю все в курсе, что в случае падения теста по исключению (не ассерту) или если забыли вызвать driver.quit()  — процесс драйвера продолжает висеть в работающих, даже если закрыть браузер. С помощью утилит, его можно убить, скажем перед началом тестов (чтобы убедиться, что нет в процессах никаких висящих драйверов)

WindowsUtils.killByName("chromedriver.exe"); //убивает хромдрайвер, если он есть в процессах

Внимание, я вовсе не рекомендую закрывать драйвера этим способом, просто показываю, что такая возможность есть в библиотеке.

 

Вот тут можно почитать о других не самых известных фишках Selenium

Software-Testing.Ru

Чтение документации как средство от граблей и костылей.

se

В этой статье я напишу о различных написанных костылях, найденных лбом граблях и просто интересных вещах, которые на самом деле обозначены в соответствующей документации, но не всегда доходят руки и прочие части тела ее почитать. Часть написанного – мой опыт, что-то услышано от коллег или найдено на просторах коммьюнити тестировщиков. Привожу те, что мне сразу пришли в голову, запомнились особо. Должен заметить, что не все поведение, описанное в документации является очевидным или логичным, именно потому и пишутся различные костыли

securityservПоиск элемента по тексту при помощи CSS. У меня за время использования Selenium скопилась целая библиотека книг, интересных статей и видео о использовании WebDriver и во многих из них, причем достаточно свежих, упоминается CSS локатор в стиле a:contains(‘text’) . То есть люди переписывают этот локатор, даже не проверяя, работает ли он. Но данный локатор не работает! В спецификации W3C можно увидеть пункт с довольно зловещим номером.

666

Особенно мне понравилось недавно просмотренное видео, где хвалили один из новомодных курсов по автоматизации, где радостный участник рассказал, что его научили применению локаторов,  в числе прочего использовать и такой локатор.

securityservБудем честны, хоть раз каждый из нас использовал паузу в стиле Thread.sleep(), а кто не признается, тот и сейчас пользуется 🙂 Как я уже писал – это плохой способ ждать чего-либо и не стоит этим злоупотреблять в своем коде, но если уж решили использовать, то не нужно писать развесистый куст с Thread.sleep() и перехватом InterruptedException. Библиотека WebDriver содержит возможность подождать, впрочем внутри там тот же самый sleep()

new Actions(driver).pause(1000).perform();

— так короче и не бросается в глаза использование слипов.

Стоит отметить, что при написании этой статьи, я обнаружил, что при использовании этого метода в паре со слушателем событий вебдрайвера и хромдрайвером, в глубинах вебдрайвера падает исключение UnsupportedOperation Exception, которое вверх не пробрасывается, но отлавливается упомянутым слушателем. Пауза при этом работает, видимо апи Actions еще не полностью реализовано в хромдрайвере. Но это не мешает использовать паузу.

 

securityservWebElement не хранит свойств элемента страницы. Работая с Java, мы привыкли, что полноценный, сформированный объект хранит в себе свои поля, предоставляет публичные геттеры и не зависит от других объектов. Скажем ArrayList со значениями, полученными откуда угодно, доступен независимо от текущей доступности источника данных. Но WebElement  для запроса тега, текста или других параметров использует запрос к вебдрайверу и если браузер закрыт или изменилась страница, был переход на другой УРЛ, то падает исключение.

Пример:

WebElement element = driver.findElement(By.id(“one”));
driver.get(“http://anotherPage.com”);
System.out.println(element.getText()); // тут падает StaleElementReferenceException так как элемента нет на странице.

Казалось бы, объект element создан и все знает о своем состоянии, но по факту это не так, любые параметры получаются запросом к драйверу. И в коде

if (element.isDisplayed()) {
    System.out.println(element.isDisplayed());
}

будет сделано два запроса и не к элементу, а непосредственно к драйверу браузера, что дольше и может вызывать исключения по указанным выше причинам.

securityservУ вебдрайвера есть АПИ работы с логами браузера, что порой очень удобно – можно после каких-то действий проверить нет ли ошибок в консоли. Но работает это апи довольно неочевидным образом – при запросе логов они удаляются (для запрошенного уровня browser, driver и так далее) и заново их получить (те же самые логи) вы не можете!

То есть допустим два простых метода получения ошибок браузера и проверки наличия таких ошибок

public List consoleErrors() {
        return driver.manage().logs().get("browser").filter(Level.SEVERE);
    }

public boolean isConsoleErrorsExists(){
        return consoleErrors().size() > 0;
}

Если мы воспользуемся методом isConsoleErrorsExists() то даже если ошибки и были, мы их уже не увидим – логов больше нет, мы их запросили внутри метода, вызвав consoleErrors(). Используйте логи сразу при получении, второго шанса не будет!

securityservПри использовании поиска по локатору className будут найдены не только все элементы у которых класс точно равен искомому, но и все те, где искомое лишь один из классов элемента. То есть при поиске By.className(«link») будут найдены и элементы, где class=’link’, и все те, кто содержит link, например class = ‘link b-sethome__link i-bem link_js_inited’. Это нужно учитывать.

securityservИногда нужно проверять какие то ссылки со страницы, или новые урл на предмет доступности, я в свое время накидал простенький код для проверок с использованием средств Java. Но в библиотеке Selenium уже есть очень полезный в подобных случаях класс UrlChecker, позволяющий проверять доступность ссылок, а конкретнее он ждет в течение заданного времени, что УРЛ вернет код ответа 200, означающий доступность страницы. Это можно сделать так

 new UrlChecker().waitUntilAvailable(timeOutInSeconds, TimeUnit.SECONDS, new URL(“http://site.com”));
// останется только обработать TimeOutException

securityservКак то приходилось писать костылек по скроллированию большой интерактивной страницы в самый низ для проверок, но оказалось и тут все написано до нас! Есть очень удобный интерфейс Locatable, который позволяет получить координаты элемента относительно окна, страницы или всего экрана. А самое важное, что для этого происходит автоматически скроллирование к этому элементу, чтобы он стал видимым. Применяется вот так

((Locatable) element).getCoordinates().inViewPort();

Магия происходит именно в методе inViewPort(); согласно спецификации вместо него с тем же эффектом можно вызвать и onScreen() – но он пока не реализован в драйверах, в отличие от inViewPort().

Данной статьей я надеялся мотивировать всех на подробное изучение документации как по Selenium, так и по сопровождающим его библиотекам, чтобы находить нюансы при чтении спеков, а не при написании кода.

И всех с прошедшими праздниками!

 Software-Testing.Ru

Отладка Selenium тестов в jshell, не забывая про Idea

java9

Многие уже в курсе, что с Java 9 к нам пришла и джава-консоль jshell, позволяющая быстро выполнять джава-код без лишних телодвижений. Например для извечного «Hello, world!» не нужно создавать класс, а в нем метод main, просто пишем в консоли System.out.println(«Hello, world!»).

Jshell как уже говорилось идет в составе 9 Java, при условии верно прописанных переменных окружения просто пишем в командной строке jshell  и немного ждем, запуск не мгновенный.

По умолчанию в jshell импортировано несколько пакетов, которые можно посмотреть командой /imports, все остальное при необходимости нужно импортировать самим.

imp

Как видим, можно проводить расчеты, работать со стримами и файлами, по-быстрому проверить какой то код не создавая классов и не обрабатывая исключений, к примеру можно вывести содержимое файла не обрабатывая FileNotFoundException

file

Но ближе к делу! Консоль можно использовать для отладки ваших тестов на  Selenium потому что она позволяет:

  • не писать излишнего кода, не создавать классов, не смотреть пока на исключения
  • в случае падения исключения продолжать выполнение, предприняв необходимые действия (изменить урл, локатор  и т.п.) при этом браузер жив и продолжает работать
  • добавлять новые переменные в код
  • в результате вывести весь ваш код командой /list  и скопировать его в ваш тест
  • демонстрировать простые действия или обучать работе с Selenium

Для начала нам нужна сама библиотека Selenium, поэтому качаем свежую версию стендалон-сервера и кладем его в нужную папку, у меня это та же папка где и драйвера браузеров лежат. Потом указываем нашей jshell где искать библиотеку, есть несколько способов сделать это, я указываю при запуске прямо в инструменте Выполнить Windows, так как он запоминает параметр и больше вводить не нужно

jshell —class-path C:\drivers\selenium-server-standalone-3.8.1.jar

path

После этого начинается стандартная работа с драйвером, главное не забывайте импортировать нужные пакеты. Ниже показан запуск хром-браузера(расположение драйвера берется из PATH)

chrome

Пошагово работаем с браузером при этом у нас и браузер доступен, мы можем в его консоли подсмотреть локаторы и прочую информацию, и драйвер доступен — мы можем продолжать выполнять наш сценарий.

Завершив, выводим весь наш сценарий

list

И на сладкое! Еще удобнее работать с jshell в среде разработки Intellij Idea! Просто открываем терминал Идеи, запускаем там jshell с нужными настройками и готово. Тут есть большое удобство в том, что можно тут же код копировать из Идеи в консоль и обратно.

idea

Не забывайте почитать документацию по jshell, там много интересного.

P.S. Я не предлагаю вам отлаживать или писать тесты именно так, скорее продемонстрировал еще одну возможность, которая, на мой взгляд, может быть удобна в определенных ситуациях.


Software-Testing.Ru

 

 

 

 

 

 

 

Ожидания в стиле Java 8

083402_kx1b2e8athumbnail

На мысль навел просмотр видео, в котором Сергей Король справедливо напомнил, что многие из нас «упираются» собственно в средства Селениума и не используют всю силу благословенной Java. Уже вышла 9 версия, а многие еще недостаточно освоили 8, часто ли вы используете в проекте лямбды, стримы, функциональные интерфейсы?

Покажу небольшой пример применения функциональных интерфейсов для ожиданий, который делает код кратким, понятным и, главное, вполне в стиле 8 Java. Идею я честно взял из вышеуказанного видео, немного поправив для своих нужд.

Сначала пишем небольшой enum, в котором используем все наиболее часто применяемые ожидания. Вот весь код, далее обсудим:

import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.util.function.Function;

public enum WaitConditions {
   visible   (ExpectedConditions::visibilityOfElementLocated),
   exist     (ExpectedConditions::presenceOfAllElementsLocatedBy),
   clickable (ExpectedConditions::elementToBeClickable),
   invisible (ExpectedConditions::invisibilityOfElementLocated);

   WaitConditions(Function<By, ExpectedCondition> type) {
      this.type = type;
   }

   public Function<By, ExpectedCondition> getType() {
      return type;
   }

   private final Function<By, ExpectedCondition> type;
}

Тип нашего enum  это функциональный интерфейс Function, который получает на вход By (наш локатор) и возвращает ExpectedCondition то есть те самые условия ожидания.

 visible (ExpectedConditions::visibilityOfElementLocated),
 exist (ExpectedConditions::presenceOfAllElementsLocatedBy),
 clickable (ExpectedConditions::elementToBeClickable),
 invisible (ExpectedConditions::invisibilityOfElementLocated);

Тут мы собственно перечисляем нужные значения и те методы, на которые их нужно завязать.

private final Function<By, ExpectedCondition> type;

Обратите внимание на ? — это необходимо для использования invisibilityOfElementLocated, так как он в отличие от остальных методов возвращает ExpectedCondition.

С enum разобрались, теперь посмотрим на метод, который будет использовать его. Сразу оговорюсь,  я использую возвращаемое значение boolean, а не кидаю исключение выше, но это мой стиль работы, вы можете модифицировать метод:

public boolean waitFor(By locator, WaitConditions conditions) {
   WebDriverWait wait = new WebDriverWait(driver, defaulTime);
   try {
      wait.until(conditions.getType().apply(locator));
      return true;
   } catch (TimeoutException ex) {
      //делаем скриншот, логируем и  т.д.
      return false;
   }
}

defaultTime — это переменная int, сколько конкретно секунд ждать по умолчанию, при желании ее можно менять, driver это конечно же наш WebDriver. Вот тут все происходит wait.until(conditions.getType().apply(locator)); — наш локатор используется для ожидания соответствующего типа.

Не так много кода мы написали, но все это просто и лаконично позволит нам в коде писать вызовы наших ожиданий в стиле

waitFor(By.id("loginButton"), visible);
или
waitFor(submitButton, clickable);

По-моему достаточно просто использовать и легко читается, даже тому, кто впервые увидит ваши тесты.

Software-Testing.Ru

 

Headless Chrome вместе с Selenium WebDriver — для нетерпеливых

google_now_in_chrome_canary_release_nemmfq

Кто еще не в курсе, начиная с 59 версии в браузер Хром будет введена возможность запуска в headless-режиме, то есть без создания визуального окна браузера. Это позволит прогонять тесты быстрее (теоретически) и с меньшими затратами ресурсов, а главное — позволит запускать тесты на системах без графической составляющей. Не беспокойтесь — возможность делать скриншоты никак не пострадает.

Естественно, кроме самого браузера необходимо дождаться и новой версии chrome driver (текущая 2.29). Но если ждать не хочется, а хочется уже сейчас посмотреть и попробовать, то вот простой рецепт (проверялось для chrome driver 2.29 на Windows 10)

Скачиваем и устанавливаем Chrome Canary, который поддерживает все новые функции будущей версии Хрома. Не беспокойтесь, установка идет в отдельную папку по умолчанию и ваш родной текущий Хром браузер никак не пострадает. Сразу запоминаем или копируем путь установки.

Стандартно указываем путь к нашему драйверу хром

System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/vendors/chromedriver.exe");

в данном случае, у меня драйвер лежит в папке проекта, в директории vendors.

Далее указываем хром проперти для использования headless режима

ChromeOptions options = new ChromeOptions();
options.setBinary("C:\\Users\\admin\\AppData\\Local\\Google\\Chrome SxS\\Application\\chrome.exe");
options.addArguments("--headless");

в методе setBinary мы указываем путь к расположению нашего Chrome Canary, ну и гвоздем программы устанавливаем аргумент —headless, который говорит сам за себя.

далее, опять же по стандарту, просто создаем объект браузера

driver = new ChromeDriver(options);

Можно запускать!

Единственный момент, который я сразу обнаружил — невидимое окно браузера всего размером 800х600, видно по скриншотам. Кому то может это и не важно, а у нас приложение меняет некоторые элементы в зависимости от размеров окна. Поэтому, нужный размер окна устанавливаем вот так

options.addArguments("window-size=1800x900");

где 1800х900 это размер, нужный вам.

Родные методы driver.manage().window().maximize(); или driver.manage().window().setSize(); тут не сработают, так как chrome driver все еще 2.29  и видимо пока не может использовать эти операции с headless браузером.

Других сбоев пока не заметил, все кликается, текст вводится, скриншоты выполняются без проблем. Так что кому не терпится — можно пробовать и экспериментировать.

Software-Testing.Ru

Не xpath единым, или использование CSS

logo14

Да, я в курсе, что в сети полно блогов и туториалов по использованию CSS, но у них всех есть общая проблема — они стремятся рассказать о всех функциях и вариантах использования и не говорят когда именно использовать именно CSS локаторы. В итоге начинающий не знает за что схватиться и не понимает когда использовать CSS, а когда Xpath.

По своему опыту убежден, что все функции не нужны для постоянной работы в 99% случаев ни в XPATH, ни в CSS. Основные полезные функции xpath я уже описывал, теперь обсудим Css и когда какие локаторы использовать.

  1. Класс. В CSS очень удобно использовать класс элемента (если он уникален), применяя просто знак «.» (точка). Например для элемента с тегом <div idc__dX351« classfbBtn btn-grflat btn font_button« enabledenabled«> можно указать локатор «.fbBtn«. Да, все так просто. Если элементов с таким словом в классе несколько, то можно указать еще один из классов в строке, например «.fbBtn.btn-grflat«. Тут нужно понимать, что все слова, перечисленные через пробел в теге class, это все классы CSS назначенные данному элементу, то есть найти его можно по любому из них, но конечно fbBtn бросается в глаза как явно уникальное слово в потоке остальных.
  2. id в случаях, когда он уникален, что в наше время роскошь, то просто используется запись в стиле #myid. Коротко и просто.
  3. Значения атрибутов. Легко найти элемент по значению его атрибута, если нет уникального класса или id. <input idc__db231_input« classinput__nativeinput« typetext«  placeholderЭл. почта« nameemail« value=»»/>  Как видим, мало что уникально в описании элемента, вполне оправдано использовать атрибут name и его значение. Получаем input[name=’email’]  Согласитесь, достаточно коротко и понятно, квадратные скобки, как и у xpath означают фильтр, если условий несколько то можно использовать запись в стиле  input[name=’email’][placeholder=’Эл. почта] — в данном случае, это тот же элемент.
  4. Поиск по частичному совпадению значения атрибута. А конкретнее, использования аналогов функций СОДЕРЖИТ, НАЧИНАЕТСЯ С, ОКАНЧИВАЕТСЯ НА. Вышеуказанный инпут можно найти и так input[placeholder*=’Эл’], запись «*=» означает СОДЕРЖИТ, аналог contains() в xpath. В данном случае ее можно заменить функцией НАЧИНАЕТСЯ С вот так input[placeholder^=’Эл’], то есть «^=» является аналогом starts-with в xpath. И, наконец, input[placeholder$=’почта’], дает нам выражение «$=» означающее ОКАНЧИВАЕТСЯ НА, не имеющее аналогов в xpath.
  5. Непосредственный наследник и потомок. Для того, чтобы добраться до непосредственного наследника (аналог child в xpath) нужно использовать запись в стиле div>div
    <div idc__da135« classsignInUsingEmailLbl font_title view« enabledenabled«>
              <div classlbl-cnt«>Входdiv>
    Тут, для того чтобы получить div с текстом Вход, можно использовать такую запись div.signInUsingEmailLbl>div  то есть сначала мы находим родителя по его классу (signInUsingEmailLbl), затем его «ребенка» с тегом div.
    <div idc__da135« classsignInUsingEmailLbl font_title view« enabledenabled«>
              <div classlbl-cnt«>Входdiv>

                   <div classex-cnt«>div>

    Чтобы получить потомка любой вложенности (аналог // или descendant в xpath) нужно просто поставить пробел! Чтобы найти элемент с классом «ex-cnt» в примере выше, используем div.signInUsingEmailLbl  div.ex-cnt то есть опять же находим родителя, а потом любого потомка с классом ex-cnt.

    securityservНа мой взгляд — это самые полезные функции  в CSS, которые легко запомнить, короткие в написании и понимании. По поводу скорости CSS по сравнению с Xpath я уже говорил — разница незначительна, но конечно чем короче в написании локатор, тем лучше. Минусом СSS является то, что поиск идет только сверху вниз, то есть мы не можем найти предка, только потомков (вспоминаем в xpath функции ancestor и parent).

Итак, используем CSS если:

  • есть уникальный класс (.fbBtn) или id
  • есть возможность определить элемент по атрибуту или его части (input*=’email’)
  • есть возможность определить элемент более короткой записью чем в xpath

В других случаях, когда нам нужен предок, нужно движение по иерархии вверх (а иногда вверх-вниз!), нужны сложные условия для получения элемента, лучше использовать xpath. Про логику и правила нахождения локаторов в сложных случаях верстки напишу в другой статье.


Software-Testing.Ru

Плагины браузера в помощь тестеру

аа

По просьбам трудящихся, решил написать о тех плагинах, которые использую в своих браузерах для тестирования нашего веб-приложения. Приложение мы проверяем в нескольких браузерах, но основные моменты проверяем в Chrome и Firefox.

Chrome:

  •  Screencastify. Удобный и понятный инструмент для записи видео, позволяет записывать как текущую вкладку так и весь рабочий стол, сохраняет  в приемлемом по размеру формате.

scr

  • Clear Cache. Обновляет вкладку со сбросам кэша (период настраивается), что бывает очень удобно, особенно для приложений, которые хранят много данных в локальном хранилище. То есть чтобы провести тест «с нуля» порой нужно сбросить кэш браузера, а лезть для этого в настройки не хочется.

cach

  • Spell Checker. Как понятно из названия -проверяет правописание на нескольких языках, не так удобен как плагин у Firefox о котором расскажу ниже. В Хроме требуется скопировать нужный текст и вставить в окно плагина для проверки, что не всегда удобно и просто.

spell

  • Quick Language Switcher. Позволяет изменить язык по умолчанию в браузере, что удобно для проверки локалей. Многие приложения, и наше не исключение, определяют язык пользователя по умолчанию и отрисовывают страницу в соответствии с ним. То есть человек из России откроет сайт на языке родных осин, а англичанин на языке Шекспира. Ну а тестеру надо иногда проверять что все это верно работает.

lang

  • What Font и ColorZilla. Плагины для проверки оформления. Первый, как видно по названию, показывает название шрифта при наведении на него. Второй показывает точный цвет любого элемента как в формате RGB так и шестнадцетеричном. Использую редко, но порой бывает, что прямо в требованиях описан конкретный шрифт или цвет.

font

color

Mozilla Firefox

  • Firebug. Отличный плагин, достойно заменяющий панель разработчика, с огромным количеством функций. В принципе аналог панели разработчика в Хроме, но на мой взгляд, в плане анализа элементов верстки гораздо удобнее. http://getfirebug.com/

fire

  • Firepath. Плагин, который работает непосредственно с Firebug и позволяет находить локаторы CSS и Xpath подсвечивая их на странице или в верстке, проверяет синтаксис введенных выражений.

path

measure

add

На этом пожалуй все, я указал только плагины, которыми пользуюсь сам, ваши могут отличаться, дело вкуса. К примеру проверка xpath для хрома в плагине реализована не так удобно, как в ФФ, элементы верстки мне тоже удобнее смотреть в Firebug, но вот другие функции панели разработчика лучше реализованы в Хроме.

Software-Testing.Ru

Польза JavaScript

В своих заметках я уже не раз упоминал о том, что верстка реальных веб-приложений далека от того что обычно демонстрируют в примерах на курсах и в книгах: ни тебе уникальных id, ни нормальных имен классов. Порой не знаешь к чему привязать локатор, чтобы все не упало при следующем запуске.

Как и  упоминал ранее, многие сложные моменты очень хорошо решаются через обращение к программистам с просьбой добавить нормальный локатор или просто с вопросом как проще достучаться до того или иного элемента.

Но если такой возможности нет, или нельзя исправить локатор в этом месте, или слишком долго, то порой очень пригождается javaScript, который не всегда входит в набор наших знаний. По своему опыту скажу, что порой использование JS реально сокращало время теста и его простоту, так как вместо «костыля» и обходных маневров, происходило обращение к нужному элементу или атрибуту напрямую.

Приведу простой пример:

Имеется вот такая форма с расположенным на ней textarea, а мне понадобился текст, который в ней расположен. Но в данном случае текст не находится в верстке, нет атрибута value или text, откуда можно его выдернуть.

textarea

Через методы getText и getAttribute родного Selenium соответственно тоже не подступиться.

Вот тут и понадобился JS, используя встроенный JavaScript Executor, нам нужно написать запрос для получения значения textarea, в данном случае я использовал CSS локатор.

JavascriptExecutor js = (JavascriptExecutor) driver;
result = (String) js.executeScript(«return document.querySelector(‘.dialog__content textarea’).value»);

По нашему локатору ищется элемент, его значение возвращают нам приводя к Стринг, в итоге мы получаем искомый текст.

К чему я это все? Java — это конечно отлично, но и знать JavaScript хотя бы в рамках написания таких запросов, тоже будет не лишним. Кроме того поможет в общении с разработчиками на их языке.

 
Software-Testing.Ru