Safari specific functionality
Unlike Chromium and Firefox drivers, the safaridriver is installed with the Operating System. To enable automation on Safari, run the following command from the terminal:
safaridriver --enable
Options
Capabilities common to all browsers are described on the Options page.
Capabilities unique to Safari can be found at Apple’s page About WebDriver for Safari
Starting a Safari session with basic defined options looks like this:
SafariOptions options = new SafariOptions();
driver = new SafariDriver(options);
/examples/java/src/test/java/dev/selenium/browsers/SafariTest.java
package dev.selenium.browsers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;
@EnabledOnOs(OS.MAC)
public class SafariTest {
public SafariDriver driver;
@AfterEach
public void quit() {
if (driver != null) {
driver.quit();
}
}
@Test
public void basicOptions() {
SafariOptions options = new SafariOptions();
driver = new SafariDriver(options);
}
@Test
public void enableLogs() {
SafariDriverService service = new SafariDriverService.Builder()
.withLogging(true)
.build();
driver = new SafariDriver(service);
}
public void safariTechnologyPreview() {
SafariOptions options = new SafariOptions();
options.setUseTechnologyPreview(true);
driver = new SafariDriver(options);
}
}
options = webdriver.SafariOptions()
driver = webdriver.Safari(options=options)
/examples/python/tests/browsers/test_safari.py
import sys
import pytest
from selenium import webdriver
@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
options = webdriver.SafariOptions()
driver = webdriver.Safari(options=options)
driver.quit()
@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
service = webdriver.SafariService(enable_logging=True)
driver = webdriver.Safari(service=service)
driver.quit()
@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
options = webdriver.SafariOptions()
options.use_technology_preview = True
service = webdriver.SafariService(
executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
)
driver = webdriver.Safari(options=options, service=service)
driver.quit()
var options = new SafariOptions();
driver = new SafariDriver(options);
/examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;
namespace SeleniumDocs.Browsers
{
[TestClassCustom]
[EnabledOnOs("OSX")]
public class SafariTest
{
private SafariDriver driver;
[TestCleanup]
public void QuitDriver()
{
driver.Quit();
}
[TestMethod]
public void BasicOptions()
{
var options = new SafariOptions();
driver = new SafariDriver(options);
}
[TestMethod]
[Ignore("Not implemented")]
public void EnableLogs()
{
var service = SafariDriverService.CreateDefaultService();
//service.EnableLogging = true;
driver = new SafariDriver(service);
}
}
}
it 'basic options' do
options = Selenium::WebDriver::Options.safari
/examples/ruby/spec/browsers/safari_spec.rb
# frozen_string_literal: true
require 'spec_helper'
# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
describe 'Options' do
it 'basic options' do
options = Selenium::WebDriver::Options.safari
@driver = Selenium::WebDriver.for :safari, options: options
end
end
describe 'Service' do
let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }
it 'enables logs' do
original_count = Dir[directory].length
service = Selenium::WebDriver::Service.safari
service.args << '--diagnose'
@driver = Selenium::WebDriver.for :safari, service: service
expect(Dir[directory].length - original_count).to eq 1
end
it 'does not set log output' do
service = Selenium::WebDriver::Service.safari
expect {
service.log = $stdout
}.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
end
end
end
RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
'have no support for Safari Technology Preview' do
it 'sets the technology preview' do
Selenium::WebDriver::Safari.technology_preview!
local_driver = Selenium::WebDriver.for :safari
expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
end
end
# rubocop:enable RSpec/MultipleDescribes
let driver = new Builder()
.forBrowser(Browser.SAFARI)
.setSafariOptions(options)
.build();
/examples/javascript/test/browser/safariSpecificCap.spec.js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process = require('node:process');
describe('Should be able to Test Command line arguments', function () {
(process.platform === 'darwin' ? it : it.skip)('headless', async function () {
let driver = new Builder()
.forBrowser(Browser.SAFARI)
.setSafariOptions(options)
.build();
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
await driver.quit();
});
});
val options = SafariOptions()
val driver = SafariDriver(options)
Mobile
Those looking to automate Safari on iOS should look to the Appium project.
Service
Service settings common to all browsers are described on the Service page.
Logging
Unlike other browsers, Safari doesn’t let you choose where logs are output, or change levels. The one option
available is to turn logs off or on. If logs are toggled on, they can be found at:~/Library/Logs/com.apple.WebDriver/
.
.withLogging(true)
examples/java/src/test/java/dev/selenium/browsers/SafariTest.java
package dev.selenium.browsers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;
@EnabledOnOs(OS.MAC)
public class SafariTest {
public SafariDriver driver;
@AfterEach
public void quit() {
if (driver != null) {
driver.quit();
}
}
@Test
public void basicOptions() {
SafariOptions options = new SafariOptions();
driver = new SafariDriver(options);
}
@Test
public void enableLogs() {
SafariDriverService service = new SafariDriverService.Builder()
.withLogging(true)
.build();
driver = new SafariDriver(service);
}
public void safariTechnologyPreview() {
SafariOptions options = new SafariOptions();
options.setUseTechnologyPreview(true);
driver = new SafariDriver(options);
}
}
Note: Java also allows setting console output by System Property;
Property key: SafariDriverService.SAFARI_DRIVER_LOGGING
Property value: "true"
or "false"
service = webdriver.SafariService(enable_logging=True)
examples/python/tests/browsers/test_safari.py
import sys
import pytest
from selenium import webdriver
@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
options = webdriver.SafariOptions()
driver = webdriver.Safari(options=options)
driver.quit()
@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
service = webdriver.SafariService(enable_logging=True)
driver = webdriver.Safari(service=service)
driver.quit()
@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
options = webdriver.SafariOptions()
options.use_technology_preview = True
service = webdriver.SafariService(
executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
)
driver = webdriver.Safari(options=options, service=service)
driver.quit()
examples/ruby/spec/browsers/safari_spec.rb
# frozen_string_literal: true
require 'spec_helper'
# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
describe 'Options' do
it 'basic options' do
options = Selenium::WebDriver::Options.safari
@driver = Selenium::WebDriver.for :safari, options: options
end
end
describe 'Service' do
let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }
it 'enables logs' do
original_count = Dir[directory].length
service = Selenium::WebDriver::Service.safari
service.args << '--diagnose'
@driver = Selenium::WebDriver.for :safari, service: service
expect(Dir[directory].length - original_count).to eq 1
end
it 'does not set log output' do
service = Selenium::WebDriver::Service.safari
expect {
service.log = $stdout
}.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
end
end
end
RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
'have no support for Safari Technology Preview' do
it 'sets the technology preview' do
Selenium::WebDriver::Safari.technology_preview!
local_driver = Selenium::WebDriver.for :safari
expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
end
end
# rubocop:enable RSpec/MultipleDescribes
Safari Technology Preview
Apple provides a development version of their browser — Safari Technology Preview
options.setUseTechnologyPreview(true);
driver = new SafariDriver(options);
examples/java/src/test/java/dev/selenium/browsers/SafariTest.java
package dev.selenium.browsers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;
@EnabledOnOs(OS.MAC)
public class SafariTest {
public SafariDriver driver;
@AfterEach
public void quit() {
if (driver != null) {
driver.quit();
}
}
@Test
public void basicOptions() {
SafariOptions options = new SafariOptions();
driver = new SafariDriver(options);
}
@Test
public void enableLogs() {
SafariDriverService service = new SafariDriverService.Builder()
.withLogging(true)
.build();
driver = new SafariDriver(service);
}
public void safariTechnologyPreview() {
SafariOptions options = new SafariOptions();
options.setUseTechnologyPreview(true);
driver = new SafariDriver(options);
}
}
options = webdriver.SafariOptions()
options.use_technology_preview = True
service = webdriver.SafariService(
executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
)
driver = webdriver.Safari(options=options, service=service)
examples/python/tests/browsers/test_safari.py
import sys
import pytest
from selenium import webdriver
@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
options = webdriver.SafariOptions()
driver = webdriver.Safari(options=options)
driver.quit()
@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
service = webdriver.SafariService(enable_logging=True)
driver = webdriver.Safari(service=service)
driver.quit()
@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
options = webdriver.SafariOptions()
options.use_technology_preview = True
service = webdriver.SafariService(
executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
)
driver = webdriver.Safari(options=options, service=service)
driver.quit()
'have no support for Safari Technology Preview' do
it 'sets the technology preview' do
examples/ruby/spec/browsers/safari_spec.rb
# frozen_string_literal: true
require 'spec_helper'
# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
describe 'Options' do
it 'basic options' do
options = Selenium::WebDriver::Options.safari
@driver = Selenium::WebDriver.for :safari, options: options
end
end
describe 'Service' do
let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }
it 'enables logs' do
original_count = Dir[directory].length
service = Selenium::WebDriver::Service.safari
service.args << '--diagnose'
@driver = Selenium::WebDriver.for :safari, service: service
expect(Dir[directory].length - original_count).to eq 1
end
it 'does not set log output' do
service = Selenium::WebDriver::Service.safari
expect {
service.log = $stdout
}.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
end
end
end
RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
'have no support for Safari Technology Preview' do
it 'sets the technology preview' do
Selenium::WebDriver::Safari.technology_preview!
local_driver = Selenium::WebDriver.for :safari
expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
end
end
# rubocop:enable RSpec/MultipleDescribes