2012-03-22 5 views
19

Я хочу выполнить свои тесты Селена на разных языках. Можно ли изменить язык существующего WebDriver во время выполнения или мне нужно воссоздать экземпляр браузера?Как изменить язык WebDriver?

Сейчас я использую только Firefox, но я хочу выполнить тесты в разных браузерах позже.

В Firefox я установить язык так:

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

Я также внедрил WebDriverPool, который содержит экземпляр WebDriver, так что может быть поделены тестами. Если язык можно установить только во время создания, я мог бы хранить экземпляр для каждого языкового стандарта.

В целом, я задаюсь вопросом, пропустил ли я что-то здесь. Почему так сложно изменить язык? не должен быть такой метод, как WebDriver.setAcceptLanguages(Locale)?

В двух словах я эти вопросы:

  1. Почему нет WebDriver.setAcceptLanguages(Locale)?
  2. Как изменить язык для dirrerent WebDrivers?
  3. Могу ли я изменить язык во время выполнения?
  4. Как вы, ребята, внедряете свой WebDriverPool или каждый раз их воссоздаете?
+2

Я могу думать о нескольких сценариях: Проверьте дату и номер форматирование и ввод для различных локалей, делать скриншоты на разных языках, может показать некоторый намек, если кто-то с неподдерживаемым языком идет вперед и так далее. Я бы сказал, если ваш webapp поддерживает несколько языков, которые тестируют его в нескольких, может иметь смысл для некоторых тестовых примеров, верно? –

ответ

13

В результате я создал WebDriverPool, который создает один экземпляр для каждой комбинации типа WebDriver (например, FirefoxDriver.class) и Locale (например, en_US). Возможно, это полезно для кого-то.

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); 
    } 
} 
+0

Мне нравится этот класс, но я не понимаю, почему вы оцениваете, какой WebDriver используется ... Могу ли я объяснить ваше объяснение? –

+0

@Frank: Ваш вопрос в том, почему Class <> clazz является параметром метода getWebDriver? Это связано с тем, что вызывающий тестовый класс может решить, какой драйвер должен быть создан. Нам это нужно, потому что есть тесты только для InternetExplorer, этот ActiveX используется. –

+0

Нет. Я не понимаю, почему вы регистрируетесь, если используется драйвер (частный список driversInUse) ... это просто для их правильного закрытия? –

-1

Я боюсь, что вся идея WebDriver является действовать как браузер - так что вы можете изменить язык браузера, но вы должны изменить локаль в операционной системе, или надеяться, что применение сделают это за вас.

Например, немецкий формат чисел разделяет десятичное число на запятую и на английском по одной точке. Если вы хотите проверить, как формат номер ведет на английском локал и в немецкой локализации, вы можете сделать это только эти двух подходов:

  1. Изменить ОСА локали с немецкого на английский или наоборот
  2. Изменить браузер языка и надеемся, что приложение изменит поведение.

Чтобы ответить на ваши вопросы:

  1. Там нет Setlocale на WebDriver, потому что WebDriver имитирует браузер, а не OS
  2. Я бы сделать это так (Java кода):

    private WebDriver driver; 
    
    public enum Language {en-us, de} 
    
    public WebDriver getDriver(Language lang){ 
        String locale = lang.toString(); 
        FirefoxProfile profile = new FirefoxProfile(); 
        profile.setPreference("intl.accept_languages", locale); 
        driver = new FirefoxDriver(profile); 
        return driver;  
    } 
    
    @Test 
    public void TestNumber(){ 
        WebDriver drv = getDriver(Language.en); 
        drv.get("http://the-site.com"); 
        WebElement el = drv.findElement //... find element 
        String number = el.getText(); 
        Assert.assertEquals(number, "123.45"); 
        drv.close(); 
        drv = getDriver(Language.de); 
        drv.get("http://the-site.com"); 
        WebElement el = drv.findElement //... find element 
        String number = el.getText(); 
        Assert.assertEquals(number, "123,45"); 
        drv.close(); 
    } 
    
  3. Боюсь, что вам нужно закрыть браузер и открыть его на другом языке.

  4. Я лично создаю новый экземпляр браузера для каждого теста.

BTW вышеупомянутый бит кода предполагает, что веб-приложение изменяет способ отображения номеров пользователю на основе языка браузера.

+1

Спасибо за ваш ответ, к сожалению, это мне не очень помогает. Вы говорите, что язык может быть изменен только на уровне ОС, это неверно. Вы можете изменить локаль в Firefox или Chrome во время работы, а при следующем запросе «accept_languages» в заголовке http будет изменен. В нашем приложении этот язык используется для выбора текстов и форматов чисел и дат. –

+0

Во-вторых, повторное создание экземпляра браузера происходит очень медленно. Вы должны подумать о реализации пула для этого. –

+1

Чтобы повлиять на значение «Accept-Language' Header в Chrome, Firefox и Internet Explorer, достаточно изменить настройки языка в браузере и перезагрузить страницу без изменения настроек ОС. – martin

4

Вы также можете сделать это через: config в firefox. Но вам нужно использовать Actions, чтобы манипулировать им.

Ниже Java кусок кода

Actions act = new Actions(webDriver);   

    webDriver.get("about:config"); 

    // warning screen 
    act.sendKeys(Keys.RETURN).perform(); 

    // Go directly to the list, don't use the search option, it's not fast enough 
    act.sendKeys(Keys.TAB).perform(); 

    // Go to the intl.accept_languages option 
    act.sendKeys("intl.accept_languages").sendKeys(Keys.RETURN).perform(); 

    // fill the alert with your parameters 
    webDriver.switchTo().alert().sendKeys("fr, fr-fr, en-us, en"); 
    webDriver.switchTo().alert().accept(); 
Смежные вопросы