如何在单独的 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中的驱动程序。您可以在下面阅读
我正在尝试创建一个新的 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中的驱动程序。您可以在下面阅读