Test Automation on Safari Browser with Safari Driver and Selenium

Test Automation on Safari Browser with Safari Driver and Selenium

We all know that Google Chrome is the most popular browser in the world. But do you know, with 17.24% of the overall browser market share, Safari is the second most popular one?

The reason behind Safari’s strong presence is that it is the default web browser for all Apple devices. And we know how much developers and coders love macOS, making it absolutely necessary to ensure that our websites’ are tested and optimized for all Safari versions.

The latest versions of Safari (10 and above) come with safaridriver, an in-built option to carry out websites’ debugging. However, the earlier versions of Safari required you to install the Safari WebDriver extension, which is no longer supported in the latest versions. Safari browser instead uses the safaridriver to implement WebDriver protocol.

In this blog, we will see how to use Selenium safaridriver to perform testing on the Safari browser.

Note: You need to have Safari on the Mac machine, as Apple has withdrawn the support of SafariDriver from Safari browser for windows.

Selenium Safari Driver For Automation Testing

To use the Selenium framework for automation testing, you should have a corresponding Selenium WebDriver (e.g., Chrome WebDriver for Chrome, Geckodriver for Firefox, etc.) installed on the machine, learn more about What Is Selenium & its importance. However, in Selenium automation testing with Safari on macOS, there is no need to download Safari driver for Selenium WebDriver separately.

Starting from Safari 10 on OS X El Capitan and macOS Sierra, the browser provides native support for the Selenium WebDriver API. As Selenium Safari driver for mac is preloaded on the OS, you need not mention the executable path for creating the Selenium WebDriver object.

Optimize your data management workflow with our SQL to YAML Converter. Convert SQL queries to YAML files and easily manage and share data configurations.

Download Safari Driver for Selenium WebDriver

As already discussed, we don’t have to download Safari’s driver for Selenium WebDriver. Instead, Safari’s in-built driver called safaridriver is presently available in most Selenium client libraries. The safaridriver is maintained by the web developer experience team at Apple. Apple’s safaridriver executable path is /usr/bin/safaridriver. As Safari Technology Preview also provides its own executable safaridriver, it is a path of the application’s bundled contents.

The safaridriver from Safari and safaridriver from Safari Technology Preview can run simultaneously, as each safaridriver only launches the Safari browser it is associated with.

The legacy SafariDriver which was maintained by the Selenium project, is deprecated and should not be used. In any case, Safari throws the error ‘Safari no longer supports unsafe extensions’ if you even attempt to install the deprecated Selenium WebDriver for Safari.

For using the Selenium safaridriver for automation testing, you only require Safari 10 (or later) installed on the machine since there is native support for Selenium WebDriver API in those Safari versions.

Starting from Selenium 3.0.0 release, Python and Java Client libraries offer support for native driver implementation of Safari.

Configure Safari for enabling WebDriver Support

Even though native support for the Selenium WebDriver API is available in Safari 10 (and above), the WebDriver support is turned off by default. Follow the below-mentioned steps for enabling WebDriver support in Safari:

macOS High Sierra (and later)

Step 1: Run the following command on the terminal:

/usr/bin/safaridriver --enable

Note: You may need to do so in case you are upgrading from a previous macOS release.

macOS Sierra (and earlier)

Step 1: Enable the ‘Show Developer’ menu in Safari through Safari ?Preferences ? Advanced ? Select ‘Show Develop menu in menu bar’ (if it is not checked).

Step 2: Choose Develop > Allow Remote Automation.

Step 3: Now, authorize safaridriver to launch the XPC service that hosts the local webserver. For this, run /usr/bin/safaridriver once and follow the authentication prompt.

As we would be using Apple’s safaridriver for Selenium test automation on macOS Catalina, we would be only executing /usr/bin/safaridriver –enable (or safaridriver –enable) once on the terminal.

From SQL to JSON in a snap! Convert SQL queries to JSON effortlessly with our SQL to JSON converter, enhancing compatibility and data interchange. Try it now!

Salient Features Of Selenium Safari Driver On macOS

For supporting WebDriver without sacrificing user’s privacy and security, there are additional safeguards that ensure that Selenium test execution is completely isolated from normal browsing data and other test runs.

Here are some of the salient features of Selenium Safari driver on macOS:

Feature #1: Isolated Automation Windows

The safaridriver developed by Apple’s web developer experienced team ensures that the test execution and Selenium test automation scenarios are confined to special automation windows. This means that the tests being executed using the safari driver will be isolated from normal browsing windows, user settings, and preferences.

Like automation testing performed using geckodriver (for Firefox), Safari windows on which tests are being executed can be identified by their orange Smart Search field.

Like a private browsing session in Safari, automation tests using Apple’s safaridriver start afresh so that the previous test session’s persistent state does not have any implications on the newly fired Selenium test automation scenario.

Simplify your data export process with our efficient SQL to CSV Converter. Convert SQL queries to CSV format seamlessly and unlock data versatility. Try it now!

Feature #2: Web Inspector

Web Inspector (or Inspect) tool can be used during and after the Selenium WebDriver test’s execution. Features such as locating details about web elements, monitoring network performance, recording performance, etc., in Web Inspector are completely functional when Selenium test automation scenarios are being executed.

The option Develop > Show Web Inspector menu item launches the inspection tool when the Selenium WebDriver tests are running.

Feature #3: Selenium WebDriver commands for debugging

Selenium Safari driver on macOS lets you specify WebDriver capabilities in a New Session for debugging.

The safaridriver preloads Web Inspector and JavaScript debugger in the background when the Safari:automaticInspection capability is passed in a New Session request. Like the Inspect tool, you also have the option to pause the test execution for checking the execution details in the Debugger tab of Web Inspector.

The safaridriver preloads Web Inspector and starts timeline recording in the background when the Safari:automaticProfiling capability is passed in a New Session request. The details can be viewed in the Timeline tab of the Web Inspector.

Feature #4: Glass Pane

A Glass Pane is installed over the Safari window, where the execution of the automation test is in progress. The glass pane intends to block any interactions such as a mouse, keyboard, resizing, closing, minimizing, etc., that can be performed manually and can hinder the test being performed in the Automation Window.

However, there is a way to break the glass pane if the test in progress is stuck (or failed) or you want to check something in the automation window manually. Once the glass pane is broken, the Selenium test automation session is interrupted, and the automation window continues to remain open for further inspection until it is closed manually.

Shown below is the popup window which comes up when we try to break the WebDriver Session:

  • Turn off All Automation — This option will disable ‘Develop > Allow Remote Automation,’ enabled for using Selenium Safari driver in macOS for running automation tests.
    The command safaridriver –enable has to be rerun on the terminal if you want to run tests in the Safari browser.

  • Stop Session — This option stops the current WebDriver session, and you can continue to interact with the browser.

  • Continue Session — This option continues the session, i.e., the test is run from the point where it was paused. Once this option is selected, you would not be able to interact with the browser.

Feature #5: Only one session at a time

At a time, you can only attach one WebDriver session to the instance of the Safari browser. Hence, only one Safari instance and WebDriver session attached to it can be active during automation testing.

As per Apple’s official blog, these constraints prevent the tests from internally competing with each other for resources like window focus, keyboard events, keyboard focus, and more. It also reflects what you can do in a macOS, windowing environment.

Testing With Selenium Safari Driver On macOS

Now that we have set up Apple’s Safari driver, we look at the process of setting up Selenium WebDriver on macOS and running a test in Python. Selenium locators should be used to locate the element on which you intend to perform the required operation. When a test scenario calls a Selenium command , the command is executed in the following manner:

  1. Every Selenium command is translated into a REST API command by the client library.

  2. The REST API command sends the HTTP request to the local web server that is hosted by Apple’s safaridriver.

  3. The safaridriver validates the HTTP request contents, and the command is forwarded to the browser instance.

  4. Once the command execution is complete, the safaridriver sends an HTTP response, which the client library interprets. The corresponding result is returned to the test code.

Let’s look at a cross browser testing scenario that showcases Selenium Safari’s driver on macOS demonstration. Here is the test scenario:

We would be using the PyTest framework for the demonstration. For a quick recap about PyTest, you can refer to this detailed Selenium WebDriver tutorial. You can install PyTest on macOS by triggering the command pip install pytest on the terminal. You can also Cross Browser Test on mac Elcapitan Browsers Online or test on mac yosemite.

Implementation

import pytest
from selenium import webdriver
@pytest.fixture(scope="class")

def driver_init(request):
    web_driver = webdriver.Safari()
    request.cls.driver = web_driver
    yield
    web_driver.close()

Looking for an easy way to convert your HTML files to JADE? Try our free online HTML to JADE converter tool to convert your HTML files to JADE format in seconds.

Code WalkThrough

A new browser instance has to be loaded for each test. Hence, the scope of the fixture is set to class instead of the session.

import pytest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
from time import sleep
import sys

@pytest.mark.usefixtures("driver_init")
class BasicTest:
    pass
class Test_URL_Safari(BasicTest):
    def test_lambdatest_todo_app(self):
        self.driver.get('https://lambdatest.github.io/sample-todo-app/')
        self.driver.maximize_window()

        self.driver.find_element(By.NAME, "li1").click()
        self.driver.find_element(By.NAME, "li2").click()

        title = "Sample page - lambdatest.com"
        assert title ==  self.driver.title

        sample_text = "Happy Testing at LambdaTest"
        email_text_field =  self.driver.find_element(By.ID, "sampletodotext")
        email_text_field.send_keys(sample_text)
        time.sleep(5)

        self.driver.find_element(By.ID, "addbutton").click()
        time.sleep(5)

        output_str =  self.driver.find_element(By.NAME, "li6").text
        sys.stderr.write(output_str)

        time.sleep(2)

Line (9) — The @pytest.mark.usefixtures is included for using the fixture driver_init().

@pytest.mark.usefixtures(“driver_init”)

Lines (14–15) — Selenium WebDriver APIs are used for setting the test URL to the LambdaTest ToDo page. The browser window is maximized using the maximize_window() method.

self.driver.get('https://lambdatest.github.io/sample-todo-app/')
self.driver.maximize_window()

Lines (17–18) — The Inspect tool in Safari (or any preferred browser of your choice on macOS) can be used for locating the details of the web element.

The find_element Selenium API is used for locating the element with NAME ‘li1’ and ‘li2’.

self.driver.find_element(By.NAME, "li1").click()
self.driver.find_element(By.NAME, "li2").click()

Lines (24–27) — The details of the web element with ID ‘sampletodotext’ are located using Safari’s Web Inspector tool. The send_keys() method is used to send the required string to that text box.

email_text_field =  self.driver.find_element(By.ID, "sampletodotext")
email_text_field.send_keys(sample_text)
time.sleep(5)

self.driver.find_element(By.ID, "addbutton").click()
time.sleep(5)

Line (29) — A click() operation is performed on the button with ID ‘addbutton’.

self.driver.find_element(By.ID, “addbutton”).click()

Execution

The execution is performed by invoking the following command on the terminal.

pytest -s –v test_lambdatest_todo_App.py

Here is the screenshot of the execution, which indicates the test did not pass!

We’ve noticed in some of the threads on Stack OverFlow that Selenium tests are broken on Safari 13 since the click() operation does not work on Safari 13. We also tried the workaround of using Selenium JavaScript with Python on macOS Catalina; however, that also did not work.

Now run your browser testing on iPad simulator!!!

Testing Of Selenium Safari Driver On macOS On Cloud-Based Grid

In this section, we’ll execute the same test scenario on LambdaTest that provides a Selenium Grid on the cloud. To get started, you need to create an account on LambdaTest and note username & access-key from the Profile page.

The test scenario will be executed on Safari 13.0, which is installed on macOS Catalina. The browser capabilities are generated using the LambdaTest capabilities generator.

We make the necessary changes in conftest.py to use the Remote SeleniumWebDriver instead of the local Selenium WebDriver.

Online CSS to STYLUS converter to convert CSS string to Styl. Get clean, readable code instantly. Start converting today!

Implementation

import pytest
from selenium import webdriver
import urllib3

saf_capabilities = {
        "build" : "Safaridriver on MacOs Catalina",
        "name" : "Safaridriver on MacOs Catalina",
        "platform" : "MacOS Catalina",
        "browserName" : "Safari",
        "version" : "13.0"
}

user_name = "user-name-not-email-address"
app_key = "access-key"

@pytest.fixture(scope="class")

def driver_init(request):
    # web_driver = webdriver.Safari()
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    remote_url = "http://" + user_name + ":" + app_key + "@hub.lambdatest.com/wd/hub"
    web_driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = saf_capabilities)
    request.cls.driver = web_driver
    yield
    # web_driver.close()
    web_driver.quit()

The implementation in test_lambdatest_todo_App.py remains unchanged since that is independent of the Selenium Grid infrastructure.

Code WalkThrough

Line (21) — The combination of user-name and access-key are used for accessing the LambdaTest Grid URL [@hub.lambdatest.com/wd/hub]

remote_url = "https://" + user_name + ":" + app_key + "@hub.lambdatest.com/wd/hub"

Line (22) — The Selenium WebDriver API uses the LambdaTest Grid URL and browser capabilities (i.e. saf_capabilities) that were generated using the LambdaTest Capabilities Generator.

web_driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = saf_capabilities)

Execution

The following command is used for triggering the test on cloud-based Selenium Grid on LambdaTest.

pytest –v -s test_lambdatest_todo_App.py

Here is the screenshot of the execution, which indicates that the click operation is working as required on the LambdaTest Grid:

Wondering How To Debug Websites On iPhone? Check this out. Test on virtual macOS versions for compatibility across latest and legacy macOS browsers.

Tired of manually creating JSON data? Generate Try random JSON Generator convert data in seconds with our easy-to-use tool. Try it now and make your development process a breeze!

Wrapping up

Setting up Apple’s safaridriver on Mac is hassle-free and straightforward since it does not require installing the safaridriver. Despite the simplicity associated with Selenium Safari driver on macOS, there are issues with events such as click, which does not work when used in Selenium automation testing. In case you do not own a device with macOS on it, there is always an option to install macOS on a virtual machine and try out Apple’s Safari driver for Selenium test automation.

The issues observed with testing using Apple’s Safari driver on the local copy of macOS are not observed with Selenium test automation on cloud-based Selenium Grid by LambdaTest. Along with proper (or expected) output, it results in expediting the process of automation testing.

Also conduct a Test on macOS Catalina— verify cross browser compatibility online with your website. Test for free on the latest and older macOS Catalina to ensure cross-browser compatibility.

If you have any issues or questions, don’t hesitate to reach out via the comment section below.

Frequently Asked Questions

Does Selenium support Safari browser?

Selenium comes with an extension for Safari browsers to run Selenium scripts. However, the extension, i.e., ‘Selenium WebDriver,’ is only supported on browser versions 10 and above.

How do I automate Safari browser using Selenium?

Step 1: Download and Install the Safari Browser Extension.

Step 2: Enable the WebDriver Browser Extension by going to Safari > Preferences and open the preferences window and then enable the “Enable WebDriver“ option.

Step 3: Restart your Browser.

How do I enable Safari drivers on Mac?

Step 1: Choose Safari > Preferences.

Step 2: On the Advanced tab, select “Show Develop menu in menu bar.”

Step 3: Choose Develop > Allow Remote Automation.