Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

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

capybara
cucumber
selenium
ruby
Теги: #<Tag:0x00007f7b62198b08> #<Tag:0x00007f7b621989c8> #<Tag:0x00007f7b62198888> #<Tag:0x00007f7b62198720>

(Алексей) #1

Добрый день. Хочу реализовать выбор рандомного значения в выпадающем списке. Тесты пишутся на Ruby, Selenium, Capybara, Cucumber, Site-prism.
Список представляет из себя примерно такое

<select id="things">
  <option value="thing1">The First Thing</option>
  <option value="thing2">The Second Thing</option>
  <option value="thing3">The Third Thing</option>
</select>

Легко и просто реализуется выбор конкретного элемента,

@class.method.element.select “The First Thing”

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

@class.method.element.select “element[3]”

В идеале реализовать это возможностями одного из используемых инструментов.


(Stan) #2

Что значит случайного? Вы не знаете что будет тестироваться в тесте?


(Алексей) #3

Значения меняются, мне нужно выбирать либо любое значение, либо к примеру первое постоянно.
Как пример на странице mail.ru форма выбора почтового домена,

#mailbox__login__domain>option

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


(You Rooock) #4

Могу предложить вот что:
-получить все елементы из выпадающего списка
-получить длинну полученного массива
-сгенерировать случайное число в диапазоне от 0 до длинны массива
-сделать селект элемента из массива, подставив туда рандомное число из шага 2

В руби не силён, но на .net написал бы так:

IWebDriver driver = new FirefoxDriver(); var dropDown = By.CssSelector('#things'); var things = By.XPath("//option[contains(@value, 'thing')]"); var elements = driver.FindElements(things); var length = elements.Count(); Random rnd = new Random(); var i = rnd.Next(0, length); SelectElement select = new SelectElement(dropDown ); select.SelectByText(elements[i].Text);
Вместо текста можно использовать value, например.
Или можно было бы сделать без Select’a:

IWebDriver driver = new FirefoxDriver(); var dropDown = By.CssSelector('#things'); var things = By.XPath("//option[contains(@value, 'thing')]"); driver.FindElement(dropDown ).Click(); var elements = driver.FindElements(things); var length = elements.Count(); Random rnd = new Random(); var i = rnd.Next(0, length); elements[i].Click();
Мне больше импонирует второй способ, но тут возможно нужно будет добавить ожидание после клика на выпадающий список, чтобы драйвер дождался появления всех option.


(Сергей Блохин) #5

Посмотрите Работа с Select tag в Selenium WebDriver на Ruby


(Daniel Castillo) #6

@class.method.element.all(:xpath, ‘option’)[1…-1].sample.select_option


(Алексей) #7

Поподробнее пожалуйста про[1..-1].sample.select_option этот кусок, если можно сразу на примере с mail.ru, который я дал выше, потому что я пробовал что-то подобное и у меня не работало


(Daniel Castillo) #8

It’s not a method problem. It’s problem with locator.
http://joxi.ru/KAgKdvGf6Lx0Al
This works. I try.
find(:xpath, ‘//*[@id=“mailbox-auth-login”]/div[1]’).all(:css,‘option’)[0…-1].sample.select_option

all(:css, ‘option’) - take ways to all options
[0…-1] - take option range
sample - random
select_option - choose option

element :domen, :xpath, ‘//*[@id=“mailbox-auth-login”]/div[1]’

@page.main_class.section.domen.all(:css,‘option’)[0…-1].sample.select_option


(Ivan Nenashev) #9

Думаю стоит сначала получить список всех доступных значений, например так:
list = Selenum::WebDriver::Support::Select.new(@driver.find_element(list_locator))
Потом получить рандомное значение
element = list.options.sample
Теперь нужно выбрать этот самый элемент например по значению ( не самый очевидный путь, можно так же по :text и :index )
value = element.attribute(‘value’)
после чего собственно выберем элемент:
list.select_by(:value,value)

Рекомендую к прочтению:
https://selenium.googlecode.com/svn/trunk/docs/api/rb/Selenium/WebDriver/Support/Select.html


(Igor) #10

У меня есть реализация на java для случайной опции или случайного текста в селекте. Мысль та же, что у ребят выше. На вход метод принимает непосредственный родительский элемента для опций и вторым параметром либо конкретный текст, либо “rand”.

 	public void selectOption(WebElement element, String option) {
 		if (option != null && !option.equals("")) {
 			if (option.equals("rand")) {
 				Random random = new Random();
				List<WebElement> options = select.getOptions();
				int index = random.nextInt(options.size());
				while (!options.get(index).isEnabled()) {
					index = random.nextInt(options.size());
				}
			log.info("select option: " + options.get(index).getText());
			(new WebDriverWait(driver, 5, 200).until(ExpectedConditions.visibilityOf(select);
			select.selectByIndex(index);
 		} else {
 			(new WebDriverWait(driver, 5, 200).until(ExpectedConditions.visibilityOf(select));
			log.info("select text: " + option);
			select.selectByVisibleText(option);
 		}
 	}

(Алексей) #11

Thanks, this work now) I don`t use call css into xpath before it. Well, may you have any link, where I will read about similar usage?


(Daniel Castillo) #12

Hello,

That myself investigation, so I can’t advise You any information.