0

I have been working on this automation project for 2 years and now I am trying to implement parallel testing with ThreadLocal. I have done a lot of research on this and I have implemented ThreadLocal driver = new ThreadLocal<>(); in my BaseTestClass. My problem is I am using the page object model where each page is a class with objects. Eclipse is saying change constructor to

public LoginLogoutPage(ThreadLocal<WebDriver> driver) {
        this.driver = driver;
}

I do that then I am prompted to change WebDriver driver; to ThreadLocal driver. After I do that all my fluent wait have a red line under them saying

"The constructor FluentWait<WebDriver>(ThreadLocal<WebDriver>) is undefined"

However I do not know how to fix this. Here is a snippet below.

public class BaseTestCriticalScenarios {
protected static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
@BeforeClass
public void setUp() throws InterruptedException, MalformedURLException {
    // --------Extent Report--------
    report = ExtentManager.getInstance();
    // -----------------------------
    System.setProperty("webdriver.chrome.driver", "C:\\GRID\\chromedriver.exe");
    ChromeOptions option = new ChromeOptions();
    // --https://stackoverflow.com/questions/43143014/chrome-is-being-controlled-by-automated-test-software
    option.setExperimentalOption("useAutomationExtension", false);
    option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
    // --https://stackoverflow.com/questions/56311000/how-can-i-disable-save-password-popup-in-selenium
    option.addArguments("--disable-features=VizDisplayCompositor");
    option.addArguments("--start-maximized");
    option.addArguments("--disable-gpu");
    Map<String, Object> prefs = new HashMap<String, Object>();
    prefs.put("credentials_enable_service", false);
    prefs.put("profile.password_manager_enabled", false);
    option.setExperimentalOption("prefs", prefs);
    System.out.println(System.getenv("BUILD_NUMBER"));
    String env = System.getProperty("BUILD_NUMBER");
    
    if (env == null) {
        DesiredCapabilities capability = DesiredCapabilities.chrome();
        capability.setCapability(CapabilityType.BROWSER_NAME, "Chrome");
        capability.setCapability(ChromeOptions.CAPABILITY, option);
        option.merge(capability);
        
        driver.set(new RemoteWebDriver(new URL(COMPLETE_NODE_URL), capability));
        getDriver().get(HOME_PAGE);
        getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    } else {
        driver.set(new ChromeDriver(option));
        getDriver().manage().window().maximize();
        getDriver().get(HOME_PAGE);
        getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }
}

public WebDriver getDriver() {
    //Get driver from ThreadLocalMap
    return driver.get();
}

Below is my page object class

enter image description here

Any help would be appreciated.

Jonathan
  • 395
  • 2
  • 8
  • 25
  • why not initialize a new driver for each class/thread? No need to use threadlocal. (I haven't used threadlocal before so maybe there's an advantage there I'm not seeing.) For instance I use a class that extends a SwingWorker. It initializes the driver and runs all tasks... you can then create as many of those as you want and call .execute to run... which calls overridden doInBackground() method(initialize driver, run tasks).. and then quits the driver instance in done() method. – pcalkins May 27 '21 at 21:55
  • btw, you should avoid mixing implicit and explicit waits. (two polling loops can/will conflict with each other... just use a webdriverwait... it's a pre-configured fluentwait.) – pcalkins May 27 '21 at 22:14
  • @pcalkins thanks for your reply can you give me an example of initializing a new driver for each class? – Jonathan May 27 '21 at 23:27
  • @pcalkins My goal is to have 2 instances of chrome driver going at one time with to different test cases my test.xml file is setup this way the problem is that the driver is not executing the test within it corresponding instance. one instance of chrome invokes and the other runs. – Jonathan May 27 '21 at 23:28
  • include your main method in your post... (or whatever starts the whole "test"... that's where you'll want to create the 2 threads/instances of the main class) – pcalkins May 28 '21 at 16:09
  • You can just have that class implement "runnable" methinks. Then move all the method calls into "run" method. ( https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html )Something like this: YourMainClass thisThread = new YourMainClaass(); thisThread.run(); YourMainClass thisThread2 = new YourMainClass(); thisThread2.run(); – pcalkins May 28 '21 at 16:46
  • You can use `Wait wait=new FluentWait(driver.get())...` and `driver.get().findElement(...)`. Its use of ThreadLocal variable. – a Learner Feb 04 '22 at 18:43

0 Answers0