[py] Enable and update Safari tests

Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/SeleniumHQ/selenium
Cr-Mirrored-Commit: 6a6bb5ecd649a786be576ddd770482ad4d02470f
diff --git a/BUILD.bazel b/BUILD.bazel
index 3dce920..d726b82 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -281,9 +281,9 @@
     name = "test-safari",
     size = "large",
     srcs = glob([
-        #        "test/selenium/webdriver/common/**/*.py",
+        "test/selenium/webdriver/common/**/*.py",
         "test/selenium/webdriver/safari/**/*.py",
-        #        "test/selenium/webdriver/support/**/*.py",
+        "test/selenium/webdriver/support/**/*.py",
     ]),
     args = [
         "--instafail",
@@ -291,6 +291,7 @@
     ],
     tags = [
         "no-sandbox",
+        "exclusive"
     ],
     deps = [
         ":init-tree",
diff --git a/test/selenium/webdriver/common/alerts_tests.py b/test/selenium/webdriver/common/alerts_tests.py
index 2e90af9..56bb7f8 100644
--- a/test/selenium/webdriver/common/alerts_tests.py
+++ b/test/selenium/webdriver/common/alerts_tests.py
@@ -159,6 +159,7 @@
 
 @pytest.mark.xfail_firefox(reason='Fails on travis')
 @pytest.mark.xfail_remote(reason='Fails on travis')
+@pytest.mark.xfail_safari
 def testShouldAllowUsersToAcceptAnAlertInAFrame(driver, pages):
     pages.load("alerts.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "iframeWithAlert"))
@@ -172,6 +173,7 @@
 
 @pytest.mark.xfail_firefox(reason='Fails on travis')
 @pytest.mark.xfail_remote(reason='Fails on travis')
+@pytest.mark.xfail_safari
 def testShouldAllowUsersToAcceptAnAlertInANestedFrame(driver, pages):
     pages.load("alerts.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "iframeWithIframe"))
@@ -227,6 +229,7 @@
     assert driver.find_element(By.ID, "text2").text == "cheddar"
 
 
+@pytest.mark.xfail_safari
 def testShouldHandleAlertOnPageLoad(driver, pages):
     pages.load("alerts.html")
     driver.find_element(By.ID, "open-page-with-onload-alert").click()
diff --git a/test/selenium/webdriver/common/api_example_tests.py b/test/selenium/webdriver/common/api_example_tests.py
index 716654d..3974925 100644
--- a/test/selenium/webdriver/common/api_example_tests.py
+++ b/test/selenium/webdriver/common/api_example_tests.py
@@ -288,6 +288,7 @@
 
 @pytest.mark.xfail_firefox(raises=WebDriverException)
 @pytest.mark.xfail_remote
+@pytest.mark.xfail_safari
 def testGetLogTypes(driver, pages):
     pages.load("blank.html")
     assert isinstance(driver.log_types, list)
@@ -295,6 +296,7 @@
 
 @pytest.mark.xfail_firefox(raises=WebDriverException)
 @pytest.mark.xfail_remote
+@pytest.mark.xfail_safari
 def testGetLog(driver, pages):
     pages.load("blank.html")
     for log_type in driver.log_types:
diff --git a/test/selenium/webdriver/common/appcache_tests.py b/test/selenium/webdriver/common/appcache_tests.py
index b79b549..cfc64ca 100644
--- a/test/selenium/webdriver/common/appcache_tests.py
+++ b/test/selenium/webdriver/common/appcache_tests.py
@@ -25,6 +25,7 @@
 @pytest.mark.xfail_chromiumedge
 @pytest.mark.xfail_firefox(raises=WebDriverException)
 @pytest.mark.xfail_remote
+@pytest.mark.xfail_safari
 def testWeCanGetTheStatusOfTheAppCache(driver, pages):
     pages.load('html5Page')
     driver.implicitly_wait(2)
diff --git a/test/selenium/webdriver/common/click_scrolling_tests.py b/test/selenium/webdriver/common/click_scrolling_tests.py
index 0c0eefc..ca0d080 100644
--- a/test/selenium/webdriver/common/click_scrolling_tests.py
+++ b/test/selenium/webdriver/common/click_scrolling_tests.py
@@ -101,6 +101,7 @@
     # If we don't throw, we're good
 
 
+@pytest.mark.xfail_safari
 def testShouldScrollOverflowElementsIfClickPointIsOutOfViewButElementIsInView(driver, pages):
     pages.load("scroll5.html")
     driver.find_element(By.ID, "inner").click()
@@ -111,6 +112,7 @@
     reason='https://github.com/w3c/webdriver/issues/408')
 @pytest.mark.xfail_remote(
     reason='https://github.com/w3c/webdriver/issues/408')
+@pytest.mark.xfail_safari
 def testShouldBeAbleToClickElementInAFrameThatIsOutOfView(driver, pages):
     pages.load("scrolling_tests/page_with_frame_out_of_view.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "frame"))
@@ -135,6 +137,7 @@
     # TODO we should assert that the click was unsuccessful
 
 
+@pytest.mark.xfail_safari
 def testShouldBeAbleToClickElementThatIsOutOfViewInAFrameThatIsOutOfView(driver, pages):
     pages.load("scrolling_tests/page_with_scrolling_frame_out_of_view.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "scrolling_frame"))
@@ -154,6 +157,7 @@
 
 
 @pytest.mark.xfail_firefox
+@pytest.mark.xfail_safari
 def testShouldBeAbleToClickElementThatIsOutOfViewInANestedFrameThatIsOutOfView(driver, pages):
     pages.load("scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "scrolling_frame"))
@@ -178,6 +182,7 @@
     reason='https://github.com/w3c/webdriver/issues/408')
 @pytest.mark.xfail_remote(
     reason='https://github.com/w3c/webdriver/issues/408')
+@pytest.mark.xfail_safari
 def testShouldBeAbleToClickElementInATallFrame(driver, pages):
     pages.load("scrolling_tests/page_with_tall_frame.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "tall_frame"))
diff --git a/test/selenium/webdriver/common/cookie_tests.py b/test/selenium/webdriver/common/cookie_tests.py
index dc7f80d..a322dd4 100644
--- a/test/selenium/webdriver/common/cookie_tests.py
+++ b/test/selenium/webdriver/common/cookie_tests.py
@@ -72,6 +72,7 @@
 
 @pytest.mark.xfail_firefox(reason='sameSite cookie attribute not implemented')
 @pytest.mark.xfail_remote(reason='sameSite cookie attribute not implemented')
+@pytest.mark.xfail_safari
 def testAddCookieSameSiteStrict(same_site_cookie_strict, driver):
     driver.add_cookie(same_site_cookie_strict)
     returned = driver.get_cookie('foo')
@@ -80,6 +81,7 @@
 
 @pytest.mark.xfail_firefox(reason='sameSite cookie attribute not implemented')
 @pytest.mark.xfail_remote(reason='sameSite cookie attribute not implemented')
+@pytest.mark.xfail_safari
 def testAddCookieSameSiteLax(same_site_cookie_lax, driver):
     driver.add_cookie(same_site_cookie_lax)
     returned = driver.get_cookie('foo')
@@ -87,6 +89,7 @@
 
 
 @pytest.mark.xfail_ie
+@pytest.mark.xfail_safari
 def testAddingACookieThatExpiredInThePast(cookie, driver):
     expired = cookie.copy()
     expired['expiry'] = calendar.timegm(time.gmtime()) - 1
diff --git a/test/selenium/webdriver/common/correct_event_firing_tests.py b/test/selenium/webdriver/common/correct_event_firing_tests.py
index 18a4d99..85a722f 100644
--- a/test/selenium/webdriver/common/correct_event_firing_tests.py
+++ b/test/selenium/webdriver/common/correct_event_firing_tests.py
@@ -15,28 +15,33 @@
 # specific language governing permissions and limitations
 # under the License.
 
+import pytest
 
 from selenium.webdriver.common.by import By
 
 
+@pytest.mark.xfail_safari
 def testShouldFireClickEventWhenClicking(driver, pages):
     pages.load("javascriptPage.html")
     _clickOnElementWhichRecordsEvents(driver)
     _assertEventFired(driver, "click")
 
 
+@pytest.mark.xfail_safari
 def testShouldFireMouseDownEventWhenClicking(driver, pages):
     pages.load("javascriptPage.html")
     _clickOnElementWhichRecordsEvents(driver)
     _assertEventFired(driver, "mousedown")
 
 
+@pytest.mark.xfail_safari
 def testShouldFireMouseUpEventWhenClicking(driver, pages):
     pages.load("javascriptPage.html")
     _clickOnElementWhichRecordsEvents(driver)
     _assertEventFired(driver, "mouseup")
 
 
+@pytest.mark.xfail_safari
 def testShouldIssueMouseDownEvents(driver, pages):
     pages.load("javascriptPage.html")
     driver.find_element(By.ID, "mousedown").click()
@@ -44,6 +49,7 @@
     assert result == "mouse down"
 
 
+@pytest.mark.xfail_safari
 def testShouldIssueClickEvents(driver, pages):
     pages.load("javascriptPage.html")
     driver.find_element(By.ID, "mouseclick").click()
@@ -51,6 +57,7 @@
     assert result == "mouse click"
 
 
+@pytest.mark.xfail_safari
 def testShouldIssueMouseUpEvents(driver, pages):
     pages.load("javascriptPage.html")
     driver.find_element(By.ID, "mouseup").click()
@@ -58,6 +65,7 @@
     assert result == "mouse up"
 
 
+@pytest.mark.xfail_safari
 def testMouseEventsShouldBubbleUpToContainingElements(driver, pages):
     pages.load("javascriptPage.html")
     driver.find_element(By.ID, "child").click()
@@ -65,6 +73,7 @@
     assert result == "mouse down"
 
 
+@pytest.mark.xfail_safari
 def testShouldEmitOnChangeEventsWhenSelectingElements(driver, pages):
     pages.load("javascriptPage.html")
     select = driver.find_element(By.ID, 'selector')
@@ -77,6 +86,7 @@
     assert driver.find_element(By.ID, "result").text == "bar"
 
 
+@pytest.mark.xfail_safari
 def testShouldEmitOnChangeEventsWhenChangingTheStateOfACheckbox(driver, pages):
     pages.load("javascriptPage.html")
     checkbox = driver.find_element(By.ID, "checkbox")
@@ -92,6 +102,7 @@
     assert clicker.get_attribute("value") == "Clicked"
 
 
+@pytest.mark.xfail_safari
 def testClearingAnElementShouldCauseTheOnChangeHandlerToFire(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(By.ID, "clearMe")
diff --git a/test/selenium/webdriver/common/driver_element_finding_tests.py b/test/selenium/webdriver/common/driver_element_finding_tests.py
index 1d7501f..d6e7842 100755
--- a/test/selenium/webdriver/common/driver_element_finding_tests.py
+++ b/test/selenium/webdriver/common/driver_element_finding_tests.py
@@ -541,6 +541,7 @@
     assert res.text == "link with formatting tags"
 
 
+@pytest.mark.xfail_safari
 def test_Driver_Can_Get_Link_By_Link_Test_Ignoring_Trailing_Whitespace(driver, pages):
     pages.load("simpleTest.html")
     link = driver.find_element(By.LINK_TEXT, "link with trailing space")
diff --git a/test/selenium/webdriver/common/element_attribute_tests.py b/test/selenium/webdriver/common/element_attribute_tests.py
index 1b36b3b..f13c5c6 100644
--- a/test/selenium/webdriver/common/element_attribute_tests.py
+++ b/test/selenium/webdriver/common/element_attribute_tests.py
@@ -100,6 +100,7 @@
     assert not textArea.is_enabled()
 
 
+@pytest.mark.xfail_safari
 def testShouldThrowExceptionIfSendingKeysToElementDisabledUsingRandomDisabledStrings(driver, pages):
     pages.load("formPage.html")
     disabledTextElement1 = driver.find_element(By.ID, "disabledTextElement1")
diff --git a/test/selenium/webdriver/common/executing_async_javascript_tests.py b/test/selenium/webdriver/common/executing_async_javascript_tests.py
index 61d2e1f..46fb270 100644
--- a/test/selenium/webdriver/common/executing_async_javascript_tests.py
+++ b/test/selenium/webdriver/common/executing_async_javascript_tests.py
@@ -91,6 +91,7 @@
     assert "body" == result.tag_name.lower()
 
 
+@pytest.mark.xfail_safari
 def testShouldBeAbleToReturnArraysOfWebElementsFromAsyncScripts(driver, pages):
     pages.load("ajaxy_page.html")
 
diff --git a/test/selenium/webdriver/common/frame_switching_tests.py b/test/selenium/webdriver/common/frame_switching_tests.py
index 8b8db3b..8a759b6 100644
--- a/test/selenium/webdriver/common/frame_switching_tests.py
+++ b/test/selenium/webdriver/common/frame_switching_tests.py
@@ -184,6 +184,7 @@
     assert driver.find_element(By.ID, "pageNumber").text == "1"
 
 
+@pytest.mark.xfail_safari
 def testShouldBeAbleToSwitchToParentFrameFromASecondLevelFrame(driver, pages):
     pages.load("frameset.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "fourth"))
@@ -229,6 +230,7 @@
                            reason='https://github.com/mozilla/geckodriver/issues/610')
 @pytest.mark.xfail_remote(raises=WebDriverException,
                           reason='https://github.com/mozilla/geckodriver/issues/610')
+@pytest.mark.xfail_safari
 def testShouldFocusOnTheReplacementWhenAFrameFollowsALinkToA_TopTargetedPage(driver, pages):
     pages.load("frameset.html")
     driver.switch_to.frame(0)
@@ -373,6 +375,7 @@
 @pytest.mark.xfail_remote(raises=WebDriverException,
                           reason='https://github.com/mozilla/geckodriver/issues/614')
 @pytest.mark.xfail_webkitgtk(raises=NoSuchElementException)
+@pytest.mark.xfail_safari
 def testShouldNotBeAbleToDoAnythingTheFrameIsDeletedFromUnderUs(driver, pages):
     pages.load("frame_switching_tests/deletingFrame.html")
     driver.switch_to.frame(driver.find_element(By.ID, "iframe1"))
@@ -398,6 +401,7 @@
 
 
 @pytest.mark.xfail_chrome(reason="Fails on Travis")
+@pytest.mark.xfail_safari
 def testShouldNotSwitchMagicallyToTheTopWindow(driver, pages):
     pages.load("frame_switching_tests/bug4876.html")
     driver.switch_to.frame(0)
diff --git a/test/selenium/webdriver/common/interactions_tests.py b/test/selenium/webdriver/common/interactions_tests.py
index d985522..8384511 100644
--- a/test/selenium/webdriver/common/interactions_tests.py
+++ b/test/selenium/webdriver/common/interactions_tests.py
@@ -46,6 +46,7 @@
     drop.perform()
 
 
+@pytest.mark.xfail_safari
 def testDraggingElementWithMouseMovesItToAnotherList(driver, pages):
     """Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""
     performDragAndDropWithMouse(driver, pages)
@@ -53,6 +54,7 @@
     assert 6 == len(dragInto.find_elements(By.TAG_NAME, "li"))
 
 
+@pytest.mark.xfail_safari
 def testDraggingElementWithMouseFiresEvents(driver, pages):
     """Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""
     performDragAndDropWithMouse(driver, pages)
@@ -69,6 +71,7 @@
         return False
 
 
+@pytest.mark.xfail_safari
 def testDragAndDrop(driver, pages):
     """Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""
     element_available_timeout = 15
@@ -97,6 +100,7 @@
     assert "Dropped!" == text
 
 
+@pytest.mark.xfail_safari
 def testDoubleClick(driver, pages):
     """Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""
     pages.load("javascriptPage.html")
@@ -144,6 +148,7 @@
         move.perform()
 
 
+@pytest.mark.xfail_safari
 def testClickingOnFormElements(driver, pages):
     """Copied from org.openqa.selenium.interactions.CombinedInputActionsTest."""
     pages.load("formSelectionPage.html")
@@ -163,6 +168,7 @@
 
 
 @pytest.mark.xfail_firefox
+@pytest.mark.xfail_safari
 def testSelectingMultipleItems(driver, pages):
     """Copied from org.openqa.selenium.interactions.CombinedInputActionsTest."""
     pages.load("selectableItems.html")
@@ -186,6 +192,7 @@
     assert "#item7" == reportingElement.text
 
 
+@pytest.mark.xfail_safari
 def testSendingKeysToActiveElementWithModifier(driver, pages):
     pages.load("formPage.html")
     e = driver.find_element(By.ID, "working")
diff --git a/test/selenium/webdriver/common/page_load_timeout_tests.py b/test/selenium/webdriver/common/page_load_timeout_tests.py
index c1d89fc..6eb935e 100644
--- a/test/selenium/webdriver/common/page_load_timeout_tests.py
+++ b/test/selenium/webdriver/common/page_load_timeout_tests.py
@@ -33,6 +33,7 @@
         pages.load("simpleTest.html")
 
 
+@pytest.mark.xfail_safari
 def testClickShouldTimeout(driver, pages):
     pages.load("simpleTest.html")
     driver.set_page_load_timeout(0.01)
diff --git a/test/selenium/webdriver/common/page_loading_tests.py b/test/selenium/webdriver/common/page_loading_tests.py
index 6cb1a63..1411ee5 100644
--- a/test/selenium/webdriver/common/page_loading_tests.py
+++ b/test/selenium/webdriver/common/page_loading_tests.py
@@ -81,6 +81,7 @@
 #     self.assertEqual(driver.title, anyOf(equalTo(originalTitle), equalTo("We Leave From Here")));
 
 
+@pytest.mark.xfail_safari
 def testShouldBeAbleToNavigateBackInTheBrowserHistory(driver, pages):
     pages.load("formPage.html")
 
@@ -91,6 +92,7 @@
     assert driver.title == "We Leave From Here"
 
 
+@pytest.mark.xfail_safari
 def testShouldBeAbleToNavigateBackInTheBrowserHistoryInPresenceOfIframes(driver, pages):
     pages.load("xhtmlTest.html")
 
diff --git a/test/selenium/webdriver/common/position_and_size_tests.py b/test/selenium/webdriver/common/position_and_size_tests.py
index 296bcb7..a6240f8 100644
--- a/test/selenium/webdriver/common/position_and_size_tests.py
+++ b/test/selenium/webdriver/common/position_and_size_tests.py
@@ -33,6 +33,7 @@
     'coordinates_tests/page_with_transparent_element.html',
     'coordinates_tests/page_with_hidden_element.html'),
     ids=('basic', 'empty', 'transparent', 'hidden'))
+@pytest.mark.xfail_safari
 def testShouldGetCoordinatesOfAnElement(page, driver, pages):
     pages.load(page)
     element = driver.find_element(By.ID, "box")
@@ -40,6 +41,7 @@
     _check_location(element.location, x=10, y=10)
 
 
+@pytest.mark.xfail_safari
 def testShouldGetCoordinatesOfAnInvisibleElement(driver, pages):
     pages.load("coordinates_tests/page_with_invisible_element.html")
     element = driver.find_element(By.ID, "box")
@@ -60,6 +62,7 @@
 @pytest.mark.xfail_chromiumedge
 @pytest.mark.xfail_firefox
 @pytest.mark.xfail_remote
+@pytest.mark.xfail_safari
 def testShouldGetCoordinatesOfAnElementInAFrame(driver, pages):
     pages.load("coordinates_tests/element_in_frame.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "ifr"))
@@ -72,6 +75,7 @@
 @pytest.mark.xfail_chromiumedge
 @pytest.mark.xfail_firefox
 @pytest.mark.xfail_remote
+@pytest.mark.xfail_safari
 def testShouldGetCoordinatesOfAnElementInANestedFrame(driver, pages):
     pages.load("coordinates_tests/element_in_nested_frame.html")
     driver.switch_to.frame(driver.find_element(By.NAME, "ifr"))
diff --git a/test/selenium/webdriver/common/select_class_tests.py b/test/selenium/webdriver/common/select_class_tests.py
index 0743286..52b7d9b 100644
--- a/test/selenium/webdriver/common/select_class_tests.py
+++ b/test/selenium/webdriver/common/select_class_tests.py
@@ -95,6 +95,7 @@
     reason='https://bugs.chromium.org/p/chromedriver/issues/detail?id=822')
 @pytest.mark.xfail_chromiumedge(
     reason='https://bugs.chromium.org/p/chromedriver/issues/detail?id=822')
+@pytest.mark.xfail_safari
 def testSelectByVisibleTextShouldNormalizeSpaces(driver, pages):
     pages.load("formPage.html")
 
diff --git a/test/selenium/webdriver/common/stale_reference_tests.py b/test/selenium/webdriver/common/stale_reference_tests.py
index bc81b25..301dbf1 100644
--- a/test/selenium/webdriver/common/stale_reference_tests.py
+++ b/test/selenium/webdriver/common/stale_reference_tests.py
@@ -29,6 +29,7 @@
         elem.click()
 
 
+@pytest.mark.xfail_safari
 def testShouldNotCrashWhenCallingGetSizeOnAnObsoleteElement(driver, pages):
     pages.load("simpleTest.html")
     elem = driver.find_element(by=By.ID, value="links")
@@ -37,6 +38,7 @@
         elem.size
 
 
+@pytest.mark.xfail_safari
 def testShouldNotCrashWhenQueryingTheAttributeOfAStaleElement(driver, pages):
     pages.load("xhtmlTest.html")
     heading = driver.find_element(by=By.XPATH, value="//h1")
diff --git a/test/selenium/webdriver/common/text_handling_tests.py b/test/selenium/webdriver/common/text_handling_tests.py
index 9c970ce..777b354 100644
--- a/test/selenium/webdriver/common/text_handling_tests.py
+++ b/test/selenium/webdriver/common/text_handling_tests.py
@@ -41,6 +41,7 @@
     assert "and block level elements" in text
 
 
+@pytest.mark.xfail_safari
 def testShouldIgnoreScriptElements(driver, pages):
     pages.load("javascriptEnhancedForm.html")
     labelForUsername = driver.find_element(by=By.ID, value="labelforusername")
@@ -51,6 +52,7 @@
     assert text == "Username:"
 
 
+@pytest.mark.xfail_safari
 def testShouldRepresentABlockLevelElementAsANewline(driver, pages):
     pages.load("simpleTest.html")
     text = driver.find_element(by=By.ID, value="multiline").text
@@ -60,6 +62,7 @@
     assert text.endswith("and block level elements")
 
 
+@pytest.mark.xfail_safari
 def testShouldCollapseMultipleWhitespaceCharactersIntoASingleSpace(driver, pages):
     pages.load("simpleTest.html")
     text = driver.find_element(by=By.ID, value="lotsofspaces").text
@@ -67,6 +70,7 @@
     assert text == "This line has lots of spaces."
 
 
+@pytest.mark.xfail_safari
 def testShouldTrimText(driver, pages):
     pages.load("simpleTest.html")
     text = driver.find_element(by=By.ID, value="multiline").text
@@ -75,6 +79,7 @@
     assert text.endswith("block level elements")
 
 
+@pytest.mark.xfail_safari
 def testShouldConvertANonBreakingSpaceIntoANormalSpaceCharacter(driver, pages):
     pages.load("simpleTest.html")
     text = driver.find_element(by=By.ID, value="nbsp").text
@@ -82,6 +87,7 @@
     assert text == "This line has a non-breaking space"
 
 
+@pytest.mark.xfail_safari
 def testShouldTreatANonBreakingSpaceAsAnyOtherWhitespaceCharacterWhenCollapsingWhitespace(driver, pages):
     pages.load("simpleTest.html")
     element = driver.find_element(by=By.ID, value="nbspandspaces")
@@ -90,6 +96,7 @@
     assert text == "This line has a   non-breaking space and spaces"
 
 
+@pytest.mark.xfail_safari
 def testHavingInlineElementsShouldNotAffectHowTextIsReturned(driver, pages):
     pages.load("simpleTest.html")
     text = driver.find_element(by=By.ID, value="inline").text
@@ -97,6 +104,7 @@
     assert text == "This line has text within elements that are meant to be displayed inline"
 
 
+@pytest.mark.xfail_safari
 def testShouldReturnTheEntireTextOfInlineElements(driver, pages):
     pages.load("simpleTest.html")
     text = driver.find_element(by=By.ID, value="span").text
@@ -127,6 +135,7 @@
     assert seenValue == expectedValue
 
 
+@pytest.mark.xfail_safari
 def testShouldReturnEmptyStringWhenTextIsOnlySpaces(driver, pages):
     pages.load("xhtmlTest.html")
 
@@ -149,6 +158,7 @@
     assert text == ""
 
 
+@pytest.mark.xfail_safari
 def testShouldHandleSiblingBlockLevelElements(driver, pages):
     pages.load("simpleTest.html")
 
@@ -156,6 +166,7 @@
     assert text == "Some text" + newLine + "Some more text"
 
 
+@pytest.mark.xfail_safari
 def testShouldHandleWhitespaceInInlineElements(driver, pages):
     pages.load("simpleTest.html")
 
@@ -170,6 +181,7 @@
     assert source.endswith("</html>")
 
 
+@pytest.mark.xfail_safari
 def testShouldOnlyIncludeVisibleText(driver, pages):
     pages.load("javascriptPage.html")
 
@@ -180,6 +192,7 @@
     assert "sub-element that is explicitly visible" == explicit
 
 
+@pytest.mark.xfail_safari
 def testShouldGetTextFromTableCells(driver, pages):
     pages.load("tables.html")
 
diff --git a/test/selenium/webdriver/common/typing_tests.py b/test/selenium/webdriver/common/typing_tests.py
index 0af7c13..8bd3590 100644
--- a/test/selenium/webdriver/common/typing_tests.py
+++ b/test/selenium/webdriver/common/typing_tests.py
@@ -101,6 +101,7 @@
     assert keyReporter.get_attribute("value") == "Test"
 
 
+@pytest.mark.xfail_safari
 def testWillSimulateAKeyUpWhenEnteringTextIntoInputElements(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyUp")
@@ -109,6 +110,7 @@
     assert result.text == "I like cheese"
 
 
+@pytest.mark.xfail_safari
 def testWillSimulateAKeyDownWhenEnteringTextIntoInputElements(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyDown")
@@ -119,6 +121,7 @@
     assert result.text == "I like chees"
 
 
+@pytest.mark.xfail_safari
 def testWillSimulateAKeyPressWhenEnteringTextIntoInputElements(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyPress")
@@ -129,6 +132,7 @@
     assert result.text == "I like chees"
 
 
+@pytest.mark.xfail_safari
 def testWillSimulateAKeyUpWhenEnteringTextIntoTextAreas(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyUpArea")
@@ -137,6 +141,7 @@
     assert result.text == "I like cheese"
 
 
+@pytest.mark.xfail_safari
 def testWillSimulateAKeyDownWhenEnteringTextIntoTextAreas(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyDownArea")
@@ -147,6 +152,7 @@
     assert result.text == "I like chees"
 
 
+@pytest.mark.xfail_safari
 def testWillSimulateAKeyPressWhenEnteringTextIntoTextAreas(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyPressArea")
@@ -294,6 +300,7 @@
     reason='https://bugzilla.mozilla.org/show_bug.cgi?id=1255258')
 @pytest.mark.xfail_remote(
     reason='https://bugzilla.mozilla.org/show_bug.cgi?id=1255258')
+@pytest.mark.xfail_safari
 def testNumberpadAndFunctionKeys(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyReporter")
@@ -313,6 +320,7 @@
     assert element.get_attribute("value") == "FUNCTION-KEYS-TOO"
 
 
+@pytest.mark.xfail_safari
 def testShiftSelectionDeletes(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="keyReporter")
diff --git a/test/selenium/webdriver/common/visibility_tests.py b/test/selenium/webdriver/common/visibility_tests.py
index 786ba85..5cdb3fb 100644
--- a/test/selenium/webdriver/common/visibility_tests.py
+++ b/test/selenium/webdriver/common/visibility_tests.py
@@ -15,6 +15,9 @@
 # specific language governing permissions and limitations
 # under the License.
 
+import pytest
+
+
 from selenium.common.exceptions import (
     ElementNotVisibleException,
     ElementNotInteractableException)
@@ -46,6 +49,7 @@
     assert shown.is_displayed() is True
 
 
+@pytest.mark.xfail_safari
 def testShouldModifyTheVisibilityOfAnElementDynamically(driver, pages):
     pages.load("javascriptPage.html")
     element = driver.find_element(by=By.ID, value="hideMe")
diff --git a/test/selenium/webdriver/common/w3c_interaction_tests.py b/test/selenium/webdriver/common/w3c_interaction_tests.py
index be4b1ba..9d02576 100644
--- a/test/selenium/webdriver/common/w3c_interaction_tests.py
+++ b/test/selenium/webdriver/common/w3c_interaction_tests.py
@@ -33,6 +33,7 @@
 
 
 @pytest.mark.xfail_firefox
+@pytest.mark.xfail_safari
 def testSendingKeysToActiveElementWithModifier(driver, pages):
     pages.load("formPage.html")
     e = driver.find_element(By.ID, "working")
@@ -149,6 +150,7 @@
 
 
 @pytest.mark.xfail_firefox
+@pytest.mark.xfail_safari
 @pytest.mark.xfail_remote(reason="Fails on Travis")
 def test_double_click(driver, pages):
     """Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""
diff --git a/test/selenium/webdriver/common/webdriverwait_tests.py b/test/selenium/webdriver/common/webdriverwait_tests.py
index c0fa6e4..b2573f1 100644
--- a/test/selenium/webdriver/common/webdriverwait_tests.py
+++ b/test/selenium/webdriver/common/webdriverwait_tests.py
@@ -167,6 +167,7 @@
         WebDriverWait(driver, 0.7).until(EC.title_contains("blanket"))
 
 
+@pytest.mark.xfail_safari
 def testExpectedConditionVisibilityOfElementLocated(driver, pages):
     pages.load("javascriptPage.html")
     with pytest.raises(TimeoutException):
@@ -176,6 +177,7 @@
     assert element.is_displayed() is True
 
 
+@pytest.mark.xfail_safari
 def testExpectedConditionVisibilityOf(driver, pages):
     pages.load("javascriptPage.html")
     hidden = driver.find_element(By.ID, 'clickToHide')
@@ -235,6 +237,7 @@
     assert element.is_displayed() is False
 
 
+@pytest.mark.xfail_safari
 def testExpectedConditionElementToBeClickable(driver, pages):
     pages.load("javascriptPage.html")
     with pytest.raises(TimeoutException):
diff --git a/test/selenium/webdriver/common/window_switching_tests.py b/test/selenium/webdriver/common/window_switching_tests.py
index d008c49..b11d2e3 100644
--- a/test/selenium/webdriver/common/window_switching_tests.py
+++ b/test/selenium/webdriver/common/window_switching_tests.py
@@ -79,6 +79,7 @@
         driver.switch_to.window("invalid name")
 
 
+@pytest.mark.xfail_safari
 def testShouldThrowNoSuchWindowExceptionOnAnAttemptToGetItsHandle(driver, pages):
     pages.load("xhtmlTest.html")
     current = driver.current_window_handle
@@ -114,6 +115,7 @@
 
 
 @pytest.mark.xfail_ie
+@pytest.mark.xfail_safari
 def testShouldThrowNoSuchWindowExceptionOnAnyElementOperationIfAWindowIsClosed(driver, pages):
     pages.load("xhtmlTest.html")
     current = driver.current_window_handle
@@ -144,6 +146,7 @@
     driver.find_element(By.ID, "linkId")
 
 
+@pytest.mark.xfail_safari
 def testCanCallGetWindowHandlesAfterClosingAWindow(driver, pages):
     pages.load("xhtmlTest.html")
     current = driver.current_window_handle
@@ -173,6 +176,7 @@
     assert current == new_handle
 
 
+@pytest.mark.xfail_safari
 def testThatAccessingFindingAnElementAfterWindowIsClosedAndHaventswitchedDoesntCrash(driver, pages):
     pages.load("xhtmlTest.html")
     current = driver.current_window_handle
diff --git a/test/selenium/webdriver/safari/launcher_tests.py b/test/selenium/webdriver/safari/launcher_tests.py
index e53391e..b4f9635 100644
--- a/test/selenium/webdriver/safari/launcher_tests.py
+++ b/test/selenium/webdriver/safari/launcher_tests.py
@@ -21,7 +21,7 @@
 
 
 def test_launch(driver):
-    assert driver.capabilities['browserName'] == 'safari'
+    assert driver.capabilities['browserName'] == 'Safari'
 
 
 def test_launch_with_invalid_executable_path_raises_exception(driver_class):
@@ -29,9 +29,10 @@
     assert not os.path.exists(path)
     with pytest.raises(Exception) as e:
         driver_class(executable_path=path)
-    assert 'SafariDriver requires Safari 10 on OSX El Capitan' in str(e)
+    assert 'are you running Safari 10 or later?' in str(e)
 
 
+@pytest.mark.skipif(not os.path.exists('/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'), reason="Preview not installed")
 class TestTechnologyPreview(object):
 
     @pytest.fixture
diff --git a/test/selenium/webdriver/support/event_firing_webdriver_tests.py b/test/selenium/webdriver/support/event_firing_webdriver_tests.py
index a901a22..e17c4f3 100644
--- a/test/selenium/webdriver/support/event_firing_webdriver_tests.py
+++ b/test/selenium/webdriver/support/event_firing_webdriver_tests.py
@@ -78,6 +78,7 @@
             b"after_navigate_forward") == log.getvalue()
 
 
+@pytest.mark.xfail_safari
 def test_should_fire_click_event(driver, log, pages):
 
     class EventListener(AbstractEventListener):
@@ -232,6 +233,7 @@
     assert to_click.get_attribute('value') == 'Clicked'
 
 
+@pytest.mark.xfail_safari
 def test_can_use_key_input_with_event_firing_webdriver(driver, pages):
     ef_driver = EventFiringWebDriver(driver, AbstractEventListener())
     pages.load("javascriptPage.html")