Search code examples
webdriverlocaleselenium-webdriver

How to change the language of a WebDriver?


I want to execute my Selenium tests in different languages. Is it possible to change the language of an existing WebDriver at runtime or do I have to recreate the browser instance?

Right now I'm only using Firefox, but I want to execute tests in different browsers at some later point.

In Firefox I set the language like this:

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("intl.accept_languages", "de");
WebDriver driver = new FirefoxDriver(profile);

I also implemented a WebDriverPool, which holds a WebDriver instance so it can be shared among tests. If the language can only be set at creation time, I could hold an instance for every locale.

All in all I wonder if I miss something here. Why is it so hard to change the language? shouldn't there be a method like WebDriver.setAcceptLanguages(Locale)?

In a nutshell I have these questions:

  1. Why isn't there WebDriver.setAcceptLanguages(Locale)?
  2. How to change the language for the dirrerent WebDrivers?
  3. Can I change the language at runtime?
  4. How did you guys implement your WebDriverPool or do you recreate them everytime?

Solution

  • I ended up creating a WebDriverPool that creates one instance for every combination of WebDriver type (e.g. FirefoxDriver.class) and Locale (e.g. en_US). Maybe this is usful for someone.

    public class WebDriverPool {
    
      private Map<String, WebDriver> drivers = new HashMap<String, WebDriver>();
      private List<WebDriver> driversInUse = new ArrayList<WebDriver>();
    
      public WebDriverPool() {
        Runtime.getRuntime().addShutdownHook(new Thread(){
          @Override
          public void run(){
            for (WebDriver driver : drivers.values())
              driver.close();
    
            if (!driversInUse.isEmpty())
              throw new IllegalStateException("There are still drivers in use, did someone forget to return it? (size: " + driversInUse.size() + ")");
          }
        });
      }
    
      private WebDriver createFirefoxDriver(Locale locale){
        FirefoxProfile profile = new FirefoxProfile();
        profile.setPreference("intl.accept_languages", formatLocale(locale));
        return new FirefoxDriver(profile);
      }
    
      private String formatLocale(Locale locale) {
        return locale.getCountry().length() == 0
          ? locale.getLanguage()
          : locale.getLanguage() + "-" + locale.getCountry().toLowerCase();
      }
    
      /**
       * @param clazz
       * @param locale
       * @return web driver which can be new or recycled
       */
      public synchronized WebDriver getWebDriver(Class<? extends WebDriver> clazz, Locale locale){
    
        String key = clazz.getName() + "-" + locale;
    
        if(!drivers.containsKey(key)){
    
          if(clazz == FirefoxDriver.class){
            drivers.put(key, createFirefoxDriver(locale));
          }
    
          // TODO create other drivers here ...
    
          // else if(clazz == ChromeDriver.class){
          //     drivers.put(key, createChromeDriver(locale));
          // }
    
          else{
            throw new IllegalArgumentException(clazz.getName() + " not supported yet!");
          }
        }
    
        WebDriver driver = drivers.get(key);
    
        if(driversInUse.contains(driver))
          throw new IllegalStateException("This driver is already in use. Did someone forgot to return it?");
    
        driversInUse.add(driver);
        return driver;
      }
    
      public synchronized void returnWebDriver(WebDriver driver){
        driversInUse.remove(driver);
      }
    }