0

I am using SpringBootTest 3.0.5, Java 17, Selenium 4.8, Junit-Jupiter 5.9.2 and trying to run tests in parallel.

My Config class is:

@Component 
public class WebDriverLibrary {
@Bean
@ConditionalOnProperty(name = "default.browser", havingValue = "chrome")
public WebDriver getDriver() {
    WebDriverManager.chromedriver().setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    return new ChromeDriver(options);
} }

My TestCase is:

@SpringBootTest
@SpringJUnitConfig(WebDriverLibrary.class)
public class AppTestCase {
    @Autowired
    public WebDriver driver;
    
    @Test
    public void testYoutube() {
        driver.get("https://www.youtube.com");
    }

    @Test
    public void testGoogle() {
        driver.get("https://www.google.com");
    }
}

The issue here is, same @Autowired instance of WebDriver is shared by two tests parallel. So only one browser session is launched and YouTube.com and google.com urls are loaded sequentially. Can anyone please let me know how to ensure a separate @Autowired WebDriver instead is created a each test (basically each thread) and ensure two separate webdriver driver sessions are launched in parallel ?

sritej_kr
  • 13
  • 3
  • have you read about prototype scope in Spring? https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-prototype Apart from this, is there something blocking you to instantiate it manually on your test? – Carlos Apr 04 '23 at 01:00
  • Thanks for response. Actually my project has obligation to launch using SpringBoot @Autowired feature only. – sritej_kr Apr 04 '23 at 08:43

1 Answers1

0

I would suggest you read up more on Spring boot SimpletThreadscope but the way you can do it is like below SimeplThreadScope

Create a WebdriverScope Class which will act like a threadlocal which you use to store Webdriver instances during parallel execution i.e. one driver per Thread so that you only access the driver that is created for the thread in which test is created

public class WebdriverScope extends SimpleThreadScope {
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        Object o = super.get(name, objectFactory);
        SessionId sessionId = ((RemoteWebDriver)o).getSessionId();
        if(Objects.isNull(sessionId)){
            super.remove(name);
            o = super.get(name, objectFactory);
        }
        return o;
    }
    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
    }
}

Create a configuration class, and it creates the WebdriverScopePostProcessor bean

@Configuration
public class WebdriverScopeConfig {
    @Bean
    public static BeanFactoryPostProcessor beanFactoryPostProcessor(){
        return new WebdriverScopePostProcessor();
    }
}

Then create and `WebdriverScopePostProcessor

public class WebdriverScopePostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerScope("webdriverscope", new WebdriverScope());
    }
}`

Then create a Configuration class for your webdriver instances like below

@Configuration
public class DriverConfig {

    @WebdriverScopeBean
    public WebDriver chromeDriver() {
        System.setProperty("webdriver.chrome.driver", "path");
        return new ChromeDriver();
    }
}

Now when you do

 @Autowired
 WebDriver driver;

you should get a Unique instance per thread

Abhay Chaudhary
  • 1,763
  • 1
  • 8
  • 13