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

Фотография

Не работает List<WebElement> из PageFactory


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

#1 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 07:28

Проблема в следующем: есть страница, в которой описан List<WebElement>:

@FindBy(xpath = "//div[@id='что-то']//img")
    public List<WebElement> linksTo;

Чтобы лист правильно отображался сделал импорт:

import java.util.List;

С другими импортами листа - не воспринимается.

 

Затем использую этот лист в тесте:

listPage.linksTo.get(1).click();

Для проверки набора листа делал следующее:

System.out.println(listPage.linksTo.size());

В последних двух случаях получаю NullPointerException!

Причем, если List использовать напрямую в тесте:

List<WebElement> linksTo = driver.findElements(By.xpath("//div[@id='что-то']//img"));
          System.out.println(linksTo.size());

то количество элементов листа счиатется.

Так же ищется нужный элемент, если вместо листа определять непосредственно каждый элемент, из которых хотим собрать лист.

Xpath для элементов листа через firepath ищутся без проблем.

 

Вопрос:

Что нужно сделать, чтобы лист заработал в тесте?

 

 


  • 0
You can't see us, we can see you.

#2 BabyRoot

BabyRoot

    Специалист

  • Members
  • PipPipPipPipPip
  • 833 сообщений


Отправлено 30 марта 2016 - 08:44

А вы инициировали элементы перед тем как к ним обращаться, раз пейджобжект используете?


  • 0

#3 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 09:07

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

Глупый вопрос: где именно их надо инициализировать?

Если на странице теста, то хватало вот этого:

List<WebElement> linksTo = driver.findElements(By.xpath("//div[@id='что-то']//img"));

а если на странице PageObject'a, то не понимаю как совместить инициализацию элемента с @FindBy?


  • 0
You can't see us, we can see you.

#4 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 09:19

Очень давно не работал с фабрикой. Такой код работает:

public class HomePage {
	
    private WebDriver driver;
    
    public HomePage(WebDriver driver) {
        PageFactory.initElements(driver, this);
        this.driver = driver;
    }
    
    
    @FindBy(id = "mainForm:userIdIt")
    private WebElement login;
    
    @FindBy(id = "mainForm:passwordIs")
    private WebElement password;
           
    @FindBy(xpath = "//div[@class='formlabel']//span[@id]")
    public List<WebElement> listErrors;

public MainPage correctLogin() throws Exception {
    	login.sendKeys(getProp("login"));
    	password.sendKeys(getProp("password"));
    	
    	btnEnter.click();
    	
    	return new MainPage(driver);
    }

Ну и сам код теста:

	@Test
	public void login() throws Exception {
		HomePage page = new  HomePage(driver);
		page.correctLogin();
		System.out.println("xx  " + homePage.msgListErrors.get(1).getText());
	}

  • 1

#5 Lzk

Lzk

    Специалист

  • Members
  • PipPipPipPipPip
  • 504 сообщений
  • ФИО:Олег
  • Город:Мск

Отправлено 30 марта 2016 - 09:20

PageFactory.initElements(driver,this)

  • 0

#6 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 09:26

PageFactory.initElements(driver,this)

Не, тогда на любом FindBy будет NPE

А тут, как я понял, проблема в том, что ТС хочет именно в тестовом методе юзать поля, помеченные FindBy.

 

А хотя м.б. ты и прав и у ТС везде будет NPE - и в тестовом методе и в классе :)


Сообщение отредактировал user12: 30 марта 2016 - 09:29

  • 0

#7 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 10:25

А тут, как я понял, проблема в том, что ТС хочет именно в тестовом методе юзать поля, помеченные FindBy.

Да, я хотел бы использовать лист c PageObject в разных ТС.

 

м.б. ты и прав и у ТС везде будет NPE - и в тестовом методе и в классе

По приведенному коду у меня NPE получились и в методе и в классе, т.е. код не сработал. :(


  • 0
You can't see us, we can see you.

#8 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 11:18

По приведенному коду у меня NPE получились и в методе и в классе, т.е. код не сработал. :(

 

 

Выкладывай код тогда. Мой пример работает


  • 0

#9 Lzk

Lzk

    Специалист

  • Members
  • PipPipPipPipPip
  • 504 сообщений
  • ФИО:Олег
  • Город:Мск

Отправлено 30 марта 2016 - 11:34

у меня тоже работает если добавить PageFactory

и выдает NPE если закомментить это.


  • 0

#10 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 12:07

Изначально было:

package com.example.pages;

import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class ListPage extends Page {
    
    @FindBy(xpath = "//div[@id='results']//img")
    public List<WebElement> linksTo;

    @FindBy(xpath = "//div[@id='results']")
    public WebElement movieForm;
    
    public boolean isOnMoviePage() {
        return movieForm.isDisplayed();
    }
}

В тесте:

@Test
   public void testEdit() throws Exception {
      goToMainPage();
      loginAs("admin", "admin");
      ListPage.linksTo.get(0).click();
}

Изменил на следующее:

package com.example.pages;

import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class ListPage extends Page {

    private WebDriver driver;
        
        public ListPage(WebDriver driver) {
            PageFactory.initElements(driver, this);
            this.driver = driver;
        }
        
            
        @FindBy(xpath = "//div[@id='results']//img")
        public List<WebElement> linksTo;

    public ListPage correct() throws Exception {
        
        linksTo.size();
            return new ListPage(driver);
        }
}

  • 0
You can't see us, we can see you.

#11 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 12:25

Где ты объявляешь драйвер, типо

driver = new FirefoxDriver();

?

 

И где в тесте у тебя :

ListPage listPage = new ListPage(driver);

?


  • 0

#12 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 13:14

package com.example.tests;

import org.junit.*;
import static org.junit.Assert.*;
import static org.openqa.selenium.support.ui.ExpectedConditions.*;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.example.pages.ListPage;

public class EditMovie {
      private WebDriver driver;
      private WebDriverWait wait;
      private String baseUrl;
      private StringBuffer verificationErrors = new StringBuffer();
      private ListPage listPage;

      @Before
      public void setUp() throws Exception {
          driver = new FirefoxDriver();
          driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
          baseUrl = "http://localhost";
          ListPage listPage = new ListPage(driver);
      }

      @Test
      public void testEdit() throws Exception {
          goToMainPage();
          loginAs("admin", "admin");
          goToMovie();
      }

      private void goToMainPage() {
            driver.get(baseUrl);
      }
      
      private void loginAs(String username, String password) {
            WebElement userNameField = wait.until(visibilityOfElementLocated(By.id("username")));
            userNameField.clear();
            userNameField.sendKeys(username);
            WebElement passwordField = wait.until(visibilityOfElementLocated(By.name("password")));
            passwordField.clear();
            passwordField.sendKeys(password);
            wait.until(visibilityOfElementLocated(By.name("submit"))).click();
      }

      private void goToMovie() throws Exception {
            listPage.correctLogin();
            System.out.println(listPage.linksTo.size());          
      }
      
      @After
      public void tearDown() throws Exception {
        String verificationErrorString = verificationErrors.toString();
        if (!"".equals(verificationErrorString)) {
          fail(verificationErrorString);
        }
      }
}


  • 0
You can't see us, we can see you.

#13 elvis

elvis

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

  • Members
  • PipPipPip
  • 189 сообщений
  • Город:Tallinn


Отправлено 30 марта 2016 - 13:23

уберите ListPage перед listPage в @Before, иначе вы создаёте локальную переменную, которую вне метода setUp не видно.


  • 0

#14 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 13:30

      private void goToMovie() throws Exception {
            listPage.correctLogin();
            System.out.println(listPage.linksTo.size());          
      }

Чтобы шарманка запустилась, надо так:

  private void goToMovie() throws Exception {
	    ListPage listPage = new ListPage(driver);
            listPage.correctLogin();
            System.out.println(listPage.linksTo.size());          
      }

  • 0

#15 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 13:31

Спасибо - заработало. :)

Работают оба варианта и от user12, и от elvis.


  • 0
You can't see us, we can see you.

#16 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 13:39

Спасибо - заработало. :)

Работают оба варианта и от user12, и от elvis.

 

Тебе обязательно нужно читать про области видимости переменных и разбирать сообщения, которые пишет IDE.

Т.е. должно было быть типо :

The value of the field listPage is not used

 


  • 0

#17 TatyanaV

TatyanaV

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

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


Отправлено 30 марта 2016 - 14:03

 

PageFactory.initElements(driver,this)

Не, тогда на любом FindBy будет NPE

 

Не будет. 

Элементы проинициализируются, но первый поиск их на странице будет только тогда, когда в рамках теста к ним будет первое обращение.

И вот тогда уже - может быть NPE, если таких элементов на странице в данный момент нет.


  • 0

#18 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 14:08

Элементы проинициализируются, но первый поиск их на странице будет только тогда, когда в рамках теста к ним будет первое обращение.

И вот тогда уже - может быть NPE, если таких элементов на странице в данный момент нет.

 

 

Ну очевидно, что если нет обращения к элементу, то не будет и NPE

 

Это очень похоже на код:

//нет ошибки     
 String s = null;
//NPE
 s.length();

  • 0

#19 Stolz

Stolz

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

  • Members
  • Pip
  • 30 сообщений
  • ФИО:Антон
  • Город:Москва

Отправлено 30 марта 2016 - 14:14

Тебе обязательно нужно читать про области видимости переменных и разбирать сообщения, которые пишет IDE.

Что-то определенное посоветуешь или инфы от гугла вполне будет достаточно?


  • 0
You can't see us, we can see you.

#20 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 30 марта 2016 - 14:28

Конечно гугла будет достаточно :)

 

Также здесь есть много тренингов по Selenium

 

http://software-testing.ru/trainings/


  • 0


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

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