File: //usr/lib/ruby/vendor_ruby/selenium/webdriver/firefox/binary.rb
# frozen_string_literal: true
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
module Selenium
module WebDriver
module Firefox
# @api private
class Binary
NO_FOCUS_LIBRARY_NAME = 'x_ignore_nofocus.so'
NO_FOCUS_LIBRARIES = [
["#{WebDriver.root}/selenium/webdriver/firefox/native/linux/amd64/#{NO_FOCUS_LIBRARY_NAME}",
"amd64/#{NO_FOCUS_LIBRARY_NAME}"],
["#{WebDriver.root}/selenium/webdriver/firefox/native/linux/x86/#{NO_FOCUS_LIBRARY_NAME}",
"x86/#{NO_FOCUS_LIBRARY_NAME}"]
].freeze
WAIT_TIMEOUT = 90
QUIT_TIMEOUT = 5
def start_with(profile, profile_path, *args)
if Platform.cygwin?
profile_path = Platform.cygwin_path(profile_path, windows: true)
elsif Platform.windows?
profile_path = Platform.windows_path(profile_path)
end
ENV['XRE_CONSOLE_LOG'] = profile.log_file if profile.log_file
ENV['XRE_PROFILE_PATH'] = profile_path
ENV['MOZ_NO_REMOTE'] = '1' # able to launch multiple instances
ENV['MOZ_CRASHREPORTER_DISABLE'] = '1' # disable breakpad
ENV['NO_EM_RESTART'] = '1' # prevent the binary from detaching from the console
modify_link_library_path profile_path if Platform.linux? && (profile.native_events? || profile.load_no_focus_lib?)
execute(*args)
end
def quit
return unless @process
@process.poll_for_exit QUIT_TIMEOUT
rescue ChildProcess::TimeoutError
# ok, force quit
@process.stop QUIT_TIMEOUT
end
def wait
return unless @process
begin
@process.poll_for_exit(WAIT_TIMEOUT)
rescue ChildProcess::TimeoutError => e
@process.stop
raise e
end
end
private
def execute(*extra_args)
args = [self.class.path, '-no-remote'] + extra_args
@process = ChildProcess.build(*args)
WebDriver.logger.debug("Executing Process #{args}")
@process.io.stdout = @process.io.stderr = WebDriver.logger.io if WebDriver.logger.debug?
@process.start
end
def modify_link_library_path(profile_path)
paths = []
NO_FOCUS_LIBRARIES.each do |from, to|
dest = File.join(profile_path, to)
FileUtils.mkdir_p File.dirname(dest)
FileUtils.cp from, dest
paths << File.expand_path(File.dirname(dest))
end
paths += ENV['LD_LIBRARY_PATH'].to_s.split(File::PATH_SEPARATOR)
ENV['LD_LIBRARY_PATH'] = paths.uniq.join(File::PATH_SEPARATOR)
ENV['LD_PRELOAD'] = NO_FOCUS_LIBRARY_NAME
end
class << self
#
# @api private
#
# @see Firefox.path=
#
def path=(path)
Platform.assert_executable(path)
@path = path
end
def reset_path!
@path = nil
end
def path
@path ||= case Platform.os
when :macosx
macosx_path
when :windows
windows_path
when :linux, :unix
Platform.find_binary('firefox3', 'firefox2', 'firefox') || '/usr/bin/firefox'
else
raise Error::WebDriverError, "unknown platform: #{Platform.os}"
end
@path = Platform.cygwin_path(@path, windows: true) if Platform.cygwin?
unless File.file?(@path.to_s)
error = "Could not find Firefox binary (os=#{Platform.os}). " \
"Make sure Firefox is installed or set the path manually with #{self}.path="
raise Error::WebDriverError, error
end
@path
end
def version
@version = case Platform.os
when :macosx
`#{path} -v`.strip[/[^\s]*$/][/^\d+/].to_i
when :windows
`\"#{path}\" -v | more`.strip[/[^\s]*$/][/^\d+/].to_i
when :linux
`#{path} -v`.strip[/[^\s]*$/][/^\d+/].to_i
else
0
end
end
private
def windows_path
windows_registry_path ||
Platform.find_in_program_files('\\Mozilla Firefox\\firefox.exe') ||
Platform.find_binary('firefox')
end
def macosx_path
path = '/Applications/Firefox.app/Contents/MacOS/firefox-bin'
path = File.expand_path('~/Applications/Firefox.app/Contents/MacOS/firefox-bin') unless File.exist?(path)
path = Platform.find_binary('firefox-bin') unless File.exist?(path)
path
end
def windows_registry_path
require 'win32/registry'
lm = Win32::Registry::HKEY_LOCAL_MACHINE
lm.open('SOFTWARE\\Mozilla\\Mozilla Firefox') do |reg|
main = lm.open("SOFTWARE\\Mozilla\\Mozilla Firefox\\#{reg.keys[0]}\\Main")
entry = main.find { |key, _type, _data| key =~ /pathtoexe/i }
return entry.last if entry
end
rescue LoadError
# older JRuby or IronRuby does not have win32/registry
rescue Win32::Registry::Error
end
end # class << self
end # Binary
end # Firefox
end # WebDriver
end # Selenium