等待直到元素不存在,使用PageFactory。

huangapple go评论79阅读模式
英文:

Wait until element doesn't exists using PageFactory

问题

我试图在我的项目中仅使用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字段,仅使用PageFactory)。

英文:

I'm trying to use only PageFactory in my project, without using fields with type By. And I'm looking to implement something like this:

@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));
}

Is there a way to implemet custom Expected Condition for this? or any other way to implement this? (without using By fields, only using page factory).

答案1

得分: 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);
    }

}

您可以在此处找到更多关于这种方法的信息。

英文:

As far as I understand you have some elements on the page that you consider ready for usage only when there is no certain element on the page (like waiting wheel).

There is a special locator class in Selenium called AjaxElementLocator. What you need to do is to extend that type by changing isElementUsable method when you initialize your page so that all the controls you use on that page would first check the condition. Here is the example:

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);
    }

}

Here you can find more information on such approach.

答案2

得分: 0

Selenium有这个方法

ExpectedConditions.InvisibilityOfElementLocated

用于检查元素是不可见的还是不在DOM中存在的期望。

对于你的代码

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

此外,你可以尝试添加一个JavaScript执行器,以等待页面加载完成

public static void waitForScriptsToLoad(WebDriver driver) {
    new 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);
}
英文:

Selenium has this method

> ExpectedConditions.InvisibilityOfElementLocated
>
> An expectation for checking that an element is either invisible or not
> present on the DOM.

For your code

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

also, you might try to add a javascript executor to wait until the page is loaded

public static void waitForScriptsToLoad(WebDriver driver) {
    WebDriverWait(driver, 30).until((ExpectedCondition&lt;Boolean&gt;) wd -&gt;
            ((JavascriptExecutor) wd).executeScript(&quot;return document.readyState&quot;).equals(&quot;complete&quot;));
}

and then your page constructor becomes this

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

答案3

得分: 0

如果在您的程序中创建等待方法,在Selenium框架中这很容易且可自定义。

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

如果您想要等待ID,应使用以下代码:

waitForElement(By.id(""), 20);
这里的20是毫秒您可以使用任何网络元素进行等待
英文:
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(&quot;&quot;),20);
Here 20 is miliseconds

and you can use any web elements to wait

答案4

得分: 0

要模拟类似于 elementNotExistsExpectedConditions,你可以使用 invisibilityOfElementLocated()invisibilityOf() 之一。


invisibilityOfElementLocated()

invisibilityOfElementLocated() 是用于检查元素是否不可见或不在DOM中的期望的实现。它定义如下:

public static ExpectedCondition<Boolean> invisibilityOfElementLocated(By locator)

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

参数:

  • locator - 用于查找元素的定位器

返回:

  • 如果元素未显示或元素不存在或元素已过期,则返回 true。

  • 代码块:

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);
    }

    public void foo()
    {
        Boolean bool = new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.className('loading-container')));
        //其他代码行
    }
}

作为替代,你也可以使用 invisibilityOf() 方法,如下所示:

invisibilityOf()

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

public static ExpectedCondition<Boolean> invisibilityOf(WebElement element)

检查元素是否不可见的期望。

参数:

  • element - 用于检查其不可见性的元素

返回:

  • 当元素不再可见时返回 true。

  • 代码块:

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()));
        //其他代码行
    }
    
    public WebElement getWebElement()
    {
        return loadingElement;
    }
}

你可以在 How to use explicit waits with PageFactory fields and the PageObject pattern 中找到详细讨论。

英文:

To simulate an ExpectedConditions like elementNotExists you can use either among invisibilityOfElementLocated() or invisibilityOf().


invisibilityOfElementLocated()

invisibilityOfElementLocated() is the implementation for an expectation for checking that an element is either invisible or not present on the DOM. It is defined as follows:

public static ExpectedCondition&lt;java.lang.Boolean&gt; 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&#39;t exist or stale element
  • Code Block:

      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&#39;t need this
      	//@FindBy(className = &quot;loading-container&quot;)
      	//private WebElement loadingElement;
    
      	public void foo()
      	{
      		Boolean bool = new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.className(&#39;loading-container&#39;)));
      		//other lines of code
      	}
      }
    

As an alternative you can also use the invisibilityOf() method as follows:

invisibilityOf()

invisibilityOf() is the implementation for an expectation for checking the element to be invisible. It is defined as follows:

public static ExpectedCondition&lt;java.lang.Boolean&gt; 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
  • Code Block:

      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= &#39;loading-container&#39;)
      	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;
      	}
      }
    

>You can find a detailed discussion in How to use explicit waits with PageFactory fields and the PageObject pattern

huangapple
  • 本文由 发表于 2020年9月21日 18:16:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63990292.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定