如何在单独的 class of Java 中存储和检索 WebElements - Selenium

How to store and retrieve WebElements in a separate class of Java - Selenium

我正在尝试创建一个新的 class,它将包含用于我们的 Selenium 测试的所有变量。以下是 classes :

Class:变量回购:

 package src;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class variablesRepo {
    
//  public static final WebElement ChkBox = null;
    static WebDriver driver = new ChromeDriver();
    static WebElement LoginButton = driver.findElement(By.id("btnLogin"));

}

Class NewTest.Java:

    package src;


import org.testng.annotations.Test;
import org.testng.annotations.BeforeSuite;

import static org.testng.Assert.assertEquals;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.annotations.AfterSuite;

public class NewTest {
    
    WebDriver Driver = variablesRepo.driver;
    
  
  @Test
  public void TestElement() {
      WebElement LoginButton = variablesRepo.LoginButton;
      assert LoginButton.isDisplayed();
      
  }
  
  @BeforeSuite
  public void beforeSuite() {
      Driver.get("https://opensource-demo.orangehrmlive.com/");
      
      
  }

  @AfterSuite
  public void afterSuite() {
      Driver.close();
  }

}

当我尝试 运行 测试时,浏览器打开,页面也打开,因此脚本能够从 veriableRepo 中检索变量。但是当涉及到网络元素时,脚本就失败了。看起来它正在尝试在 Repo 文件中找到网络元素。我收到以下错误:

Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#btnLogin"}

我们如何解决这个问题并从 Repo 中导入变量 class?

更新:我得到的错误堆栈是:

[RemoteTestNG] detected TestNG version 7.3.0 Starting ChromeDriver 85.0.4183.87 (cd6713ebf92fa1cacc0f1a598df280093af0c5d7-refs/branch-heads/4183@{#1689}) on port 25606 Only local connections are allowed. Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe. ChromeDriver was started successfully. Sep 02, 2020 11:13:42 AM org.openqa.selenium.remote.ProtocolHandshake createSession INFO: Detected dialect: W3C org.testng.TestNGException: Cannot instantiate class src.NewTest at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:30) at org.testng.internal.InstanceCreator.instantiateUsingDefaultConstructor(InstanceCreator.java:193) at org.testng.internal.InstanceCreator.createInstanceUsingObjectFactory(InstanceCreator.java:113) at org.testng.internal.InstanceCreator.createInstance(InstanceCreator.java:79) at org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:109) at org.testng.internal.ClassImpl.getInstances(ClassImpl.java:167) at org.testng.TestClass.getInstances(TestClass.java:102) at org.testng.TestClass.initTestClassesAndInstances(TestClass.java:82) at org.testng.TestClass.init(TestClass.java:74) at org.testng.TestClass.(TestClass.java:39) at org.testng.TestRunner.initMethods(TestRunner.java:457) at org.testng.TestRunner.init(TestRunner.java:336) at org.testng.TestRunner.init(TestRunner.java:289) at org.testng.TestRunner.(TestRunner.java:220) at org.testng.remote.support.RemoteTestNG6_12.newTestRunner(RemoteTestNG6_12.java:33) at org.testng.remote.support.RemoteTestNG6_12$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG6_12.java:66) at org.testng.ITestRunnerFactory.newTestRunner(ITestRunnerFactory.java:55) at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:676) at org.testng.SuiteRunner.init(SuiteRunner.java:178) at org.testng.SuiteRunner.(SuiteRunner.java:112) at org.testng.TestNG.createSuiteRunner(TestNG.java:1306) at org.testng.TestNG.createSuiteRunners(TestNG.java:1282) at org.testng.TestNG.runSuitesLocally(TestNG.java:1131) at org.testng.TestNG.runSuites(TestNG.java:1069) at org.testng.TestNG.run(TestNG.java:1037) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:23) ... 27 more Caused by: java.lang.ExceptionInInitializerError at src.NewTest.(NewTest.java:13) ... 32 more Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#btnLogin"}
(Session info: chrome=85.0.4183.83) For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:48' System info: host: 'DML-02213', ip: '10.9.9.5', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_261' Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 85.0.4183.83, chrome: {chromedriverVersion: 85.0.4183.87 (cd6713ebf92fa..., userDataDir: C:\Users\nhassan\AppData\Lo...}, goog:chromeOptions: {debuggerAddress: localhost:62831}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true} Session ID: 6793977a08f3b6eefb43d17e34597557 *** Element info: {Using=id, value=btnLogin} at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:323) at org.openqa.selenium.remote.RemoteWebDriver.findElementById(RemoteWebDriver.java:372) at org.openqa.selenium.By$ById.findElement(By.java:188) at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315) at src.variablesRepo.(variablesRepo.java:12) ... 33 more

实际问题发生在您的 variablesRepo class 中。请参阅错误日志底部的下方

at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315) at src.variablesRepo.(variablesRepo.java:12)

您遇到此问题的原因是,在 NewTest class 中的 WebDriver Driver = variablesRepo.driver; 行为驱动程序创建了两个线程,而另一个线程是在您使用驱动程序查找登录按钮时创建的在 variablesRepo class 中。这就是为什么当您尝试直接在 NewTest 中查找登录按钮时,它与您在 @BeforeSuite 方法中用于打开 url 的同一线程一样成功。

如果您只想初始化您的驱动程序一次并用于所有其他 classes 则使用 BaseTest 类型的 class 并实施 get_driver 类型的方法来初始化您的驱动程序.并使用此方法获取所有测试classes中的驱动程序。您可以在下面阅读