Class: WebkitRemote::Process
- Inherits:
-
Object
- Object
- WebkitRemote::Process
- Defined in:
- lib/webkit_remote/process.rb
Overview
Tracks a Webkit process.
Instance Attribute Summary collapse
-
#port ⇒ Integer
readonly
Port that the process’ remote debugging server listens to.
-
#running ⇒ Boolean
(also: #running?)
readonly
True if the Webkit process is running.
Class Method Summary collapse
-
.chrome_binary ⇒ String
Path to a Google Chrome / Chromium binary.
-
.xvfb_binary ⇒ String
Path to the Xvfb virtual X server binary.
Instance Method Summary collapse
-
#chrome_cli(opts) ⇒ Array<String>
Command-line that launches Google Chrome / Chromium.
-
#chrome_cli_flags(opts) ⇒ Array<String>
Flags used on the command-line that launches Google Chrome / Chromium.
-
#chrome_env(opts) ⇒ Hash<String, String>
Environment variables set when launching Chrome.
-
#finalize ⇒ Object
Remove temporary directory if it’s still there at garbage collection time.
-
#initialize(opts = {}) ⇒ Process
constructor
Tracker for a yet-unlaunched process.
-
#start ⇒ WebkitRemote::Browser
Starts the browser process.
-
#stop ⇒ WebkitRemote::Process
Stops the browser process.
-
#xvfb_cli(opts) ⇒ Array<String>
Command-line that launches Xvfb.
Constructor Details
#initialize(opts = {}) ⇒ Process
Tracker for a yet-unlaunched process.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/webkit_remote/process.rb', line 29 def initialize(opts = {}) @port = opts[:port] || 9292 @timeout = opts[:timeout] || 10 @running = false @data_dir = Dir.mktmpdir 'webkit-remote' @pid = nil @xvfb_pid = nil if opts[:window] @window = opts[:window] else @window = { } end if opts[:xvfb] @xvfb_cli = xvfb_cli opts if opts[:xvfb].respond_to? :[] @window[:width] ||= opts[:xvfb][:width] @window[:height] ||= opts[:xvfb][:height] end else @xvfb_cli = nil end @window[:top] ||= 0 @window[:left] ||= 0 @window[:width] ||= 256 @window[:height] ||= 256 @cli = chrome_cli opts end |
Instance Attribute Details
#port ⇒ Integer (readonly)
Returns port that the process’ remote debugging server listens to.
139 140 141 |
# File 'lib/webkit_remote/process.rb', line 139 def port @port end |
#running ⇒ Boolean (readonly) Also known as: running?
Returns true if the Webkit process is running.
101 102 103 |
# File 'lib/webkit_remote/process.rb', line 101 def running @running end |
Class Method Details
.chrome_binary ⇒ String
Path to a Google Chrome / Chromium binary.
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/webkit_remote/process.rb', line 268 def self.chrome_binary return @chrome_binary unless @chrome_binary == false case RUBY_PLATFORM when /linux/ [ 'google-chrome', 'google-chromium', ].each do |binary| path = `which #{binary}` unless path.empty? @chrome_binary = path.strip break end end when /darwin/ [ '/Applications/Chromium.app/Contents/MacOS/Chromium', '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary', ].each do |path| if File.exist? path @chrome_binary = path break end end else raise "Unsupported platform #{RUBY_PLATFORM}" end @chrome_binary ||= nil end |
.xvfb_binary ⇒ String
Path to the Xvfb virtual X server binary.
304 305 306 307 308 309 310 311 312 |
# File 'lib/webkit_remote/process.rb', line 304 def self.xvfb_binary return @xvfb_binary unless @xvfb_binary == false path = `which Xvfb` unless path.empty? @xvfb_binary = path.strip end @xvfb_binary ||= nil end |
Instance Method Details
#chrome_cli(opts) ⇒ Array<String>
Command-line that launches Google Chrome / Chromium
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/webkit_remote/process.rb', line 150 def chrome_cli(opts) # The Chromium wiki recommends this page for available flags: # http://peter.sh/experiments/chromium-command-line-switches/ [ chrome_env(opts), opts[:chrome_binary] || self.class.chrome_binary, ] + chrome_cli_flags(opts) + [ "--remote-debugging-port=#{@port}", # Webkit remote debugging "--user-data-dir=#{@data_dir}", # really ensure a clean slate "--window-position=#{@window[:left]},#{@window[:top]}", "--window-size=#{@window[:width]},#{@window[:height]}", 'about:blank', # don't load the homepage { chdir: @data_dir, in: '/dev/null', out: File.join(@data_dir, '.stdout'), err: File.join(@data_dir, '.stderr') }, ] end |
#chrome_cli_flags(opts) ⇒ Array<String>
Flags used on the command-line that launches Google Chrome / Chromium.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/webkit_remote/process.rb', line 176 def chrome_cli_flags(opts) flags = [ '--bwsi', # disable extensions, sync, bookmarks '--disable-default-apps', # no bundled apps '--disable-extensions', # no extensions '--disable-java', # no plugins '--disable-logging', # don't trash stdout / stderr '--disable-plugins', # no native content '--disable-prompt-on-repost', # no confirmation dialog on POST refresh '--disable-sync', # no talking with the Google servers '--disable-translate', # no Google Translate calls '--incognito', # don't use old state, don't preserve state '--homepage=about:blank', # don't go to Google in new tabs '--keep-alive-for-test', # don't kill process if the last window dies '--lang=en-US', # set a default language '--log-level=3', # FATAL, because there's no setting for "none" '--mute-audio', # don't let the computer make noise '--no-default-browser-check', # don't hang when Chrome isn't default '--no-experiments', # not sure this is useful '--no-first-run', # don't show the help UI '--no-js-randomness', # consistent Date.now() and Math.random() '--no-message-box', # don't let user scripts show dialogs '--no-service-autorun', # don't mess with autorun settings '--noerrdialogs', # don't hang on error dialogs ] flags << '--disable-popup-blocking' if opts[:allow_popups] flags end |
#chrome_env(opts) ⇒ Hash<String, String>
Environment variables set when launching Chrome.
210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/webkit_remote/process.rb', line 210 def chrome_env(opts) if opts[:xvfb] if opts[:xvfb].respond_to?(:[]) and opts[:xvfb][:display] display = opts[:xvfb][:display] else display = 20 end { 'DISPLAY' => ":#{display}.0" } else {} end end |
#finalize ⇒ Object
Remove temporary directory if it’s still there at garbage collection time.
142 143 144 |
# File 'lib/webkit_remote/process.rb', line 142 def finalize PathUtils.rm_rf @data_dir if File.exists?(@data_dir) end |
#start ⇒ WebkitRemote::Browser
Starts the browser process.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/webkit_remote/process.rb', line 62 def start return self if running? if @xvfb_cli unless @xvfb_pid = POSIX::Spawn.spawn(*@xvfb_cli) # The Xvfb launch failed. return nil end end unless @pid = POSIX::Spawn.spawn(*@cli) # The launch failed. stop return nil end (@timeout * 20).times do # Check if the browser exited. begin break if status = ::Process.wait(@pid, ::Process::WNOHANG) rescue SystemCallError # no children break end # Check if the browser finished starting up. begin browser = WebkitRemote::Browser.new process: self @running = true return browser rescue SystemCallError # most likely ECONNREFUSED Kernel.sleep 0.05 end end # The browser failed, or was too slow to start. stop nil end |
#stop ⇒ WebkitRemote::Process
Stops the browser process.
Only call this after you’re done with the process.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/webkit_remote/process.rb', line 109 def stop return self unless running? if @pid begin ::Process.kill 'TERM', @pid ::Process.wait @pid rescue SystemCallError # Process died on its own. ensure @pid = nil end end if @xvfb_pid begin ::Process.kill 'TERM', @xvfb_pid ::Process.wait @xvfb_pid rescue SystemCallError # Process died on its own. ensure @xvfb_pid = nil end end FileUtils.rm_rf @data_dir if File.exists?(@data_dir) @running = false self end |
#xvfb_cli(opts) ⇒ Array<String>
Command-line that launches Xvfb.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/webkit_remote/process.rb', line 227 def xvfb_cli(opts) # The OSX man page for Xvfb: # http://developer.apple.com/library/mac/documentation/darwin/reference/manpages/man1/Xvfb.1.html xvfb_opts = opts[:xvfb] unless xvfb_opts.respond_to? :[] xvfb_opts = {} end display = xvfb_opts[:display] || 20 width = xvfb_opts[:width] || 1280 height = xvfb_opts[:height] || 1024 depth = xvfb_opts[:depth] || 32 dpi = xvfb_opts[:dpi] || 72 # https://bugs.freedesktop.org/show_bug.cgi?id=17453 if depth == 32 depth = '24+32' end [ self.class.xvfb_binary, ":#{display}", '-screen', '0', "#{width}x#{height}x#{depth}", '-auth', File.join(@data_dir, '.Xauthority'), '-c', '-dpi', dpi.to_s, '-terminate', '-wr', { chdir: @data_dir, in: '/dev/null', out: File.join(@data_dir, '.X_stdout'), err: File.join(@data_dir, '.X_stderr'), }, ] end |