Skip to content

Commit

Permalink
Add Safari::Options + add support for custom extensions.
Browse files Browse the repository at this point in the history
This fixes issue 6815.
  • Loading branch information
jarib committed Feb 17, 2014
1 parent 9554b5a commit 0fcd051
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 68 deletions.
3 changes: 2 additions & 1 deletion rb/lib/selenium/webdriver/safari.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def resource_path

require 'selenium/webdriver/safari/browser'
require 'selenium/webdriver/safari/server'
require 'selenium/webdriver/safari/extension'
require 'selenium/webdriver/safari/extensions'
require 'selenium/webdriver/safari/options'
require 'selenium/webdriver/safari/bridge'

55 changes: 16 additions & 39 deletions rb/lib/selenium/webdriver/safari/bridge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,33 @@ class Bridge < Remote::Bridge
COMMAND_TIMEOUT = 60

def initialize(opts = {})
timeout = Integer(opts[:timeout] || COMMAND_TIMEOUT)
caps = fetch_capability_options(opts)
safari_opts = caps['safari.options']
command_timeout = Integer(opts[:timeout] || COMMAND_TIMEOUT)
safari_options = opts.kind_of?(Safari::Options) ? opts : Safari::Options.new(opts)
capabilities = merge_capabilities(opts, safari_options)

@command_id ||= 0

unless safari_opts['skipExtensionInstallation']
@extension = Extension.new(:data_dir => safari_opts['dataDir'])
@extension.install
end
@extensions = Extensions.new(safari_options)
@extensions.install

# TODO: handle safari_opts['cleanSession']
@server = Server.new(safari_opts['port'], timeout)
@server = Server.new(safari_options.port, command_timeout)
@server.start

@safari = Browser.new
@safari.start(prepare_connect_file)

@server.wait_for_connection

super(desired_capabilities: caps)
super(desired_capabilities: capabilities)
end

def quit
super

@server.stop
@safari.stop
@extension && @extension.uninstall
@extensions && @extensions.uninstall
end

def driver_extensions
Expand Down Expand Up @@ -103,39 +101,18 @@ def prepare_connect_file
path
end

def fetch_capability_options(opts)
# TODO: deprecate
#
# :custom_data_dir (replaced by :data_dir)
# :install_extension (replaced by :skip_extension_installation)

capabilities = opts.fetch(:desired_capabilities) { Remote::Capabilities.safari }
safari_options = capabilities['safari.options'] ||= {}

port = Integer(opts[:port] || safari_options['port'] || PortProber.random)
data_dir = opts[:custom_data_dir] || opts[:data_dir] || safari_options['dataDir']
clean_session = opts.fetch(:clean_session) { safari_options['cleanSession'] }

skip_extension = false
def merge_capabilities(opts, safari_options)
caps = safari_options.to_capabilities
other = opts[:desired_capabilities]

if opts.key?(:install_extension)
skip_extension = !opts[:install_extension]
elsif opts.key?(:skip_extension_installation)
skip_extension = opts[:skip_extension_installation]
elsif safari_options['skipExtensionInstallation'] != nil
skip_extension = opts['skipExtensionInstallation']
if other
other = opts[:desired_capabilities].as_json
caps['safari.options'].merge!(other.delete('safari.options') || {})
caps.merge!(other)
end

safari_options['port'] = port
safari_options['skipExtensionInstallation'] = skip_extension
safari_options['dataDir'] = data_dir
safari_options['cleanSession'] = clean_session

# TODO: customDriverExtension

capabilities
caps
end

end

end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Safari
# @api private
#

class Extension
class Extensions

PLIST = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
Expand All @@ -21,47 +21,75 @@ class Extension
</dict>
<key>Installed Extensions</key>
<array>
<dict>
<key>Added Non-Default Toolbar Items</key>
<array/>
<key>Archive File Name</key>
<string>WebDriver.safariextz</string>
<key>Bundle Directory Name</key>
<string>WebDriver.safariextension</string>
<key>Enabled</key>
<true/>
<key>Hidden Bars</key>
<array/>
<key>Removed Default Toolbar Items</key>
<array/>
</dict>
%s
</array>
<key>Version</key>
<integer>1</integer>
</dict>
</plist>
XML

def initialize(opts = {})
@data_dir = opts[:data_dir] || safari_data_dir
PLIST_EXTENSION_LINE = <<-XML
<dict>
<key>Added Non-Default Toolbar Items</key>
<array/>
<key>Archive File Name</key>
<string>%s.safariextz</string>
<key>Bundle Directory Name</key>
<string>%s.safariextension</string>
<key>Enabled</key>
<true/>
<key>Hidden Bars</key>
<array/>
<key>Removed Default Toolbar Items</key>
<array/>
</dict>
XML

@backup = Backup.new
@installed = false
def initialize(opts = {})
@data_dir = opts.data_dir || safari_data_dir
@skip = opts.skip_extension_installation?
@extensions = opts.extensions
@backup = Backup.new
@installed = false
end

def install
return if @installed
installed_extensions = []

if install_directory.exist?
@backup.backup install_directory
end

install_directory.mkpath

extension_destination.rmtree if extension_destination.exist?
FileUtils.cp extension_source.to_s, extension_destination.to_s
unless @skip
extension_destination.rmtree if extension_destination.exist?
FileUtils.cp extension_source.to_s, extension_destination.to_s

installed_extensions << extension_destination
end

plist_destination.open('w') { |io| io << PLIST }
@extensions.each do |extension|
target = install_directory.join(extension.basename)

if extension.expand_path == target.expand_path
@backup.backup(target)
else
FileUtils.cp extension, target
end

installed_extensions << target
end

plist_destination.open('w') do |io|
extension_lines = installed_extensions.map do |ext|
name = ext.basename('.safariextz').to_s
PLIST_EXTENSION_LINE % [name, name]
end
io << PLIST % extension_lines.join("\n")
end

Platform.exit_hook { uninstall }
@installed = true
Expand Down Expand Up @@ -115,7 +143,7 @@ def safari_data_dir

class Backup
def initialize
@dir = Pathname.new(Dir.mktmpdir('webdriver-safari-backups'))
@dir = Pathname.new(Dir.mktmpdir('webdriver-safari-backups'))
@backups = {}
end

Expand Down
79 changes: 79 additions & 0 deletions rb/lib/selenium/webdriver/safari/options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module Selenium
module WebDriver
module Safari
class Options
attr_accessor :port, :data_dir, :skip_extension_installation
attr_reader :extensions

def initialize(opts = {})
@extensions = []
extract_options(opts)
end

def add_extension(ext)
@extensions << verify_safari_extension(ext)
end

def clean_session?
!!@clean_session
end

def skip_extension_installation?
!!@skip_extension_installation
end

def to_capabilities
caps = Remote::Capabilities.safari
caps.merge!('safari.options' => as_json)

caps
end

def as_json
{
'port' => port,
'dataDir' => data_dir,
'cleanSession' => clean_session?,
'extensions' => extensions_as_json,
'skipExtensionInstallation' => skip_extension_installation?
}
end

private

def extensions_as_json
@extensions.map do |path|
{'filename' => path.basename, 'contents' => Base64.strict_encode64(path.read) }
end
end

def extract_options(opts)
@port = Integer(opts[:port] || PortProber.random)
@data_dir = opts[:custom_data_dir] || opts[:data_dir]
@clean_session = opts[:clean_session]

Array(opts[:extensions]).each { |ext| add_extension(ext) }

if opts.key?(:install_extension)
@skip_extension_installation = !opts[:install_extension]
elsif opts.key?(:skip_extension_installation)
@skip_extension_installation = opts[:skip_extension_installation]
else
@skip_extension_installation = false
end
end

def verify_safari_extension(path)
pn = Pathname.new(path)

unless pn.file? && pn.extname == '.safariextz'
raise ArgumentError, "invalid Safari extension path: #{path}"
end

pn
end

end
end
end
end
13 changes: 13 additions & 0 deletions rb/lib/selenium/webdriver/safari/session_data.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Selenium
module WebDriver
module Safari
class SessionData

def self.for_platform

end

end
end
end
end
1 change: 0 additions & 1 deletion rb/spec/integration/selenium/webdriver/options_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require File.expand_path("../spec_helper", __FILE__)
require 'pry'

module Selenium
module WebDriver
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module Selenium
module WebDriver
module Safari

describe 'with custom extension', focus: true do
before { GlobalTestEnv.quit_driver }
after { @driver.quit if @driver }

let(:wait) { Wait.new(timeout: 2) }
let(:extension_path) { }

def create_driver(with_extension = false)
extensions = []

if with_extension
extensions << GlobalTestEnv.root.join('java/client/test/org/openqa/selenium/safari/setAttribute.safariextz').to_s
end

@driver = WebDriver.for :safari, extensions: extensions
@driver.get url_for('blank.html')

@driver
end

def custom_extension_installed?(driver)
wait.until { driver.find_element(css: "html[istestsafariextzinstalled759='yes']") }
true
rescue Error::TimeOutError
false
end

it 'should start without custom extension by default' do
driver = create_driver
custom_extension_installed?(driver).should be_false
end

it 'should start with custom extension if requested' do
driver = create_driver(true)
custom_extension_installed?(driver).should be_true
end
end

end # Safari
end # WebDriver
end # Selenium

1 change: 1 addition & 0 deletions rb/spec/integration/selenium/webdriver/spec_support.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'pathname'
require 'selenium/server'
require 'selenium/webdriver/spec_support/test_environment'
require 'selenium/webdriver/spec_support/guards'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ def new_driver_instance

def app_server
@app_server ||= (
path = File.join(root, "common/src/web")
s = RackServer.new(path)
s = RackServer.new(root.join("common/src/web").to_s)
s.start

s
Expand All @@ -66,7 +65,7 @@ def remote_server
end

def remote_server_jar
@remote_server_jar ||= File.join(root, "build/java/server/test/org/openqa/selenium/server-with-tests-standalone.jar")
@remote_server_jar ||= root.join("build/java/server/test/org/openqa/selenium/server-with-tests-standalone.jar").to_s
end

def quit
Expand Down Expand Up @@ -97,7 +96,7 @@ def url_for(filename)
end

def root
@root ||= File.expand_path("../../../../../../../", __FILE__)
@root ||= Pathname.new("../../../../../../../").expand_path(__FILE__)
end

private
Expand Down

0 comments on commit 0fcd051

Please sign in to comment.