Проблемы с инициализацией Page Factory, Java

selenium
page-factory
java
webdriver
Теги: #<Tag:0x00007fedb9a11928> #<Tag:0x00007fedb9a117c0> #<Tag:0x00007fedb9a11680> #<Tag:0x00007fedb9a114f0>

(Алексей Смиян) #1

Добрый день.
Никак не могу разобраться с инициализацией полей в классе Page. Буду очень признателен за совет.
В классе используется Page Factory, c аннотацией @FindBy. Но есть некоторые элементы, для инициализации которых я не могу использовать @FindBy, так как в их локаторе используется переменная. И мне нужно объявить эти поля на уровне класса. Пробовал несколько вариантов,итоге получаю Exception in thread "main" java.lang.ExceptionInInitializerError.

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

package Pages;

import aps.market.local.CreateTenderTest;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;

public class AddOfferPage {

    public AddOfferPage(WebDriver driver) {
        PageFactory.initElements(driver, this);
        this.driver = driver;
       }
    public WebDriver driver;
    private static String lotN1 = CreateTenderTest.lotNames.get(0);
    private String lotN2 = CreateTenderTest.lotNames.get(1);
    private String lotN3 = CreateTenderTest.lotNames.get(2);
    private String posN2 = CreateTenderTest.posNames.get(1);
    private String posN3 = CreateTenderTest.posNames.get(2);

    @FindBy(xpath = "//span[@id='labelTenderStatus']")
    public WebElement statusTender;

    @FindBy(id = "tab_view_bids")
    public WebElement switchOffer;

    @FindBy(xpath = "(//div[@class='col-md-6'])[11]/select")
    public WebElement selectFeature1Purchase;

    @FindBy(xpath = "(//div[@class='col-md-6'])[12]/select")
    public WebElement selectFeature2Purchase;

   @FindBy(id = "addBidButton")
    public WebElement buttonBidAdd;

    @FindBy(id = "addBid")
    public WebElement buttonPublishBid;

    @FindBy(id = "BidFileUpload")
    public WebElement buttonAddFileOffer;

    @FindBy(id = "btnDeleteBid_multilot")
    public WebElement buttonDeleteBidMultilot;

    public void switchOfferPage() {
        for(int i=0; i<10; i++){
            String st = statusTender.getText();
            if("Уточнення".equals(st)){
                try{
                    Thread.sleep(60000);
                    driver.navigate().refresh();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            else {
                switchOffer.click();
            }
        }
    }
   
   static WebElement buttonLot1;
   static {
       By buttonLot1 = By.xpath("//a[contains(text(), '"+lotN1+"')]");
    }

    static String idLot1;
    static {
       idLot1 = buttonLot1.getAttribute("itemid");
    }

    static WebElement fieldOfferLot1;
    static {
       By fieldOfferLot1 = By.xpath("//input[@id = 'editBid"+idLot1+"']");
    }

(Alexander Zvonov) #2

Первый раз вижу такую нетривиальную реализацию. Подразумевается что cтатические вебэлементы и локаторы By в блоках должны иметь некую связь для далтнейшей инициализации? Можно взглянуть как вы используете статические вебэлементы и как они инициализируются?


(Алексей Смиян) #4

В данный момент, из-за того, что @FindBy не принимает переменные в локаторе, приходится использовать такой способ. И так во многих методах этого класса. Пытаюсь как-то оптимизировать код. Чтобы тот же butLot1 можно было использовать во всем классе.

public AddOfferPage inputOfferLot1(String off1) {
        WebElement butLot1 = driver.findElement(By.xpath("//a[contains(text(), '"+lotN1+"')]"));
        String idLot1 = butLot1.getAttribute("itemid");
        WebElement fieldOfferLot1 = driver.findElement(By.xpath("//input[@id = 'editBid"+idLot1+"']"));
        fieldOfferLot1.sendKeys(off1);
        return this;
    }

Понимаю, что жесть. Опыт мало.


(Alexander Zvonov) #5

Убирайте эту статику. не к добру это все.

Сделайте обычные приватные поля для вебэлиментов.
Инициализируйте элементы в гетерах, подставляя что там вам надо.
Используйте String.format() для подстановки
Локаторы с переменными нужно вынести в константы

В методах пейджи обращайтесь к таким полям через гетеры


(Taras) #6

на почитайте

и вопросов не должно бить