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

nafvub8i  于 2023-06-29  发布在  其他
关注(0)|答案(4)|浏览(165)

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

Page对象和方法

  1. public class LoginPage extends ReusableComponents {
  2. WebDriver driver;
  3. @FindBy(xpath="//input[@name='username']")
  4. public WebElement in_username;
  5. @FindBy(xpath="//input[@name='password']")
  6. WebElement in_password;
  7. @FindBy(xpath="//button[@type='submit']")
  8. WebElement btn_submit;
  9. public LoginPage(WebDriver driver) {
  10. super(driver);
  11. this.driver = driver;
  12. PageFactory.initElements(driver, this);
  13. }
  14. public void enterUname(String uname) {
  15. in_username.sendKeys(uname);
  16. }
  17. public void enterPassword(String pass) {
  18. in_password.sendKeys(pass);
  19. }
  20. public void clickSubmit() {
  21. btn_submit.click();
  22. }
  23. }

可复用组件类

  1. public class ReusableComponents {
  2. WebDriver driver;
  3. public ReusableComponents(WebDriver driver) {
  4. this.driver = driver;
  5. }
  6. public void setup() {
  7. WebDriverManager.chromedriver().setup();
  8. driver = new ChromeDriver();
  9. driver.manage().window().maximize();
  10. driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login");
  11. }
  12. public void waitElementToAppear(WebElement findby){
  13. WebDriverWait wait = new WebDriverWait(driver, 30);
  14. wait.until(ExpectedConditions.visibilityOfElementLocated((By) findby));
  15. }
  16. public void closeBrowser() {
  17. driver.close();
  18. }
  19. }

测试类

  1. public class OpenBrowser {
  2. static WebDriver driver;
  3. public static void main(String[] args) {
  4. LoginPage login = new LoginPage(driver);
  5. ReusableComponents common = new ReusableComponents(driver);
  6. common.setup();
  7. common.waitElementToAppear(login.in_username);
  8. login.enterUname("Admin");
  9. login.enterPassword("admin123");
  10. login.clickSubmit();
  11. common.closeBrowser();
  12. }
  13. }

错误日志

  1. SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
  2. SLF4J: Defaulting to no-operation (NOP) logger implementation
  3. SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
  4. Starting ChromeDriver 114.0.5735.90 (386bc09e8f4f2e025eddae123f36f6263096ae49-refs/branch-heads/5735@{#1052}) on port 31559
  5. Only local connections are allowed.
  6. Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
  7. ChromeDriver was started successfully.
  8. Jun 29, 2023 8:43:53 AM org.openqa.selenium.remote.ProtocolHandshake createSession
  9. INFO: Detected dialect: W3C
  10. 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')
  11. at com.orange.reusablecomponents.ReusableComponents.waitElementToAppear(ReusableComponents.java:32)
  12. 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,这是不允许的。
通过对代码进行以下修改,应该可以解决异常:

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

ckx4rj1h2#

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

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

jchrr9hc3#

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

q9yhzks0

q9yhzks04#

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

  1. 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类结合使用时:

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

你面临的:

  1. 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***类中添加两个方法,如下所示:

  1. public void LoginPage()
  2. {
  3. WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(LoginPage.getUsernameElement()));
  4. email.sendKeys("TestBite");
  5. }
  6. public WebElement getUsernameElement()
  7. {
  8. return in_username;
  9. }

参考资料

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

展开查看全部

相关问题