Skip to content

Commit 9564733

Browse files
authored
[py][bidi]: add set_timezone_override command in emulation (#16500)
1 parent 269608c commit 9564733

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

py/selenium/webdriver/common/bidi/emulation.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,38 @@ def set_geolocation_override(
215215
params["userContexts"] = user_contexts
216216

217217
self.conn.execute(command_builder("emulation.setGeolocationOverride", params))
218+
219+
def set_timezone_override(
220+
self,
221+
timezone: Optional[str] = None,
222+
contexts: Optional[list[str]] = None,
223+
user_contexts: Optional[list[str]] = None,
224+
) -> None:
225+
"""Set timezone override for the given contexts or user contexts.
226+
227+
Parameters:
228+
-----------
229+
timezone: Timezone identifier (IANA timezone name or offset string like '+01:00'),
230+
or None to clear the override.
231+
contexts: List of browsing context IDs to apply the override to.
232+
user_contexts: List of user context IDs to apply the override to.
233+
234+
Raises:
235+
------
236+
ValueError: If both contexts and user_contexts are provided, or if neither
237+
contexts nor user_contexts are provided.
238+
"""
239+
if contexts is not None and user_contexts is not None:
240+
raise ValueError("Cannot specify both contexts and user_contexts")
241+
242+
if contexts is None and user_contexts is None:
243+
raise ValueError("Must specify either contexts or user_contexts")
244+
245+
params: dict[str, Any] = {"timezone": timezone}
246+
247+
if contexts is not None:
248+
params["contexts"] = contexts
249+
elif user_contexts is not None:
250+
params["userContexts"] = user_contexts
251+
252+
self.conn.execute(command_builder("emulation.setTimezoneOverride", params))

py/test/selenium/webdriver/common/bidi_emulation_tests.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@
2121
from selenium.webdriver.common.window import WindowTypes
2222

2323

24+
def get_browser_timezone_string(driver):
25+
result = driver.script._evaluate(
26+
"Intl.DateTimeFormat().resolvedOptions().timeZone",
27+
{"context": driver.current_window_handle},
28+
await_promise=False,
29+
)
30+
return result.result["value"]
31+
32+
33+
def get_browser_timezone_offset(driver):
34+
result = driver.script._evaluate(
35+
"new Date().getTimezoneOffset()", {"context": driver.current_window_handle}, await_promise=False
36+
)
37+
return result.result["value"]
38+
39+
2440
def get_browser_geolocation(driver, user_context=None):
2541
origin = driver.execute_script("return window.location.origin;")
2642
driver.permissions.set_permission("geolocation", PermissionState.GRANTED, origin, user_context=user_context)
@@ -214,3 +230,66 @@ def test_set_geolocation_override_with_error(driver, pages):
214230

215231
result = get_browser_geolocation(driver)
216232
assert "error" in result, f"Expected geolocation error, got: {result}"
233+
234+
235+
def test_set_timezone_override_with_context(driver, pages):
236+
"""Test setting timezone override with a browsing context."""
237+
context_id = driver.current_window_handle
238+
pages.load("blank.html")
239+
240+
initial_timezone_string = get_browser_timezone_string(driver)
241+
242+
# Set timezone to Tokyo (UTC+9)
243+
driver.emulation.set_timezone_override(timezone="Asia/Tokyo", contexts=[context_id])
244+
245+
timezone_offset = get_browser_timezone_offset(driver)
246+
timezone_string = get_browser_timezone_string(driver)
247+
248+
# Tokyo is UTC+9, so the offset should be -540 minutes (negative because it's ahead of UTC)
249+
assert timezone_offset == -540, f"Expected timezone offset -540, got: {timezone_offset}"
250+
assert timezone_string == "Asia/Tokyo", f"Expected timezone 'Asia/Tokyo', got: {timezone_string}"
251+
252+
# Clear the timezone override
253+
driver.emulation.set_timezone_override(timezone=None, contexts=[context_id])
254+
255+
# verify setting timezone to None clears the timezone override
256+
timezone_after_clear_with_none = get_browser_timezone_string(driver)
257+
assert timezone_after_clear_with_none == initial_timezone_string
258+
259+
260+
def test_set_timezone_override_with_user_context(driver, pages):
261+
"""Test setting timezone override with a user context."""
262+
user_context = driver.browser.create_user_context()
263+
context_id = driver.browsing_context.create(type=WindowTypes.TAB, user_context=user_context)
264+
265+
driver.switch_to.window(context_id)
266+
pages.load("blank.html")
267+
268+
driver.emulation.set_timezone_override(timezone="America/New_York", user_contexts=[user_context])
269+
270+
timezone_string = get_browser_timezone_string(driver)
271+
assert timezone_string == "America/New_York", f"Expected timezone 'America/New_York', got: {timezone_string}"
272+
273+
driver.emulation.set_timezone_override(timezone=None, user_contexts=[user_context])
274+
275+
driver.browsing_context.close(context_id)
276+
driver.browser.remove_user_context(user_context)
277+
278+
279+
@pytest.mark.xfail_firefox(reason="Firefox returns UTC as timezone string in case of offset.")
280+
def test_set_timezone_override_using_offset(driver, pages):
281+
"""Test setting timezone override using offset."""
282+
context_id = driver.current_window_handle
283+
pages.load("blank.html")
284+
285+
# set timezone to India (UTC+05:30) using offset
286+
driver.emulation.set_timezone_override(timezone="+05:30", contexts=[context_id])
287+
288+
timezone_offset = get_browser_timezone_offset(driver)
289+
timezone_string = get_browser_timezone_string(driver)
290+
291+
# India is UTC+05:30, so the offset should be -330 minutes (negative because it's ahead of UTC)
292+
assert timezone_offset == -330, f"Expected timezone offset -540, got: {timezone_offset}"
293+
assert timezone_string == "+05:30", f"Expected timezone '+05:30', got: {timezone_string}"
294+
295+
driver.emulation.set_timezone_override(timezone=None, contexts=[context_id])

0 commit comments

Comments
 (0)