How To Handle Internationalization In Selenium WebDriver?
Himanshu Sheth
Posted On: September 30, 2020
87576 Views
13 Min Read
There are many software products that are built for a global audience. In my tenure as a developer, I have worked on multiple web (website or web app) projects that supported different languages. Though the Selenium framework was used for automation testing, using Internationalization in Selenium WebDriver Tutorial posed a huge challenge.
The major challenge was to develop automated tests that could be run on all localized UIs. When performing Internationalization in Selenium WebDriver, it is essential to create an Internationalization testing checklist to ensure that the interface of the application is displayed in the language corresponding to the client locale.
Google is a classic example of a product that is available across multiple regions, shown below are screenshots of the search page in Japanese and Hebrew languages-
Many developers use Internationalization testing and Localization testing interchangeably but there is a massive difference between the two. In this article, we take a look at how Internationalization in Selenium WebDriver can be used for performing Selenium test automation for software products that cater to a global audience. We also look at some of the essential points that should be a part of your Internationalization testing checklist for ensuring efficiency in the Internationalization tests.
What Is Internationalization Testing?
Internationalization is the technique of designing and preparing the software product (or application) so that it is usable in different languages, regions, and locales across the globe. Internationalization is also termed i18n, where 18 is the count of the number of letters between ‘i’ and ‘n’ in the word Internationalization.
The locale is the one that identifies the region in which the customer (or consumer) uses that particular language (or it’s variant). The formatting (and parsing) of data such as dates, currencies, numbers, etc. and the translated names of countries, languages, etc. is determined by the locale.
A software product with a global audience should be designed in a manner that it adapts to different languages and regions without many changes. Internationalization testing is the process of testing the software for international support (i.e. different locales) while ensuring that there is no breakage in the functionality or loss of data or compromise on data security (and integrity).
Interesting read: Geolocation Testing With Selenium
Internationalization Testing Checklist
When the website (or web app) is built to handle different languages, it becomes essential to test all the features against those languages. Internationalization in Selenium WebDriver can be performed using Selenium test automation against the intended locales (or languages).
Before you proceed with the test execution, you should make sure all the requirements in the Internationalization testing checklist are met. Here are some of the necessary things that should comprise your Internationalization testing checklist:
- The software should be developed in a manner that the deployment of Internationalization features can be done with ease. Testing should make sure that the rendering of the page using the particular locale is as per the expectation.
- If there are some custom installations for catering to certain locales, the settings should be verified as a part of Internationalization in Selenium WebDriver activity.
- Selenium test automation should be used for testing whether the interface of the application is displayed in native language strings corresponding to that of the client locale. This includes date time formats, data presentation, numeric formats, etc. in accordance to the regional language and other cultural preferences.
- When developing the ‘localized features’ in the product, developers ensure that localizable elements are not tightly coupled with the source code. For example, strings (or other localized content) in different languages can be set in resource files so that those can be loaded whenever required (depending on the client locale).
- Internationalization testing should check whether specific language property files are a part of the resource bundles. Depending on the primary market, a default language should be set for the entire application. For example, if the application is built for the ‘French’ market, the primary language can be set to French (instead of English).
- The Internationalization testing (or i18n testing) should verify whether the interface is displayed in the ‘default language’ when accessed from an environment which is different from the client locale.
- The display order of address differs from one language to another. For example, the order in English is name, city, state & postal code. Whereas, the order in Japanese is postal code, state, city, and name.
Hence, Internationalization testing should verify whether the display order (with respect to important elements like address, etc.) is maintained as per the client locale.
These are some of the pivotal points that should be a part of your Internationalization testing checklist. Apart from these checks, you could also add specific rules that should be followed when performing Internationalization in Selenium WebDriver. To help you finalize those rules, let’s see how to handle Internationalization in Selenium WebDriver.
Internationalization In Selenium WebDriver
There are two commonly used mechanisms for requesting the language on a localized website (or app). You have the option to use a ‘country specific URL’ as done by web products like Google. The commonly used option is choosing the language based on the Accept-Language header sent by the browser.
When performing Selenium test automation, I came across the Locale Switcher add-on for Chrome that lets you switch browser locale for testing localization on your website. It supports 500 locales from across the world. Internationalization in Selenium WebDriver is demonstrated using popular languages supported by the Selenium framework (i.e. Python, Java, and C#).
Internationalization in Selenium WebDriver, or Chrome and Firefox in this case, is done by setting intl.accept_languages preference to the necessary BCP 47 tag in the profile. The profile should be set in the DriverOptions so that the updated locale is reflected in the profile.
Alternatively, addArguments option for DriverOptions can also be used for setting to the necessary locale in Chrome. Apart from the difference in syntax, the fundamentals of using DriverOptions across Python, C#, and Java remains the same. I made use of Locale Switcher for determining the locale that has to be used in the implementation.
Internationalization In ChromeDriver
To understand the Internationalization in Selenium WebDriver i.e. I will go on a case to case basis. First, I will see how to achieve Internationalization testing in Selenium ChromeDriver.
Here is the code snippet for achieving Internationalization for Selenium Python:
1 2 3 4 5 |
# Set the locale chrome_locale = 'locale-of-choice' chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--lang={}".format(chrome_locale)) # End - Set the locale |
Here is the code snippet for achieving Internationalization for Selenium Java:
1 2 |
ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.addArguments("--lang= locale-of-choice"); |
Here is the code snippet for achieving Internationalization for Selenium C#:
1 2 |
var chromeOptions = new ChromeOptions(); chromeOptions.AddArgument("--lang=locale-of-choice"); |
Internationalization In FirefoxDriver
In this section of Internationalization in Selenium WebDriver guide, I will show how to implement Internationalization in Selenium FirefoxDriver.
Here is the code snippet for achieving Internationalization for Selenium Python:
1 2 3 4 5 |
# Set the locale ff_locale = 'locale-of-choice' ff_profile = webdriver.FirefoxProfile() ff_profile.set_preference("intl.accept_languages", firefox_locale) ff_profile.update_preferences() |
Here is the code snippet for achieving Internationalization for Selenium Java:
1 2 3 |
FirefoxProfile firefoxProfile = new FirefoxProfile(); firefoxProfile.setPreference("intl.accept_languages", "locale-of-choice"); firefoxOptions.setProfile(firefoxProfile); |
Here is the code snippet for achieving Internationalization for Selenium C#:
1 2 |
var firefoxOptions = new FirefoxOptions(); firefoxOptions.SetPreference("intl.accept_languages", "locale-of-choice"); |
Demonstrating Internationalization In Selenium WebDriver
For demonstration of Internationalization in Selenium WebDriver for Chrome and Firefox, the following test scenarios are used:
Test Combination (Browser – Chrome 80.0, Platform – Windows 10, Locale – he-IL)
- Set the Chrome browser locale to ‘he-IL’
- Navigate to the URL https://manytools.org/http-html-text/browser-language/
- Assert if the locale is not set properly
Test Combination (Browser – Firefox 78.0, Platform – macOS Mojave, Locale – ja-JP)
- Set the Firefox browser locale to ‘ja-JP’
- Navigate to the URLhttps://manytools.org/http-html-text/browser-language/
- Assert if the locale is not set properly
The test scenarios are executed on cloud-based Selenium Grid on LambdaTest. Once you’ve created an account on LambdaTest platform, make a note of the user-name and access-key from the profile page. The combination of user-name and access-key is used for accessing the Grid on LambdaTest. The browser capabilities for the corresponding browser and platform combination is generated using the LambdaTest capabilities generator.
WebDriver Internationalization With Selenium Python
For Internationalization in Selenium WebDriver, the implementation that uses Firefox and Chrome only differs in the manner in which browser locale is set and the rest of the implementation remains unchanged.
Code WalkThrough
Step 1
The capabilities for the two test scenarios are generated using the LambdaTest capabilities generator. Shown below is the capabilities for Test Scenario – 1
1 2 3 4 5 6 7 |
ch_capabilities = { "build" : "[Python] Locale Testing with Chrome & Windows on LambdaTest Selenium Grid", "name" : "[Python] Locale Testing with Chrome & Windows on LambdaTest Selenium Grid", "platform" : "Windows 10", "browserName" : "Chrome", "version" : "80.0" } |
Step 2
The functions driver_chrome_init()
and driver_ff_init()
are used for initialization and de-initialization of the Chrome and Firefox browsers respectively. These functions are used with the @pytest.mark.usefixtures in the test code.
The scope is set to ‘class’ so that a fresh browser instance is used for every test scenario.
1 2 3 4 5 6 7 8 9 |
@pytest.fixture(scope="class") def driver_chrome_init(request): …………………………………………………. …………………………………………………. @pytest.fixture(scope="class") def driver_ff_init(request): …………………………………………………. …………………………………………………. |
Step 3
The required locale i.e. ‘he-IL’ is set using the instance of ChromeOptions (i.e chrome_options). The browser capabilities are also set using chrome_options instead of DesiredCapabilities, since ChromeOptions offers convenient methods for setting ChromeDriver specific capabilities. This is an important step of implementing Internationalization in Selenium WebDriver.
1 2 |
chrome_locale = 'he-IL' chrome_options = webdriver.ChromeOptions() |
Step 4
The add_argument method in ChromeOptions is used for setting the necessary locale.
1 |
chrome_options.add_argument("--lang={}".format(chrome_locale)) |
Step 5
The combination of user-name and access-key are used for accessing the LambdaTest Grid URL [@hub.lambdatest.com/wd/hub].
1 |
remote_url = "https://" + user_name + ":" + app_key + "@hub.lambdatest.com/wd/hub" |
Step 6
The Selenium WebDriver API uses the LambdaTest Grid URL and browser capabilities (i.e. ch_capabilities) that was generated using the LambdaTest Capabilities Generator.
1 |
web_driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = ch_capabilities, options=chrome_options) |
Step 7
A new Firefox Profile is created using the FirefoxProfile() method offered by the webdriver package.
1 2 |
firefox_locale = 'ja-JP' ff_profile = webdriver.FirefoxProfile() |
Step 8
The set_preference() method in FirefoxProfile is used with intl.accept_languages set to ‘ja-JP’ (i.e. locale under test). The update_preferences() method is called to update the preferences set using set_preference() method.
1 2 |
ff_profile.set_preference("intl.accept_languages", firefox_locale) ff_profile.update_preferences() |
Code WalkThrough
The implementation of Internationalization in Selenium WebDriver is self-explanatory hence, I would not go deeper into the aspects of implementation.
To verify whether the browser locale is set to the expected locale (i.e. he-IL for Test Scenario -1 & ja-JP for Test Scenario – 2), driver.execute_script() method is used for executing JavaScript within the browser window.
The JS code returns the browser language which is compared with the expected locale. Assert is raised if the language does not match the expected locale.
1 2 |
language = self.driver.execute_script("return window.navigator.userlanguage || window.navigator.language") assert language == 'he-IL' |
Execution
The execution is performed by invoking the following command on the terminal.
1 |
pytest -s –v test_pytest.py |
Here is the screenshot of the execution which indicates the tests passed (i.e. browser locale was set without any issues):
WebDriver Internationalization With Selenium C#
Like Python, the implementation of Internationalization in Selenium WebDriver that uses Firefox and Chrome only differs in the handling of the browser locale.
Code WalkThrough
Step 1
The FluentAssertions package provides an extensive set of extension methods for checking the expected outcome (w.r.t locale). Hence, the FluentAssertions package is installed by executing the following command on the Package Manager Console.
1 |
PM > Install-Package FluentAssertions |
The package is imported before it is used in the code.
1 |
using FluentAssertions; |
Step 2
An instance of ChromeOptions is created. The AddArgument() method of ChromeOptions is used for setting the language to Hebrew (i.e. he-IL).
1 2 |
var chromeOptions = new ChromeOptions(); chromeOptions.AddArgument("--lang=he-IL"); |
Step 3
The chromeOptions.ToCapabilities() method is used for passing the required browser capabilities to the RemoteWebDriver interface.
The combination of user-name and access-key is used for accessing the Selenium Grid cloud on LambdaTest [@hub.lambdatest.com/wd/hub]
1 |
driver = new RemoteWebDriver(new Uri("https://" + username + ":" + accesskey + gridURL), chromeOptions.ToCapabilities(), TimeSpan.FromSeconds(600)); |
Step 4
Like Python, I use the ExecuteScript method for executing JavaScript code that returns the language of the browser window.
1 2 |
var executor = (IJavaScriptExecutor)driver; String language = executor.ExecuteScript("return window.navigator.userlanguage || window.navigator.language").ToString(); |
Step 5
Should() method offered by FluentAssertions is used for checking whether the browser language is set to Hebrew (i.e. he-IL).
1 |
language.Should().Be("he-IL"); |
Code WalkThrough
The implementation for Test Scenario – 2 (that uses Firefox browser) only differs in the way locale is set for the browser.
An instance of FirefoxOptions is created and the SetPreference() method is used for setting the browser locale to Japanese (i.e. ‘ja-JP’). intl.accept_languages is the preferences key for manipulating the language for the web page to ja-JP.
1 2 |
var firefoxOptions = new FirefoxOptions(); firefoxOptions.SetPreference("intl.accept_languages", "ja-JP"); |
For clarity, I have marked the code changes for running Test Scenario -1 and Test Scenario – 2 using Java:
Execution
We used Visual Studio Code 2019 (Community Edition) for creating a project and running the tests. Shown below is the execution snapshot of Internationalization in Selenium WebDriver from LambdaTest which indicates that the browser locale was set as expected:
WebDriver Internationalization With Selenium Java
The TestNG framework is used in the implementation for Selenium test automation. For a quick recap about the TestNG framework, you can refer to this detailed coverage on TestNG annotations.
Code WalkThrough
Step 1
The TestNG framework is used for Selenium test automation, hence the necessary packages are included before I start with the implementation of Internationalization in Selenium WebDriver .
1 2 3 |
import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; |
Step 2
The implementation under @BeforeClass annotation will be executed before the test case is triggered. Like implementation in Python and C#, an instance of ChromeOptions is used and addArguments() method is used for setting the language to ‘he-IL’.
1 2 |
ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.addArguments("--lang=he-IL"); |
Step 3
Test case implementation is included under the @Test annotation. JavaScript code is triggered using the interface offered by JavascriptExecutor. The executeScript method is used for getting the browser locale (i.e. window.navigator.userlanguage or window.navigator.language).
1 2 3 4 5 6 |
@Test public void test_Selenium4_ToDoApp() throws InterruptedException { ……………………………………….. ……………………………………….. JavascriptExecutor executor = (JavascriptExecutor) driver; String language = executor.executeScript("return window.navigator.userlanguage || window.navigator.language").toString(); |
Code WalkThrough
The implementation for Test Scenario – 2 differs in the way its locale is set. An instance of FirefoxOptions() is created so that the browser capabilities can be set.
1 2 3 |
@BeforeClass public void testSetUp() throws MalformedURLException { FirefoxOptions firefoxOptions = new FirefoxOptions(); |
An instance of FirefoxProfile() is created for a customized profile that suits our needs. The setPreference() method modifies the intl.accept_languages key to ‘ja-JP’.
1 2 3 4 5 |
@BeforeClass public void testSetUp() throws MalformedURLException { FirefoxOptions firefoxOptions = new FirefoxOptions(); FirefoxProfile firefoxProfile = new FirefoxProfile(); firefoxProfile.setPreference("intl.accept_languages", "ja-JP"); |
The modified profile is set using the setProfile() method of FirefoxOptions.
1 |
firefoxOptions.setProfile(firefoxProfile); |
Rest of the implementation is same as the one used for Test Scenario – 1, the code changes are shown below for better understanding:
Execution
I used the IntelliJ IDEA IDE for creating a project and running the tests. Shown below is the execution snapshot from LambdaTest which indicates that the browser locale was set as expected:
Wrap up
Internationalization testing is extremely important for companies that develop products for the global audience. The resources (i.e. strings, images, etc.) that are specific to a particular locale should be coupled less tightly from the resources that are used for the main target market. If you like, you can find more information about the need to test your website from different country locations.
Before using Internationalization in Selenium WebDriver for automation testing, it is necessary to follow the i18n rules mentioned in the Internationalization testing checklist. Depending on the browser share for the primary target market, you should lay down a plan to use Selenium test automation for Internationalization testing of your web product. The options used in Internationalization in Selenium WebDriver depend on the browser on which locale is set hence, it is important to prioritize the testing on browsers that matter the most. LambdaTest can help chalk out your Internationalization testing checklist by performing browser compatibility testing over 2000+ browser and operating system combinations.
Happy Testing!
Got Questions? Drop them on LambdaTest Community. Visit now