Question

I'm using WATIR to control browser, but there is page that never fully loads everything stucks. After 60 second timeout WATIR gives me error and I can keep writing commands, but If I try to close the browser with WATIR in made functions everything stucks.

If I close the browser manually everything seems to keep going ok so I'm looking for option to find chrome process id, PID and kill the process using ruby.

Here is code sample I found:

irb

require "watir-webdriver"

proxy = "78.159.102.86:49295"
browser = Watir::Browser.new :chrome, :switches => ['--proxy-server=' + proxy]

bridge = browser.instance_variable_get(:@bridge)
launcher = bridge.instance_variable_get(:@launcher)
binary = launcher.instance_variable_get(:@binary)
process = binary.instance_variable_get(:@process)
process.pid

All this methods gives me NIL. The last one - NoMethodError: undefined method `pid' for nil:NilClass

From my research I think that I need to get PID. Then I can close process.

Any tips? I'm using windows! So far it seems that there are no in made methods for killing process by name in Ruby.

edit:

I found what works from windows command line:

taskkill /im Firefox.exe /f /t >nul 2>&1

But since I'm on ruby it gives me error:

SyntaxError: (irb):1: unknown regexp option - f (irb):1: syntax error, unexpected tINTEGER, expecting keyword_do or '{' or '(' taskkill /im Firefox.exe /f /t >nul 2>&1

How to execute cmd command from ruby?

Était-ce utile?

La solution

I'm not sure system works on windows but give it a try.

system("taskkill /im Firefox.exe /f /t >nul 2>&1")

Autres conseils

You can do this:

a) Get the PID of the Chrome process:

browser_pid = @browser.driver.instance_variable_get(:@bridge).instance_variable_get(:@service).instance_variable_get(:@process).pid

Pass the browser_pid to system kill:

system("taskkill pid #{browser_pid} /f /t >nul 2>&1")

The sample code in the original post combined with @daremkd answer gives us the internal variables for Firefox and Chrome. Putting them together, here's what I'll be using as a watir-webdriver Watir::Browser#pid:

require 'watir-webdriver'

module Watir
  class Browser
    def pid
      if driver.browser == :firefox
        [:@bridge, :@launcher, :@binary, :@process, :@pid]
      elsif driver.browser == :chrome
        [:@bridge, :@service, :@process, :@pid]
      else
        raise NotImplementedError.new "PID lookup undefined for Watir::Browser :#{driver.browser}"
      end.
        inject(browser.driver) { |pv, sym| pv.instance_variable_get sym }
    end
  end
end


Here's the monkey patch used in the context used to close both browsers:

browser = Watir::Browser.new :firefox
pid = browser.pid
`taskkill /pid #{pid}` # browser.close

browser = Watir::Browser.new :chrome
pid = browser.pid
`taskkill /pid #{pid} /f /t`  # note the `/t` to kill the spawned tree
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top