Home > Мелочи, JavaScript, XPath > А вот else if, тогда я бы…

А вот else if, тогда я бы…

Поступил вопрос: “Можно ли в Selenium IDE реализовать цикл if? Например, если есть кнопка “Войти”, тогда нажимаем ее, иначе нажимаем на “Регистрация”?

Можно.

Но только в рамках одного файла из тест-сьюта. Возможность произвольного перехода между файлами в контексте тест-сьюта в Selenium IDE я не нашел.

Подобные переходы делаются с помощью ярлыков (labels), и команды gotoIf, а эти штучки появляются только после подключения внешнего js-файла.

Ярлык (label) сам по себе ничего не делает – это просто особым образом именованная строчка, к которой Selenium IDE насильно переходит, после чего начинает выполнять команды, которые следуют далее по коду

.

Адекватное решение

.

Во-первых, слегка изменю условия примера из заданного вопроса:

  1. “Если залогинен:
    • перейти на страницу ‘My Dashboard’.
  2. Если не залогинен:
    • перейти на страницу Login,
    • залогиниться,
    • перейти на страницу ‘My Dashboard'”

Такой алгоритм я использую непосредственно в работе, и мне он кажется более используябельным, нежели “если нет кнопки “Логин”, тогда выбрать кнопку “Регистрация”.

Изменение не существенное, поэтому поехали дальше.

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

  1. Открыть сайт.
  2. Выяснить, залогинен ли я. Для этого надо поискать на странице элемент ‘link=Account’.
  3. Если элемент ‘link=Account’ присутствует:
    • кликнуть по этому линку
    • перейти на страницу ‘My Dashboard’ (это будет сделано автоматически)
  4. Если элемент ‘link=Account’ отсутствует:
    • перейти на страницу Login
    • залогиниться
    • перейти на страницу ‘My Dashboard’

Если я попытаюсь втиснуть в одну getEval-строку и проверку наличия элемента, и выполнение какого-то кода, я в этой строке запутаюсь при последующем рефакторинге.

Поэтому:

  1. еще раз нужно убедиться в том, что внешний js-файл правильно подключен.
  2. сделаю три ярлыка (labels):
    • openPageDashboard,
    • loginOnTheSite,
    • testingClosed.

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

  3. Открою главную страницу сайта.
  4. Проверю наличие или отсутствие линка ‘Account’ на ней, присутствие которого символизирует то, что я залогинен.
  5. В зависимости от результата, перейду к нужному месту в коде, и сделаю определенные действия.
  6. Перейду к ярлыку testingClosed.

Финиш.

Правильная демонстрация логики IF в Selenium IDE

Указываем используемые в тест-сьютах переменные
storeExpression http://test.com/ mainPage
storeExpression http://test.com/LogIn.aspx loginPage
storeExpression http://test.com/UserAccount.aspx myDashboardPage
storeExpression Customer Login customerLoginPage
Открываем страницу
open ${mainPage}
Ищем элемент ‘link=Account’ и принимаем решение о следующем шаге
storeEval if (selenium.isElementPresent(‘link=Account’) == true) {nextMove = ‘openPageDashboard’} else if (selenium.isElementPresent(‘link=Account’) == false) {nextMove = ‘loginOnTheSite’} nextMove
echo ${nextMove}
двигаемся согласно результату в ‘nextMove’
gotolabel ${nextMove}
Отрабатываем положительный результат теста
label openPageDashboard
Открыть страницу аккаунта
open ${myDashboardPage}
verifyTitle ${customerLoginPage}
Переходим к завершению теста
gotolabel testingClosed
Отрабатываем отрицательный результат теста
label loginOnTheSite
Открыть страницу Login и залогиниться
open ${loginPage}
type username user
type password 12345
clickAndWait sign_in
verifyTitle ${customerLoginPage}
Переходим к завершению теста
gotolabel testingClosed
Полное завершение теста
label testingClosed

.

Важно знать

.

0)

Можно (это модно) сократить код

storeEval if (selenium.isElementPresent(‘link=Account’) == true) {nextMove = ‘openPageDashboard’} else if (selenium.isElementPresent(‘link=Account’) == false) {nextMove = ‘loginOnTheSite’} nextMove

следующим образом:

storeEval if (selenium.isElementPresent(‘link=Account’) == true) {‘openPageDashboard’} else if (selenium.isElementPresent(‘link=Account’) == false) {‘loginOnTheSite’} nextMove

Дело в том, что в буковках {nextMove = ‘openPageDashboard’} имеет значение только то, что сокрыто в ординарных кавычках. Да еще важно  название создаваемой объявляемой созданной и объявленной переменной ‘nextMove’. Все остальное – просто информационный фон.

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

Можно еще проще, если ситуация бинарна, вроде “или true, или false”:

if (selenium.isTextPresent(‘You are logged in’) == true)
{nextMove = ‘alreadyLoggedIn’}

else {nextMove = ‘loginOnSite’}

А можно вообще перечислить все нужные ситуации и указать, куда надо иттить в каждом отдельном случае? В таком случае будут сплошные указатели “true” и ни одного “false”:

if (selenium.isElementPresent(“//input[@value=’Logout‘]”) == true)
{nextMove = ‘logoutThenLogin‘}

else if (selenium.isElementPresent(“//input[@id=’password‘]”) == true)
{nextMove = ‘login‘}

else if (selenium.isElementPresent(“//input[@id=’question‘]”) == true)
{nextMove = ‘askYourQuestion‘}

 else alert(‘Чё те надо, старче?’)

Конечно, не возбраняется писать “{then = ‘openPageDashboard’}”, чтобы код читался прям как третий акт вторая сцена технодрамы “Отелло и Джульетта”.

1)

Если вместо selenium.isElementPresent(“link=Account”) написать только isElementPresent(“link=Account”) – получим [error] Threw an exception: isElementPresent is not defined. Ибо selenium. есть объявление соответствующего класса, а классовую борьбу со времен Маркса ещё никто не отменял.

2)

Если вместо (link=Account) написать (link=Account) – в Selenium IDE это сработает без вопросов, но если в будущем код будет экспортироваться в формат java, то двойные кавычки из (“link=Account”) превратятся в (\”link=Account\”). Та же ситуация, что и в Xpath.

3)

Условий может быть больше двух 🙂

Например:

<td>storeEval</td>

<td>if (selenium.isTextPresent(‘Ошибка 404’) == true) {nextMove = ‘showAlert’} else if (selenium.isTextPresent(‘Exception’) == true) {nextMove = ‘showAlert’} else if (selenium.isTextPresent(‘FreeMarker’) == true) {nextMove = ‘showAlert’} else if {nextMove =’testOk’}</td>

<td>nextMove</td>

Тут Selenium проверит наличие всех трех условий последовательно. Если хотя бы одно слово их указанных будет обнаружено, то в переменную nextMove будет положена инструкция перехода к ‘showAlert’. Если ничего не будет обнаружено – то перейдем к ярлыку ‘testOk’.

В моем основном случае есть только два условия, ведь искомый элемент или есть, или отсутствует. В действительности можно понауказать “else if (условие поиска) {решение вопроса}” столько, сколько нужно было бы богу любой религии, если бы он решил накодить краткий справочник по психологии рядовой жительницы Кишинева XXI века.

Другой вопрос – как потом разобраться во всех этих условиях.

4)

Как выяснить правильное название команды типа selenium.isElementPresent:

  • Резко создать новый кейс, чтобы не запутаться в строках.
  • написать нужную команду. Например, verifyTitle (команды вроде waitFor сгенерируют чуток более сложный код, чем ожидается, поэтому пример простой).
  • Options > Format > Java
  • обнаружить строки вроде
public void testUntitled() throws Exception
   {
verifyEquals("", selenium.getTitle());
   }
  • Скопировать selenium.getTitle, и заюзать в своем контексте.

5) Если скопированный код не работает – рецепт. Вероятнее всего, дело в кавычках.

6) Если нужно проверить наличие элемента по более сложному xpath, нежели просто link=Account, то нужно будет обрамлять элемент в двойные кавычки. Например, проверяем наличие //input[@type=’checkbox’ and @value=’true’ and @name=’RulesEnabled’] следующим образом:

if (selenium.isElementPresent(//input[@type=’checkbox’ and @value=’true’ and @name=’RulesEnabled’])  == true) {nextMove = ‘createNewRule’}

7) Если нужно проверить, есть ли на странице текст, который мы сохранили в переменную (например, в переменную ‘accountName’), то пишем так:

if (selenium.isTextPresent(storedVars[‘accountName’]) == false) {nextMove = ‘listToNextPage’} else if (selenium.isTextPresent(storedVars[‘accountName’]) == true) {nextMove = ‘openUserPage’}

Тут фишка в том, что вместо ${accountName} нужно писать storedVars[‘accountName’] – так предусмотрено в расово правильном для Selenium языке JavaScript.

8) Если знаете javasctipt, можете обойтись без расширений, например:

runScript | javascript{if(document.getElementById(‘p1’).style.display == ‘inline’) document.getElementById(‘p1’).click(); else document.getElementById(‘p2’).click();} | nextMove

Если видим элемент “p1” – делаем клик по нему, иначе делаем клик по “p2”.

Обрамление javascript{…} неоднозначное. Иногда требуется безусловно, иногда можно и без него…

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: