Как выбрать значение из выпадающего списка (Selenium WebDriver, C#)

Как выбрать значение из выпадающего списка (Selenium WebDriver, C#)
Сегодня рассмотрим вопрос, как выбрать требуемое нам значение из выпадающего списка при написании тестов на C# и Selenium WebDriver. В процессе написания тестов я столкнулся с двумя типами выпадающих списков, работу с которыми мы и рассмотрим.

Обычный выпадающий список. Я его так называю так как у него значения выбираются по нажатию на стрелку, т.е. мы сразу видим все значения выпадающего списка:

Как выбрать значение из выпадающего списка (Selenium WebDriver, C#)

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

Как выбрать значение из выпадающего списка (Selenium WebDriver, C#)

Может есть «академические» названия этих списков, но я не тратил время на то чтобы это выяснять. Я практик, а не теоретик.

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

Выбор значения из обычного выпадающего списка

К примеру, есть у нас список, код HTML которого выглядит следующим образом:


И если мы хотим выбрать из списка значение «18%», то мы это сделаем при помощи следующего кода:

IWebElement selectElem = driver.FindElement(By.ClassName("class-spiska")); // обращаемся к списку по его классу, если нет ни id, ни class, то обращайтесь по XPath или CssSelector
SelectElement select = new SelectElement(selectElem);
System.Collections.Generic.IList options = select.Options;
select.SelectByText("18%");

Выбор значения из ajax выпадающего списка

К примеру, есть у нас «input» и когда мы вводим в него значения, то система с помощью ajax начинает нам отображать подходящие элементы списка. Пример кода HTML:

<input type="text" class="class-spiska">

Если мы хотим выбрать из списка значение «Миллиметр», то мы это сделаем при помощи следующего кода:

System.Collections.ObjectModel.ReadOnlyCollection iElements;
driver.FindElement(By.ClassName("class-spiska")).SendKeys("Миллим");
driver.FindElement(By.ClassName("class-spiska")).Click();
Thread.Sleep(1000);
iElements = driver.FindElements(By.TagName("a"));
for (int i = 0; i < iElements.Count; i = i + 1)
{
	if (iElements[i].Text == "Миллиметр" && iElements[i].Displayed)
	{
		iElements[i].Click();
		break;
	}
}

Строка 1 - объявление переменной.
Строка 2 - отправим часть требуемого значения в заполняемое поле выпадающего списка.
Строка 3 - кликаем на заполняемое поле списка, чтобы ajax начал отрабатывать (в моём случае, только так он инициализируется).
Строка 4 - ожидаем появления значений, иначе значения не успеют появиться и на следующих шагах появится ошибка выполнения. Тут экспериментируйте, возможно в вашем случае можно будет убрать данную строку.
Строка 5 - элементы списка, которые появляются, у меня помещены в теги "a", поэтому я говорю, что надо найти все элементы "a":

Как выбрать значение из выпадающего списка (Selenium WebDriver, C#)

Вы смотрите в какие теги заключены ваши элементы списка.
Строка 6 - в строке 5 мы нашли все теги "a" и их количество равно "iElements.Count", теперь начинаем перебирать элементы на странице пока они не кончатся "i < iElements.Count" и...
Строка 8 - если выполняется условие «если элемент перебираемый сейчас содержит требуемый текст И данный элемент видимый», то выбираем данный элемент.

Возможно у вас список будет реализован не с помощью "input", а с помощью другого элемента/тега, но обращаться к нему можно так как я описал.

Эпилог

Хочу обратить ваше внимание на то, что у рассматриваемых мной списков есть «class = class-spiska». Желательно чтобы разработчики при разработке добавляли к спискам «id» или «class», тогда вам будет легче писать тесты. Если у списка нет ничего, то вам к нему придётся обращаться по «By.CssSelector» или по «By.XPath», а мы все прекрасно знаем, что если добавят дополнительные элементы на страницу, то ваши тесты «посыпятся», так как изменятся «By.CssSelector» и «By.XPath».

Если у вас Studio будет на что-то ругаться при добавлении приведённого мной кода, то привожу список всего того, что у меня подключено к проекту, а вы уже сами подберёте чего у вас не хватает:

using System;
using System.IO;
using System.Threading;
using NUnit.Framework;
using Selenium;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.PhantomJS;
using OpenQA.Selenium.Support.UI;

3 комментария

  1. Cool, thanks!

  2. Мимо проходил

    В цикле Вы ищете по ВСЕМ элементам на странице, которые содержат тег «a». Это не очень продуктивно, поставьте хотя бы break; после нахождения нужного элемента — сразу после iElements[i].Click(); Так вы теоретически сократите время поиска.

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

Добавить комментарий

Ваш адрес email не будет опубликован.