В процессе написания автоматических тестов, с использованием Selenium WebDriver, появилась необходимость проверять наличие элемента на странице и, если элемент не существует, выполнять одни действия, если существует, то выполнять другие действия. К примеру, сейчас я работаю в сфере туристического бизнеса. При проверке функциональности сайта надо перейти в определённый тур и если есть билеты на текущее число (и кнопка «Бронировать»), то произвести заказ, если нету, то надо вернуться назад и выбрать другой тур. И так до тех пор, пока не будет найден тур, по которому можно осуществить заказ.
Если нам надо провести проверку наличия элемента на странице, то мы можем написать код:
Assert.NotNull(driver.FindElement(By.Id(“id_elementa”)).Displayed);
Если элемент существует, то тест пройден. Если элемента нет, то получим исключение и тест будет считаться не пройденным. Это решение и его модифицированное использование в других решениях не подходит для нашего случая, так как всегда когда элемента не будет на странице будет появляться исключение и тест будет прерываться.
Раздумывая над этим, я подумал о том, что исключения в коде мы обрабатываем с помощью «try – catch». Через определённое время было найдено решение, которое позволило проверять наличие элемента на странице и не прерывать теста, так как отсутствие элемента естественное состояние проверемой системы в определённых случаях и условиях. Если кратко, то в условии «if» мы будем проверять «true» или «false» нам возвращает функция, которая ищет элемент на странице.
Пишем метод, который обращается на странице к элементу, и которая возвращает «true» (элемент есть) или «false» (элемента нет):
/// /// Метод проверяет наличие элемента на странице и возвращает true/false (существует/не существует). /// "iClassName" = By.Id("id"), By.CssSelector("selector") и т.д. /// public static bool IsElementExists(By iClassName) { try { driver.FindElement(iClassName); return true; } catch (NoSuchElementException) { return false; } } // в метод передаётся "iClassName" это By.Id("id_elementa"), By.CssSelector("selector") и т.д.
Строка 5 — ищем элемент.
Строка 6 — если находим элемент, то метод возвращает «true» (return true;).
Строка 10 — если не находим элемент, то метод возвращает «false» (return false;).
public static bool — так как у меня метод находится в другом файле CS. Если метод в том же CS, что и основной код, то замените на «private bool».
После этого в нужном нам месте кода надо будет проверить есть ли элемент на странице, вызвав выше описанный метод, и дальше по ситуации совершить требуемые действия:
// ... тут произвольный код if (IsElementExists(By.Id("id_elementa")) == true) { MessageBox.Show("Элемент есть"); // или здесь код, который выполняется при наличии элемента } else { MessageBox.Show("Элемента нет"); // или здесь код, который выполняется при отсутствии элемента } // ... тут произвольный код
Строка 2 — вызываем метод передавая в метод «By.Id» элемента и сравниваем возвращаемый методом результат с «true», т.е. есть ли элемент. В метод можно передавать «By.Id», «By.ClassName» и т.д.
Остальное понятно по комментариям в коде.
Также можно проверять видимость элемента видим/не видим:
/// /// Метод проверяет видимость элемента на странице и возвращает true/false (видимый/не видимый). /// "iClassName" = By.Id("id"), By.CssSelector("selector") и т.д. /// public static bool IsElementVisible(By iClassName) { try { var iv = driver.FindElement(iClassName).Displayed; if (iv == true) { return true; } else { return false; } } catch (NoSuchElementException) { return false; } // если элемент вообще не найден }
Selenium WebDriver вроде прост и удобен, но некоторые вещи надо реализовывать самому, как в описанном мною случае на проверку существования элемента (IF … EXIST в Selenium WebDriver нет).
Если у вас, что-то не будет работать, то привожу список того что у меня подключено:
using System; using System.IO; using System.Threading; using NUnit.Framework; using Selenium; using OpenQA.Selenium; using OpenQA.Selenium.Interactions; using OpenQA.Selenium.Remote; using OpenQA.Selenium.Firefox; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.PhantomJS; using OpenQA.Selenium.Support.UI; using System.Drawing.Imaging; using System.Windows.Forms; // для MessageBox, использую в отладке using System.Data.SqlClient;
дай бог здоровья автору, я очень рад что нашел эту статью
Большое спасибо!)
Спасибо
Большое СПАСИБО!
Примите еще одну благодарность.
public static bool IsElementExists(By iClassName)
{
try
{
Browser.FindElement(iClassName);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Ошибка 1 Для нестатического поля, метода или свойства «_Bot.Form1.Browser» требуется ссылка на объект
удалил public static. Все заработало. Спасибо вам))
Ошибка 5 Имя «Assert» отсутствует в текущем контексте
Что не так?
Если хотите использовать Assert, то используйте NUnit и другие библиотеки имеющие Assert.
Автор вначале как пример привёл проверку с помощью Assert и судя по using NUnit.Framework он использует NUnit. Потом он расписал методы без Assert.
Ошибка 5 Не удалось найти имя типа или пространства имен «NUnit» (пропущена директива using или ссылка на сборку?)
после добавления библотеки
Для подключения NUnit добавьте пакеты через Nuget, о которых говорится здесь https://victorz.ru/20161218341
И после этого добавляете «using NUnit.Framework;»
Но это в том случае, если вам действительно нужен NUnit.
пытаюсь вот так сделать теперь
if (Browser.FindElements(By.Id(login)).size() == 0))
но словил ошибку
Ошибка 4 «System.Collections.ObjectModel.ReadOnlyCollection» не содержит определения для «size» и не был найден метод расширения «size», принимающий тип «System.Collections.ObjectModel.ReadOnlyCollection» в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку)
Не знаешь какая библиотека нужна?
В «C# + Webdriver» нету size(), используется в Java. В C# есть Count().
Если вы пытаетесь проверить наличие элемента, то прочтите статью выше и вы сможете без проблем это делать без всяких Count:
if (IsElementExists(By.Id("id_elementa")) == true)
Ошибка 4 Имя «IsElementExists» отсутствует в текущем контексте
Это метод, о котором я писал выше в статье.
C#
public static bool HasElement(this IWebDriver drv, By selector) {
return drv.FindElements(selector).size() > 0;
}
…
if (driver.HasElement(By.Id(«id»))) {
…
}
В «C# + Webdriver» нету size(), используется в Java. В C# есть Count(). Но в указанном выше контексте он не может использоваться.
Может и используется.