Вывод списка элементов на странице, работа со списком с помощью WebDriver

Доброго времени суток, и снова я (надеюсь еще не надоел). 

У меня вопрос, простисте если это уже рассматривали, я искал по форуму, решение своей проблеммы не нашел.

На странице имеется список отчетов, каждый отчет это ссылка.

2 задачи 

1) Проверить список ссылок (т.е. отчетов), что все они присутсвуют.

2) Проверить по очереди каждый отчет, если он есть нажать на него, и так по всему списку.

Заранее всем спасибо

Использую WebDriver & Java

собственно в чем вопрос? :)

что у вас не получается?

Не получается собвственно вот что:

 

Есть класс, метод в котором как я надеюсь должен выдать список элементов (ссылок) на страннице:

 

public class SummaryReportsPage {
WebDriver driver;
public SummaryReportsPage(WebDriver driver) {
this.driver = driver;
}
protected final  List <WebElement> findElements(By by) {
return (List<WebElement>) driver.findElements(by);
}
}
 
Вот сам тест
public class SummaryReports {
 
WebDriver driver;
 
@Before 
public void setUp(){
    System.setProperty("webdriver.chrome.driver", "D://chromedriver.exe");
    driver =  new ChromeDriver();
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    driver.get("http://robot2:38504/argus/home/home.seam");
}
 
@Test
public void setSummaryReports() {
 
LoginPage lg = new LoginPage(driver);
MainPage mp = lg.login("developer", "developer");
mp.setSummaryReports(driver);
SummaryReportsPage srp = mp.setSummaryReports(driver);
assertTrue(srp.findElements(By.xpath("//a")).contains("По участкам"));   // Здесь тест падает
}
}

 

Который должен проверить есть ли в списке отчет "По участкам". 

 

Но тест, падает, отчет "По участкам" есть на странице.

 

Извините, может я чего не знаю - а как вы заранее номер порта знаете? Можно запустить драйвер через сервис (OpenQA.Selenium.Chrome.ChromeDriverService в C#), а оттуда получить порт.

Или вы порт один раз подсмотрели и навсегда внесли в код?

Если вы об этом порте  - driver.get("http://robot2:38504/argus/home/home.seam") - это порта сервера на котором установленно веб клиент (это не сайт, это система учета). Здесь http://robot2:38504/argus/home/home.seam" -  это страница ввода логина и пароля далее http://robot2:38504/argus/ не меняется

Извините, протупил :) у нас в C# это называется только Navigate(), get в джаве.

Если это у вас в тайтле, вот такой XPath:

//*[contains(@*, 'другие')]

www.anekdot.ru, возвращает вот такое:

<a class="title block_title" title="Смешные анекдоты про Вовочку, Штирлица, Чапаева и другие" href="/tags/">Анекдоты про</a>

а вот так возвращает, если это innertext

//a[contains(@*, 'карикатуры')]

там же, вернуло вот это:

<a title="Лучшие карикатуры месяца" href="/an/top/e1211-1211;20.html">карикатуры</a>

Firefox, firepath

 

Я не особый знаток Джавы, но на мой взгляд что-то не то в этом коде:
srp.findElements(By.xpath("//a")).contains("По участкам")
 
findElements возвращает массив WebElement, а вы ищите в нем строку. 
Скорее всего, вам сначала нужно преобразовать список вебэлементов в список строк, а потом уже искать строку в массиве. 
 
В любом случае, лучше писать так, сохраняя результат от вебдрайвера в отдельную переменную: 
JavaArraySyntaxHere webElements = srp.findElements(By.xpath("//a"));
assertTrue(webElements.contains("По участкам"));   // Здесь тест падает
 
Теперь можно поставить точку останова и под дебагером проследить что на самом деле вернул вебдрайвер
 

К сожалению в contains()  неполучилось поместить массив, пробовал с containsAll() все, единственный тест который сработал выглядит так (пробовал много комбинаций)

 

 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
 
public class SummaryReports {
 
WebDriver driver;
Collection<WebElement> webElements;
 
 
@Before
public void setUp() {
System.setProperty("webdriver.chrome.driver", "D://chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://robot2:38504/argus/home/home.seam");
 
}
 
@Test
public void setSummaryReports() {
 
LoginPage lg = new LoginPage(driver);
MainPage mp = lg.login("developer", "developer");
mp.setSummaryReports(driver);
SummaryReportsPage srp = mp.setSummaryReports(driver);
webElements = srp.findElements(By.xpath("//div[4]//a"));
assertTrue(webElements.containsAll(webElements));
}
}

Не нашел способа webElements представить ввиде массива, присваивая ему  srp.findElements(By.xpath("//a"));

WebElements является коллекцией, в первом варианте был List(список). он по сути является динамическим массивом, и преобразовывать конкретно к массиву его не имеет смысла, можно итеративно по нему пройтись.

Если же хотите преобразовать к классическому массиву используйте метод toArray у List или Collection (учтите что лист и коллекция это интерфейсы).

 

А можете на моем примере показать, как иттеративно пройтись по динамическому массиву?

Как в автоматизации так и в java я новичек

предложу вот такой пример:

ArrayList arrayList = new ArrayList(); 

al.add("C"); 
al.add("A"); 
al.add("E"); 
al.add("B"); 
al.add("D"); 
al.add("F");

Iterator it = arrayList.iterator(); 
while(it.hasNext()) {

    Object element = it.next(); 
    System.out.print(element + " ");

}

это с использованием итераторов.

 

также для прохода по списку можно использовать обычный foreach цикл:

ArrayList<WebElement> arrayList = new ArrayList<WebElement>();

for(WebElement element: arrayList){

element.getTextOfElement();// тут element это текущий элемент в теле цикла

}

вот переделанный код именно на вашем примере, попробуйте 

@Test
public void setSummaryReports() {
LoginPage lg = new LoginPage(driver);
MainPage mp = lg.login("developer", "developer");
mp.setSummaryReports(driver);
SummaryReportsPage srp = mp.setSummaryReports(driver);
List<WebElement> elements = srp.findElements(By.xpath("//a");
for(WebElement element: elements){
assertTrue(element.getText().contains("По участкам"));
}
}

Здравствуйте, а у меня подобный код не работает ((

Причем если написать вот так, то есть найти один элемент,

 

     WebElement elemt = driver.findElement(By.xpath(".//*[@id='menu1']"));  
    System.out.println(elemt.getText());
    assertTrue(elemt.getText().contains("tralyaya"));   
 
То всё нормально. Проверка проходит и печатается содержимое.
 
 
А если написать найти список элементов, куда входит вышеописаный элемент и ещё один, то выдается ошибка java.lang.AssertionError
Вот код
List<WebElement> linkList = driver.findElements(By.xpath("//div[@id='menu']/ul/li"));
for(WebElement element: linkList){
System.out.println(element.getText());
assertTrue(element.getText().contains("tralyaya"));
}
При этом содержимое печатается! Не проходит только проверка assertTrue ((
 
Не подскажете, в чём проблема?
 

 

Видимо в том, что у вас не все элементы списка содержат "траляля". :)

ArtOfLife правильно написал, значит в этом строке нету подстроки, которую Вы ищите

вообще, в таком случае очень тяжело сказать почему оно не работает

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

Спасибо!

Да, именно так и есть. Слово "траляля" присутствует только в одном элементе. Добавил и в другой элемент - тест прошёл.

Похоже, что я неправильно понял сам механизм проверки. Получается, что assertTrue проверяет все элементы массива и если хоть в одном из них нету этого  "траляля", то тест падает. А я думал, что если хоть в одном элементе есть "траляля", то тест проходит.

А Вы можете подсказать, как тогда сделать, чтобы пройтись по массиву и вытащить из него тот самый элемент, в котором содержится "траляля"? Чтобы например потом из него вывести на экран какой-нибудь атрибут, тот же tooltip? Или сравнить "траляля" с каким-нибудь expected-значением?

В массиве  два элемента li. Этот код html  уже приводился в одном из примеров на форуме.

 

<html>
   <head></head>
<body>
   <div id="menu" class="header_menu">   
   <ul id="v_menu" class="menu">
       <li id=" " class="item">
           <a id="menu1" class="sitem_href" title=" " href="/blyablya/page/ tralyaya  " tooltip=" "> tralyaya </a>
       </li>
       <li id=" " class="item">
           <a id="menu2" class="sitem_href" title=" " href="/blyablya/page/BUM" tooltip=" "> BUM </a>
       </li>
   </ul>
   </div>
<div>
</div>
</body>
</html>

 

 

Если нужно реализовать сравнение элементов меню с их expected вариантом, то можно сделать как-то так:

 

    @Test
    public void checkMenuValues() {
        List<String> actualValues = new ArrayList<String>();
        List<String> expectedValues = dataProvider.getExpectedValues(); /* не принципиально, как получать expected values */
 
        getMainPage().
                getMenuItems(actualValues);
 
        Assert.assertEquals(
                actualValues,
                expectedValues,
                "Menu contains unexpected set of values!"
        );
    }
 
Ваш Page Object будет приблизительно таким:
 
public class MainPage extends AbstractPage {
 
    private By menuList = By.xpath("//div[@id='menu']/ul/li");
 
    public MainPage(RemoteWebDriver remoteWebDriver) {
        super(remoteWebDriver);
    }
 
    public MainPage getMenuItems(List<String> actualValues) {
        List<WebElement> linkList = findElements(menuList);
 
        for(WebElement element: linkList){
            actualValues.add(element.getText());
        }
 
        return this;
    }
}

Таким же образом можно в цикле собирать атрибуты меню айтемов:

actualValues.add(element.findElement(By.xpath("./a")).getAttribute("tooltip"));

Если ссылок больше 1, то формируем список и для каждого элемента получаем атрибут.