Class: Headless
- Inherits:
-
Object
- Object
- Headless
- Defined in:
- lib/headless.rb,
lib/headless/cli_util.rb,
lib/headless/video/video_recorder.rb
Overview
A class incapsulating the creation and usage of a headless X server
Prerequisites
-
X Window System
Usage
Block mode:
require 'rubygems'
require 'headless'
require 'selenium-webdriver'
Headless.ly do
driver = Selenium::WebDriver.for :firefox
driver.navigate.to 'http://google.com'
puts driver.title
end
Object mode:
require 'rubygems'
require 'headless'
require 'selenium-webdriver'
headless = Headless.new
headless.start
driver = Selenium::WebDriver.for :firefox
driver.navigate.to 'http://google.com'
puts driver.title
headless.destroy
– TODO test that reuse actually works with an existing xvfb session ++
Defined Under Namespace
Classes: CliUtil, Exception, VideoRecorder
Constant Summary collapse
- DEFAULT_DISPLAY_NUMBER =
99
- MAX_DISPLAY_NUMBER =
10_000
- DEFAULT_DISPLAY_DIMENSIONS =
'1280x1024x24'
- DEFAULT_XVFB_LAUNCH_TIMEOUT =
10
Instance Attribute Summary collapse
-
#dimensions ⇒ Object
readonly
The display dimensions.
-
#display ⇒ Object
readonly
The display number.
-
#xvfb_launch_timeout ⇒ Object
readonly
Returns the value of attribute xvfb_launch_timeout.
Class Method Summary collapse
-
.run(options = {}, &block) ⇒ Object
(also: ly)
Block syntax:.
Instance Method Summary collapse
-
#destroy ⇒ Object
Switches back from the headless server and terminates the headless session while waiting for Xvfb process to terminate.
-
#destroy_at_exit? ⇒ Boolean
Whether the headless display will be destroyed when the script finishes.
-
#destroy_sync ⇒ Object
Deprecated.
-
#destroy_without_sync ⇒ Object
Same as the old destroy function – doesn’t wait for Xvfb to die.
-
#initialize(options = {}) ⇒ Headless
constructor
Creates a new headless server, but does NOT switch to it immediately.
-
#start ⇒ Object
Switches to the headless server.
-
#stop ⇒ Object
Switches back from the headless server.
- #take_screenshot(file_path, options = {}) ⇒ Object
- #video ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Headless
Creates a new headless server, but does NOT switch to it immediately. Call #start for that
List of available options:
-
display
(default 99) - what display number to listen to; -
reuse
(default true) - if given display server already exists, should we use it or try another? -
autopick
(default true if display number isn’t explicitly set) - if Headless should automatically pick a display, or fail if the given one is not available. -
dimensions
(default 1280x1024x24) - display dimensions and depth. Not all combinations are possible, refer to man Xvfb. -
destroy_at_exit
- if a display is started but not stopped, should it be destroyed when the script finishes? (default true unless reuse is true and a server is already running) -
xvfb_launch_timeout
- how long should we wait for Xvfb to open a display, before assuming that it is frozen (in seconds, default is 10) -
video
- options to be passed to the ffmpeg video recorder. See Headless::VideoRecorder#initialize for documentation
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/headless.rb', line 77 def initialize( = {}) CliUtil.ensure_application_exists!('Xvfb', 'Xvfb not found on your system') @display = .fetch(:display, DEFAULT_DISPLAY_NUMBER).to_i @xvfb_launch_timeout = .fetch(:xvfb_launch_timeout, DEFAULT_XVFB_LAUNCH_TIMEOUT).to_i @autopick_display = .fetch(:autopick, !.key?(:display)) @reuse_display = .fetch(:reuse, true) @dimensions = .fetch(:dimensions, DEFAULT_DISPLAY_DIMENSIONS) @video_capture_options = .fetch(:video, {}) already_running = xvfb_running? rescue false @destroy_at_exit = .fetch(:destroy_at_exit, !(@reuse_display && already_running)) @pid = nil # the pid of the running Xvfb process # FIXME Xvfb launch should not happen inside the constructor attach_xvfb end |
Instance Attribute Details
#dimensions ⇒ Object (readonly)
The display dimensions
56 57 58 |
# File 'lib/headless.rb', line 56 def dimensions @dimensions end |
#display ⇒ Object (readonly)
The display number
53 54 55 |
# File 'lib/headless.rb', line 53 def display @display end |
#xvfb_launch_timeout ⇒ Object (readonly)
Returns the value of attribute xvfb_launch_timeout.
57 58 59 |
# File 'lib/headless.rb', line 57 def xvfb_launch_timeout @xvfb_launch_timeout end |
Class Method Details
Instance Method Details
#destroy ⇒ Object
Switches back from the headless server and terminates the headless session while waiting for Xvfb process to terminate.
110 111 112 113 |
# File 'lib/headless.rb', line 110 def destroy stop CliUtil.kill_process(pid_filename, preserve_pid_file: true, wait: true) end |
#destroy_at_exit? ⇒ Boolean
Whether the headless display will be destroyed when the script finishes.
130 131 132 |
# File 'lib/headless.rb', line 130 def destroy_at_exit? @destroy_at_exit end |
#destroy_sync ⇒ Object
Deprecated. Same as destroy. Kept for backward compatibility in June 2015.
118 119 120 |
# File 'lib/headless.rb', line 118 def destroy_sync destroy end |
#destroy_without_sync ⇒ Object
Same as the old destroy function – doesn’t wait for Xvfb to die. Can cause zombies: stackoverflow.com/a/31003621/1651458
124 125 126 127 |
# File 'lib/headless.rb', line 124 def destroy_without_sync stop CliUtil.kill_process(pid_filename, preserve_pid_file: true) end |
#start ⇒ Object
Switches to the headless server
97 98 99 100 101 |
# File 'lib/headless.rb', line 97 def start @old_display = ENV['DISPLAY'] ENV['DISPLAY'] = ":#{display}" hook_at_exit end |
#stop ⇒ Object
Switches back from the headless server
104 105 106 |
# File 'lib/headless.rb', line 104 def stop ENV['DISPLAY'] = @old_display end |
#take_screenshot(file_path, options = {}) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/headless.rb', line 153 def take_screenshot(file_path, ={}) using = .fetch(:using, :imagemagick) case using when :imagemagick CliUtil.ensure_application_exists!('import', "imagemagick is not found on your system. Please install it using sudo apt-get install imagemagick") system "#{CliUtil.path_to('import')} -display localhost:#{display} -window root #{file_path}" when :xwd CliUtil.ensure_application_exists!('xwd', "xwd is not found on your system. Please install it using sudo apt-get install X11-apps") system "#{CliUtil.path_to('xwd')} -display localhost:#{display} -silent -root -out #{file_path}" when :graphicsmagick, :gm CliUtil.ensure_application_exists!('gm', "graphicsmagick is not found on your system. Please install it.") system "#{CliUtil.path_to('gm')} import -display localhost:#{display} -window root #{file_path}" else raise Headless::Exception.new('Unknown :using option value') end end |
#video ⇒ Object
149 150 151 |
# File 'lib/headless.rb', line 149 def video @video_recorder ||= VideoRecorder.new(display, dimensions, @video_capture_options) end |