Java 将WebElement作为参数传递给隐式等待方法

Java 将WebElement作为参数传递给隐式等待方法,java,selenium,selenium-webdriver,pageobjects,page-factory,Java,Selenium,Selenium Webdriver,Pageobjects,Page Factory,为了重用隐式等待,我在Page.class中编写了以下方法 public WebDriver waitForElementToLoad(WebElement element) { WebDriverWait wait = new WebDriverWait(driver, 60); wait.until(ExpectedConditions.presenceOfElementLocated((By) element)); return (drive

为了重用隐式等待,我在Page.class中编写了以下方法

public WebDriver waitForElementToLoad(WebElement element)
{
        WebDriverWait wait = new WebDriverWait(driver, 60);
        wait.until(ExpectedConditions.presenceOfElementLocated((By) element));
        return (driver);
}
在我的test.class中,我使用了页面工厂元素,例如:

//Save button
@FindBy(xpath = "//*[@*='Save']")
private WebElement saveButton;
现在我想打电话:
waitForElementToLoad(保存按钮)
从测试。类,但我得到下面的错误

“java.lang.ClassCastException:class com.sun.proxy.$Proxy12不能为空。” 转换到类org.openqa.selenium.By(com.sun.proxy.$Proxy12和 org.openqa.selenium.By位于加载器“app”的未命名模块中。“

我也试过了

WebElement saveButton = driver.findElement(By.xpath("//*[@*='Save']"));
waitForElementToLoad(saveButton);
但是没有运气


我怎样才能做到这一点呢?

WebDriverWait
是显式等待,而不是隐式等待。您不能将
WebElement
转换为
By

如果
saveButton
不是
null
而页面工厂已经找到了它,那么等待它的出现是毫无意义的,这就是为什么
WebElement
没有过载的原因。而是等待可见性

wait.until(ExpectedConditions.visibilityOf(element));

如果需要将
ExpectedConditions
用于包含异步加载元素的“Page”类,我建议使用以下方法:

  • 扩展AjaxElementLocator
  • 其中override
    受保护的布尔值IsElementAvailable(WebElement元素)
    ,以便它使用
    ExpectedConditions
    来确定元素是否可以使用
  • 扩展
    AjaxElementLocatorFactory
    where override
    public ElementLocator createLocator(Field-Field)
    方法,以便它现在返回扩展类的实例
  • 初始化元素时使用
    PageFactory.initElements(新的MyAjaxElementLocatorFactory(驱动程序,10),这是)其中
    MyAjaxElementLocatorFactory
    是您在步骤2中创建的类
  • 此错误消息

    java.lang.ClassCastException: class com.sun.proxy.$Proxy12 cannot be cast to class org.openqa.selenium.By (com.sun.proxy.$Proxy12 and org.openqa.selenium.By are in unnamed module of loader 'app')
    
    …表示尝试强制转换代理时发生ClassCastException

    你需要考虑以下几点:

    package com.pol.zoho.PageObjects;
    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.WebDriverWait;
    
    public class ZohoLoginPage {
    
        WebDriver driver;
        public ZohoLoginPage(WebDriver driver)
        {
        PageFactory.initElements(driver, this);
        }
    
        //Save button
        @FindBy(xpath = "//*[@*='Save']")
        private WebElement saveButton;
    
        public void waitForElementToLoad()
        {
        WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(ZohoLoginPage.getWebElement()));
        saveButton.click();
        }
    
        public WebElement getWebElement()
        {
        return saveButton;
        }
    
    }
    
    • 您在
      waitForElementToLoad()
      中引入的等待不是这样的,而是一种等待。见:
    • presenceOfElementLocated()
      不会夸耀任何元素的可见性或可交互性。因此,对于可见性或可交互性,您需要使用匹配的预期条件
      visibilityOf(WebElement元素)
      element to eclickable(By locator)
      。有关详细信息,请参阅:
    • 如果您的用例涉及诱导WebDriverWait,则在
      waitForElementToLoad()
      中以代理对象的形式传递WebElementsaveButton,如下所示:

      package com.pol.zoho.PageObjects;
      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.WebDriverWait;
      
      public class ZohoLoginPage {
      
          WebDriver driver;
          public ZohoLoginPage(WebDriver driver)
          {
          PageFactory.initElements(driver, this);
          }
      
          //Save button
          @FindBy(xpath = "//*[@*='Save']")
          private WebElement saveButton;
      
          public void waitForElementToLoad()
          {
          WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(ZohoLoginPage.getWebElement()));
          saveButton.click();
          }
      
          public WebElement getWebElement()
          {
          return saveButton;
          }
      
      }
      

    参考 您可以在以下内容中找到一些相关讨论:


    这很有效,谢谢。现在,如果我有一个动态xpath,比如:driver.findElement(By.xpath(//a[@class='profile-link-label'和text()='“+userName+”)[1]”);我想把它作为参数传递给同一个方法。我该怎么做?@user194258您需要发送返回的
    WebElement
    ,或者构建一个新方法,用
    ExpectedConditions.visibilityOfElementLocated(By.xpath(//a[@class='profile-link-label'and text()='+userName+'][1])
    为通过接收的新方法,如果不是WebElement,那么数据类型是什么?另外,当我发送参数时,是否应该发送driver.findElement(By.xpath(//a[@class='profile-link-label'和text()='“+userName+”)[1]”);或者只(//a[@class='profile-link-label'和text()='“+userName+”)[1]”?@user194258通过
    发送,
    通过.xpath(“…”)