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

Viewed 521

I am trying to create a new class that will contain all variables to be used for our Selenium tests. Below are the classes :

Class: variablesRepo:

 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();
  }

}

When I try to run the tests, the browser opens, and the page also opens, so the script is able to retrieve the variables from the veriableRepo. But when it comes to the web elements, the script fails. It looks like it is trying to locate the webelements inside the Repo file. I am getting the following error:

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

How can we resolve this issue and import the variables from the Repo class?

Update: The errorstack that I am getting is :

[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$1.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

1 Answers

The actual issue is happening in your variablesRepo class. See below at bottom of your error log

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

The reason you are getting this issue, because two threads are created for driver once at line WebDriver Driver = variablesRepo.driver; in NewTest class and another one when you used driver to find login button in variablesRepo class. That's why when you are trying to find login button directly into NewTest it is successful as same thread you have used to open the url in @BeforeSuite method.

If you want to initialize your driver only once and use into all other classes then use a BaseTest sort of class and implement get_driver kind of method to initialize your driver. And use this method to get the driver in all test classes. You can read below for How can I initialize web driver globally?

Related