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

как в List<WebElement> получить только видимые на странице элементы?

css-selectors
selenium
webdriver
Теги: #<Tag:0x00007f7b64f35bb0> #<Tag:0x00007f7b64f35a48> #<Tag:0x00007f7b64f358e0>

(pauloo89) #1

В Chrome можно сделать вот так $(’#flights-to .col1:visible’) и отобразятся только видимые элементы, а как такое можно сделать в selenium?


(Ray Romanov) #2

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


(pauloo89) #3

@FindBy(css = “#flights-to .col1:visible”)
public List airFrom;

но я просто в аннотацию не могу ведь вставить запись?


(Ray Romanov) #4

Тут не подскажу, работаю на другом фреймворке (Codeception) используется РНР.


(Roma Marinsky) #5

Ты попробуй, а в целом это полноценно работающий css локатор который может не работать в ie8-9. И он не поддерживается selenium - да


(Roma Marinsky) #6

А лучше перед .col1 ставь наименование тега, чаще всего это помогает


(pauloo89) #7

@FindBy(css = “#flights-to td.col1:visible”) вот с такой записью падает,


(Roma Marinsky) #8

на http://www.w3schools.com/cssref/css_selectors.asp такой штуки как visible нет, я попробывал у себя :enabled, но тоже чёт не заработало… дичь какая-то, что-то в них более тонкое

Может у класса td.col1 есть ещё один класс который отвечает за видимость? Или может есть display=“true/block/bla-bla” или ещё какой-либо атрибут для видимых td
У вас что табличная вёрстка?))


(pauloo89) #9

на данной странице да) ) но это не критично просто мне стало интересно работает или нет такой способ.


(Roma Marinsky) #10

хмм а в xpath есть такая штука: [not(@disabled)]
но не знаю как с классами там дела у xpath


(Дмитрий Мирошник) #11

Вот так:
@FindAll({@FindBy(how = How.CSS, using = “#flights-to .col1:visible”)})
public List airFrom;

Примерно так. Могут быть ошибки синтаксиса.


(pauloo89) #12

не работает ваш вариант, вроде как Selenide умеет так делать.


(Roma Marinsky) #13

всегда интересовало,
зачем писать FindBy(how = How.CSS, using = “#flights-to .col1”)
если можно FindBy(css = “#flights-to .col1”)


(Dmitrii Demin) #14

@pauloo89
У меня не было такой потребности ранее, но сейчас решил опробовать Selenide подход к этой проблеме:

    @Test
    public void someTest(){
        Selenide.open("http://google.ru");
        
        String[] textsAll = $$(By.xpath("//span"))
                .getTexts();
        String[] textsVisible = $$(By.xpath("//span"))
                .filter(Condition.visible)
                .getTexts();
        
        System.out.println("All: " + Joiner.on(",").join(textsAll));
        System.out.println("Visible: " + Joiner.on(",").join(textsVisible));
    }

Вроде все достаточно коротко и понятно =)


(Roma Marinsky) #15

я и забыл про фильтры у селенида, никогда не использовал ещё)


(Дмитрий Мирошник) #16

Привычка :slight_smile:


(Дмитрий Мирошник) #17

Что именно не работает? Дайте ссылку на страницу и покажите, какие элементы нужно найти.
Например, вот такая аннотация находит список доменов на странице mail.ru

@FindAll({@FindBy(how = How.XPATH, using = “//select[@id=‘mailbox__login__domain’]/option”)})public List<WebElement> domainDropdownOptions;

Есть подозрение, что ошибка в css тогда.


(pauloo89) #18

selenium падает если в css селектор добавить :visible.


(pauloo89) #19

Я делаю поиск авиабилетов, и отображаются все результаты, (второй скрин), затем я ставлю галочку только прямые рейсы при этом на странице результатов становится 5, а поиск выдает все элементы в том числе и те которые не видно(первыйскрин), я добавляю :visible. и он показывает только видимые элементы(третий скрин).
Но если локатору в Selemiun просто добавить :visible, то селениум ругается на неправильный локатор




(Aleksey Ilyenko) #20

Вы можете отфильтровать список средствами джава, и никаких Селенидов вам для этого не нужно:

list.stream()
    .filter(WebElement::isDisplayed)
    .collect(Collectors.toList())