selenium 我得到一个错误,而悬停在对象,因此自动化脚本是失败的

nafvub8i  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(114)

我为登录页面编写了一个简单的基于Selenium的自动化脚本。但是我有一个单独的用于页面对象和方法的类,另一个用于可重用组件的类,然后是测试类。

Page对象和方法

public class LoginPage extends ReusableComponents {
    WebDriver driver;
    
    @FindBy(xpath="//input[@name='username']")
    public WebElement in_username;
    
    @FindBy(xpath="//input[@name='password']")
    WebElement in_password;
    
    @FindBy(xpath="//button[@type='submit']")
    WebElement btn_submit;
    
    public LoginPage(WebDriver driver) {
        super(driver);
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }
    
    public void enterUname(String uname)  {
        in_username.sendKeys(uname);
    }
    
    public void enterPassword(String pass) {
        in_password.sendKeys(pass);
    }
    
    public void clickSubmit() {
        btn_submit.click();
    }   
}

可复用组件类

public class ReusableComponents {
    
    WebDriver driver;

    public ReusableComponents(WebDriver driver) {
        this.driver = driver;
    }
    
    public void setup()  {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login");
    }

    public void waitElementToAppear(WebElement findby){
        
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(ExpectedConditions.visibilityOfElementLocated((By) findby));
                
    }
    
    public void closeBrowser() {
        driver.close();
    }   
}

测试类

public class OpenBrowser {
    static WebDriver driver;

    public static void main(String[] args) {
        
        LoginPage login = new LoginPage(driver);
        ReusableComponents common = new ReusableComponents(driver);
        common.setup();
        common.waitElementToAppear(login.in_username);
        login.enterUname("Admin");
        login.enterPassword("admin123");
        login.clickSubmit();
        common.closeBrowser();
        
    }
}

错误日志

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Starting ChromeDriver 114.0.5735.90 (386bc09e8f4f2e025eddae123f36f6263096ae49-refs/branch-heads/5735@{#1052}) on port 31559
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
Jun 29, 2023 8:43:53 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Exception in thread "main" java.lang.ClassCastException: class jdk.proxy2.$Proxy4 cannot be cast to class org.openqa.selenium.By (jdk.proxy2.$Proxy4 is in module jdk.proxy2 of loader 'app'; org.openqa.selenium.By is in unnamed module of loader 'app')
    at com.orange.reusablecomponents.ReusableComponents.waitElementToAppear(ReusableComponents.java:32)
    at com.orangehrm.OpenBrowser.main(OpenBrowser.java:27)
  • 当我在调试模式下将鼠标悬停在测试中的“in_username”对象上时,它会给我一个错误,因为我已经附加在这里。有人能帮我解决这个问题吗?* Screenshot of the error

我尝试创建一个webelement对象,但没有; I don’我帮不上忙。

4xy9mtcn

4xy9mtcn1#

在您的情况下,当您尝试将类型为jdk.proxy2.$Proxy4的对象强制转换为org.openqa.selenium.By时会出现问题,这不是有效的强制转换操作。
使用PageFactory时,它会为使用@FindBy注解的变量创建代理。InvocationHandler管理诸如搜索元素之类的任务。例如,当使用driver.findElements()时,它与代理交互,然后代理调用实际的方法。这就是为什么类被表示为类jdk.proxy2.$Proxy的原因。
在您的特定情况下,您实际上是试图将org.openqa.selenium.remote.RemoteWebElement类型的代理对象强制转换为org.openqa.selenium.By,这是不允许的。
通过对代码进行以下修改,应该可以解决异常:

wait.until(ExpectedConditions.visibilityOf(webelement));
ckx4rj1h

ckx4rj1h2#

请看下面的代码,它为我工作。只需要在启动Web URL后添加等待即可。

// TODO Auto-generated method stub
    WebDriverManager.chromedriver().setup();
    WebDriver driver = new ChromeDriver();
    driver.manage().window().maximize();        
    driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login");
    Thread.sleep(3000);
    driver.findElement(By.name("username")).sendKeys("Admin");
    driver.findElement(By.name("password")).sendKeys("admin123");
    driver.findElement(By.xpath("//button[@type='submit']")).click();
jchrr9hc

jchrr9hc3#

您可以在页面对象初始化代码中添加一个默认的等待时间,而不是显式地等待元素
//根据需要设置超时值(秒)PageFactory.initElements(new AjaxElementLocatorFactory(driver,10),this);

q9yhzks0

q9yhzks04#

在您使用的 *Page对象和方法 * 类中:

PageFactory.initElements(driver, this);

根据Class PageFactory的文档:

  • initElements​(SearchContext searchContext, java.lang.Class<T> pageClassToProxy):此方法示例化给定类的示例,并为已声明的每个WebElementList<WebElement>字段设置一个惰性代理,假设字段名称也是HTML元素的“id”或“name”。此方法返回类的示例化示例,并代理了WebElementList<WebElement>字段。

下面是@FindBys

  • @FindBy(xpath="//input[@name='username']") public WebElement in_username;
  • @FindBy(xpath="//input[@name='password']") WebElement in_password;
  • @FindBy(xpath="//button[@type='submit']") WebElement btn_submit;

是代理的字段。当你尝试将它们与By类结合使用时:

wait.until(ExpectedConditions.visibilityOfElementLocated((By) findby));

你面临的:

Exception in thread "main" java.lang.ClassCastException: class jdk.proxy2.$Proxy4 cannot be cast to class org.openqa.selenium.By (jdk.proxy2.$Proxy4 is in module jdk.proxy2 of loader 'app'; org.openqa.selenium.By is in unnamed module of loader 'app')

解决方案

若要等待 in_username 字段可见并发送字符序列,可以在***LoginPage***类中添加两个方法,如下所示:

public void LoginPage()
{
    WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(LoginPage.getUsernameElement()));
    email.sendKeys("TestBite");
}

public WebElement getUsernameElement()
{
    return in_username;
}

参考资料

您可以在以下内容中找到一些相关的详细讨论:

相关问题