使用gem watir:是否有办法获取打开的浏览器的pid(用于杀死该特定进程)?

时间:2018-07-20 08:47:30

标签: ruby watir

我已经搜索了很长时间,但我没有发现任何优雅解决方案,我的意思是使用一些watir方法...

我正在尝试这样做(不优雅)。列表“ ante”是有关已经打开并且在打开新浏览器之前的watir chrome浏览器的pid列表。 列表“ post”是创建新浏览器后所有pid的列表。 清单“待杀”是2的区别。

这是我的代码。等待一些延迟进行测试:)

def brow_gotosafe  url

  begin
    # liste_ante des pid chrome
    # liste des process type chromedriver n chromwebdriver
    # listedes pids : ante
    ante = []
    system('ps -Af | grep chromedriver > ../assets/chrdrv_ante.txt')
    system('ps -Af | grep "webdriver --use-mock" > ../assets/chromwebdriver_ante.txt')

    File.readlines("../assets/chrdrv_ante.txt").each do |line|
      ante << line.split(" ")[1].to_i
    end
    File.readlines("../assets/chromwebdriver_ante.txt").each do |line|
      ante << line.split(" ")[1].to_i
    end
    pp ante
    # on cree le browser et on point sur l url
    br = Watir::Browser.new
    br.goto url
  rescue => e
    puts e.class
    puts e.message
    puts e.backtrace.inspect

    # on ferme le browser br
    begin
      Timeout::timeout(5) { br.close }
    rescue Timeout::Error
      # on va fermer le br via le systeme
      # creation nouvelle liste : post
      post = []
      system('ps -Af | grep chromedriver > ../assets/chrdrv_post.txt')
      system('ps -Af | grep "webdriver --use-mock" > ../assets/chromwebdriver_post.txt')

      File.readlines("../assets/chrdrv_post.txt").each do |line|
        post << line.split(" ")[1].to_i
      end
      File.readlines("../assets/chromwebdriver_post.txt").each do |line|
        post << line.split(" ")[1].to_i
      end
      pp post

      # liste_tobekilled = liste_post - liste_ante
      tobekilled = []
      post.each do |p|
        if !ante.include?(p)
          tobekilled << p
        end
      end
      pp tobekilled

      # killing the pids tbk
      tobekilled.each do |tbk|
        system("kill #{tbk}")
      end

    end
  retry # on va au debut du begin
  end
  # c'est le resultat de la methode le browser br pointant sur url
  br
end

事实是我正在使用watir宝石。不是watir-classic或watir-webdriver。 谢谢您的帮助。

1 个答案:

答案 0 :(得分:1)

进行了快速测试,除非您出于某种原因希望父进程保持活动状态,否则这总是会终止浏览器。

def brow_gotosafe url
require 'timeout'
require 'watir'

    begin          
      br = Watir::Browser.new    
      br.goto url  
      pid = $$
      puts "this is pid: #{pid}"  
      puts "lets test script execution fail: "
      asdasdasd #this will fail execution         
    rescue => e
      puts "browser exists: #{br.exists?}"  
      puts "error class: #{e.class}"  
      puts "error message: #{e.message}"  
      puts "error inspect: #{e.backtrace.inspect}"  

      begin
          puts "lets test failin to close the browser within timeout: "    
          Timeout::timeout(5) {           
            #br.close
            sleep 10
           }
      rescue Timeout::Error
        puts "Timeout error happened, browser still exists: #{br.exists?}"  
        puts "Killing browser by killing pid #{pid.to_s}"  
        system("kill #{pid}") 
      end    
    ensure
      #consider putting it here as well
      begin
        Timeout::timeout(5) { br.close }
      rescue Timeout::Error
        system("kill #{pid}") 
      end  
    end
end

brow_gotosafe "www.google.com"

这样,您无需将进程grep到文件中,然后将文件读入数组并在执行之前和之后比较数组。

因为每次执行都会在未在超时时间内正常关闭(通过杀死其父项)清理打开的浏览器

希望它对您有用。

编辑:父母需要活着

深入浏览器实例后,我仅设法找到chromedriver / geckodriver pid,但是由于浏览器实例是chromedriver / geckodriver的长子,因此您可以轻松地使用 ps

获取浏览器pid。
def brow_gotosafe url
  require 'timeout'
  require 'watir'  

  begin          
    br = Watir::Browser.new    
    br.goto url      
    driver_pid = br.driver.instance_variable_get(:@service).instance_variable_get(:@process).instance_variable_get(:@pid)
    puts "this is driver_pid pid: #{driver_pid}" 
    browser_pid =  `ps --ppid #{driver_pid} | awk '{print $1}'| sed "1 d"`
    puts "this is browser pid: #{browser_pid}"  
    puts "lets test script execution fail: "
    asdasdasd #this will fail execution         
  rescue => e
    puts "browser exists: #{br.exists?}"  
    puts "error class: #{e.class}"  
    puts "error message: #{e.message}"  
    puts "error inspect: #{e.backtrace.inspect}"  

    begin
        puts "lets test failin to close the browser within timeout: "    
        Timeout::timeout(5) {           
          #br.close
          sleep 10
         }
    rescue Timeout::Error
      puts "Timeout error happened"  
      puts "Killing browser by killing browser pid #{browser_pid}"  
      system("kill -9 #{browser_pid}")    
      sleep 20 #here check if browser is really killed
      puts "if youre seeing this then main process exists after killing 
      browser"  
    end  
  end
end

brow_gotosafe "www.google.com"