|
21 | 21 |
|
22 | 22 | from selenium.common.exceptions import WebDriverException |
23 | 23 | from selenium.webdriver.common.bidi.browsing_context import ReadinessState |
24 | | -from selenium.webdriver.common.bidi.network import Request |
| 24 | +from selenium.webdriver.common.bidi.network import Request, Response |
25 | 25 | from selenium.webdriver.common.by import By |
26 | 26 |
|
27 | 27 |
|
@@ -121,3 +121,202 @@ def callback(request: Request): |
121 | 121 | assert driver.find_element(By.ID, "data-url-image").is_displayed() |
122 | 122 | assert len(data_requests) > 0, "BiDi event not captured" |
123 | 123 | assert len(exceptions) == 0, "Exception raised when continuing request in callback" |
| 124 | + |
| 125 | + |
| 126 | +# Network Data Collector Tests |
| 127 | +def test_add_data_collector(driver): |
| 128 | + collector_id = driver.network.add_data_collector(data_types=["response"], max_encoded_data_size=1000) |
| 129 | + assert collector_id is not None, "Data collector not added" |
| 130 | + assert collector_id in driver.network.data_collectors, "Collector not tracked" |
| 131 | + |
| 132 | + |
| 133 | +def test_add_data_collector_with_contexts(driver): |
| 134 | + collector_id = driver.network.add_data_collector( |
| 135 | + data_types=["response"], max_encoded_data_size=1000, contexts=[driver.current_window_handle] |
| 136 | + ) |
| 137 | + assert collector_id is not None, "Data collector with contexts not added" |
| 138 | + |
| 139 | + |
| 140 | +def test_remove_data_collector(driver): |
| 141 | + collector_id = driver.network.add_data_collector(data_types=["response"], max_encoded_data_size=1000) |
| 142 | + assert collector_id in driver.network.data_collectors, "Collector not tracked" |
| 143 | + |
| 144 | + driver.network.remove_data_collector(collector_id) |
| 145 | + assert collector_id not in driver.network.data_collectors, "Collector not removed" |
| 146 | + |
| 147 | + |
| 148 | +# Response Handler Tests |
| 149 | +def test_add_and_remove_response_handler(driver, pages): |
| 150 | + responses = [] |
| 151 | + |
| 152 | + def callback(response: Response): |
| 153 | + responses.append(response) |
| 154 | + |
| 155 | + callback_id = driver.network.add_response_handler("response_completed", callback) |
| 156 | + assert callback_id is not None, "Response handler not added" |
| 157 | + |
| 158 | + driver.network.remove_response_handler("response_completed", callback_id) |
| 159 | + |
| 160 | + pages.load("formPage.html") |
| 161 | + assert not responses, "Responses captured after handler removal" |
| 162 | + |
| 163 | + |
| 164 | +def test_clear_response_handlers(driver, pages): |
| 165 | + responses = [] |
| 166 | + |
| 167 | + def callback(response: Response): |
| 168 | + responses.append(response) |
| 169 | + |
| 170 | + callback_id_1 = driver.network.add_response_handler("response_completed", callback) |
| 171 | + assert callback_id_1 is not None, "Response handler not added" |
| 172 | + callback_id_2 = driver.network.add_response_handler("response_started", callback) |
| 173 | + assert callback_id_2 is not None, "Response handler not added" |
| 174 | + |
| 175 | + driver.network.clear_response_handlers() |
| 176 | + |
| 177 | + url = pages.url("formPage.html") |
| 178 | + driver.browsing_context.navigate(context=driver.current_window_handle, url=url, wait=ReadinessState.COMPLETE) |
| 179 | + |
| 180 | + assert not responses, "Responses captured after clearing handlers" |
| 181 | + |
| 182 | + |
| 183 | +def test_response_handler_captures_response_data(driver, pages): |
| 184 | + responses = [] |
| 185 | + |
| 186 | + def callback(response: Response): |
| 187 | + responses.append(response) |
| 188 | + |
| 189 | + callback_id = driver.network.add_response_handler("response_completed", callback) |
| 190 | + assert callback_id is not None, "Response handler not added" |
| 191 | + |
| 192 | + url = pages.url("formPage.html") |
| 193 | + driver.browsing_context.navigate(context=driver.current_window_handle, url=url, wait=ReadinessState.COMPLETE) |
| 194 | + |
| 195 | + # Wait for response |
| 196 | + time.sleep(2) |
| 197 | + |
| 198 | + assert len(responses) > 0 |
| 199 | + |
| 200 | + response = responses[0] |
| 201 | + assert response.request_id is not None |
| 202 | + assert "formPage.html" in response.url |
| 203 | + assert response.status_code is not None |
| 204 | + |
| 205 | + driver.network.remove_response_handler("response_completed", callback_id) |
| 206 | + |
| 207 | + |
| 208 | +# Integrated Tests: Response Handlers + Data Collection |
| 209 | +def test_data_collection_with_response_handler(driver, pages): |
| 210 | + captured_responses = [] |
| 211 | + collected_data = [] |
| 212 | + |
| 213 | + # Add a data collector |
| 214 | + collector_id = driver.network.add_data_collector(data_types=["response"], max_encoded_data_size=50000) |
| 215 | + |
| 216 | + def response_callback(response: Response): |
| 217 | + captured_responses.append(response) |
| 218 | + data = driver.network.get_data("response", response.request_id, collector_id) |
| 219 | + collected_data.append({"request_id": response.request_id, "url": response.url, "data": data}) |
| 220 | + |
| 221 | + # Add response handler |
| 222 | + handler_id = driver.network.add_response_handler("response_completed", response_callback) |
| 223 | + |
| 224 | + url = pages.url("formPage.html") |
| 225 | + driver.browsing_context.navigate(context=driver.current_window_handle, url=url, wait=ReadinessState.COMPLETE) |
| 226 | + |
| 227 | + # Wait for responses |
| 228 | + time.sleep(2) |
| 229 | + |
| 230 | + assert len(captured_responses) > 0, "No responses captured" |
| 231 | + assert "<title>We Leave From Here</title>" in collected_data[0]["data"].value |
| 232 | + |
| 233 | + driver.network.remove_response_handler("response_completed", handler_id) |
| 234 | + driver.network.remove_data_collector(collector_id) |
| 235 | + |
| 236 | + |
| 237 | +def test_response_handler_event_types(driver, pages): |
| 238 | + """Test both response_started and response_completed events.""" |
| 239 | + started_responses = [] |
| 240 | + completed_responses = [] |
| 241 | + |
| 242 | + def started_callback(response: Response): |
| 243 | + started_responses.append(response) |
| 244 | + |
| 245 | + def completed_callback(response: Response): |
| 246 | + completed_responses.append(response) |
| 247 | + |
| 248 | + # Add handlers for both events |
| 249 | + driver.network.add_response_handler("response_started", started_callback) |
| 250 | + driver.network.add_response_handler("response_completed", completed_callback) |
| 251 | + |
| 252 | + url = pages.url("formPage.html") |
| 253 | + driver.browsing_context.navigate(context=driver.current_window_handle, url=url, wait=ReadinessState.COMPLETE) |
| 254 | + |
| 255 | + # Wait for events |
| 256 | + time.sleep(1) |
| 257 | + |
| 258 | + assert len(completed_responses) > 0, "No response_completed events captured" |
| 259 | + assert len(started_responses) > 0, "No response_started events captured" |
| 260 | + |
| 261 | + driver.network.clear_response_handlers() |
| 262 | + |
| 263 | + |
| 264 | +def test_continue_response_with_intercept(driver, pages): |
| 265 | + """Test continue_response with response interception. |
| 266 | +
|
| 267 | + This test tests that response_started events can be intercepted |
| 268 | + and modified using continue_response(). |
| 269 | + """ |
| 270 | + intercepted_responses = [] |
| 271 | + |
| 272 | + def response_handler(response: Response): |
| 273 | + # Modify the response when it's intercepted |
| 274 | + response.continue_response( |
| 275 | + status_code=200, |
| 276 | + headers=[ |
| 277 | + {"name": "X-Modified", "value": {"type": "string", "value": "true"}}, |
| 278 | + ], |
| 279 | + ) |
| 280 | + intercepted_responses.append(response) |
| 281 | + |
| 282 | + handler_id = driver.network.add_response_handler("response_started", response_handler, intercept=True) |
| 283 | + |
| 284 | + url = pages.url("formPage.html") |
| 285 | + driver.browsing_context.navigate(context=driver.current_window_handle, url=url, wait=ReadinessState.COMPLETE) |
| 286 | + |
| 287 | + # Wait for events |
| 288 | + time.sleep(1) |
| 289 | + |
| 290 | + driver.network.remove_response_handler("response_started", handler_id) |
| 291 | + |
| 292 | + |
| 293 | +def test_response_handler_with_url_patterns(driver, pages): |
| 294 | + """Test response handler with URL pattern filtering.""" |
| 295 | + matched_responses = [] |
| 296 | + all_responses = [] |
| 297 | + |
| 298 | + def matched_callback(response: Response): |
| 299 | + matched_responses.append(response) |
| 300 | + |
| 301 | + def all_callback(response: Response): |
| 302 | + all_responses.append(response) |
| 303 | + |
| 304 | + # Add handler with URL pattern - only matches formPage.html |
| 305 | + driver.network.add_response_handler( |
| 306 | + "response_completed", matched_callback, url_patterns=[{"type": "string", "pattern": "*/formPage.html"}] |
| 307 | + ) |
| 308 | + |
| 309 | + # Add handler without pattern - matches all |
| 310 | + driver.network.add_response_handler("response_completed", all_callback) |
| 311 | + |
| 312 | + url = pages.url("formPage.html") |
| 313 | + driver.browsing_context.navigate(context=driver.current_window_handle, url=url, wait=ReadinessState.COMPLETE) |
| 314 | + |
| 315 | + # Wait for events |
| 316 | + time.sleep(1) |
| 317 | + |
| 318 | + assert len(matched_responses) <= len(all_responses) |
| 319 | + |
| 320 | + assert len(all_responses) > 0, "No responses captured" |
| 321 | + |
| 322 | + driver.network.clear_response_handlers() |
0 commit comments