Class: BlackStack::BrowserFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/browserfactory.rb

Constant Summary collapse

HOST_LOCK_FILENAME =

This file is to launch one browser at time in the same host. There is one, and only one, lock file for reach host where Blackstack is running. More information here: bitbucket.org/leandro_sardi/blackstack/issues/1155/browserfactory-use-one-single-lock-file

"./sba.host.#{BlackStack::MyProcess.macaddress}.lock"
PROFILE_PID_LIST_FILENAME =

This file keeps the PIDs of all the child processes of this process. It is neccessary to kill all the child processes of this process when you have started a chrome browser, and you want to be sure that you have closed it. More infromation here: bitbucket.org/leandro_sardi/blackstack/issues/943/browserfactory-deja-exploradores-abiertos

"./sba.profile.%PROFILE_NAME%.list"
PROFILE_LOCK_FILENAME =

This file store the PID of the last processes that started a browser with this profile name. There is one, and only one, pid_lockfile for each browser profile; and such pid_lockfile is shared by all the hosts where BlackStack is running.

"./sba.profile.%PROFILE_NAME%.lock"
DEFAULT_LOAD_TIMEOUT =

Page load timeout by default. Works for chrome browsers only.

360
DEFAULT_CHROMEDRIVER_PATH =

Location of the chromedriver.exe file by default. Works for chrome browsers only.

'./chromedriver.exe'
TYPE_CHROME =

Different supported browsers.

1
TYPE_MIMIC =
2
@@fd_host_lock =

File handler for HOST_LOCK_FILENAME

File.open(HOST_LOCK_FILENAME,"w")
@@fd_profile_pid_list =

File handler for PROFILE_PID_LIST_FILENAME

nil
@@fd_profile_lock =

File handler for PROFILE_LOCK_FILENAME

nil
@@driver =

Selenium driver

nil
@@browser =

Selenium browser

nil
@@pid =

PID of this browser. Works for Chrme only.

nil
@@profile_name =

Profile name of this browser. For Chrome, it will store the name of the profile folder. For Mimic, it will store the profileId in the MultiLogin APP.

nil
@@type =

Type of this browser. Only TYPE_CHROME or TYPE_MIMIC are supported at this moment.

nil
@@arAgents =

NOTA: esta lista debe estar permitida por LinkedIn. De caso contrario, aparecera el mensaje “Upgrad your browser” Se puede obtener una lista actualizada de este sitio: techblog.willshouse.com/2012/01/03/most-common-user-agents/

[
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",  
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063", 
]

Class Method Summary collapse

Class Method Details

.addPidToProfileList(profile_name, pid) ⇒ Object

Add a PID to the PROFILE_PID_LIST_FILENAME file. For more information, read documentations about PROFILE_PID_LIST_FILENAME. This method is used for chrome browsers only.



366
367
368
369
370
371
# File 'lib/browserfactory.rb', line 366

def self.addPidToProfileList(profile_name, pid)
  fname = PROFILE_PID_LIST_FILENAME.gsub('%PROFILE_NAME%', profile_name)
  f = File.open(fname, 'a')
  f.write("#{pid},")
  f.close
end

.agentsObject

Returns a suggested list of user-agents



515
516
517
# File 'lib/browserfactory.rb', line 515

def self.agents
  return @@arAgents
end

.browserObject

Returns the PampaBrowser object



335
336
337
# File 'lib/browserfactory.rb', line 335

def self.browser
  @@browser
end

.chrome(h) ⇒ Object

It will call launch_chrome to launch a chrome browser. The hash parameters musy have the following keys:

  • proxy: a BlackStack::RemoteProxy object;

  • load_timeout: max number of seconds to wait a page to load;

  • user_agent: user agent of the browser;

  • profile_name: will create a folder with ths name to store all the data of the chrome profile (history, cookies, saved passwords, etc);

  • chromedriver_path: location of the chromedriver.exe file, will use DEFAULT_CHROMEDRIVER_PATH by default.



756
757
758
759
760
761
762
763
764
765
766
767
# File 'lib/browserfactory.rb', line 756

def self.chrome(h)
  # TODO: check if h is a hash
  # TODO: check the variable type of each param
  # TODO: check mandatory params 
  self.launch_chrome(
    h[:proxy], 
    h[:load_timeout].nil? ? DEFAULT_LOAD_TIMEOUT : h[:load_timeout], 
    h[:user_agent],
    h[:profile_name],
    h[:chromedriver_path]
  )
end

.chrome_versionObject

Returns the version of the availalble chrome browser.



641
642
643
644
645
646
# File 'lib/browserfactory.rb', line 641

def self.chrome_version
  res = `reg query \"HKEY_CURRENT_USER\\Software\\Google\\Chrome\\BLBeacon\" /v version`.scan(/REG_SZ    (.*)$/).first
  return nil if res.nil?
  return res[0] if res.size > 0
  return nil
end

.chromedriver_version(filename = nil) ⇒ Object

Returns the version of the availalble chromedriver. The filename parameter is the full path of the chromedriver.exe command. If filename parameter is nil, it will look for the chromedriver.exe in the PATH environment.

Not valid for Mimic, since MLA handle its own chromedriver into its installation folder.



654
655
656
657
658
659
660
# File 'lib/browserfactory.rb', line 654

def self.chromedriver_version(filename=nil)
  res = `chromedriver -v`.scan(/ChromeDriver\s(.*)\s\(/).first if filename.nil?
  res = `#{filename} -v`.scan(/ChromeDriver\s(.*)\s\(/).first if !filename.nil?
  return nil if res.nil?
  return res[0] if res.size > 0
  return nil
end

.destroyObject

Close the browser only if itIsMe? returns true. Set nil to @@browser, @@pid, @@profile_name, @@driver, @@type.



544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
# File 'lib/browserfactory.rb', line 544

def self.destroy
  #if self.itIsMe?
    begin        
      # borro el contenido de PROFILE_LOCK_FILENAME 
      #if !@@profile_name.nil?
      #  fname = PROFILE_LOCK_FILENAME.gsub('%PROFILE_NAME%', @@profile_name) 
      #  File.open(fname,'w')
      #end
      
      # 
      if @@type == BlackStack::BrowserFactory::TYPE_CHROME
        # kill all child process
        self.lockProfileList()
        self.readPidToProfileList(@@profile_name).each { |pid|
          MyProcess.kill(pid)
          self.removePidToProfileList(@@profile_name, pid)      
        }
        self.releaseProfileList()
        
        begin
          @@browser.close if !@@browser.nil?
        rescue
        end
        
      elsif @@type == BlackStack::BrowserFactory::TYPE_MIMIC
=begin
puts ''
        begin
print 'Close browser?... '
          if !@@browser.nil?
puts 'yes'
print 'Close browser... '
				@@browser.close 
puts 'done'
			else
puts 'no'							
			end
        rescue => e
puts "error: #{e.to_s}"
        end
=end
=begin
        begin
          # TODO: entender porque debo hacer esta llamada a start para que el perfil se cierre cuando ya estaba iniciado
puts ''
print 'Close browser?... '
			if !@@profile_name.nil?
puts 'yes'
print 'Close browser... '
				BlackStack::BrowserFactory.mimic(@@profile_name)
puts 'done'
print 'Close browser (2)... '
				@@browser.close 
puts 'done'
			else
puts 'no'
			end
        rescue
          # nothing here
        end
=end

        i = 0
        max = 90
        success = 0 # I have to call this access point many times to get the browser closed.
		max_success_required = 30
        while i<max && success<max_success_required
#puts ''
          i+=1
         url = "http://127.0.0.1:#{BlackStack::StealthBrowserAutomation::Multilogin::mla_local_port}/api/v1/profile/stop?profileId=#{@@profile_name}"
#print "Api Call ##{i.to_s} to: #{url}... "
          uri = URI.parse(url)
          body = Net::HTTP.get(uri)
          res = JSON.parse(body)
          success += 1 if res['status'].to_s == 'OK'
#puts "response: #{res['status'].to_s}"
        end # while i<max &&  && success<max_success_required
        raise "Error requesting Mimic to stop (tried #{i.to_s} times)" if success<max_success_required

      else
        raise 'Cannot destroy browser due unknown browser type'
      end
    rescue => e
      self.release
      raise e
    end
  #end # if self.isItMe?
  
  # reseteo las variables    
  @@browser = nil
  @@pid = nil
  @@profile_name = nil
  @@driver = nil
  @@type = nil
end

.getPidObject

Returns the PID of the browser. Returns always nill if the browser is Mimic.



521
522
523
# File 'lib/browserfactory.rb', line 521

def self.getPid
  return @@pid
end

.isCreatedObject

Returns true if @@browser is not nil, or @@profile_name is not nil. Otherwise, returns false If the browser type is Chrome, this method will return true if the PROFILE_PID_LIST_FILENAME has one or more PIDs registered. For more information, read documentations about PROFILE_PID_LIST_FILENAME.



412
413
414
415
416
417
418
419
# File 'lib/browserfactory.rb', line 412

def self.isCreated
  if @@type == BlackStack::BrowserFactory::TYPE_CHROME
    if (self.readPidToProfileList(@@profile_name).size>0)
      return true
    end
  end
  !@@browser.nil? || !@@profile_name.nil?
end

.isCreated?Boolean

Call isCreated() method. For more information, read the documentation of isCreated() method.

Returns:

  • (Boolean)


423
424
425
# File 'lib/browserfactory.rb', line 423

def self.isCreated?
  self.isCreated()
end

.itIsMe?Boolean

Retorna true si el perfil en @@profile_name esta siendo trabajado por este proceso

Returns:

  • (Boolean)


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/browserfactory.rb', line 428

def self.itIsMe?
  # el archivo tiene una unica primera linea de ancho fijo
  line_chars = 100
  # obtengo el id de este proceso que esta corriendo
  my_pid = PROCESS.pid
  # bloqueo el archivo de este perfil
  @@fd_profile_lock.flock(File::LOCK_EX) if !@@fd_profile_lock.nil?
  # valido que my_pid no tenga mas caracteres que al ancho fijo
  raise 'Cannot work browser profile lockfile because the lenght if the id of this process is larger than the max number of chars allowed (#{line_chars.to_s})' if line_chars < my_pid.size 
  # obtengo el id del proceso que se reservo este perfil
  @@fd_profile_lock.seek(-line_chars, IO::SEEK_CUR) if !@@fd_profile_lock.nil?
  lock_pid = @@fd_profile_lock.read.to_s      
  # libero el archivo de este perfil
  @@fd_profile_lock.flock(File::LOCK_UN) if !@@fd_profile_lock.nil?
  # return
  my_pid.strip.upcase == lock_pid.strip.upcase
end

.launch_chrome(proxy = nil, load_timeout = DEFAULT_LOAD_TIMEOUT, user_agent = nil, profile_name = nil, chromedriver_path = nil) ⇒ Object

Launch a chrome browser.



770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
# File 'lib/browserfactory.rb', line 770

def self.launch_chrome(proxy=nil, load_timeout=DEFAULT_LOAD_TIMEOUT, user_agent=nil, profile_name=nil, chromedriver_path=nil)
  #
  @@browser = nil
  @@driver = nil
  @@type = BlackStack::BrowserFactory::TYPE_CHROME
  @@profile_name = profile_name

  #
  #fname = PROFILE_LOCK_FILENAME.gsub('%PROFILE_NAME%', @@profile_name)
  #File.open(fname,'w') if !File.file?(fname)
  #@@fd_profile_lock = File.open(fname, 'r+')
  
  # 
  agent = @@arAgents[0] if user_agent.nil?
  agent = user_agent if !user_agent.nil?
  
  # #959 - valido que el parametro agents sea un array - porque si se pasa un string se lo procesa como array y se toma un UA name de un char.
  #raise "Array expected in parameter agents in BrowserFactory.create." if !(agent.is_a? String) 
  
  # 
  while (@@browser == nil)            
    
    begin
      # Levantar el flag de reserva a mi favor
      self.lock()
  
      # 
      #self.lockProfile()
  
      # 
      self.lockProfileList()

      #
      client = Selenium::WebDriver::Remote::Http::Default.new
      begin
        client.read_timeout = load_timeout # for newest selenium webdriver version 
      rescue => e
        client.timeout = load_timeout # deprecated in newest selenium webdriver version
      end
  
      # se agregan extensiones por el issue #1171
      #
      # UPDATE: Las extensiones en JavaScript para eliminar rastros, dejan rastros en si mismas.
      # 
      switches = ["lang=en", "--log-level=3", "--user-agent=#{agent}", "disable-infobars", "load-extension=#{File.absolute_path('./chrome_extension')}"]
  
      # 
      if (profile_name!=nil)
            
        # issue #964
        filename = "chrome_profiles/#{profile_name}/#{profile_name}/Default/Preferences"
        if ( File.file?(filename) == true )
          File.delete(filename)
        end
  
        # issue #964
        filename = "chrome_profiles/#{profile_name}/#{profile_name}/Local State"
        if ( File.file?(filename) == true )
          File.delete(filename)
        end
            
        # configuro el browser para que use este perfil
        switches += ["--user-data-dir=chrome_profiles/#{profile_name}/#{profile_name}"]
            
      end
          
      if (proxy!=nil)
        switches += proxy.chrome_switches
      end

      Selenium::WebDriver::Chrome.driver_path = chromedriver_path if !chromedriver_path.nil?
      Selenium::WebDriver::Chrome.driver_path = DEFAULT_CHROMEDRIVER_PATH if chromedriver_path.nil?
        
      @@driver = Selenium::WebDriver.for :chrome, :switches => switches
      bridge = @@driver.instance_variable_get(:@bridge)
      service = bridge.instance_variable_get(:@service)
      process = service.instance_variable_get(:@process)
      @@pid = process.pid.to_s # es el PID del chromedriver
      @@driver.manage.window().maximize()
      @@browser = PampaBrowser.new(@@driver)
      @@browser.proxy = proxy.clone if !proxy.nil?    
      @@browser.agent_name = agent
      @@browser.profile_name = profile_name
      self.updateProfileList              
  
    # 
    rescue => e # TODO: Se atrapa una expecion porque sigue ocurreiendo el error reportado en el issue #134 y #129
      # 
      p1 = PROCESS.list().select { |p| p[:ppid] == PROCESS.pid && p[:executablepath] =~ /chromedriver\.exe/ }.first
      if (p1 != nil)
        @@pid = p1[:pid]
        self.updateProfileList              
      end              
      self.releaseProfileList()

      #
      #self.releaseProfile()

      # Liberar el flag de reserva de creacion del browser
      self.release()
  
      # disparar la exepcion
      raise e          
    end                  

    #
    #self.releaseProfile()
        
    # Liberar el flag de reserva de creacion del browser
    self.release()

  end # while
  
  #
  @@browser
end

.lockObject

This method will lock the lockfile regarding this host, in order to get all processes in the same host launching one browser at time.

Since chromedriver can’t take one starting request at time, this method is to force the BrowserFactory classs, running in many processes of the same host at the same time, to try

to launch browsers at the same time.



533
534
535
# File 'lib/browserfactory.rb', line 533

def self.lock
  @@fd_host_lock.flock(File::LOCK_EX) if @@type == BlackStack::BrowserFactory::TYPE_CHROME
end

.lockProfileObject

This method is to open no more than one browser of the same profile at time. It will lock the file at the begining. If the content of the file is the PID of this process, so this process is good to start the browser. If the content of the file is different than the PID of this process, but such content is not equal to the PID of any other process alive, so this process is good to start the browser. If the content of the file is different than the PID of this process, and such content is equal to the PID of another process alive, this method unlock the file and will raise an exception.



451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
# File 'lib/browserfactory.rb', line 451

def self.lockProfile
  # el archivo tiene una unica primera linea de ancho fijo
  line_chars = 100
  # bloqueo el archivo de este perfil
  @@fd_profile_lock.flock(File::LOCK_EX)
  # obtengo el id de este proceso que esta corriendo
  my_pid = PROCESS.pid
  # valido que my_pid no tenga mas caracteres que al ancho fijo
  raise 'Cannot work browser profile lockfile because the lenght if the id of this process is larger than the max number of chars allowed (#{line_chars.to_s})' if line_chars < my_pid.size 
  # obtengo el id del proceso que se reservo este perfil
  lock_pid = @@fd_profile_lock.read.to_s
  # 
  if lock_pid.size == 0
    @@fd_profile_lock.write my_pid
    @@fd_profile_lock.write ' ' * (line_chars - my_pid.size)
    @@fd_profile_lock.flush
  elsif lock_pid.strip.upcase != my_pid.strip.upcase
    # verifico si el proceso que reservo este perfil esta activo
    p = PROCESS.list().select { |h| h[:pid].strip.upcase == lock_pid.strip.upcase }.first
    lock_process_is_alive = !p.nil?
    # levanto una excepcion de bloqueo si este perfil fue reservado por otro proceso y el proceso sigue activo
    if lock_process_is_alive
      # libero el archivo de este perfil
      @@fd_profile_lock.flock(File::LOCK_UN)
      # 
      raise 'Profile is locked'
    # me reservo este perfil si fue reservado por un proceso que ya no esta activo
    else # if lock_process_is_alive
      @@fd_profile_lock.seek(-line_chars, IO::SEEK_CUR)
      @@fd_profile_lock.write my_pid
      @@fd_profile_lock.write ' ' * (line_chars - my_pid.size)
      @@fd_profile_lock.flush
    end # if lock_process_is_alive
  else # lock_pid.strip.upcase == my_pid.strip.upcase
    # go ahead
  end # if lock_pid.size == 0
end

.lockProfileListObject

Lock PROFILE_PID_LIST_FILENAME file. For more information, read documentations about PROFILE_PID_LIST_FILENAME.



353
354
355
# File 'lib/browserfactory.rb', line 353

def self.lockProfileList()
  #@@fd_profile.flock(File::LOCK_EX)
end

.mimic(mimic_profile_id, load_timeout = DEFAULT_LOAD_TIMEOUT) ⇒ Object

Launch a Mimic browser.



663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
# File 'lib/browserfactory.rb', line 663

def self.mimic(mimic_profile_id, load_timeout=DEFAULT_LOAD_TIMEOUT)
  # 
  @@type = BlackStack::BrowserFactory::TYPE_MIMIC
  @@profile_name = mimic_profile_id

  #
  #fname = PROFILE_LOCK_FILENAME.gsub('%PROFILE_NAME%', @@profile_name)
  #File.open(fname,'w') if !File.file?(fname)
  #@@fd_profile_lock = File.open(fname,'r+')

  begin          
    # Levantar el flag de reserva a mi favor
    self.lock()
  
    # 
    #self.lockProfile()

    url_2 = nil
    i = 0
    max = 3
    while (i<max && url_2.nil?)
      i += 1

      # cierro el perfil por si estaba corriendo
      url = "http://127.0.0.1:#{BlackStack::StealthBrowserAutomation::Multilogin::mla_local_port}/api/v1/profile/stop?profileId=#{@@profile_name}"
      uri = URI.parse(url)
      body = Net::HTTP.get(uri)
      res = JSON.parse(body)

      url = "http://127.0.0.1:#{BlackStack::StealthBrowserAutomation::Multilogin::mla_local_port}/api/v1/profile/start?automation=true&profileId=#{@@profile_name}"
      uri = URI.parse(url)
      body = Net::HTTP.get(uri)
      res = JSON.parse(body)

      if !res.has_key?('status')
        if i>=max
          self.release() # libero el flag de reserva de turno para crar un browser
          raise "Error requesting Mimic to start (try #{i.to_s}): #{res.to_s}"
        end
      elsif res['status'] != 'OK'
        if i>=max
          self.release() # libero el flag de reserva de turno para crar un browser
          raise "Error requesting Mimic to start (try #{i.to_s}): #{res.to_s}"
        end
      else
        begin
          url_2 = res['value']
          if !url_2.nil?
            #uri_2 = URI.parse(url_2)
            #req_2 = Net::HTTP::Get.new(url_2)
            #res_2 = Net::HTTP.start(uri_2.host, uri_2.port, :use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE) {|http|
            #  http.request(req_2)
            #}        
            @@driver = Selenium::WebDriver.for(:remote, :url => url_2)
				@@driver.manage.timeouts.page_load = load_timeout
            #bridge = @@driver.instance_variable_get(:@bridge)
            #service = bridge.instance_variable_get(:@service)
            #process = service.instance_variable_get(:@process)
            #@@pid = process.pid.to_s # es el PID del chromedriver
            @@driver.manage.window().maximize()
            @@browser = PampaBrowser.new(@@driver) # Watir::Browser.new(@@driver)
          end
        rescue => e
          raise e if i>=max
        end
      end # if !res.has_key?('status')
    end # while  
  rescue => e
    # 
    #self.releaseProfile()              
    # libero el flag de reserva de turno para crar un browser
    self.release() 
    # 
    raise e
  end

  # 
  #self.releaseProfile()              

  # libero el flag de reserva de turno para crar un browser
  self.release() 

  # 
  @@browser
end

.readPidToProfileList(profile_name) ⇒ Object

Returns an array of strings with the PIDs registered for this browser. For more information, read documentations about PROFILE_PID_LIST_FILENAME. This method is used for chrome browsers only.



388
389
390
391
392
393
394
395
396
# File 'lib/browserfactory.rb', line 388

def self.readPidToProfileList(profile_name)
  if profile_name != nil
    fname = PROFILE_PID_LIST_FILENAME.gsub('%PROFILE_NAME%', profile_name)
    s = File.read(fname)
    return s.split(",")
  else
    return []
  end
end

.releaseObject

Releases the lockfile regarding this host.



538
539
540
# File 'lib/browserfactory.rb', line 538

def self.release
  @@fd_host_lock.flock(File::LOCK_UN) if @@type == BlackStack::BrowserFactory::TYPE_CHROME
end

.releaseProfileObject

This method is to open no more than one browser of the same profile at time. It will unlock the file at the begining.



491
492
493
494
# File 'lib/browserfactory.rb', line 491

def self.releaseProfile
  # libero el archivo de este perfil
  @@fd_profile_lock.flock(File::LOCK_UN)
end

.releaseProfileListObject

Unlock PROFILE_PID_LIST_FILENAME file. For more information, read documentations about PROFILE_PID_LIST_FILENAME.



359
360
361
# File 'lib/browserfactory.rb', line 359

def self.releaseProfileList()
  #@@fd_profile.flock(File::LOCK_UN)
end

.removePidToProfileList(profile_name, pid) ⇒ Object

Remove a PID from the PROFILE_PID_LIST_FILENAME file. For more information, read documentations about PROFILE_PID_LIST_FILENAME. This method is used for chrome browsers only.



376
377
378
379
380
381
382
383
# File 'lib/browserfactory.rb', line 376

def self.removePidToProfileList(profile_name, pid)
  fname = PROFILE_PID_LIST_FILENAME.gsub('%PROFILE_NAME%', profile_name)
  s = File.read(fname)
  s = s.gsub("#{pid},", "")
  f = File.open(fname, 'w')
  f.write(s)
  f.close
end

.screenshot(filename) ⇒ Object

Toma una captura del area visible de la pagina. Mas informacion: stackoverflow.com/questions/25543651/screenshot-of-entire-webpage-using-selenium-webdriver-rc-rails



510
511
512
# File 'lib/browserfactory.rb', line 510

def self.screenshot(filename)
  @@driver.save_screenshot(filename)
end

.typeDesc(type) ⇒ Object

Returns the description string from a browser type code



345
346
347
348
349
# File 'lib/browserfactory.rb', line 345

def self.typeDesc(type)
  return 'Chrome' if @@type == BlackStack::BrowserFactory::TYPE_CHROME
  return 'Mimic' if @@type == BlackStack::BrowserFactory::TYPE_MIMIC
  raise 'Unknown browser type'
end

.typesObject

Returns the list of supported browsers



340
341
342
# File 'lib/browserfactory.rb', line 340

def self.types
  [BlackStack::BrowserFactory::TYPE_CHROME, BlackStack::BrowserFactory::TYPE_MIMIC]
end

.updateProfileListObject

Add the PID of this browser; and the PID of all the child processes of this, with name like /chrome.exe/. For more information, read documentations about PROFILE_PID_LIST_FILENAME. This method is used for chrome browsers only.



401
402
403
404
405
406
# File 'lib/browserfactory.rb', line 401

def self.updateProfileList
  addPidToProfileList(@@profile_name, @@pid)
  PROCESS.list().select { |p| p[:ppid] == @@pid && p[:executablepath] =~ /chrome\.exe/ }.each { |p2|
    addPidToProfileList(@@profile_name, p2[:pid])                  
  }
end