0

我试图在我的项目中仅使用 PageFactory,而不使用 By 类型的字段。我正在寻找实现这样的东西:

@FindBy(className = "loading-container")
private WebElement loadingElement;

public LoadingPage(WebDriver driver) {
    PageFactory.initElements(driver, this);
    this.waitDriver = new WebDriverWait(this.driver, 20);
}

public void waitLoadingToFinish() {
    this.waitDriver.until(ExpectedConditions.elementNotExists(loadingElement));
}

有没有办法为此实现自定义预期条件?或任何其他方式来实现这一点?(不使用 By 字段,仅使用页面工厂)。

4

4 回答 4

1

据我了解,您认为页面上有一些元素只有在页面上没有特定元素(如等待轮)时才可以使用。

Selenium 中有一个特殊的定位器类,称为AjaxElementLocator. 您需要做的是通过isElementUsable在初始化页面时更改方法来扩展该类型,以便您在该页面上使用的所有控件首先检查条件。这是示例:

package click.webelement.pagefactory.conditions;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.AjaxElementLocator;

public class LoadablePage {

    @FindBy(id = "cntrl-id")
    WebElement control;

    public LoadablePage(WebDriver driver){
        PageFactory.initElements(field -> new AjaxElementLocator(driver, field, 10){
            @Override
            protected boolean isElementUsable(WebElement element) {
                return driver.findElements(By.xpath("//WHEEL_XPATH")).size() == 0;
            }
        }, this);
    }

}

在这里您可以找到有关这种方法的更多信息。

于 2020-09-21T11:33:38.383 回答
0

Selenium 有这个方法

ExpectedConditions.InvisibilityOfElementLocated

检查元素是否不可见或不存在于 DOM 上的期望。

对于您的代码

public void waitLoadingToFinish() {
    this.waitDriver.until(ExpectedConditions.invisibilityOfElementLocated(loadingElement));
}

另外,您可能会尝试添加一个 javascript 执行程序以等待页面加载

public static void waitForScriptsToLoad(WebDriver driver) {
    WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

然后你的页面构造函数变成这个

public LoadingPage(WebDriver driver) {
    PageFactory.initElements(driver, this);
    this.waitDriver = new WebDriverWait(this.driver, 20);
    waitForScriptsToLoad(driver);
}
于 2020-09-21T10:38:25.290 回答
0

要模拟ExpectedConditions,您elementNotExists可以使用 betweeninvisibilityOfElementLocated()invisibilityOf()


invisibilityOfElementLocated()

invisibilityOfElementLocated()是一种实现,用于检查元素是否不可见或不存在于 DOM 上。定义如下:

public static ExpectedCondition<java.lang.Boolean> invisibilityOfElementLocated(By locator)
An expectation for checking that an element is either invisible or not present on the DOM.

Parameters:
    locator - used to find the element

Returns:
    true if the element is not displayed or the element doesn't exist or stale element
  • 代码块:

      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.WebDriverWait;
    
      public class fooPage {
    
          WebDriver driver;
          public fooPage(WebDriver driver)
          {
              PageFactory.initElements(driver, this);
          }
    
          //you don't need this
          //@FindBy(className = "loading-container")
          //private WebElement loadingElement;
    
          public void foo()
          {
              Boolean bool = new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.className('loading-container')));
              //other lines of code
          }
      }
    

作为替代方案,您还可以使用以下invisibilityOf()方法:

隐形()

invisibilityOf()是检查元素是否不可见的期望的实现。定义如下:

public static ExpectedCondition<java.lang.Boolean> invisibilityOf(WebElement element)
An expectation for checking the element to be invisible

Parameters:
    element - used to check its invisibility

Returns:
    Boolean true when elements is not visible anymore
  • 代码块:

      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.WebDriverWait;
    
      public class fooPage {
    
          WebDriver driver;
          public fooPage(WebDriver driver)
          {
              PageFactory.initElements(driver, this);
          }
    
    
          @FindBy(className= 'loading-container')
          WebElement loadingElement;
    
          public void foo()
          {
              Boolean bool = new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOf(fooPage.getWebElement()));
              //other lines of code
          }
    
          public WebElement getWebElement()
          {
              return loadingElement;
          }
      }
    

您可以在如何使用 PageFactory 字段和 PageObject 模式使用显式等待中找到详细讨论

于 2020-09-21T13:57:36.757 回答
0
If you create wait method in your program that is easy and customize in selenium framework 

 private static WebElement waitForElement(By locator, int timeout)
    {
        WebElement element=new WebDriverWait(driver,timeout).until(ExpectedConditions.presenceOfElementLocated(locator));
        return element;
    }


//If you want wait for id  following code should use 

waitForElement(By.id(""),20);
Here 20 is miliseconds

你可以使用任何网页元素等待

于 2020-09-21T10:58:56.493 回答