Skip to content

Commit 702c97b

Browse files
authored
[py] retry safaridriver startup in tests (#17615)
* [py][rb] retry SafariDriver startup and remove Safari 26.5 test guards * [py] retry driver start on connection errors, not just WebDriverException
1 parent f98e870 commit 702c97b

25 files changed

Lines changed: 67 additions & 123 deletions

py/conftest.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,20 @@
1717

1818
import http.server
1919
import json
20+
import logging
2021
import os
2122
import socketserver
2223
import sys
2324
import threading
25+
import time
2426
import types
2527
from dataclasses import dataclass
2628
from pathlib import Path
2729

2830
import pytest
2931
import rich.console
3032
import rich.traceback
33+
import urllib3
3134

3235
try:
3336
from python.runfiles import Runfiles # only exists when using bazel
@@ -41,6 +44,8 @@
4144
from test.selenium.webdriver.common.network import get_lan_ip
4245
from test.selenium.webdriver.common.webserver import SimpleWebServer
4346

47+
logger = logging.getLogger(__name__)
48+
4449
drivers = (
4550
"chrome",
4651
"edge",
@@ -296,6 +301,9 @@ class SupportedBidiDrivers(ContainerProtocol):
296301

297302

298303
class Driver:
304+
DRIVER_START_RETRIES = 3
305+
DRIVER_START_INTERVAL = 1
306+
299307
def __init__(self, driver_class, request):
300308
self.driver_class = driver_class
301309
self._request = request
@@ -455,9 +463,25 @@ def _initialize_driver(self):
455463
if self.is_remote:
456464
kwargs["command_executor"] = self._server.status_url.removesuffix("/status")
457465
return webdriver.Remote(**kwargs)
458-
if self.driver_path is not None:
459-
kwargs["service"] = self.service
460-
return getattr(webdriver, self.driver_class)(**kwargs)
466+
return self._start_local_driver(kwargs)
467+
468+
def _start_local_driver(self, kwargs):
469+
for attempt in range(1, self.DRIVER_START_RETRIES + 1):
470+
if self.driver_path is not None:
471+
kwargs["service"] = self.service
472+
try:
473+
return getattr(webdriver, self.driver_class)(**kwargs)
474+
except (WebDriverException, urllib3.exceptions.HTTPError, OSError) as e:
475+
if attempt == self.DRIVER_START_RETRIES:
476+
raise
477+
logger.warning(
478+
"%s failed to start (attempt %s/%s); retrying. Error: %s",
479+
self.driver_class,
480+
attempt,
481+
self.DRIVER_START_RETRIES,
482+
e,
483+
)
484+
time.sleep(self.DRIVER_START_INTERVAL)
461485

462486
def stop_driver(self):
463487
driver_to_stop = self._driver

py/test/selenium/webdriver/common/alerts_tests.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def close_alert(driver):
3838
pass
3939

4040

41-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
4241
def test_should_be_able_to_override_the_window_alert_method(driver, pages):
4342
pages.load("alerts.html")
4443
driver.execute_script("window.alert = function(msg) { document.getElementById('text').innerHTML = msg; }")
@@ -55,7 +54,6 @@ def test_should_be_able_to_override_the_window_alert_method(driver, pages):
5554
raise e
5655

5756

58-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
5957
def test_should_allow_users_to_accept_an_alert_manually(driver, pages):
6058
pages.load("alerts.html")
6159
driver.find_element(by=By.ID, value="alert").click()
@@ -65,7 +63,6 @@ def test_should_allow_users_to_accept_an_alert_manually(driver, pages):
6563
assert "Testing Alerts" == driver.title
6664

6765

68-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
6966
def test_should_allow_users_to_accept_an_alert_with_no_text_manually(driver, pages):
7067
pages.load("alerts.html")
7168
driver.find_element(By.ID, "empty-alert").click()
@@ -76,7 +73,6 @@ def test_should_allow_users_to_accept_an_alert_with_no_text_manually(driver, pag
7673
assert "Testing Alerts" == driver.title
7774

7875

79-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
8076
def test_should_get_text_of_alert_opened_in_set_timeout(driver, pages):
8177
pages.load("alerts.html")
8278
driver.find_element(By.ID, "slow-alert").click()
@@ -92,7 +88,6 @@ def test_should_get_text_of_alert_opened_in_set_timeout(driver, pages):
9288
alert.accept()
9389

9490

95-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
9691
def test_should_allow_users_to_dismiss_an_alert_manually(driver, pages):
9792
pages.load("alerts.html")
9893
driver.find_element(by=By.ID, value="alert").click()
@@ -102,7 +97,6 @@ def test_should_allow_users_to_dismiss_an_alert_manually(driver, pages):
10297
assert "Testing Alerts" == driver.title
10398

10499

105-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
106100
def test_should_allow_auser_to_accept_aprompt(driver, pages):
107101
pages.load("alerts.html")
108102
driver.find_element(by=By.ID, value="prompt").click()
@@ -113,7 +107,6 @@ def test_should_allow_auser_to_accept_aprompt(driver, pages):
113107
assert "Testing Alerts" == driver.title
114108

115109

116-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
117110
def test_should_allow_auser_to_dismiss_aprompt(driver, pages):
118111
pages.load("alerts.html")
119112
driver.find_element(by=By.ID, value="prompt").click()
@@ -124,7 +117,6 @@ def test_should_allow_auser_to_dismiss_aprompt(driver, pages):
124117
assert "Testing Alerts" == driver.title
125118

126119

127-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
128120
def test_should_allow_auser_to_set_the_value_of_aprompt(driver, pages):
129121
pages.load("alerts.html")
130122
driver.find_element(by=By.ID, value="prompt").click()
@@ -136,7 +128,6 @@ def test_should_allow_auser_to_set_the_value_of_aprompt(driver, pages):
136128
assert "cheese" == result
137129

138130

139-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
140131
@pytest.mark.xfail_firefox
141132
@pytest.mark.xfail_remote
142133
def test_setting_the_value_of_an_alert_throws(driver, pages):
@@ -155,7 +146,6 @@ def test_setting_the_value_of_an_alert_throws(driver, pages):
155146
@pytest.mark.xfail_edge(
156147
condition=sys.platform == "darwin", reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=26", run=False
157148
)
158-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
159149
def test_alert_should_not_allow_additional_commands_if_dimissed(driver, pages):
160150
pages.load("alerts.html")
161151
driver.find_element(By.ID, "alert").click()
@@ -208,7 +198,6 @@ def test_should_throw_an_exception_if_an_alert_has_not_been_dealt_with_and_dismi
208198
# Alert would be dismissed automatically
209199

210200

211-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
212201
def test_prompt_should_use_default_value_if_no_keys_sent(driver, pages):
213202
pages.load("alerts.html")
214203
driver.find_element(By.ID, "prompt-with-default").click()
@@ -220,7 +209,6 @@ def test_prompt_should_use_default_value_if_no_keys_sent(driver, pages):
220209
assert "This is a default value" == txt
221210

222211

223-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
224212
def test_prompt_should_have_null_value_if_dismissed(driver, pages):
225213
pages.load("alerts.html")
226214
driver.find_element(By.ID, "prompt-with-default").click()
@@ -230,7 +218,6 @@ def test_prompt_should_have_null_value_if_dismissed(driver, pages):
230218
assert "null" == driver.find_element(By.ID, "text").text
231219

232220

233-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
234221
def test_handles_two_alerts_from_one_interaction(driver, pages):
235222
pages.load("alerts.html")
236223

@@ -270,7 +257,6 @@ def test_should_handle_alert_on_page_load_using_get(driver, pages):
270257
)
271258

272259

273-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
274260
@pytest.mark.xfail_chrome(reason="Non W3C conformant")
275261
@pytest.mark.xfail_edge(reason="Non W3C conformant")
276262
def test_should_handle_alert_on_page_before_unload(driver, pages):
@@ -281,7 +267,6 @@ def test_should_handle_alert_on_page_before_unload(driver, pages):
281267
WebDriverWait(driver, 3).until(EC.title_is("Testing Alerts"))
282268

283269

284-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
285270
def test_should_allow_the_user_to_get_the_text_of_an_alert(driver, pages):
286271
pages.load("alerts.html")
287272
driver.find_element(by=By.ID, value="alert").click()
@@ -291,7 +276,6 @@ def test_should_allow_the_user_to_get_the_text_of_an_alert(driver, pages):
291276
assert "cheese" == value
292277

293278

294-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
295279
def test_should_allow_the_user_to_get_the_text_of_aprompt(driver, pages):
296280
pages.load("alerts.html")
297281
driver.find_element(By.ID, "prompt").click()
@@ -303,7 +287,6 @@ def test_should_allow_the_user_to_get_the_text_of_aprompt(driver, pages):
303287
assert "Enter something" == value
304288

305289

306-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
307290
def test_alert_should_not_allow_additional_commands_if_dismissed(driver, pages):
308291
pages.load("alerts.html")
309292
driver.find_element(By.ID, "alert").click()

py/test/selenium/webdriver/common/click_scrolling_tests.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from selenium.webdriver.support.ui import WebDriverWait
2424

2525

26-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
2726
def test_clicking_on_anchor_scrolls_page(driver, pages):
2827
scrollScript = """var pageY;
2928
if (typeof(window.pageYOffset) == 'number') {
@@ -54,7 +53,6 @@ def test_should_scroll_to_click_on_an_element_hidden_by_overflow(driver, pages):
5453
pytest.fail(f"Should not be out of bounds: {e.msg}")
5554

5655

57-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
5856
def test_should_be_able_to_click_on_an_element_hidden_by_overflow(driver, pages):
5957
pages.load("scroll.html")
6058

@@ -64,7 +62,6 @@ def test_should_be_able_to_click_on_an_element_hidden_by_overflow(driver, pages)
6462
assert "line8" == driver.find_element(By.ID, "clicked").text
6563

6664

67-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
6865
@pytest.mark.xfail_firefox
6966
@pytest.mark.xfail_remote
7067
def test_should_be_able_to_click_on_an_element_hidden_by_double_overflow(driver, pages):
@@ -74,7 +71,6 @@ def test_should_be_able_to_click_on_an_element_hidden_by_double_overflow(driver,
7471
WebDriverWait(driver, 3).until(EC.title_is("Clicked Successfully!"))
7572

7673

77-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
7874
def test_should_be_able_to_click_on_an_element_hidden_by_yoverflow(driver, pages):
7975
pages.load("scrolling_tests/page_with_y_overflow_auto.html")
8076

@@ -125,7 +121,6 @@ def test_should_be_able_to_click_element_in_aframe_that_is_out_of_view(driver, p
125121
assert element.is_selected()
126122

127123

128-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
129124
def test_should_be_able_to_click_element_that_is_out_of_view_in_aframe(driver, pages):
130125
pages.load("scrolling_tests/page_with_scrolling_frame.html")
131126
driver.switch_to.frame(driver.find_element(By.NAME, "scrolling_frame"))
@@ -151,7 +146,6 @@ def test_should_be_able_to_click_element_that_is_out_of_view_in_aframe_that_is_o
151146
assert element.is_selected()
152147

153148

154-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
155149
@pytest.mark.xfail_firefox
156150
@pytest.mark.xfail_chrome
157151
@pytest.mark.xfail_remote

py/test/selenium/webdriver/common/click_tests.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,11 @@ def loadPage(pages):
2727
pages.load("clicks.html")
2828

2929

30-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
3130
def test_can_click_on_alink_that_overflows_and_follow_it(driver):
3231
driver.find_element(By.ID, "overflowLink").click()
3332
WebDriverWait(driver, 3).until(EC.title_is("XHTML Test Page"))
3433

3534

36-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
3735
def test_clicking_alink_made_up_of_numbers_is_handled_correctly(driver):
3836
driver.find_element(By.LINK_TEXT, "333333").click()
3937
WebDriverWait(driver, 3).until(EC.title_is("XHTML Test Page"))

py/test/selenium/webdriver/common/correct_event_firing_tests.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ def test_should_emit_on_change_events_when_changing_the_state_of_acheckbox(drive
9494
assert driver.find_element(By.ID, "result").text == "checkbox thing"
9595

9696

97-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
9897
def test_should_emit_click_event_when_clicking_on_atext_input_element(driver, pages):
9998
pages.load("javascriptPage.html")
10099
clicker = driver.find_element(By.ID, "clickField")

py/test/selenium/webdriver/common/element_attribute_tests.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ def test_should_indicate_when_aselect_is_disabled(driver, pages):
123123
assert not disabled.is_enabled()
124124

125125

126-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
127126
def test_should_return_the_value_of_checked_for_acheckbox_even_if_it_lacks_that_attribute(driver, pages):
128127
pages.load("formPage.html")
129128
checkbox = driver.find_element(By.XPATH, "//input[@id='checky']")
@@ -132,7 +131,6 @@ def test_should_return_the_value_of_checked_for_acheckbox_even_if_it_lacks_that_
132131
assert "true" == checkbox.get_attribute("checked")
133132

134133

135-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
136134
def test_should_return_the_value_of_selected_for_radio_buttons_even_if_they_lack_that_attribute(driver, pages):
137135
pages.load("formPage.html")
138136
neverSelected = driver.find_element(By.ID, "cheese")

py/test/selenium/webdriver/common/executing_async_javascript_tests.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ def test_should_catch_errors_when_executing_initial_script(driver, pages):
151151
driver.execute_async_script("throw Error('you should catch this!');")
152152

153153

154-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
155154
def test_should_be_able_to_execute_asynchronous_scripts(driver, pages):
156155
pages.load("ajaxy_page.html")
157156

py/test/selenium/webdriver/common/form_handling_tests.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from selenium.webdriver.support.ui import WebDriverWait
2424

2525

26-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
2726
def test_should_click_on_submit_input_elements(driver, pages):
2827
pages.load("formPage.html")
2928
driver.find_element(By.ID, "submitButton").click()
@@ -35,7 +34,6 @@ def test_clicking_on_unclickable_elements_does_nothing(driver, pages):
3534
driver.find_element(By.XPATH, "//body").click()
3635

3736

38-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
3937
def test_should_be_able_to_click_image_buttons(driver, pages):
4038
pages.load("formPage.html")
4139
driver.find_element(By.ID, "imageButton").click()
@@ -100,7 +98,6 @@ def test_should_enter_data_into_form_fields(driver, pages):
10098
assert newFormValue == "some text"
10199

102100

103-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
104101
def test_should_be_able_to_select_acheck_box(driver, pages):
105102
pages.load("formPage.html")
106103
checkbox = driver.find_element(By.ID, "checky")
@@ -111,7 +108,6 @@ def test_should_be_able_to_select_acheck_box(driver, pages):
111108
assert checkbox.is_selected() is False
112109

113110

114-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
115111
def test_should_toggle_the_checked_state_of_acheckbox(driver, pages):
116112
pages.load("formPage.html")
117113
checkbox = driver.find_element(By.ID, "checky")
@@ -122,7 +118,6 @@ def test_should_toggle_the_checked_state_of_acheckbox(driver, pages):
122118
assert checkbox.is_selected() is False
123119

124120

125-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
126121
def test_toggling_acheckbox_should_return_its_current_state(driver, pages):
127122
pages.load("formPage.html")
128123
checkbox = driver.find_element(By.ID, "checky")
@@ -133,7 +128,6 @@ def test_toggling_acheckbox_should_return_its_current_state(driver, pages):
133128
assert checkbox.is_selected() is False
134129

135130

136-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
137131
def test_should_be_able_to_select_aradio_button(driver, pages):
138132
pages.load("formPage.html")
139133
radioButton = driver.find_element(By.ID, "peas")
@@ -142,7 +136,6 @@ def test_should_be_able_to_select_aradio_button(driver, pages):
142136
assert radioButton.is_selected() is True
143137

144138

145-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
146139
def test_should_be_able_to_select_aradio_button_by_clicking_on_it(driver, pages):
147140
pages.load("formPage.html")
148141
radioButton = driver.find_element(By.ID, "peas")
@@ -226,7 +219,6 @@ def test_should_be_able_to_clear_text_from_text_areas(driver, pages):
226219
assert len(value) == 0
227220

228221

229-
@pytest.mark.xfail_safari(reason="SafariDriver 26.5 regression")
230222
def test_radio_should_not_be_selected_after_selecting_sibling(driver, pages):
231223
pages.load("formPage.html")
232224
cheese = driver.find_element(By.ID, "cheese")

0 commit comments

Comments
 (0)