title: Use non-static WebDriver for parallel execution - Selenium - TestNG - Java
body: <p>Is this the correct way to initialize a ThreadLocal RemoteWebDriver?</p>
  
  <p>I have seen posts where people say that you should not have a static WebDriver, however, if I remove the static modifier, I end up with NULL pointer exception.</p>
  
  <p>Everything is running fine for the most part, but I am encountering a problem where one thread will occasionally enter data in a different thread. I'm trying to troubleshoot that issue which lead me to this.</p>
  
  <p><strong>TestSetup class:</strong></p>
  
  <pre><code>public class TestSetup {
  
      private static ThreadLocal&lt;RemoteWebDriver&gt; threadDriver;// = new ThreadLocal&lt;RemoteWebDriver&gt;();
  
      @Parameters({"browserParam"})
      @BeforeClass(alwaysRun = true)
      public void beforeClass(@Optional("") final String browserParam) throws InterruptedException, MalformedURLException {
  
          // Set Driver
          threadDriver = new ThreadLocal&lt;RemoteWebDriver&gt;()
          {
  
              @Override
              protected RemoteWebDriver initialValue()
              {
  
                  String browser = "Chrome";
                  DesiredCapabilities dc = new DesiredCapabilities();
  
                  if (browser.equals("Chrome"))
                  {
  
                      String chromeDriver = "C:\\workspace\\drivers\\chromedriver.exe";
                      System.setProperty("webdriver.chrome.driver", chromeDriver);
  
                      // Access Grid Hub
                      dc.setBrowserName(DesiredCapabilities.chrome().getBrowserName());
  
                  } // end Chrome
  
                  // Set the driver
                  try {
                      threadDriver.set(new RemoteWebDriver(new URL(hubURL), dc));
                  } catch (MalformedURLException e) {
                      e.printStackTrace();
                  }
  
                  return getDriver();
  
              } // end initialValue
  
          } // end threadDriver
  
      } // end beforeClass
  
  
  
      @AfterClass(alwaysRun = true)
      public void afterClass() {
  
          // Quit the Webdriver
          getDriver().quit();
  
      } // end afterClass
  
  
  
      public RemoteWebDriver getDriver() {
  
          return threadDriver.get();
  
      } // end getDriver
  
  } // end TestSetup class
  </code></pre>
  
  <p><strong>LoginTest class:</strong></p>
  
  <pre><code>private Function perform = new Function();
  
  @Test (retryAnalyzer = Retry.class, groups={"baseline", "negative"})
  public synchronized void loginEmptyUsername() throws InterruptedException {
  
  ExtentTest test = ExtentTestManager.getTest();
  
  // Go to Secure
  getDriver().get(StoredVariables.getsecureSite().get());
  
  // Wait for password
  perform.waitForElementToBeClickable(SLogin.password_txtbx(), "id");
  
  // Clear email field
  SLogin.email_txtbx(getDriver()).clear();
  
  // enter password
  SLogin.password_txtbx(getDriver()).clear();
  SLogin.password_txtbx(getDriver()).sendKeys(StoredVariables.getpassword().get());
  
  // click Sign In
  SLogin.signIn_btn(getDriver()).click();
  
  // Wait for error
  perform.waitForElementToBeClickable(SLogin.loginError_txt(), "id");
  
  // Verify error text
  Assert.assertTrue(SLogin.loginError_txt(getDriver()).getText().contains("Oops! Your email or password (case sensitive) was incorrect. Please try again."));
  
  // Log test
  test.log(LogStatus.INFO, "login", "Tried logging in with an empty email");
  
  } // end loginEmptyUsername
  </code></pre>
  
  <p>How would I pass the WebDriver to the test class if it is not static in the TestSetup class?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>It appears that using my initial implementation but restricting the Node to only allow 3 instances as opposed to utilizing the max of 5 instances has resolved my issue (at least for the moment).</p>