Skip to content

Commit 2e0d0e5

Browse files
authored
[py][bidi]: add emulation command set_scripting_enabled (#16513)
1 parent d6ed112 commit 2e0d0e5

File tree

2 files changed

+114
-29
lines changed

2 files changed

+114
-29
lines changed

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

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ def __init__(
3535
):
3636
"""Initialize GeolocationCoordinates.
3737
38-
Parameters:
39-
-----------
38+
Args:
4039
latitude: Latitude coordinate (-90.0 to 90.0).
4140
longitude: Longitude coordinate (-180.0 to 180.0).
4241
accuracy: Accuracy in meters (>= 0.0), defaults to 1.0.
@@ -46,7 +45,6 @@ def __init__(
4645
speed: Speed in meters per second (>= 0.0) or None, defaults to None.
4746
4847
Raises:
49-
------
5048
ValueError: If coordinates are out of valid range or if altitude_accuracy is provided without altitude.
5149
"""
5250
self.latitude = latitude
@@ -180,18 +178,16 @@ def set_geolocation_override(
180178
) -> None:
181179
"""Set geolocation override for the given contexts or user contexts.
182180
183-
Parameters:
184-
-----------
181+
Args:
185182
coordinates: Geolocation coordinates to emulate, or None.
186183
error: Geolocation error to emulate, or None.
187184
contexts: List of browsing context IDs to apply the override to.
188185
user_contexts: List of user context IDs to apply the override to.
189186
190187
Raises:
191-
------
192188
ValueError: If both coordinates and error are provided, or if both contexts
193-
and user_contexts are provided, or if neither contexts nor
194-
user_contexts are provided.
189+
and user_contexts are provided, or if neither contexts nor
190+
user_contexts are provided.
195191
"""
196192
if coordinates is not None and error is not None:
197193
raise ValueError("Cannot specify both coordinates and error")
@@ -224,17 +220,15 @@ def set_timezone_override(
224220
) -> None:
225221
"""Set timezone override for the given contexts or user contexts.
226222
227-
Parameters:
228-
-----------
223+
Args:
229224
timezone: Timezone identifier (IANA timezone name or offset string like '+01:00'),
230-
or None to clear the override.
225+
or None to clear the override.
231226
contexts: List of browsing context IDs to apply the override to.
232227
user_contexts: List of user context IDs to apply the override to.
233228
234229
Raises:
235-
------
236230
ValueError: If both contexts and user_contexts are provided, or if neither
237-
contexts nor user_contexts are provided.
231+
contexts nor user_contexts are provided.
238232
"""
239233
if contexts is not None and user_contexts is not None:
240234
raise ValueError("Cannot specify both contexts and user_contexts")
@@ -259,16 +253,14 @@ def set_locale_override(
259253
) -> None:
260254
"""Set locale override for the given contexts or user contexts.
261255
262-
Parameters:
263-
-----------
256+
Args:
264257
locale: Locale string as per BCP 47, or None to clear override.
265258
contexts: List of browsing context IDs to apply the override to.
266259
user_contexts: List of user context IDs to apply the override to.
267260
268261
Raises:
269-
------
270262
ValueError: If both contexts and user_contexts are provided, or if neither
271-
contexts nor user_contexts are provided, or if locale is invalid.
263+
contexts nor user_contexts are provided, or if locale is invalid.
272264
"""
273265
if contexts is not None and user_contexts is not None:
274266
raise ValueError("Cannot specify both contexts and userContexts")
@@ -284,3 +276,39 @@ def set_locale_override(
284276
params["userContexts"] = user_contexts
285277

286278
self.conn.execute(command_builder("emulation.setLocaleOverride", params))
279+
280+
def set_scripting_enabled(
281+
self,
282+
enabled: Union[bool, None] = False,
283+
contexts: Optional[list[str]] = None,
284+
user_contexts: Optional[list[str]] = None,
285+
) -> None:
286+
"""Set scripting enabled override for the given contexts or user contexts.
287+
288+
Args:
289+
enabled: False to disable scripting, None to clear the override.
290+
Note: Only emulation of disabled JavaScript is supported.
291+
contexts: List of browsing context IDs to apply the override to.
292+
user_contexts: List of user context IDs to apply the override to.
293+
294+
Raises:
295+
ValueError: If both contexts and user_contexts are provided, or if neither
296+
contexts nor user_contexts are provided, or if enabled is True.
297+
"""
298+
if enabled:
299+
raise ValueError("Only emulation of disabled JavaScript is supported (enabled must be False or None)")
300+
301+
if contexts is not None and user_contexts is not None:
302+
raise ValueError("Cannot specify both contexts and userContexts")
303+
304+
if contexts is None and user_contexts is None:
305+
raise ValueError("Must specify either contexts or userContexts")
306+
307+
params: dict[str, Any] = {"enabled": enabled}
308+
309+
if contexts is not None:
310+
params["contexts"] = contexts
311+
elif user_contexts is not None:
312+
params["userContexts"] = user_contexts
313+
314+
self.conn.execute(command_builder("emulation.setScriptingEnabled", params))

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

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,11 @@ def get_browser_locale(driver):
7474

7575

7676
def test_emulation_initialized(driver):
77-
"""Test that the emulation module is initialized properly."""
7877
assert driver.emulation is not None
7978
assert isinstance(driver.emulation, Emulation)
8079

8180

8281
def test_set_geolocation_override_with_coordinates_in_context(driver, pages):
83-
"""Test setting geolocation override with coordinates."""
8482
context_id = driver.current_window_handle
8583
pages.load("blank.html")
8684
coords = GeolocationCoordinates(45.5, -122.4194, accuracy=10.0)
@@ -96,7 +94,6 @@ def test_set_geolocation_override_with_coordinates_in_context(driver, pages):
9694

9795

9896
def test_set_geolocation_override_with_coordinates_in_user_context(driver, pages):
99-
"""Test setting geolocation override with coordinates in a user context."""
10097
# Create a user context
10198
user_context = driver.browser.create_user_context()
10299

@@ -121,7 +118,6 @@ def test_set_geolocation_override_with_coordinates_in_user_context(driver, pages
121118

122119

123120
def test_set_geolocation_override_all_coords(driver, pages):
124-
"""Test setting geolocation override with coordinates."""
125121
context_id = driver.current_window_handle
126122
pages.load("blank.html")
127123
coords = GeolocationCoordinates(
@@ -147,7 +143,6 @@ def test_set_geolocation_override_all_coords(driver, pages):
147143

148144

149145
def test_set_geolocation_override_with_multiple_contexts(driver, pages):
150-
"""Test setting geolocation override with multiple browsing contexts."""
151146
# Create two browsing contexts
152147
context1_id = driver.browsing_context.create(type=WindowTypes.TAB)
153148
context2_id = driver.browsing_context.create(type=WindowTypes.TAB)
@@ -181,7 +176,6 @@ def test_set_geolocation_override_with_multiple_contexts(driver, pages):
181176

182177

183178
def test_set_geolocation_override_with_multiple_user_contexts(driver, pages):
184-
"""Test setting geolocation override with multiple user contexts."""
185179
# Create two user contexts
186180
user_context1 = driver.browser.create_user_context()
187181
user_context2 = driver.browser.create_user_context()
@@ -229,7 +223,6 @@ def test_set_geolocation_override_with_multiple_user_contexts(driver, pages):
229223

230224
@pytest.mark.xfail_firefox
231225
def test_set_geolocation_override_with_error(driver, pages):
232-
"""Test setting geolocation override with error."""
233226
context_id = driver.current_window_handle
234227
pages.load("blank.html")
235228

@@ -242,7 +235,6 @@ def test_set_geolocation_override_with_error(driver, pages):
242235

243236

244237
def test_set_timezone_override_with_context(driver, pages):
245-
"""Test setting timezone override with a browsing context."""
246238
context_id = driver.current_window_handle
247239
pages.load("blank.html")
248240

@@ -267,7 +259,6 @@ def test_set_timezone_override_with_context(driver, pages):
267259

268260

269261
def test_set_timezone_override_with_user_context(driver, pages):
270-
"""Test setting timezone override with a user context."""
271262
user_context = driver.browser.create_user_context()
272263
context_id = driver.browsing_context.create(type=WindowTypes.TAB, user_context=user_context)
273264

@@ -287,7 +278,6 @@ def test_set_timezone_override_with_user_context(driver, pages):
287278

288279
@pytest.mark.xfail_firefox(reason="Firefox returns UTC as timezone string in case of offset.")
289280
def test_set_timezone_override_using_offset(driver, pages):
290-
"""Test setting timezone override using offset."""
291281
context_id = driver.current_window_handle
292282
pages.load("blank.html")
293283

@@ -320,7 +310,6 @@ def test_set_timezone_override_using_offset(driver, pages):
320310
],
321311
)
322312
def test_set_locale_override_with_contexts(driver, pages, locale, expected_locale):
323-
"""Test setting locale override with browsing contexts."""
324313
context_id = driver.current_window_handle
325314

326315
driver.emulation.set_locale_override(locale=locale, contexts=[context_id])
@@ -345,7 +334,6 @@ def test_set_locale_override_with_contexts(driver, pages, locale, expected_local
345334
],
346335
)
347336
def test_set_locale_override_with_user_contexts(driver, pages, value):
348-
"""Test setting locale override with user contexts."""
349337
user_context = driver.browser.create_user_context()
350338
try:
351339
context_id = driver.browsing_context.create(type=WindowTypes.TAB, user_context=user_context)
@@ -362,3 +350,72 @@ def test_set_locale_override_with_user_contexts(driver, pages, value):
362350
driver.browsing_context.close(context_id)
363351
finally:
364352
driver.browser.remove_user_context(user_context)
353+
354+
355+
@pytest.mark.xfail_firefox(reason="Not yet supported")
356+
def test_set_scripting_enabled_with_contexts(driver, pages):
357+
context_id = driver.current_window_handle
358+
359+
# disable scripting
360+
driver.emulation.set_scripting_enabled(enabled=False, contexts=[context_id])
361+
362+
driver.browsing_context.navigate(
363+
context=context_id,
364+
url="data:text/html,<script>window.foo=123;</script>",
365+
wait="complete",
366+
)
367+
result = driver.script._evaluate("'foo' in window", {"context": context_id}, await_promise=False)
368+
assert result.result["value"] is False, "Page script should not have executed when scripting is disabled"
369+
370+
# clear override via None to restore JS
371+
driver.emulation.set_scripting_enabled(enabled=None, contexts=[context_id])
372+
driver.browsing_context.navigate(
373+
context=context_id,
374+
url="data:text/html,<script>window.foo=123;</script>",
375+
wait="complete",
376+
)
377+
result = driver.script._evaluate("'foo' in window", {"context": context_id}, await_promise=False)
378+
assert result.result["value"] is True, "Page script should execute after clearing the override"
379+
380+
381+
@pytest.mark.xfail_firefox(reason="Not yet supported")
382+
def test_set_scripting_enabled_with_user_contexts(driver, pages):
383+
user_context = driver.browser.create_user_context()
384+
try:
385+
context_id = driver.browsing_context.create(type=WindowTypes.TAB, user_context=user_context)
386+
try:
387+
driver.switch_to.window(context_id)
388+
389+
driver.emulation.set_scripting_enabled(enabled=False, user_contexts=[user_context])
390+
391+
url = pages.url("javascriptPage.html")
392+
driver.browsing_context.navigate(context_id, url, wait="complete")
393+
394+
# Check that inline event handlers don't work; this page has an onclick handler
395+
click_field = driver.find_element("id", "clickField")
396+
initial_value = click_field.get_attribute("value") # initial value is 'Hello'
397+
click_field.click()
398+
399+
# Get the value after click, it should remain unchanged if scripting is disabled
400+
result_value = driver.script._evaluate(
401+
"document.getElementById('clickField').value", {"context": context_id}, await_promise=False
402+
)
403+
assert result_value.result["value"] == initial_value, (
404+
"Inline onclick handler should not execute, i.e, value should not change to 'clicked'"
405+
)
406+
407+
# Clear the scripting override
408+
driver.emulation.set_scripting_enabled(enabled=None, user_contexts=[user_context])
409+
410+
driver.browsing_context.navigate(context_id, url, wait="complete")
411+
412+
# Click the element again, it should change to 'Clicked' now
413+
driver.find_element("id", "clickField").click()
414+
result_value = driver.script._evaluate(
415+
"document.getElementById('clickField').value", {"context": context_id}, await_promise=False
416+
)
417+
assert result_value.result["value"] == "Clicked"
418+
finally:
419+
driver.browsing_context.close(context_id)
420+
finally:
421+
driver.browser.remove_user_context(user_context)

0 commit comments

Comments
 (0)