Перейти к содержимому

Selenium WebDriver: полное руководство
онлайн, начало 19 октября
Логи как инструмент тестировщика
онлайн, начало 22 октября
Первый Онлайн ИНститут Тестировщиков
онлайн, начало 15 октября
Тестирование REST API
онлайн, начало 22 октября
Фотография

Уважаемые гуру прошу помощи с elementToBeClickable


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 8

#1 Voproshaikin

Voproshaikin

    Новый участник

  • Members
  • Pip
  • 4 сообщений
  • ФИО:Владимир

Отправлено 21 Март 2018 - 14:57

Задача проста: при движении по странице снизу вверх появляется "всплывающее меню". соответственно нужно кликнуть в один из элементов

Вот пример простейшего теста для подобной ситуации в открытом доступе 

@Test
public void myTest() throws Exception {
driver.get("https://www.virtuoso...ohidingnavbar/");
WebElement myElem = driver.findElements(By.cssSelector("[class = 'table table-striped table-bordered docs']")).get(1);
Actions actions = new Actions(driver);
  actions.moveToElement(myElem).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).build().perform();
  actions.moveToElement(myElem).sendKeys(Keys.ARROW_UP).sendKeys(Keys.ARROW_UP).sendKeys(Keys.ARROW_UP).sendKeys(Keys.ARROW_UP).build().perform();
myElem = driver.findElements(By.cssSelector("li")).get(12);
wait.until(elementToBeClickable(myElem));
//Thread.sleep(3000);
myElem.click();

 

Если убрать комментарий с Thread.sleep то все работает. Но sleep как известно - зло. Подскажите пожалуйста что не так с использованием elementToBeClickable. И как сделать нормальное ожидание в данной ситуации?


  • 0

#2 DmitriyQA

DmitriyQA

    Постоянный участник

  • Members
  • PipPipPip
  • 182 сообщений
  • ФИО:Коваленко Дмитрий Владимирович
  • Город:Tel Aviv

Отправлено 21 Март 2018 - 15:19

Код конечно у тебя жесть))

Во первых советую заменить жесть с нажаитеи вниз на нормальный скролл

WebElement element = driver.findElement(By.id("id_of_element"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);

 
Затем тебе нужено вначале ожидание что элемент visible а затем уже clicable/ 
 
Поищи сам как это на джаве на питоне так
element = WebDriverWait(self.driver, time).until(
EC.visibility_of_element_located(by_locator))
 
И потом выучи пейджобжект

  • 1

Senior QA/ Wix.com / qaacademy.net


#3 Voproshaikin

Voproshaikin

    Новый участник

  • Members
  • Pip
  • 4 сообщений
  • ФИО:Владимир

Отправлено 22 Март 2018 - 11:52

Уважаемый, Коваленко Дмитрий Владимирович!

К сожалению Ваш ответ не помог решить мою проблему:

 

1. То, что лучше обращаться по id-шнику к элементу никто не спорит. (К сожалению я не проверил свое сообщение и не заметил, что адрес сайта https://www.virtuoso...tohidingnavbar/, который я использовал в качестве примера был "скомкан". (хотя как оказалось он "рабочий")

Буду вам премного признателен за консультацию, какие тут лучше использовать id-шники. (да использовать длинные css локаторы это моветон. Просто надо было создать пример за 2-ру минут – тут уж не до изысков)

 

2. Не все знакомы с JS, задача решалась подручными средствами seleniuma. Да, в принципе, с помощью scrollIntoView можно прыгнуть на некий нижний элемент страницы, а потом прыгнуть на верхний, но к сожалению такой способ не приведет к появлению "Auto-Hiding Navbar".

Вот тут http://qaru.site/que...river-with-java  (если вам будет интересно) один из примеров, где пользователи обсуждают различные способы применения JS (и отчасти комментируют их неэффективность в определенных ситуациях). Согласен, использование подряд нескольких sendKeys выглядит некрасиво, и ввиду сжатости сроков написания примера был использован Ctrl-C Ctrl-V.

 

3. Если верить описанию класса ExpectedConditions https://seleniumhq.g...qa.selenium.By- , то цитирую "Returns: the WebElement once it is located and clickable (visible and enabled)"

 

4. Большое спасибо за рекомендацию изучать Page Object, частично я с ней уже знаком, но вот как она конкретно сможет помочь с проблемами возникшими с использованием  ExpectedConditions  - извините, не понял.

 

 

 


  • 0

#4 Voproshaikin

Voproshaikin

    Новый участник

  • Members
  • Pip
  • 4 сообщений
  • ФИО:Владимир

Отправлено 22 Март 2018 - 11:58

Уважаемые форумчане! Кажется мне удалось смоделировать мою проблему на общедоступном ресурсе. Как мне кажется проблема в том, что программа по каким то причинам не дожидается "окончательного появления" "Auto-Hiding Navbar"
В моем далеко не изящном коде (простите я только знакомлюсь с автоматизацией) осуществляется переход к нижнему элементу страницы. Затем специально применяется слип, что бы продемонстрировать ситуацию, когда после "паузы", после первого же действия пользователя должен появиться NavBar, но ExpectedConditions не обрабатывает корректно данную ситуацию.
Пример кода демонстрирующего проблему
Скрытый текст
 
Буду рад любому конструктивному переложению 

  • 0

#5 Spock

Spock

    Гуру

  • Members
  • PipPipPipPipPipPip
  • 1 051 сообщений
  • ФИО:Роман

Отправлено 22 Март 2018 - 13:25

а что вообще происходит в этом коде в последнем посте? какую ошибку выдаёт?

проходит ли код если выставить тред.слип 30000 ?


  • 0

#6 TatyanaV

TatyanaV

    Опытный участник

  • Members
  • PipPipPipPip
  • 315 сообщений
  • ФИО:Воробьева Татьяна


Отправлено 22 Март 2018 - 13:32

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

 

Например, css первого пункта меню (если оно видно): 

.navbar[style*=' 0px'] .active a[href='#']

 

Если меню не отображается - в style будет что-то вроде "-50px".

п.с. (в первом css пробел перед 0)

 

п.п.с: элемент с локатором "(.//li[1]/a)[1]" существует ещё до появления менюшки. Он не перекрыт каким либо другим элементом, вероятно поэтому с точки зрения Селениума - он вполне может считаться visible и enabled (в коде меняется только указанный мной выше атрибут style).

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


  • 0

#7 DmitriyQA

DmitriyQA

    Постоянный участник

  • Members
  • PipPipPip
  • 182 сообщений
  • ФИО:Коваленко Дмитрий Владимирович
  • Город:Tel Aviv

Отправлено 22 Март 2018 - 15:16

Cоглашусь с предыдущим участником. Советую вам максимально избегать использования xpath. Под категорию /li[1]/a)[1] подходит любая ссылка внутри списка. По умолчанию селениум берет первый компонент. Скорее всего при появлении попапа он будет первым. По этому и работает. А вот если его нет обращается к другому. Ваша задачу тут взять уникальный локатор попапа (подождать его).  А уже внутри него взять то что вам нужно. И учитесь сами писать селекторы, а не брать их из консоли или помощника. 

 

Вот руководство

https://www.w3school...s_selectors.asp


  • 0

Senior QA/ Wix.com / qaacademy.net


#8 Voproshaikin

Voproshaikin

    Новый участник

  • Members
  • Pip
  • 4 сообщений
  • ФИО:Владимир

Отправлено 22 Март 2018 - 16:31

проходит ли код если выставить тред.слип 3000 ?

Да тогда если раскомментить слип, то с моими "кривыми" xpath локаторами тест работает. И сие ужасно ибо провоцирует слабых духом на костыльные слипы.

 

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

 

Например, css первого пункта меню (если оно видно): 

.navbar[style*=' 0px'] .active a[href='#']

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

<div class="navbar navbar-default navbar-fixed-top" role="navigation" style="top: 0px;">
<div class="navbar navbar-default navbar-fixed-top navbar-hidden" role="navigation" style="top: -50px;">
для различных состояний меню.
 
т.е. например можно было бы проверять видимость "родительского" элемента , что-нибудь наподобие "[class $='navbar-fixed-top']", но Ваш вариант лучше.
 

Вот руководство

https://www.w3school...s_selectors.asp

Спасибо, Дмитрий


  • 0

#9 sergueik

sergueik

    Активный участник

  • Members
  • PipPip
  • 75 сообщений
  • ФИО:кузьмин сергей

Отправлено 23 Март 2018 - 23:26

простите запоздалый комментарий 

может кому пригодится 

можно прератить длинный селектор

```

element = driver.findElements(By.cssSelector("div.navbar.navbar-fixed-top div.navbar-collapse li:nth-child(4) > a")).get(0);
wait.until(ExpectedConditions.elementToBeClickable(element));
 

```

в chain of 

```

element = driver
.findElements(
    new ByChained(By.cssSelector("body"),
                  By.cssSelector("div.navbar"),
                  By.cssSelector("div.navbar-collapse"),
                  By.cssSelector("li"),
                  By.xpath(
                     String.format(
                          "//a[contains(text()[normalize-space()],'%s')]", "Blog")
                     )
                   )
        )
        .get(0);
wait.until(ExpectedConditions.elementToBeClickable(element));
highlight(element);
 

```

и оттуда уже прямой путь в отладчик 

```

element = driver

           .findElements(new ByChained(
                                By.cssSelector("body"),
                                By.cssSelector("div.navbar-fixed-top"),
                                By.cssSelector("div.navbar-collapse"),
                                By.cssSelector("li"))
                       ).stream().map(
                                  o -> {
                                          System.err.println(o.getAttribute("innerHTML"));
                                          return o;
                                        }
    ).filter(
               o -> o.findElements(
                      By.xpath(String.format(
                                "//a[contains(text()[normalize-space()],'%s')]","Blog"))
     ).size() > 0).collect(Collectors.toList()).get(0);
wait.until(ExpectedConditions.elementToBeClickable(element));
highlight(element);
element.click();
 

```

 

то есть можно посмотркть как оно фильтруется по дороге по DOMу:

типа 

 

```

 

<a href="/">Home</a>
 
<a href="/code/" class="dropdown-toggle" data-toggle="dropdown">Plugins <b class
="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/code/bootstrap-dropdown-hover/">Bootstrap Dropdown Hover</a></li>
<li class="active"><a href="/code/bootstrap-autohidingnavbar/">Bootstrap Auto-Hi
ding Navbar</a></li>
<li><a href="/code/bootstrap-colorpickersliders/">Bootstrap Color Picker Sliders
</a></li>
<li><a href="/code/bootstrap-touchspin/">Bootstrap TouchSpin</a></li>
<li><a href="/code/jquery-colorpickersliders/">jQuery Color Picker Sliders</a></
li>
<li><a href="/code/bootstrap-duallistbox/">Bootstrap Duallistbox</a></li>
</ul>
 
<a href="/code/bootstrap-dropdown-hover/">Bootstrap Dropdown Hover</a>
<a href="/code/bootstrap-autohidingnavbar/">Bootstrap Auto-Hiding Navbar</a>
<a href="/code/bootstrap-colorpickersliders/">Bootstrap Color Picker Sliders</a>
 
<a href="/code/bootstrap-touchspin/">Bootstrap TouchSpin</a>
<a href="/code/jquery-colorpickersliders/">jQuery Color Picker Sliders</a>
<a href="/code/bootstrap-duallistbox/">Bootstrap Duallistbox</a>
 
<a href="/tools/" class="dropdown-toggle" data-toggle="dropdown">Tools <b class=
"caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/tools/live-less-theme-customizer/">Live LESS Theme Customizer</a><
/li>
<li><a href="/tools/bootstrap-live-customizer/">Bootstrap Live Customizer</a></l
i>
<li><a href="/tools/css-gradient-generator/">Gradient Generator</a></li>
</ul>
 
<a href="/tools/live-less-theme-customizer/">Live LESS Theme Customizer</a>
<a href="/tools/bootstrap-live-customizer/">Bootstrap Live Customizer</a>
<a href="/tools/css-gradient-generator/">Gradient Generator</a>
<a href="/blog/" style="">Blog</a>
<a href="/codepen/">Codepen</a>

```


  • 0


Selenium 2.0: стартовый уровень
онлайн, начало 9 ноября
Программирование на Java для тестировщиков
онлайн, начало 12 октября
Автоматизация функционального тестирования
онлайн, начало 5 октября
Selenium WebDriver: полное руководство
онлайн, начало 19 октября



Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных

Яндекс.Метрика
Реклама на портале