Skip to content

Commit a6db75e

Browse files
committed
Add the ability to set the browser's Language/Locale
1 parent ec3f23b commit a6db75e

File tree

7 files changed

+184
-24
lines changed

7 files changed

+184
-24
lines changed

examples/raw_parameter_script.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
sb.headless = False
3131
sb.headed = False
3232
sb.start_page = None
33+
sb.locale_code = None
3334
sb.servername = "localhost"
3435
sb.port = 4444
3536
sb.data = None

help_docs/customizing_test_runs.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ SeleniumBase provides additional ``pytest`` command-line options for tests:
113113
--extension-dir=DIR # (Load a Chrome Extension directory, comma-separated.)
114114
--headless # (Run tests headlessly. Default mode on Linux OS.)
115115
--headed # (Run tests with a GUI on Linux OS.)
116+
--locale=LOCALE_CODE # (Set the Language Locale Code for the web browser.)
116117
--start-page=URL # (The starting URL for the web browser when tests begin.)
117118
--archive-logs # (Archive old log files instead of deleting them.)
118119
--time-limit=SECONDS # (Safely fail any test that exceeds the limit limit.)

help_docs/locale_codes.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<h2><img src="https://seleniumbase.io/img/sb_icon.png" title="SeleniumBase" width="24" /> Language Locale Codes</h2>
2+
3+
You can specify a Language Locale Code to customize web pages on supported websites. With SeleniumBase you can change the web browser's Locale on the command line by adding:
4+
5+
```bash
6+
--locale=CODE # Example: --locale=ru
7+
```
8+
9+
<h3><img src="https://seleniumbase.io/img/sb_icon.png" title="SeleniumBase" width="24" /> List of Language Locale Codes:</h3>
10+
11+
<table>
12+
<thead><tr><th>Language</th><th>Code</th></tr></thead>
13+
<tbody class="list">
14+
<tr><td>Afrikaans</td><td><code translate="no" dir="ltr">af</code></td></tr>
15+
<tr><td>Amharic</td><td><code translate="no" dir="ltr">am</code></td></tr>
16+
<tr><td>Arabic</td><td><code translate="no" dir="ltr">ar</code></td></tr>
17+
<tr><td>Arabic (Egypt)</td><td><code translate="no" dir="ltr">ar_<wbr>eg</code></td></tr>
18+
<tr><td>Arabic (Saudi Arabia)</td><td><code translate="no" dir="ltr">ar_<wbr>sa</code></td></tr>
19+
<tr><td>Basque</td><td><code translate="no" dir="ltr">eu</code></td></tr>
20+
<tr><td>Belarusian</td><td><code translate="no" dir="ltr">be</code></td></tr>
21+
<tr><td>Bengali</td><td><code translate="no" dir="ltr">bn</code></td></tr>
22+
<tr><td>Bulgarian</td><td><code translate="no" dir="ltr">bg</code></td></tr>
23+
<tr><td>Catalan</td><td><code translate="no" dir="ltr">ca</code></td></tr>
24+
<tr><td>Chinese</td><td><code translate="no" dir="ltr">zh</code></td></tr>
25+
<tr><td>Chinese (China Mainland)</td><td><code translate="no" dir="ltr">zh_<wbr>cn</code></td></tr>
26+
<tr><td>Chinese (Hong Kong)</td><td><code translate="no" dir="ltr">zh_<wbr>hk</code></td></tr>
27+
<tr><td>Chinese (Taiwan)</td><td><code translate="no" dir="ltr">zh_<wbr>tw</code></td></tr>
28+
<tr><td>Croatian</td><td><code translate="no" dir="ltr">hr</code></td></tr>
29+
<tr><td>Czech</td><td><code translate="no" dir="ltr">cs</code></td></tr>
30+
<tr><td>Danish</td><td><code translate="no" dir="ltr">da</code></td></tr>
31+
<tr><td>Dutch</td><td><code translate="no" dir="ltr">nl</code></td></tr>
32+
<tr><td>English</td><td><code translate="no" dir="ltr">en</code></td></tr>
33+
<tr><td>English (United States)</td><td><code translate="no" dir="ltr">en_<wbr>us</code></td></tr>
34+
<tr><td>English (Australia)</td><td><code translate="no" dir="ltr">en_<wbr>au</code></td></tr>
35+
<tr><td>English (Canada)</td><td><code translate="no" dir="ltr">en_<wbr>ca</code></td></tr>
36+
<tr><td>English (United Kingdom)</td><td><code translate="no" dir="ltr">en_<wbr>gb</code></td></tr>
37+
<tr><td>English (Ireland)</td><td><code translate="no" dir="ltr">en_<wbr>ie</code></td></tr>
38+
<tr><td>English (India)</td><td><code translate="no" dir="ltr">en_<wbr>in</code></td></tr>
39+
<tr><td>English (Singapore)</td><td><code translate="no" dir="ltr">en_<wbr>sg</code></td></tr>
40+
<tr><td>English (South Africa)</td><td><code translate="no" dir="ltr">en_<wbr>za</code></td></tr>
41+
<tr><td>Estonian</td><td><code translate="no" dir="ltr">et</code></td></tr>
42+
<tr><td>Farsi</td><td><code translate="no" dir="ltr">fa</code></td></tr>
43+
<tr><td>Filipino</td><td><code translate="no" dir="ltr">fil</code></td></tr>
44+
<tr><td>Finnish</td><td><code translate="no" dir="ltr">fi</code></td></tr>
45+
<tr><td>French</td><td><code translate="no" dir="ltr">fr</code></td></tr>
46+
<tr><td>French (Canada)</td><td><code translate="no" dir="ltr">fr_<wbr>ca</code></td></tr>
47+
<tr><td>French (Switzerland)</td><td><code translate="no" dir="ltr">fr_<wbr>ch</code></td></tr>
48+
<tr><td>Galician</td><td><code translate="no" dir="ltr">gl</code></td></tr>
49+
<tr><td>German</td><td><code translate="no" dir="ltr">de</code></td></tr>
50+
<tr><td>German (Austria)</td><td><code translate="no" dir="ltr">de_<wbr>at</code></td></tr>
51+
<tr><td>Greek</td><td><code translate="no" dir="ltr">el</code></td></tr>
52+
<tr><td>Gujarati</td><td><code translate="no" dir="ltr">gu</code></td></tr>
53+
<tr><td>Hebrew</td><td><code translate="no" dir="ltr">he</code></td></tr>
54+
<tr><td>Hindi</td><td><code translate="no" dir="ltr">hi</code></td></tr>
55+
<tr><td>Hungarian</td><td><code translate="no" dir="ltr">hu</code></td></tr>
56+
<tr><td>Icelandic</td><td><code translate="no" dir="ltr">is</code></td></tr>
57+
<tr><td>Indonesian</td><td><code translate="no" dir="ltr">id</code></td></tr>
58+
<tr><td>Italian</td><td><code translate="no" dir="ltr">it</code></td></tr>
59+
<tr><td>Japanese</td><td><code translate="no" dir="ltr">ja</code></td></tr>
60+
<tr><td>Kannada</td><td><code translate="no" dir="ltr">kn</code></td></tr>
61+
<tr><td>Korean</td><td><code translate="no" dir="ltr">ko</code></td></tr>
62+
<tr><td>Lao</td><td><code translate="no" dir="ltr">lo</code></td></tr>
63+
<tr><td>Latvian</td><td><code translate="no" dir="ltr">lv</code></td></tr>
64+
<tr><td>Lingala</td><td><code translate="no" dir="ltr">ln</code></td></tr>
65+
<tr><td>Lithuanian</td><td><code translate="no" dir="ltr">lt</code></td></tr>
66+
<tr><td>Malay</td><td><code translate="no" dir="ltr">ms</code></td></tr>
67+
<tr><td>Malayalam</td><td><code translate="no" dir="ltr">ml</code></td></tr>
68+
<tr><td>Marathi</td><td><code translate="no" dir="ltr">mr</code></td></tr>
69+
<tr><td>Norwegian</td><td><code translate="no" dir="ltr">no</code></td></tr>
70+
<tr><td>Polish</td><td><code translate="no" dir="ltr">pl</code></td></tr>
71+
<tr><td>Portuguese</td><td><code translate="no" dir="ltr">pt</code></td></tr>
72+
<tr><td>Portuguese (Brazil)</td><td><code translate="no" dir="ltr">pt_<wbr>br</code></td></tr>
73+
<tr><td>Portuguese (Portugal)</td><td><code translate="no" dir="ltr">pt_<wbr>pt</code></td></tr>
74+
<tr><td>Romanian</td><td><code translate="no" dir="ltr">ro</code></td></tr>
75+
<tr><td>Russian</td><td><code translate="no" dir="ltr">ru</code></td></tr>
76+
<tr><td>Serbian</td><td><code translate="no" dir="ltr">sr</code></td></tr>
77+
<tr><td>Slovak</td><td><code translate="no" dir="ltr">sk</code></td></tr>
78+
<tr><td>Slovenian</td><td><code translate="no" dir="ltr">sl</code></td></tr>
79+
<tr><td>Spanish</td><td><code translate="no" dir="ltr">es</code></td></tr>
80+
<tr><td>Spanish (Latin America)</td><td><code translate="no" dir="ltr">es_<wbr>419</code></td></tr>
81+
<tr><td>Spanish (Argentina)</td><td><code translate="no" dir="ltr">es_<wbr>ar</code></td></tr>
82+
<tr><td>Spanish (Chile)</td><td><code translate="no" dir="ltr">es_<wbr>cl</code></td></tr>
83+
<tr><td>Spanish (Colombia)</td><td><code translate="no" dir="ltr">es_<wbr>co</code></td></tr>
84+
<tr><td>Spanish (Costa Rica)</td><td><code translate="no" dir="ltr">es_<wbr>cr</code></td></tr>
85+
<tr><td>Spanish (Dominican Rep.)</td><td><code translate="no" dir="ltr">es_<wbr>do</code></td></tr>
86+
<tr><td>Spanish (Ecuador)</td><td><code translate="no" dir="ltr">es_<wbr>ec</code></td></tr>
87+
<tr><td>Spanish (El Salvador)</td><td><code translate="no" dir="ltr">es_<wbr>sv</code></td></tr>
88+
<tr><td>Spanish (Guatemala)</td><td><code translate="no" dir="ltr">es_<wbr>gt</code></td></tr>
89+
<tr><td>Spanish (Honduras)</td><td><code translate="no" dir="ltr">es_<wbr>hn</code></td></tr>
90+
<tr><td>Spanish (Mexico)</td><td><code translate="no" dir="ltr">es_<wbr>mx</code></td></tr>
91+
<tr><td>Spanish (Nicaragua)</td><td><code translate="no" dir="ltr">es_<wbr>ni</code></td></tr>
92+
<tr><td>Spanish (Panama)</td><td><code translate="no" dir="ltr">es_<wbr>pa</code></td></tr>
93+
<tr><td>Spanish (Peru)</td><td><code translate="no" dir="ltr">es_<wbr>pe</code></td></tr>
94+
<tr><td>Spanish (Puerto Rico)</td><td><code translate="no" dir="ltr">es_<wbr>pr</code></td></tr>
95+
<tr><td>Spanish (Paraguay)</td><td><code translate="no" dir="ltr">es_<wbr>py</code></td></tr>
96+
<tr><td>Spanish (United States)</td><td><code translate="no" dir="ltr">es_<wbr>us</code></td></tr>
97+
<tr><td>Spanish (Uruguay)</td><td><code translate="no" dir="ltr">es_<wbr>uy</code></td></tr>
98+
<tr><td>Spanish (Venezuela)</td><td><code translate="no" dir="ltr">es_<wbr>ve</code></td></tr>
99+
<tr><td>Swahili</td><td><code translate="no" dir="ltr">sw</code></td></tr>
100+
<tr><td>Swedish</td><td><code translate="no" dir="ltr">sv</code></td></tr>
101+
<tr><td>Swiss German</td><td><code translate="no" dir="ltr">gsw</code></td></tr>
102+
<tr><td>Tagalog</td><td><code translate="no" dir="ltr">tl</code></td></tr>
103+
<tr><td>Tamil</td><td><code translate="no" dir="ltr">ta</code></td></tr>
104+
<tr><td>Telugu</td><td><code translate="no" dir="ltr">te</code></td></tr>
105+
<tr><td>Thai</td><td><code translate="no" dir="ltr">th</code></td></tr>
106+
<tr><td>Turkish</td><td><code translate="no" dir="ltr">tr</code></td></tr>
107+
<tr><td>Ukrainian</td><td><code translate="no" dir="ltr">uk</code></td></tr>
108+
<tr><td>Urdu</td><td><code translate="no" dir="ltr">ur</code></td></tr>
109+
<tr><td>Vietnamese</td><td><code translate="no" dir="ltr">vi</code></td></tr>
110+
<tr><td>Zulu</td><td><code translate="no" dir="ltr">zu</code></td></tr>
111+
</tbody>
112+
</table>

seleniumbase/core/browser_launcher.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def _add_chrome_disable_csp_extension(chrome_options):
129129

130130

131131
def _set_chrome_options(
132-
browser_name, downloads_path, headless,
132+
browser_name, downloads_path, headless, locale_code,
133133
proxy_string, proxy_auth, proxy_user, proxy_pass,
134134
user_agent, disable_csp, enable_sync, use_auto_ext,
135135
no_sandbox, disable_gpu, incognito, guest_mode, devtools, swiftshader,
@@ -140,10 +140,16 @@ def _set_chrome_options(
140140
"download.default_directory": downloads_path,
141141
"local_discovery.notifications_enabled": False,
142142
"credentials_enable_service": False,
143+
"download.prompt_for_download": False,
144+
"download.directory_upgrade": True,
145+
"safebrowsing.enabled": False,
146+
"safebrowsing.disable_download_protection": True,
143147
"profile": {
144148
"password_manager_enabled": False
145149
}
146150
}
151+
if locale_code:
152+
prefs["intl.accept_languages"] = locale_code
147153
if block_images:
148154
prefs["profile.managed_default_content_settings.images"] = 2
149155
chrome_options.add_experimental_option("prefs", prefs)
@@ -283,7 +289,7 @@ def _set_safari_capabilities():
283289

284290

285291
def _create_firefox_profile(
286-
downloads_path, proxy_string, user_agent, disable_csp):
292+
downloads_path, locale_code, proxy_string, user_agent, disable_csp):
287293
profile = webdriver.FirefoxProfile()
288294
profile.accept_untrusted_certs = True
289295
profile.set_preference("reader.parse-on-load.enabled", False)
@@ -328,6 +334,8 @@ def _create_firefox_profile(
328334
profile.set_preference("security.csp.enable", False)
329335
profile.set_preference(
330336
"browser.download.manager.showAlertOnComplete", False)
337+
if locale_code:
338+
profile.set_preference("intl.accept_languages", locale_code)
331339
profile.set_preference("browser.shell.checkDefaultBrowser", False)
332340
profile.set_preference("browser.startup.page", 0)
333341
profile.set_preference("browser.download.panel.shown", False)
@@ -389,9 +397,10 @@ def validate_proxy_string(proxy_string):
389397
return proxy_string
390398

391399

392-
def get_driver(browser_name, headless=False, use_grid=False,
393-
servername='localhost', port=4444, proxy_string=None,
394-
user_agent=None, cap_file=None, cap_string=None,
400+
def get_driver(browser_name, headless=False, locale_code=None,
401+
use_grid=False, servername='localhost', port=4444,
402+
proxy_string=None, user_agent=None,
403+
cap_file=None, cap_string=None,
395404
disable_csp=None, enable_sync=None, use_auto_ext=None,
396405
no_sandbox=None, disable_gpu=None,
397406
incognito=None, guest_mode=None, devtools=None,
@@ -430,7 +439,7 @@ def get_driver(browser_name, headless=False, use_grid=False,
430439
"Name length of Chrome's User Data Directory must be >= 3.")
431440
if use_grid:
432441
return get_remote_driver(
433-
browser_name, headless, servername, port,
442+
browser_name, headless, locale_code, servername, port,
434443
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
435444
cap_file, cap_string, disable_csp, enable_sync, use_auto_ext,
436445
no_sandbox, disable_gpu, incognito, guest_mode, devtools,
@@ -439,7 +448,7 @@ def get_driver(browser_name, headless=False, use_grid=False,
439448
mobile_emulator, device_width, device_height, device_pixel_ratio)
440449
else:
441450
return get_local_driver(
442-
browser_name, headless, servername,
451+
browser_name, headless, locale_code, servername,
443452
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
444453
disable_csp, enable_sync, use_auto_ext, no_sandbox, disable_gpu,
445454
incognito, guest_mode, devtools, swiftshader, block_images,
@@ -448,10 +457,11 @@ def get_driver(browser_name, headless=False, use_grid=False,
448457

449458

450459
def get_remote_driver(
451-
browser_name, headless, servername, port, proxy_string, proxy_auth,
452-
proxy_user, proxy_pass, user_agent, cap_file, cap_string,
453-
disable_csp, enable_sync, use_auto_ext, no_sandbox, disable_gpu,
454-
incognito, guest_mode, devtools, swiftshader, block_images,
460+
browser_name, headless, locale_code, servername, port,
461+
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
462+
cap_file, cap_string, disable_csp, enable_sync, use_auto_ext,
463+
no_sandbox, disable_gpu, incognito, guest_mode,
464+
devtools, swiftshader, block_images,
455465
user_data_dir, extension_zip, extension_dir, test_id,
456466
mobile_emulator, device_width, device_height, device_pixel_ratio):
457467
downloads_path = download_helper.get_downloads_folder()
@@ -480,7 +490,7 @@ def get_remote_driver(
480490
desired_caps["name"] = test_id
481491
if browser_name == constants.Browser.GOOGLE_CHROME:
482492
chrome_options = _set_chrome_options(
483-
browser_name, downloads_path, headless,
493+
browser_name, downloads_path, headless, locale_code,
484494
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
485495
disable_csp, enable_sync, use_auto_ext, no_sandbox, disable_gpu,
486496
incognito, guest_mode, devtools, swiftshader, block_images,
@@ -497,7 +507,8 @@ def get_remote_driver(
497507
try:
498508
# Use Geckodriver for Firefox if it's on the PATH
499509
profile = _create_firefox_profile(
500-
downloads_path, proxy_string, user_agent, disable_csp)
510+
downloads_path, locale_code,
511+
proxy_string, user_agent, disable_csp)
501512
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
502513
firefox_capabilities['marionette'] = True
503514
if headless:
@@ -515,7 +526,8 @@ def get_remote_driver(
515526
except WebDriverException:
516527
# Don't use Geckodriver: Only works for old versions of Firefox
517528
profile = _create_firefox_profile(
518-
downloads_path, proxy_string, user_agent, disable_csp)
529+
downloads_path, locale_code,
530+
proxy_string, user_agent, disable_csp)
519531
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
520532
firefox_capabilities['marionette'] = False
521533
if headless:
@@ -604,7 +616,7 @@ def get_remote_driver(
604616

605617

606618
def get_local_driver(
607-
browser_name, headless, servername,
619+
browser_name, headless, locale_code, servername,
608620
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
609621
disable_csp, enable_sync, use_auto_ext, no_sandbox, disable_gpu,
610622
incognito, guest_mode, devtools, swiftshader, block_images,
@@ -622,7 +634,8 @@ def get_local_driver(
622634
try:
623635
# Use Geckodriver for Firefox if it's on the PATH
624636
profile = _create_firefox_profile(
625-
downloads_path, proxy_string, user_agent, disable_csp)
637+
downloads_path, locale_code,
638+
proxy_string, user_agent, disable_csp)
626639
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
627640
firefox_capabilities['marionette'] = True
628641
options = webdriver.FirefoxOptions()
@@ -661,7 +674,8 @@ def get_local_driver(
661674
options=options)
662675
except Exception:
663676
profile = _create_firefox_profile(
664-
downloads_path, proxy_string, user_agent, disable_csp)
677+
downloads_path, locale_code,
678+
proxy_string, user_agent, disable_csp)
665679
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
666680
firefox_driver = webdriver.Firefox(
667681
firefox_profile=profile,
@@ -694,7 +708,7 @@ def get_local_driver(
694708
elif browser_name == constants.Browser.EDGE:
695709
try:
696710
chrome_options = _set_chrome_options(
697-
browser_name, downloads_path, headless,
711+
browser_name, downloads_path, headless, locale_code,
698712
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
699713
disable_csp, enable_sync, use_auto_ext,
700714
no_sandbox, disable_gpu, incognito, guest_mode, devtools,
@@ -735,10 +749,16 @@ def get_local_driver(
735749
"download.default_directory": downloads_path,
736750
"local_discovery.notifications_enabled": False,
737751
"credentials_enable_service": False,
752+
"download.prompt_for_download": False,
753+
"download.directory_upgrade": True,
754+
"safebrowsing.enabled": False,
755+
"safebrowsing.disable_download_protection": True,
738756
"profile": {
739757
"password_manager_enabled": False
740758
}
741759
}
760+
if locale_code:
761+
prefs["intl.accept_languages"] = locale_code
742762
if block_images:
743763
prefs["profile.managed_default_content_settings.images"] = 2
744764
edge_options.add_experimental_option("prefs", prefs)
@@ -820,7 +840,7 @@ def get_local_driver(
820840
logging.debug("\nWarning: Could not make operadriver"
821841
" executable: %s" % e)
822842
opera_options = _set_chrome_options(
823-
browser_name, downloads_path, headless,
843+
browser_name, downloads_path, headless, locale_code,
824844
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
825845
disable_csp, enable_sync, use_auto_ext,
826846
no_sandbox, disable_gpu, incognito, guest_mode, devtools,
@@ -839,7 +859,7 @@ def get_local_driver(
839859
elif browser_name == constants.Browser.GOOGLE_CHROME:
840860
try:
841861
chrome_options = _set_chrome_options(
842-
browser_name, downloads_path, headless,
862+
browser_name, downloads_path, headless, locale_code,
843863
proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
844864
disable_csp, enable_sync, use_auto_ext,
845865
no_sandbox, disable_gpu, incognito, guest_mode, devtools,

0 commit comments

Comments
 (0)