Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/test/selenium/webdriver/common/bidi_browser_tests.py
4020 views
1
# Licensed to the Software Freedom Conservancy (SFC) under one
2
# or more contributor license agreements. See the NOTICE file
3
# distributed with this work for additional information
4
# regarding copyright ownership. The SFC licenses this file
5
# to you under the Apache License, Version 2.0 (the
6
# "License"); you may not use this file except in compliance
7
# with the License. You may obtain a copy of the License at
8
#
9
# http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing,
12
# software distributed under the License is distributed on an
13
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
# KIND, either express or implied. See the License for the
15
# specific language governing permissions and limitations
16
# under the License.
17
18
import os
19
20
import pytest
21
22
from selenium.common.exceptions import TimeoutException
23
from selenium.webdriver.common.bidi.browser import ClientWindowInfo, ClientWindowState
24
from selenium.webdriver.common.bidi.browsing_context import ReadinessState
25
from selenium.webdriver.common.bidi.session import UserPromptHandler, UserPromptHandlerType
26
from selenium.webdriver.common.by import By
27
from selenium.webdriver.common.proxy import Proxy, ProxyType
28
from selenium.webdriver.common.window import WindowTypes
29
from selenium.webdriver.support.ui import WebDriverWait
30
31
32
def test_browser_initialized(driver):
33
"""Test that the browser module is initialized properly."""
34
assert driver.browser is not None
35
36
37
def test_create_user_context(driver):
38
"""Test creating a user context."""
39
user_context = driver.browser.create_user_context()
40
assert user_context is not None
41
42
# Clean up
43
driver.browser.remove_user_context(user_context)
44
45
46
def test_get_user_contexts(driver):
47
"""Test getting user contexts."""
48
user_context1 = driver.browser.create_user_context()
49
user_context2 = driver.browser.create_user_context()
50
51
user_contexts = driver.browser.get_user_contexts()
52
# it should be 3 since there is a default user context present, therefore >= 2
53
assert len(user_contexts) >= 2
54
55
# Clean up
56
driver.browser.remove_user_context(user_context1)
57
driver.browser.remove_user_context(user_context2)
58
59
60
def test_remove_user_context(driver):
61
"""Test removing a user context."""
62
user_context1 = driver.browser.create_user_context()
63
user_context2 = driver.browser.create_user_context()
64
65
user_contexts = driver.browser.get_user_contexts()
66
assert len(user_contexts) >= 2
67
68
driver.browser.remove_user_context(user_context2)
69
70
updated_user_contexts = driver.browser.get_user_contexts()
71
assert user_context1 in updated_user_contexts
72
assert user_context2 not in updated_user_contexts
73
74
# Clean up
75
driver.browser.remove_user_context(user_context1)
76
77
78
def test_get_client_windows(driver):
79
"""Test getting client windows."""
80
client_windows = driver.browser.get_client_windows()
81
82
assert client_windows is not None
83
assert len(client_windows) > 0
84
85
window_info = client_windows[0]
86
assert isinstance(window_info, ClientWindowInfo)
87
assert window_info.get_client_window() is not None
88
assert window_info.get_state() is not None
89
assert isinstance(window_info.get_state(), str)
90
assert window_info.get_width() > 0
91
assert window_info.get_height() > 0
92
assert isinstance(window_info.is_active(), bool)
93
assert window_info.get_x() >= 0
94
assert window_info.get_y() >= 0
95
96
97
def test_raises_exception_when_removing_default_user_context(driver):
98
with pytest.raises(Exception):
99
driver.browser.remove_user_context("default")
100
101
102
def test_client_window_state_constants(driver):
103
assert ClientWindowState.FULLSCREEN == "fullscreen"
104
assert ClientWindowState.MAXIMIZED == "maximized"
105
assert ClientWindowState.MINIMIZED == "minimized"
106
assert ClientWindowState.NORMAL == "normal"
107
108
109
def test_create_user_context_with_accept_insecure_certs(driver):
110
"""Test creating a user context with accept_insecure_certs parameter."""
111
INSECURE_TEST_SITE = "https://self-signed.badssl.com/"
112
user_context = driver.browser.create_user_context(accept_insecure_certs=True)
113
114
bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)
115
driver.switch_to.window(bc)
116
assert user_context is not None
117
assert bc is not None
118
119
driver.get(INSECURE_TEST_SITE)
120
121
h1 = driver.find_element(By.TAG_NAME, "h1")
122
assert h1.text.strip() == "self-signed.\nbadssl.com"
123
124
# Clean up
125
driver.browser.remove_user_context(user_context)
126
127
128
def test_create_user_context_with_direct_proxy(driver):
129
"""Test creating a user context with direct proxy configuration."""
130
proxy = Proxy()
131
proxy.proxy_type = ProxyType.DIRECT
132
133
user_context = driver.browser.create_user_context(proxy=proxy)
134
assert user_context is not None
135
136
bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)
137
driver.switch_to.window(bc)
138
139
# Visiting a site should load directly without proxy
140
driver.get("http://example.com/")
141
body_text = driver.find_element(By.TAG_NAME, "body").text.lower()
142
assert "example domain" in body_text
143
144
# Clean up
145
driver.browser.remove_user_context(user_context)
146
147
148
@pytest.mark.xfail_chrome(reason="Chrome auto upgrades HTTP to HTTPS in untrusted networks like CI environments")
149
def test_create_user_context_with_manual_proxy_all_params(driver, proxy_server):
150
"""Test creating a user context with manual proxy configuration."""
151
create_proxy_server = proxy_server(response_content=b"proxied response")
152
no_proxy_server = proxy_server(response_content=b"direct connection - not proxied")
153
154
proxy_port = create_proxy_server["port"]
155
no_proxy_port = no_proxy_server["port"]
156
157
proxy = Proxy()
158
proxy.proxy_type = ProxyType.MANUAL
159
proxy.http_proxy = f"localhost:{proxy_port}"
160
proxy.ssl_proxy = f"localhost:{proxy_port}"
161
proxy.socks_proxy = f"localhost:{proxy_port}"
162
proxy.socks_version = 5
163
proxy.no_proxy = [f"localhost:{no_proxy_port}"]
164
165
user_context = driver.browser.create_user_context(proxy=proxy)
166
167
# Create and switch to a new browsing context using this proxy
168
bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)
169
driver.switch_to.window(bc)
170
171
try:
172
# Visit no proxy site, it should bypass proxy
173
driver.get(f"http://localhost:{no_proxy_port}/")
174
body_text = driver.find_element(By.TAG_NAME, "body").text.lower()
175
assert "direct connection - not proxied" in body_text
176
177
# Visit a site that should be proxied
178
driver.get("http://example.com/")
179
180
body_text = driver.find_element("tag name", "body").text
181
assert "proxied response" in body_text.lower()
182
183
finally:
184
driver.browser.remove_user_context(user_context)
185
186
187
@pytest.mark.xfail_chrome(reason="Chrome auto upgrades HTTP to HTTPS in untrusted networks like CI environments")
188
def test_create_user_context_with_proxy_and_accept_insecure_certs(driver, proxy_server):
189
"""Test creating a user context with both acceptInsecureCerts and proxy parameters."""
190
create_proxy_server = proxy_server(response_content=b"proxied response")
191
port = create_proxy_server["port"]
192
193
proxy = Proxy()
194
proxy.proxy_type = ProxyType.MANUAL
195
proxy.http_proxy = f"localhost:{port}"
196
proxy.ssl_proxy = f"localhost:{port}"
197
proxy.no_proxy = ["self-signed.badssl.com"]
198
199
user_context = driver.browser.create_user_context(accept_insecure_certs=True, proxy=proxy)
200
201
bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)
202
driver.switch_to.window(bc)
203
204
try:
205
# Visit a site with an invalid certificate
206
driver.get("https://self-signed.badssl.com/")
207
h1 = driver.find_element(By.TAG_NAME, "h1")
208
assert "badssl.com" in h1.text.lower()
209
210
# Visit a site that should go through the fake proxy
211
driver.get("http://example.com/")
212
body_text = driver.find_element(By.TAG_NAME, "body").text
213
assert "proxied response" in body_text.lower()
214
215
finally:
216
driver.browser.remove_user_context(user_context)
217
218
219
def test_create_user_context_with_unhandled_prompt_behavior(driver, pages):
220
"""Test creating a user context with unhandled prompt behavior configuration."""
221
prompt_handler = UserPromptHandler(
222
alert=UserPromptHandlerType.DISMISS, default=UserPromptHandlerType.DISMISS, prompt=UserPromptHandlerType.DISMISS
223
)
224
225
user_context = driver.browser.create_user_context(unhandled_prompt_behavior=prompt_handler)
226
assert user_context is not None
227
228
# create a new browsing context with the user context
229
bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)
230
assert bc is not None
231
232
driver.switch_to.window(bc)
233
pages.load("alerts.html")
234
235
# TODO: trigger an alert and test that it is dismissed automatically, currently not working,
236
# conftest.py unhandled_prompt_behavior set to IGNORE, see if it is related
237
# driver.find_element(By.ID, "alert").click()
238
# # accessing title should be possible since alert is auto handled
239
# assert driver.title == "Testing Alerts"
240
241
# Clean up
242
driver.browser.remove_user_context(user_context)
243
244
245
@pytest.mark.xfail_firefox
246
def test_set_download_behavior_allowed(driver, pages, tmp_path):
247
print(f"Driver info: {driver.capabilities}")
248
try:
249
driver.browser.set_download_behavior(allowed=True, destination_folder=tmp_path)
250
251
context_id = driver.current_window_handle
252
url = pages.url("downloads/download.html")
253
driver.browsing_context.navigate(context=context_id, url=url, wait=ReadinessState.COMPLETE)
254
255
driver.find_element(By.ID, "file-1").click()
256
257
WebDriverWait(driver, 5).until(lambda d: "file_1.txt" in os.listdir(tmp_path))
258
259
files = os.listdir(tmp_path)
260
assert "file_1.txt" in files, f"Expected file_1.txt in {tmp_path}, but found: {files}"
261
finally:
262
driver.browser.set_download_behavior(allowed=None)
263
264
265
@pytest.mark.xfail_firefox
266
def test_set_download_behavior_denied(driver, pages, tmp_path):
267
try:
268
driver.browser.set_download_behavior(allowed=False)
269
270
context_id = driver.current_window_handle
271
url = pages.url("downloads/download.html")
272
driver.browsing_context.navigate(context=context_id, url=url, wait=ReadinessState.COMPLETE)
273
274
driver.find_element(By.ID, "file-1").click()
275
276
try:
277
WebDriverWait(driver, 3, poll_frequency=0.2).until(lambda _: len(os.listdir(tmp_path)) > 0)
278
files = os.listdir(tmp_path)
279
pytest.fail(f"A file was downloaded unexpectedly: {files}")
280
except TimeoutException:
281
pass # Expected, no file downloaded
282
finally:
283
driver.browser.set_download_behavior(allowed=None)
284
285
286
@pytest.mark.xfail_firefox
287
def test_set_download_behavior_user_context(driver, pages, tmp_path):
288
user_context = driver.browser.create_user_context()
289
290
try:
291
bc = driver.browsing_context.create(type=WindowTypes.WINDOW, user_context=user_context)
292
driver.switch_to.window(bc)
293
294
try:
295
driver.browser.set_download_behavior(
296
allowed=True, destination_folder=tmp_path, user_contexts=[user_context]
297
)
298
299
url = pages.url("downloads/download.html")
300
driver.browsing_context.navigate(context=bc, url=url, wait=ReadinessState.COMPLETE)
301
302
driver.find_element(By.ID, "file-1").click()
303
304
WebDriverWait(driver, 5).until(lambda d: "file_1.txt" in os.listdir(tmp_path))
305
306
files = os.listdir(tmp_path)
307
assert "file_1.txt" in files, f"Expected file_1.txt in {tmp_path}, but found: {files}"
308
309
initial_file_count = len(files)
310
311
driver.browser.set_download_behavior(allowed=False, user_contexts=[user_context])
312
313
driver.find_element(By.ID, "file-2").click()
314
315
try:
316
WebDriverWait(driver, 3, poll_frequency=0.2).until(
317
lambda _: len(os.listdir(tmp_path)) > initial_file_count
318
)
319
files_after = os.listdir(tmp_path)
320
pytest.fail(f"A file was downloaded unexpectedly: {files_after}")
321
except TimeoutException:
322
pass # Expected, no file downloaded
323
finally:
324
driver.browser.set_download_behavior(allowed=None, user_contexts=[user_context])
325
finally:
326
driver.browser.remove_user_context(user_context)
327
328
329
@pytest.mark.xfail_firefox
330
def test_set_download_behavior_validation(driver):
331
with pytest.raises(ValueError, match="destination_folder is required when allowed=True"):
332
driver.browser.set_download_behavior(allowed=True)
333
334
with pytest.raises(ValueError, match="destination_folder should not be provided when allowed=False"):
335
driver.browser.set_download_behavior(allowed=False, destination_folder="/tmp")
336
337