vapir-firefox 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/vapir-firefox/browser.rb +226 -115
 - data/lib/vapir-firefox/clear_tracks.rb +6 -6
 - data/lib/vapir-firefox/config.rb +5 -0
 - data/lib/vapir-firefox/container.rb +74 -65
 - data/lib/vapir-firefox/element.rb +13 -13
 - data/lib/vapir-firefox/firefox_socket/base.rb +790 -0
 - data/lib/vapir-firefox/firefox_socket/jssh.rb +49 -0
 - data/lib/vapir-firefox/firefox_socket/mozrepl.rb +58 -0
 - data/lib/vapir-firefox/{prototype.functional.js → firefox_socket/prototype.functional.js} +0 -0
 - data/lib/vapir-firefox/javascript_object.rb +736 -0
 - data/lib/vapir-firefox/modal_dialog.rb +4 -4
 - data/lib/vapir-firefox/page_container.rb +4 -4
 - data/lib/vapir-firefox/version.rb +1 -1
 - metadata +16 -13
 - data/lib/vapir-firefox/jssh_socket.rb +0 -1418
 
| 
         @@ -85,7 +85,6 @@ require 'vapir-common/waiter' 
     | 
|
| 
       85 
85 
     | 
    
         
             
            require 'vapir-common/browser'
         
     | 
| 
       86 
86 
     | 
    
         
             
            require 'vapir-firefox/window'
         
     | 
| 
       87 
87 
     | 
    
         
             
            require 'vapir-firefox/modal_dialog'
         
     | 
| 
       88 
     | 
    
         
            -
            require 'vapir-firefox/jssh_socket'
         
     | 
| 
       89 
88 
     | 
    
         
             
            require 'vapir-firefox/container'
         
     | 
| 
       90 
89 
     | 
    
         
             
            require 'vapir-firefox/page_container'
         
     | 
| 
       91 
90 
     | 
    
         | 
| 
         @@ -97,36 +96,115 @@ module Vapir 
     | 
|
| 
       97 
96 
     | 
    
         
             
                include Firefox::Window
         
     | 
| 
       98 
97 
     | 
    
         
             
                include Firefox::ModalDialogContainer
         
     | 
| 
       99 
98 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
                # initializes a  
     | 
| 
       101 
     | 
    
         
            -
                def self. 
     | 
| 
       102 
     | 
    
         
            -
                   
     | 
| 
       103 
     | 
    
         
            -
                  @@ 
     | 
| 
       104 
     | 
    
         
            -
                   
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
      
 99 
     | 
    
         
            +
                # initializes a FirefoxSocket and stores in a class variable. 
         
     | 
| 
      
 100 
     | 
    
         
            +
                def self.initialize_firefox_socket(socket_class, socket_options) # :nodoc:
         
     | 
| 
      
 101 
     | 
    
         
            +
                  uninitialize_firefox_socket
         
     | 
| 
      
 102 
     | 
    
         
            +
                  @@firefox_socket=socket_class.new(socket_options)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  vapir_javascript_functions = {
         
     | 
| 
      
 104 
     | 
    
         
            +
                    :element_real_visibility => %Q(
         
     | 
| 
      
 105 
     | 
    
         
            +
                      function(element_to_check, document_object)
         
     | 
| 
      
 106 
     | 
    
         
            +
                      { var real_visibility = null;
         
     | 
| 
      
 107 
     | 
    
         
            +
                        while(element_to_check && real_visibility==null)
         
     | 
| 
      
 108 
     | 
    
         
            +
                        { var style = element_to_check.nodeType==1 ? document_object.defaultView.getComputedStyle(element_to_check, null) : null;
         
     | 
| 
      
 109 
     | 
    
         
            +
                          if(style)
         
     | 
| 
      
 110 
     | 
    
         
            +
                          { // only pay attention to the innermost definition that really defines visibility - one of 'hidden', 'collapse' (only for table elements), 
         
     | 
| 
      
 111 
     | 
    
         
            +
                            // or 'visible'. ignore 'inherit'; keep looking upward. 
         
     | 
| 
      
 112 
     | 
    
         
            +
                            // this makes it so that if we encounter an explicit 'visible', we don't pay attention to any 'hidden' further up. 
         
     | 
| 
      
 113 
     | 
    
         
            +
                            // this style is inherited - may be pointless for firefox, but IE uses the 'inherited' value. not sure if/when ff does.
         
     | 
| 
      
 114 
     | 
    
         
            +
                            if(style.visibility)
         
     | 
| 
      
 115 
     | 
    
         
            +
                            { var visibility=style.visibility.toLowerCase();
         
     | 
| 
      
 116 
     | 
    
         
            +
                              if($A(['hidden', 'collapse', 'visible']).include(visibility))
         
     | 
| 
      
 117 
     | 
    
         
            +
                              { real_visibility = visibility;
         
     | 
| 
      
 118 
     | 
    
         
            +
                              }
         
     | 
| 
      
 119 
     | 
    
         
            +
                            }
         
     | 
| 
      
 120 
     | 
    
         
            +
                          }
         
     | 
| 
      
 121 
     | 
    
         
            +
                          element_to_check=element_to_check.parentNode;
         
     | 
| 
      
 122 
     | 
    
         
            +
                        }
         
     | 
| 
      
 123 
     | 
    
         
            +
                        return real_visibility;
         
     | 
| 
      
 124 
     | 
    
         
            +
                      }
         
     | 
| 
      
 125 
     | 
    
         
            +
                    ),
         
     | 
| 
      
 126 
     | 
    
         
            +
                    :element_displayed => %Q(
         
     | 
| 
      
 127 
     | 
    
         
            +
                      function(node, document_object)
         
     | 
| 
      
 128 
     | 
    
         
            +
                      { var style = node.nodeType==1 ? document_object.defaultView.getComputedStyle(node, null) : null;
         
     | 
| 
      
 129 
     | 
    
         
            +
                        var display = style && style.display;
         
     | 
| 
      
 130 
     | 
    
         
            +
                        var displayed = display ? display.toLowerCase() != 'none' : true;
         
     | 
| 
      
 131 
     | 
    
         
            +
                        return displayed;
         
     | 
| 
      
 132 
     | 
    
         
            +
                      }
         
     | 
| 
      
 133 
     | 
    
         
            +
                    ),
         
     | 
| 
      
 134 
     | 
    
         
            +
                    :visible_text_nodes => %Q(
         
     | 
| 
      
 135 
     | 
    
         
            +
                      function(element_object, document_object)
         
     | 
| 
      
 136 
     | 
    
         
            +
                      { var recurse_text_nodes = Vapir.Ycomb(function(recurse)
         
     | 
| 
      
 137 
     | 
    
         
            +
                        { return function(node, parent_visibility)
         
     | 
| 
      
 138 
     | 
    
         
            +
                          { if(node.nodeType==1 || node.nodeType==9)
         
     | 
| 
      
 139 
     | 
    
         
            +
                            { var style = node.nodeType==1 ? document_object.defaultView.getComputedStyle(node, null) : null;
         
     | 
| 
      
 140 
     | 
    
         
            +
                              var our_visibility = style && style.visibility;
         
     | 
| 
      
 141 
     | 
    
         
            +
                              if(!(our_visibility && $A(['hidden', 'collapse', 'visible']).include(our_visibility.toLowerCase())))
         
     | 
| 
      
 142 
     | 
    
         
            +
                              { our_visibility = parent_visibility;
         
     | 
| 
      
 143 
     | 
    
         
            +
                              }
         
     | 
| 
      
 144 
     | 
    
         
            +
                              if(!Vapir.element_displayed(node, document_object))
         
     | 
| 
      
 145 
     | 
    
         
            +
                              { return [];
         
     | 
| 
      
 146 
     | 
    
         
            +
                              }
         
     | 
| 
      
 147 
     | 
    
         
            +
                              else
         
     | 
| 
      
 148 
     | 
    
         
            +
                              { return $A(node.childNodes).inject([], function(result, child_node)
         
     | 
| 
      
 149 
     | 
    
         
            +
                                { return result.concat(recurse(child_node, our_visibility));
         
     | 
| 
      
 150 
     | 
    
         
            +
                                });
         
     | 
| 
      
 151 
     | 
    
         
            +
                              }
         
     | 
| 
      
 152 
     | 
    
         
            +
                            }
         
     | 
| 
      
 153 
     | 
    
         
            +
                            else if(node.nodeType==3)
         
     | 
| 
      
 154 
     | 
    
         
            +
                            { if(parent_visibility && $A(['hidden', 'collapse']).include(parent_visibility.toLowerCase()))
         
     | 
| 
      
 155 
     | 
    
         
            +
                              { return [];
         
     | 
| 
      
 156 
     | 
    
         
            +
                              }
         
     | 
| 
      
 157 
     | 
    
         
            +
                              else
         
     | 
| 
      
 158 
     | 
    
         
            +
                              { return [node.data];
         
     | 
| 
      
 159 
     | 
    
         
            +
                              }
         
     | 
| 
      
 160 
     | 
    
         
            +
                            }
         
     | 
| 
      
 161 
     | 
    
         
            +
                            else
         
     | 
| 
      
 162 
     | 
    
         
            +
                            { return [];
         
     | 
| 
      
 163 
     | 
    
         
            +
                            }
         
     | 
| 
      
 164 
     | 
    
         
            +
                          };
         
     | 
| 
      
 165 
     | 
    
         
            +
                        });
         
     | 
| 
      
 166 
     | 
    
         
            +
                        var element_to_check = element_object;
         
     | 
| 
      
 167 
     | 
    
         
            +
                        while(element_to_check)
         
     | 
| 
      
 168 
     | 
    
         
            +
                        { // check for display property. this is not inherited, so ascend the heirarchy looking. 
         
     | 
| 
      
 169 
     | 
    
         
            +
                          //
         
     | 
| 
      
 170 
     | 
    
         
            +
                          // any parent with display of 'none' overrides a more-immediate visibility='visible', so if any parent has 
         
     | 
| 
      
 171 
     | 
    
         
            +
                          // display=none, this is not visible and has no visible child text nodes.
         
     | 
| 
      
 172 
     | 
    
         
            +
                          if(!Vapir.element_displayed(element_to_check, document_object))
         
     | 
| 
      
 173 
     | 
    
         
            +
                          { return [];
         
     | 
| 
      
 174 
     | 
    
         
            +
                          }
         
     | 
| 
      
 175 
     | 
    
         
            +
                          element_to_check=element_to_check.parentNode;
         
     | 
| 
      
 176 
     | 
    
         
            +
                        }
         
     | 
| 
      
 177 
     | 
    
         
            +
                        return recurse_text_nodes(element_object, Vapir.element_real_visibility(document_object, element_object));
         
     | 
| 
      
 178 
     | 
    
         
            +
                      }
         
     | 
| 
      
 179 
     | 
    
         
            +
                    )
         
     | 
| 
      
 180 
     | 
    
         
            +
                  }
         
     | 
| 
      
 181 
     | 
    
         
            +
                  vapir_javascript_functions.each do |name, function_string|
         
     | 
| 
      
 182 
     | 
    
         
            +
                    @@firefox_socket.root.Vapir[name]=@@firefox_socket.object(function_string)
         
     | 
| 
      
 183 
     | 
    
         
            +
                  end
         
     | 
| 
      
 184 
     | 
    
         
            +
                  @@firefox_socket
         
     | 
| 
       106 
185 
     | 
    
         
             
                end
         
     | 
| 
       107 
     | 
    
         
            -
                # returns a connected  
     | 
| 
      
 186 
     | 
    
         
            +
                # returns a connected FirefoxSocket. pass :reset_if_dead => true if you suspect an existing 
         
     | 
| 
       108 
187 
     | 
    
         
             
                # socket may be dead, and you want a new one. a warning will be printed if this occurs. 
         
     | 
| 
       109 
     | 
    
         
            -
                def self. 
     | 
| 
       110 
     | 
    
         
            -
                  if options[:reset] || !(class_variable_defined?('@@ 
     | 
| 
       111 
     | 
    
         
            -
                     
     | 
| 
      
 188 
     | 
    
         
            +
                def self.firefox_socket(options={}) # :nodoc:
         
     | 
| 
      
 189 
     | 
    
         
            +
                  if options[:reset] || !(class_variable_defined?('@@firefox_socket') && @@firefox_socket)
         
     | 
| 
      
 190 
     | 
    
         
            +
                    initialize_firefox_socket(options[:socket_class], options[:socket_options])
         
     | 
| 
       112 
191 
     | 
    
         
             
                  end
         
     | 
| 
       113 
192 
     | 
    
         
             
                  if options[:reset_if_dead]
         
     | 
| 
       114 
193 
     | 
    
         
             
                    begin
         
     | 
| 
       115 
     | 
    
         
            -
                      @@ 
     | 
| 
       116 
     | 
    
         
            -
                    rescue  
     | 
| 
       117 
     | 
    
         
            -
                      Kernel.warn "WARNING:  
     | 
| 
       118 
     | 
    
         
            -
                       
     | 
| 
      
 194 
     | 
    
         
            +
                      @@firefox_socket.assert_socket
         
     | 
| 
      
 195 
     | 
    
         
            +
                    rescue FirefoxSocketConnectionError
         
     | 
| 
      
 196 
     | 
    
         
            +
                      Kernel.warn "WARNING: Firefox socket RESET: resetting connection to firefox. Any active javascript references will not exist on the new socket!"
         
     | 
| 
      
 197 
     | 
    
         
            +
                      initialize_firefox_socket(options[:socket_class], options[:socket_options])
         
     | 
| 
       119 
198 
     | 
    
         
             
                    end
         
     | 
| 
       120 
199 
     | 
    
         
             
                  end
         
     | 
| 
       121 
     | 
    
         
            -
                  @@ 
     | 
| 
      
 200 
     | 
    
         
            +
                  @@firefox_socket
         
     | 
| 
       122 
201 
     | 
    
         
             
                end
         
     | 
| 
       123 
     | 
    
         
            -
                # unsets a the current  
     | 
| 
       124 
     | 
    
         
            -
                def self. 
     | 
| 
       125 
     | 
    
         
            -
                  @@ 
     | 
| 
       126 
     | 
    
         
            -
                  @@firewatir_jssh_objects=nil
         
     | 
| 
      
 202 
     | 
    
         
            +
                # unsets a the current firefox socket 
         
     | 
| 
      
 203 
     | 
    
         
            +
                def self.uninitialize_firefox_socket # :nodoc:
         
     | 
| 
      
 204 
     | 
    
         
            +
                  @@firefox_socket=nil
         
     | 
| 
       127 
205 
     | 
    
         
             
                end
         
     | 
| 
       128 
     | 
    
         
            -
                def  
     | 
| 
       129 
     | 
    
         
            -
                  options ? self.class. 
     | 
| 
      
 206 
     | 
    
         
            +
                def firefox_socket(options=nil)
         
     | 
| 
      
 207 
     | 
    
         
            +
                  options ? self.class.firefox_socket(options) : @@firefox_socket
         
     | 
| 
       130 
208 
     | 
    
         
             
                end
         
     | 
| 
       131 
209 
     | 
    
         | 
| 
       132 
210 
     | 
    
         
             
                # Description: 
         
     | 
| 
         @@ -158,15 +236,14 @@ module Vapir 
     | 
|
| 
       158 
236 
     | 
    
         
             
                    @binary_path=options[:binary_path]
         
     | 
| 
       159 
237 
     | 
    
         
             
                  end
         
     | 
| 
       160 
238 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
                   
     | 
| 
       162 
     | 
    
         
            -
                  # 
     | 
| 
       163 
     | 
    
         
            -
                  # error if running without jssh, we don't want to kill their current window (mac only)
         
     | 
| 
      
 239 
     | 
    
         
            +
                  require 'vapir-firefox/firefox_socket/base'
         
     | 
| 
      
 240 
     | 
    
         
            +
                  # check for extension not listening; firefox may be open but not listening (extension not set up) 
         
     | 
| 
       164 
241 
     | 
    
         
             
                  begin
         
     | 
| 
       165 
     | 
    
         
            -
                     
     | 
| 
       166 
     | 
    
         
            -
                  rescue  
     | 
| 
      
 242 
     | 
    
         
            +
                    firefox_socket(:reset_if_dead => true, :socket_class => firefox_socket_class, :socket_options => firefox_socket_class_options).assert_socket
         
     | 
| 
      
 243 
     | 
    
         
            +
                  rescue FirefoxSocketConnectionError
         
     | 
| 
       167 
244 
     | 
    
         
             
                    # here we're going to assume that since it's not connecting, we need to launch firefox. 
         
     | 
| 
       168 
245 
     | 
    
         
             
                    if options[:attach]
         
     | 
| 
       169 
     | 
    
         
            -
                      raise Vapir::Exception::NoBrowserException, "cannot attach using #{options[:attach].inspect} - could not connect to Firefox 
     | 
| 
      
 246 
     | 
    
         
            +
                      raise Vapir::Exception::NoBrowserException, "cannot attach using #{options[:attach].inspect} - could not connect to Firefox"
         
     | 
| 
       170 
247 
     | 
    
         
             
                    else
         
     | 
| 
       171 
248 
     | 
    
         
             
                      launch_browser(options)
         
     | 
| 
       172 
249 
     | 
    
         
             
                      # if we just launched a the browser process, attach to the window
         
     | 
| 
         @@ -178,16 +255,16 @@ module Vapir 
     | 
|
| 
       178 
255 
     | 
    
         
             
                        options[:attach]=[:title, //]
         
     | 
| 
       179 
256 
     | 
    
         
             
                      end
         
     | 
| 
       180 
257 
     | 
    
         
             
                    end
         
     | 
| 
       181 
     | 
    
         
            -
                    ::Waiter.try_for(options[:timeout], :exception => Vapir::Exception::NoBrowserException.new("Could not connect to the  
     | 
| 
      
 258 
     | 
    
         
            +
                    ::Waiter.try_for(options[:timeout], :exception => Vapir::Exception::NoBrowserException.new("Could not connect to the #{config.firefox_extension} socket on the browser after #{options[:timeout]} seconds. Either Firefox did not start or #{config.firefox_extension} is not installed and listening.")) do
         
     | 
| 
       182 
259 
     | 
    
         
             
                      begin
         
     | 
| 
       183 
     | 
    
         
            -
                         
     | 
| 
      
 260 
     | 
    
         
            +
                        firefox_socket(:reset_if_dead => true, :socket_class => firefox_socket_class, :socket_options => firefox_socket_class_options).assert_socket
         
     | 
| 
       184 
261 
     | 
    
         
             
                        true
         
     | 
| 
       185 
     | 
    
         
            -
                      rescue  
     | 
| 
      
 262 
     | 
    
         
            +
                      rescue FirefoxSocketUnableToStart
         
     | 
| 
       186 
263 
     | 
    
         
             
                        false
         
     | 
| 
       187 
264 
     | 
    
         
             
                      end
         
     | 
| 
       188 
265 
     | 
    
         
             
                    end
         
     | 
| 
       189 
266 
     | 
    
         
             
                  end
         
     | 
| 
       190 
     | 
    
         
            -
                  @ 
     | 
| 
      
 267 
     | 
    
         
            +
                  @browser_objects = firefox_socket.object('{}').store_rand_temp
         
     | 
| 
       191 
268 
     | 
    
         | 
| 
       192 
269 
     | 
    
         
             
                  @pid = begin
         
     | 
| 
       193 
270 
     | 
    
         
             
                    self.pid
         
     | 
| 
         @@ -196,7 +273,16 @@ module Vapir 
     | 
|
| 
       196 
273 
     | 
    
         
             
                  end
         
     | 
| 
       197 
274 
     | 
    
         | 
| 
       198 
275 
     | 
    
         
             
                  if options[:attach]
         
     | 
| 
       199 
     | 
    
         
            -
                     
     | 
| 
      
 276 
     | 
    
         
            +
                    how, what = *options[:attach]
         
     | 
| 
      
 277 
     | 
    
         
            +
                    @browser_window_object = case how
         
     | 
| 
      
 278 
     | 
    
         
            +
                    when :browser_window_object
         
     | 
| 
      
 279 
     | 
    
         
            +
                      what
         
     | 
| 
      
 280 
     | 
    
         
            +
                    else
         
     | 
| 
      
 281 
     | 
    
         
            +
                      ::Waiter.try_for(options[:timeout], :exception => Vapir::Exception::NoMatchingWindowFoundException.new("Unable to locate a window with #{how} of #{what}")) do
         
     | 
| 
      
 282 
     | 
    
         
            +
                        find_window(how, what)
         
     | 
| 
      
 283 
     | 
    
         
            +
                      end
         
     | 
| 
      
 284 
     | 
    
         
            +
                    end
         
     | 
| 
      
 285 
     | 
    
         
            +
                    set_browser_document
         
     | 
| 
       200 
286 
     | 
    
         
             
                  else
         
     | 
| 
       201 
287 
     | 
    
         
             
                    open_window
         
     | 
| 
       202 
288 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -217,13 +303,14 @@ module Vapir 
     | 
|
| 
       217 
303 
     | 
    
         
             
                end
         
     | 
| 
       218 
304 
     | 
    
         | 
| 
       219 
305 
     | 
    
         
             
                def exists?
         
     | 
| 
       220 
     | 
    
         
            -
                  #  
     | 
| 
       221 
     | 
    
         
            -
                   
     | 
| 
      
 306 
     | 
    
         
            +
                  # firefox_socket may be nil if the window has closed 
         
     | 
| 
      
 307 
     | 
    
         
            +
                  # if the socket disconnects, we'll assume that means the browser quit and therefore the window doesn't exist 
         
     | 
| 
      
 308 
     | 
    
         
            +
                  firefox_socket && firefox_socket.handling_connection_error(:handle => proc{ return false }) do
         
     | 
| 
      
 309 
     | 
    
         
            +
                    browser_window_object && self.class.browser_window_objects.include?(browser_window_object)
         
     | 
| 
      
 310 
     | 
    
         
            +
                  end
         
     | 
| 
       222 
311 
     | 
    
         
             
                end
         
     | 
| 
       223 
312 
     | 
    
         | 
| 
       224 
313 
     | 
    
         
             
                # Launches firebox browser
         
     | 
| 
       225 
     | 
    
         
            -
                # options as .new
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
314 
     | 
    
         
             
                def launch_browser(options = {})
         
     | 
| 
       228 
315 
     | 
    
         
             
                  ff_options = []
         
     | 
| 
       229 
316 
     | 
    
         
             
                  if(options[:profile])
         
     | 
| 
         @@ -232,7 +319,8 @@ module Vapir 
     | 
|
| 
       232 
319 
     | 
    
         | 
| 
       233 
320 
     | 
    
         
             
                  bin = path_to_bin()
         
     | 
| 
       234 
321 
     | 
    
         
             
                  @self_launched_browser = true
         
     | 
| 
       235 
     | 
    
         
            -
                   
     | 
| 
      
 322 
     | 
    
         
            +
                  ff_options += firefox_socket_class.command_line_flags(firefox_socket_class_options).map(&:to_s)
         
     | 
| 
      
 323 
     | 
    
         
            +
                  @t = Thread.new { system(bin, *ff_options) } # TODO: launch process in such a way that @pid can be noted 
         
     | 
| 
       236 
324 
     | 
    
         
             
                end
         
     | 
| 
       237 
325 
     | 
    
         
             
                private :launch_browser
         
     | 
| 
       238 
326 
     | 
    
         | 
| 
         @@ -263,13 +351,13 @@ module Vapir 
     | 
|
| 
       263 
351 
     | 
    
         
             
                    end
         
     | 
| 
       264 
352 
     | 
    
         
             
                    CGI.escape(key.to_s)+'='+CGI.escape(val)
         
     | 
| 
       265 
353 
     | 
    
         
             
                  end.join("&")
         
     | 
| 
       266 
     | 
    
         
            -
                  stringStream =  
     | 
| 
      
 354 
     | 
    
         
            +
                  stringStream = firefox_socket.Components.classes["@mozilla.org/io/string-input-stream;1"].createInstance(firefox_socket.Components.interfaces.nsIStringInputStream)
         
     | 
| 
       267 
355 
     | 
    
         
             
                  if stringStream.to_hash.key?('data')
         
     | 
| 
       268 
356 
     | 
    
         
             
                    stringStream.data=dataString
         
     | 
| 
       269 
357 
     | 
    
         
             
                  else
         
     | 
| 
       270 
358 
     | 
    
         
             
                    stringStream.setData(dataString, dataString.unpack("U*").length)
         
     | 
| 
       271 
359 
     | 
    
         
             
                  end
         
     | 
| 
       272 
     | 
    
         
            -
                  postData =  
     | 
| 
      
 360 
     | 
    
         
            +
                  postData = firefox_socket.Components.classes["@mozilla.org/network/mime-input-stream;1"].createInstance(firefox_socket.Components.interfaces.nsIMIMEInputStream)
         
     | 
| 
       273 
361 
     | 
    
         
             
                  postData.addHeader("Content-Type", "application/x-www-form-urlencoded")
         
     | 
| 
       274 
362 
     | 
    
         
             
                  postData.addContentLength = true
         
     | 
| 
       275 
363 
     | 
    
         
             
                  postData.setData(stringStream)
         
     | 
| 
         @@ -309,12 +397,12 @@ module Vapir 
     | 
|
| 
       309 
397 
     | 
    
         
             
                  @error_checkers = []
         
     | 
| 
       310 
398 
     | 
    
         
             
                end
         
     | 
| 
       311 
399 
     | 
    
         | 
| 
       312 
     | 
    
         
            -
                #   Sets the document, window and browser variables to point to correct  
     | 
| 
      
 400 
     | 
    
         
            +
                #   Sets the document, window and browser variables to point to correct objects.
         
     | 
| 
       313 
401 
     | 
    
         
             
                def set_browser_document
         
     | 
| 
       314 
402 
     | 
    
         
             
                  unless browser_window_object
         
     | 
| 
       315 
403 
     | 
    
         
             
                    raise "Window must be set (using open_window or attach) before the browser document can be set!"
         
     | 
| 
       316 
404 
     | 
    
         
             
                  end
         
     | 
| 
       317 
     | 
    
         
            -
                  @browser_object=@ 
     | 
| 
      
 405 
     | 
    
         
            +
                  @browser_object=@browser_objects[:browser]= ::Waiter.try_for(2, :exception => Vapir::Exception::NoMatchingWindowFoundException.new("The browser could not be found on the specified Firefox window!")) do
         
     | 
| 
       318 
406 
     | 
    
         
             
                    if browser_window_object.respond_to?(:getBrowser)
         
     | 
| 
       319 
407 
     | 
    
         
             
                      browser_window_object.getBrowser
         
     | 
| 
       320 
408 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -326,27 +414,27 @@ module Vapir 
     | 
|
| 
       326 
414 
     | 
    
         
             
                  @content_window_object=browser_object.contentWindow
         
     | 
| 
       327 
415 
     | 
    
         
             
                    # note that browser_window_object.content is the same thing, but simpler to refer to stuff on browser_object since that is updated by the nsIWebProgressListener below
         
     | 
| 
       328 
416 
     | 
    
         
             
                  @body_object=document_object.body
         
     | 
| 
       329 
     | 
    
         
            -
                  @ 
     | 
| 
       330 
     | 
    
         
            -
                  @requests_in_progress=@ 
     | 
| 
       331 
     | 
    
         
            -
                  @ 
     | 
| 
      
 417 
     | 
    
         
            +
                  @browser_objects[:requests_in_progress]=[]
         
     | 
| 
      
 418 
     | 
    
         
            +
                  @requests_in_progress=@browser_objects[:requests_in_progress].to_array
         
     | 
| 
      
 419 
     | 
    
         
            +
                  @browser_objects[:unmatched_stopped_requests_count]=0
         
     | 
| 
       332 
420 
     | 
    
         | 
| 
       333 
     | 
    
         
            -
                  @updated_at_epoch_ms=@ 
     | 
| 
       334 
     | 
    
         
            -
                  @updated_at_offset=Time.now.to_f- 
     | 
| 
      
 421 
     | 
    
         
            +
                  @updated_at_epoch_ms=@browser_objects.attr(:updated_at_epoch_ms).assign_expr('new Date().getTime()')
         
     | 
| 
      
 422 
     | 
    
         
            +
                  @updated_at_offset=Time.now.to_f-firefox_socket.value_json('new Date().getTime()')/1000.0
         
     | 
| 
       335 
423 
     | 
    
         | 
| 
       336 
424 
     | 
    
         
             
                  # Add eventlistener for browser window so that we can reset the document back whenever there is redirect
         
     | 
| 
       337 
425 
     | 
    
         
             
                  # or browser loads on its own after some time. Useful when you are searching for flight results etc and
         
     | 
| 
       338 
426 
     | 
    
         
             
                  # page goes to search page after that it goes automatically to results page.
         
     | 
| 
       339 
427 
     | 
    
         
             
                  # Details : http://zenit.senecac.on.ca/wiki/index.php/Mozilla.dev.tech.xul#What_is_an_example_of_addProgressListener.3F
         
     | 
| 
       340 
     | 
    
         
            -
                  @ 
     | 
| 
       341 
     | 
    
         
            -
                  listener_object=@ 
     | 
| 
       342 
     | 
    
         
            -
                  listener_object[:QueryInterface]= 
     | 
| 
      
 428 
     | 
    
         
            +
                  @browser_objects[:listener_object]={}
         
     | 
| 
      
 429 
     | 
    
         
            +
                  listener_object=@browser_objects[:listener_object]
         
     | 
| 
      
 430 
     | 
    
         
            +
                  listener_object[:QueryInterface]=firefox_socket.function(:aIID) do %Q(
         
     | 
| 
       343 
431 
     | 
    
         
             
                       if(aIID.equals(Components.interfaces.nsIWebProgressListener) || aIID.equals(Components.interfaces.nsISupportsWeakReference) || aIID.equals(Components.interfaces.nsISupports))
         
     | 
| 
       344 
432 
     | 
    
         
             
                       { return this;
         
     | 
| 
       345 
433 
     | 
    
         
             
                       }
         
     | 
| 
       346 
434 
     | 
    
         
             
                       throw Components.results.NS_NOINTERFACE;
         
     | 
| 
       347 
435 
     | 
    
         
             
                  )
         
     | 
| 
       348 
436 
     | 
    
         
             
                  end
         
     | 
| 
       349 
     | 
    
         
            -
                  listener_object[:onStateChange]=  
     | 
| 
      
 437 
     | 
    
         
            +
                  listener_object[:onStateChange]= firefox_socket.function(:aWebProgress, :aRequest, :aStateFlags, :aStatus) do %Q(
         
     | 
| 
       350 
438 
     | 
    
         
             
                       var requests_in_progress=#{@requests_in_progress.ref};
         
     | 
| 
       351 
439 
     | 
    
         
             
                       if(aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
         
     | 
| 
       352 
440 
     | 
    
         
             
                       { #{@updated_at_epoch_ms.ref}=new Date().getTime();
         
     | 
| 
         @@ -365,7 +453,7 @@ module Vapir 
     | 
|
| 
       365 
453 
     | 
    
         
             
                           }
         
     | 
| 
       366 
454 
     | 
    
         
             
                         }
         
     | 
| 
       367 
455 
     | 
    
         
             
                         if(!matched)
         
     | 
| 
       368 
     | 
    
         
            -
                         { #{@ 
     | 
| 
      
 456 
     | 
    
         
            +
                         { #{@browser_objects.attr(:unmatched_stopped_requests_count).ref}++; //.push({webProgress: aWebProgress, request: aRequest, stateFlags: aStateFlags, status: aStatus});
         
     | 
| 
       369 
457 
     | 
    
         
             
                           // count any stop requests that we fail to match so that we can compare that count to the number of unmatched start requests. 
         
     | 
| 
       370 
458 
     | 
    
         
             
                         }
         
     | 
| 
       371 
459 
     | 
    
         
             
                       }
         
     | 
| 
         @@ -409,27 +497,28 @@ module Vapir 
     | 
|
| 
       409 
497 
     | 
    
         
             
                  assert_exists
         
     | 
| 
       410 
498 
     | 
    
         
             
                  # we expect the browser may exit if there are no windows which aren't ourself. except on mac. 
         
     | 
| 
       411 
499 
     | 
    
         
             
                  expect_exit = !self.class.window_objects.any?{|other_window| other_window != self.browser_window_object } && current_os != :macosx
         
     | 
| 
       412 
     | 
    
         
            -
             
     | 
| 
      
 500 
     | 
    
         
            +
             
     | 
| 
      
 501 
     | 
    
         
            +
                  connection_error_handler = proc do
         
     | 
| 
      
 502 
     | 
    
         
            +
                    Vapir::Firefox.uninitialize_firefox_socket
         
     | 
| 
      
 503 
     | 
    
         
            +
                    wait_for_process_exit(@pid)
         
     | 
| 
      
 504 
     | 
    
         
            +
                  end
         
     | 
| 
      
 505 
     | 
    
         
            +
                  firefox_socket.handling_connection_error(:handle => connection_error_handler) do
         
     | 
| 
       413 
506 
     | 
    
         
             
                    browser_window_object.close
         
     | 
| 
       414 
     | 
    
         
            -
                     
     | 
| 
       415 
     | 
    
         
            -
                    ::Waiter.try_for(32, :exception => Exception::WindowFailedToCloseException.new("The browser window did not close")) do
         
     | 
| 
      
 507 
     | 
    
         
            +
                    ::Waiter.try_for(config.close_timeout, :exception => Exception::WindowFailedToCloseException.new("The browser window did not close")) do
         
     | 
| 
       416 
508 
     | 
    
         
             
                      !exists?
         
     | 
| 
       417 
509 
     | 
    
         
             
                    end
         
     | 
| 
       418 
510 
     | 
    
         
             
                    if expect_exit
         
     | 
| 
       419 
     | 
    
         
            -
                      ::Waiter.try_for( 
     | 
| 
       420 
     | 
    
         
            -
                         
     | 
| 
      
 511 
     | 
    
         
            +
                      ::Waiter.try_for(config.quit_timeout, :exception => nil) do
         
     | 
| 
      
 512 
     | 
    
         
            +
                        firefox_socket.assert_socket # this should error, going up past the waiter to #handling_connection_error
         
     | 
| 
       421 
513 
     | 
    
         
             
                        false
         
     | 
| 
       422 
514 
     | 
    
         
             
                      end
         
     | 
| 
       423 
515 
     | 
    
         
             
                    else
         
     | 
| 
       424 
     | 
    
         
            -
                       
     | 
| 
      
 516 
     | 
    
         
            +
                      firefox_socket.assert_socket
         
     | 
| 
       425 
517 
     | 
    
         
             
                    end
         
     | 
| 
       426 
     | 
    
         
            -
                  rescue JsshConnectionError # the socket may disconnect when we close the browser, causing the JsshSocket to complain 
         
     | 
| 
       427 
     | 
    
         
            -
                    Vapir::Firefox.uninitialize_jssh_socket
         
     | 
| 
       428 
     | 
    
         
            -
                    wait_for_process_exit(@pid)
         
     | 
| 
       429 
518 
     | 
    
         
             
                  end
         
     | 
| 
       430 
     | 
    
         
            -
             
     | 
| 
      
 519 
     | 
    
         
            +
             
     | 
| 
       431 
520 
     | 
    
         
             
                  @browser_window_object=@browser_object=@document_object=@content_window_object=@body_object=nil
         
     | 
| 
       432 
     | 
    
         
            -
                  if @self_launched_browser &&  
     | 
| 
      
 521 
     | 
    
         
            +
                  if @self_launched_browser && firefox_socket && !self.class.window_objects.any?{ true }
         
     | 
| 
       433 
522 
     | 
    
         
             
                    quit_browser(:force => false)
         
     | 
| 
       434 
523 
     | 
    
         
             
                  end
         
     | 
| 
       435 
524 
     | 
    
         
             
                end
         
     | 
| 
         @@ -444,9 +533,9 @@ module Vapir 
     | 
|
| 
       444 
533 
     | 
    
         
             
                  #
         
     | 
| 
       445 
534 
     | 
    
         
             
                  # quit_browser(:force => true) will force the browser to quit. 
         
     | 
| 
       446 
535 
     | 
    
         
             
                  #
         
     | 
| 
       447 
     | 
    
         
            -
                  # if there is no existing connection to  
     | 
| 
      
 536 
     | 
    
         
            +
                  # if there is no existing connection to firefox, this will attempt to create one. If that fails, FirefoxSocketUnableToStart will be raised. 
         
     | 
| 
       448 
537 
     | 
    
         
             
                  def quit_browser(options={})
         
     | 
| 
       449 
     | 
    
         
            -
                     
     | 
| 
      
 538 
     | 
    
         
            +
                    firefox_socket(:reset_if_dead => true, :socket_class => firefox_socket_class, :socket_options => firefox_socket_class_options).assert_socket
         
     | 
| 
       450 
539 
     | 
    
         
             
                    options=handle_options(options, :force => false)
         
     | 
| 
       451 
540 
     | 
    
         | 
| 
       452 
541 
     | 
    
         
             
                    pid = @pid || begin
         
     | 
| 
         @@ -456,16 +545,14 @@ module Vapir 
     | 
|
| 
       456 
545 
     | 
    
         
             
                    end
         
     | 
| 
       457 
546 
     | 
    
         | 
| 
       458 
547 
     | 
    
         
             
                    # from https://developer.mozilla.org/en/How_to_Quit_a_XUL_Application
         
     | 
| 
       459 
     | 
    
         
            -
                    appStartup=  
     | 
| 
       460 
     | 
    
         
            -
                    quitSeverity = options[:force] ?  
     | 
| 
       461 
     | 
    
         
            -
                     
     | 
| 
      
 548 
     | 
    
         
            +
                    appStartup= firefox_socket.Components.classes['@mozilla.org/toolkit/app-startup;1'].getService(firefox_socket.Components.interfaces.nsIAppStartup)
         
     | 
| 
      
 549 
     | 
    
         
            +
                    quitSeverity = options[:force] ? firefox_socket.Components.interfaces.nsIAppStartup.eForceQuit : firefox_socket.Components.interfaces.nsIAppStartup.eAttemptQuit
         
     | 
| 
      
 550 
     | 
    
         
            +
                    firefox_socket.handling_connection_error(:handle => proc{ Vapir::Firefox.uninitialize_firefox_socket }) do
         
     | 
| 
       462 
551 
     | 
    
         
             
                      appStartup.quit(quitSeverity)
         
     | 
| 
       463 
     | 
    
         
            -
                      ::Waiter.try_for( 
     | 
| 
       464 
     | 
    
         
            -
                         
     | 
| 
      
 552 
     | 
    
         
            +
                      ::Waiter.try_for(config.quit_timeout, :exception => Exception::WindowFailedToCloseException.new("The browser did not quit")) do
         
     | 
| 
      
 553 
     | 
    
         
            +
                        firefox_socket.assert_socket # this should error, going up past the waiter to #handling_connection_error
         
     | 
| 
       465 
554 
     | 
    
         
             
                        false
         
     | 
| 
       466 
555 
     | 
    
         
             
                      end
         
     | 
| 
       467 
     | 
    
         
            -
                    rescue JsshConnectionError
         
     | 
| 
       468 
     | 
    
         
            -
                      Vapir::Firefox.uninitialize_jssh_socket
         
     | 
| 
       469 
556 
     | 
    
         
             
                    end
         
     | 
| 
       470 
557 
     | 
    
         | 
| 
       471 
558 
     | 
    
         
             
                    wait_for_process_exit(pid)
         
     | 
| 
         @@ -481,8 +568,8 @@ module Vapir 
     | 
|
| 
       481 
568 
     | 
    
         
             
                  def pid
         
     | 
| 
       482 
569 
     | 
    
         
             
                    begin
         
     | 
| 
       483 
570 
     | 
    
         
             
                      begin
         
     | 
| 
       484 
     | 
    
         
            -
                        ctypes =  
     | 
| 
       485 
     | 
    
         
            -
                      rescue  
     | 
| 
      
 571 
     | 
    
         
            +
                        ctypes = firefox_socket.Components.utils.import("resource://gre/modules/ctypes.jsm").ctypes
         
     | 
| 
      
 572 
     | 
    
         
            +
                      rescue FirefoxSocketJavascriptError
         
     | 
| 
       486 
573 
     | 
    
         
             
                        raise NotImplementedError, "Firefox 3.6 or greater is required for this method.\n\nOriginal error from firefox: #{$!.class}: #{$!.message}", $!.backtrace
         
     | 
| 
       487 
574 
     | 
    
         
             
                      end
         
     | 
| 
       488 
575 
     | 
    
         
             
                      lib, pidfunction, abi = *case current_os
         
     | 
| 
         @@ -491,12 +578,25 @@ module Vapir 
     | 
|
| 
       491 
578 
     | 
    
         
             
                      when :linux
         
     | 
| 
       492 
579 
     | 
    
         
             
                        ["libc.so.6", 'getpid', ctypes.default_abi]
         
     | 
| 
       493 
580 
     | 
    
         
             
                      when :windows
         
     | 
| 
       494 
     | 
    
         
            -
                         
     | 
| 
      
 581 
     | 
    
         
            +
                        # winapi is correct - we do not want stdcall's mangling. ff4+ does the stdcall
         
     | 
| 
      
 582 
     | 
    
         
            +
                        # mangling correctly with ctypes.stdcall_abi, and since we don't want mangling, 
         
     | 
| 
      
 583 
     | 
    
         
            +
                        # that fails here. ff < 4 does not do stdcall mangling (and has no winapi abi 
         
     | 
| 
      
 584 
     | 
    
         
            +
                        # to skip mangling) so ends up working correctly. 
         
     | 
| 
      
 585 
     | 
    
         
            +
                        # so, we want winapi if it's defined to skip mangling, but if 
         
     | 
| 
      
 586 
     | 
    
         
            +
                        # it's not defined, use stdcall because it won't mangle anyway. 
         
     | 
| 
      
 587 
     | 
    
         
            +
                        #
         
     | 
| 
      
 588 
     | 
    
         
            +
                        # see https://bugzilla.mozilla.org/show_bug.cgi?id=585175
         
     | 
| 
      
 589 
     | 
    
         
            +
                        ['kernel32', 'GetCurrentProcessId', ctypes['winapi_abi'] || ctypes['stdcall_abi']]
         
     | 
| 
       495 
590 
     | 
    
         
             
                      else
         
     | 
| 
       496 
591 
     | 
    
         
             
                        raise NotImplementedError, "don't know how to get pid for #{current_os}"
         
     | 
| 
       497 
592 
     | 
    
         
             
                      end
         
     | 
| 
       498 
     | 
    
         
            -
             
     | 
| 
       499 
     | 
    
         
            -
                       
     | 
| 
      
 593 
     | 
    
         
            +
                       lib = ctypes.open(lib)
         
     | 
| 
      
 594 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 595 
     | 
    
         
            +
                        getpid = lib.declare(pidfunction, abi, ctypes['int32_t'])
         
     | 
| 
      
 596 
     | 
    
         
            +
                        return getpid.call()
         
     | 
| 
      
 597 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 598 
     | 
    
         
            +
                        lib.close
         
     | 
| 
      
 599 
     | 
    
         
            +
                      end
         
     | 
| 
       500 
600 
     | 
    
         
             
                    end
         
     | 
| 
       501 
601 
     | 
    
         
             
                  end
         
     | 
| 
       502 
602 
     | 
    
         | 
| 
         @@ -540,7 +640,7 @@ module Vapir 
     | 
|
| 
       540 
640 
     | 
    
         
             
                  # the pfirefox process has exited. 
         
     | 
| 
       541 
641 
     | 
    
         
             
                  def wait_for_process_exit(pid)
         
     | 
| 
       542 
642 
     | 
    
         
             
                    if pid
         
     | 
| 
       543 
     | 
    
         
            -
                      ::Waiter.try_for( 
     | 
| 
      
 643 
     | 
    
         
            +
                      ::Waiter.try_for(config.quit_timeout, :exception => Exception::WindowFailedToCloseException.new("The browser did not quit")) do
         
     | 
| 
       544 
644 
     | 
    
         
             
                        !process_running?(pid)
         
     | 
| 
       545 
645 
     | 
    
         
             
                      end
         
     | 
| 
       546 
646 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -571,45 +671,53 @@ module Vapir 
     | 
|
| 
       571 
671 
     | 
    
         
             
                      end
         
     | 
| 
       572 
672 
     | 
    
         
             
                    end
         
     | 
| 
       573 
673 
     | 
    
         
             
                  end
         
     | 
| 
       574 
     | 
    
         
            -
                end
         
     | 
| 
       575 
     | 
    
         
            -
                include FirefoxClassAndInstanceMethods
         
     | 
| 
       576 
     | 
    
         
            -
                extend FirefoxClassAndInstanceMethods
         
     | 
| 
       577 
     | 
    
         
            -
             
     | 
| 
       578 
     | 
    
         
            -
                
         
     | 
| 
       579 
674 
     | 
    
         | 
| 
       580 
     | 
    
         
            -
             
     | 
| 
       581 
     | 
    
         
            -
             
     | 
| 
       582 
     | 
    
         
            -
             
     | 
| 
       583 
     | 
    
         
            -
             
     | 
| 
       584 
     | 
    
         
            -
             
     | 
| 
       585 
     | 
    
         
            -
             
     | 
| 
       586 
     | 
    
         
            -
             
     | 
| 
       587 
     | 
    
         
            -
             
     | 
| 
       588 
     | 
    
         
            -
             
     | 
| 
       589 
     | 
    
         
            -
                     
     | 
| 
       590 
     | 
    
         
            -
             
     | 
| 
       591 
     | 
    
         
            -
                     
     | 
| 
      
 675 
     | 
    
         
            +
                  private
         
     | 
| 
      
 676 
     | 
    
         
            +
                  # returns the class inheriting from FirefoxSocket which will be used to connect to a firefox extension
         
     | 
| 
      
 677 
     | 
    
         
            +
                  def firefox_socket_class
         
     | 
| 
      
 678 
     | 
    
         
            +
                    if config.firefox_extension.is_a?(String) && config.firefox_extension.downcase=='mozrepl'
         
     | 
| 
      
 679 
     | 
    
         
            +
                      require 'vapir-firefox/firefox_socket/mozrepl'
         
     | 
| 
      
 680 
     | 
    
         
            +
                      MozreplSocket
         
     | 
| 
      
 681 
     | 
    
         
            +
                    elsif config.firefox_extension.is_a?(String) && config.firefox_extension.downcase=='jssh'
         
     | 
| 
      
 682 
     | 
    
         
            +
                      require 'vapir-firefox/firefox_socket/jssh'
         
     | 
| 
      
 683 
     | 
    
         
            +
                      JsshSocket
         
     | 
| 
      
 684 
     | 
    
         
            +
                    else
         
     | 
| 
      
 685 
     | 
    
         
            +
                      raise Vapir::Configuration::InvalidValueError, "Unrecognized firefox extension #{config.firefox_extension.inspect}. Vapir supports the JSSH and Mozrepl extensions."
         
     | 
| 
      
 686 
     | 
    
         
            +
                    end
         
     | 
| 
       592 
687 
     | 
    
         
             
                  end
         
     | 
| 
       593 
     | 
    
         
            -
                  
         
     | 
| 
       594 
     | 
    
         
            -
                   
     | 
| 
       595 
     | 
    
         
            -
             
     | 
| 
      
 688 
     | 
    
         
            +
                  # returns a hash of options in the current configuration, prefixed with the firefox extension 
         
     | 
| 
      
 689 
     | 
    
         
            +
                  # to be used, to pass along to to the firefox socket class as needed 
         
     | 
| 
      
 690 
     | 
    
         
            +
                  def firefox_socket_class_options
         
     | 
| 
      
 691 
     | 
    
         
            +
                    # pass any config options that look like firefox_jssh_something or firefox_mozrepl_something 
         
     | 
| 
      
 692 
     | 
    
         
            +
                    prefix = "firefox_#{config.firefox_extension}_"
         
     | 
| 
      
 693 
     | 
    
         
            +
                    config.defined_hash.inject({}) do |opts, (key, val)|
         
     | 
| 
      
 694 
     | 
    
         
            +
                      if key[0...prefix.length] == prefix
         
     | 
| 
      
 695 
     | 
    
         
            +
                        opts.merge(key[prefix.length..-1] => val)
         
     | 
| 
      
 696 
     | 
    
         
            +
                      else
         
     | 
| 
      
 697 
     | 
    
         
            +
                        opts
         
     | 
| 
      
 698 
     | 
    
         
            +
                      end
         
     | 
| 
      
 699 
     | 
    
         
            +
                    end
         
     | 
| 
       596 
700 
     | 
    
         
             
                  end
         
     | 
| 
       597 
     | 
    
         
            -
                   
     | 
| 
       598 
     | 
    
         
            -
                  self
         
     | 
| 
      
 701 
     | 
    
         
            +
                  private :firefox_socket_class_options
         
     | 
| 
       599 
702 
     | 
    
         
             
                end
         
     | 
| 
       600 
     | 
    
         
            -
                 
     | 
| 
      
 703 
     | 
    
         
            +
                include FirefoxClassAndInstanceMethods
         
     | 
| 
      
 704 
     | 
    
         
            +
                extend FirefoxClassAndInstanceMethods
         
     | 
| 
       601 
705 
     | 
    
         | 
| 
       602 
706 
     | 
    
         
             
                # loads up a new window in an existing process
         
     | 
| 
       603 
     | 
    
         
            -
                # Vapir::Browser.attach() with no arguments passed the attach method will create a new window
         
     | 
| 
       604 
     | 
    
         
            -
                # this will only be called one time per instance we're only ever going to run in 1 window
         
     | 
| 
       605 
707 
     | 
    
         
             
                def open_window
         
     | 
| 
       606 
708 
     | 
    
         
             
                  begin
         
     | 
| 
       607 
709 
     | 
    
         
             
                    @browser_window_name="firewatir_window_%.16x"%rand(2**64)
         
     | 
| 
       608 
710 
     | 
    
         
             
                  end while self.class.browser_window_objects.any?{|browser_window_object| browser_window_object.name == @browser_window_name }
         
     | 
| 
       609 
     | 
    
         
            -
                  watcher= 
     | 
| 
      
 711 
     | 
    
         
            +
                  watcher=firefox_socket.Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(firefox_socket.Components.interfaces.nsIWindowWatcher)
         
     | 
| 
       610 
712 
     | 
    
         
             
                  # nsIWindowWatcher is used to launch new top-level windows. see https://developer.mozilla.org/en/Working_with_windows_in_chrome_code
         
     | 
| 
       611 
713 
     | 
    
         | 
| 
       612 
     | 
    
         
            -
                   
     | 
| 
      
 714 
     | 
    
         
            +
                  # for openWindow's fourth argument, turn on all the features listed https://developer.mozilla.org/en/DOM/window.open 
         
     | 
| 
      
 715 
     | 
    
         
            +
                  # this doesn't enable anything that's not shown by default (for example, having personalbar won't turn on the bookmorks bar
         
     | 
| 
      
 716 
     | 
    
         
            +
                  # if it's set to not be shown), but lacking anything here does disable things which are on by default (if the bookmarks bar is
         
     | 
| 
      
 717 
     | 
    
         
            +
                  # set to show by default and personalbar is not set here, it will not show)
         
     | 
| 
      
 718 
     | 
    
         
            +
                  #
         
     | 
| 
      
 719 
     | 
    
         
            +
                  # see https://developer.mozilla.org/en/DOM/window.open
         
     | 
| 
      
 720 
     | 
    
         
            +
                  @browser_window_object=@browser_objects[:browser_window]=watcher.openWindow(nil, 'chrome://browser/content/browser.xul', @browser_window_name, 'chrome,resizable,toolbar,menubar,personalbar,location,status,scrollbars,titlebar', nil)
         
     | 
| 
       613 
721 
     | 
    
         
             
                  return @browser_window_object
         
     | 
| 
       614 
722 
     | 
    
         
             
                end
         
     | 
| 
       615 
723 
     | 
    
         
             
                private :open_window
         
     | 
| 
         @@ -625,7 +733,7 @@ module Vapir 
     | 
|
| 
       625 
733 
     | 
    
         
             
                    Enumerator.new(self, :each_browser)
         
     | 
| 
       626 
734 
     | 
    
         
             
                  end
         
     | 
| 
       627 
735 
     | 
    
         
             
                  def each_browser_window_object
         
     | 
| 
       628 
     | 
    
         
            -
                    mediator= 
     | 
| 
      
 736 
     | 
    
         
            +
                    mediator=firefox_socket.Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(firefox_socket.Components.interfaces.nsIWindowMediator)
         
     | 
| 
       629 
737 
     | 
    
         
             
                    enumerator=mediator.getEnumerator("navigator:browser")
         
     | 
| 
       630 
738 
     | 
    
         
             
                    while enumerator.hasMoreElements
         
     | 
| 
       631 
739 
     | 
    
         
             
                      win=enumerator.getNext
         
     | 
| 
         @@ -637,7 +745,7 @@ module Vapir 
     | 
|
| 
       637 
745 
     | 
    
         
             
                    Enumerator.new(self, :each_browser_window_object)
         
     | 
| 
       638 
746 
     | 
    
         
             
                  end
         
     | 
| 
       639 
747 
     | 
    
         
             
                  def each_window_object
         
     | 
| 
       640 
     | 
    
         
            -
                    mediator= 
     | 
| 
      
 748 
     | 
    
         
            +
                    mediator=firefox_socket.Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(firefox_socket.Components.interfaces.nsIWindowMediator)
         
     | 
| 
       641 
749 
     | 
    
         
             
                    enumerator=mediator.getEnumerator(nil)
         
     | 
| 
       642 
750 
     | 
    
         
             
                    while enumerator.hasMoreElements
         
     | 
| 
       643 
751 
     | 
    
         
             
                      win=enumerator.getNext
         
     | 
| 
         @@ -650,7 +758,7 @@ module Vapir 
     | 
|
| 
       650 
758 
     | 
    
         
             
                  end
         
     | 
| 
       651 
759 
     | 
    
         
             
                end
         
     | 
| 
       652 
760 
     | 
    
         | 
| 
       653 
     | 
    
         
            -
                # return the window  
     | 
| 
      
 761 
     | 
    
         
            +
                # return the window javascript object for the browser window with the given title or url.
         
     | 
| 
       654 
762 
     | 
    
         
             
                #   how - :url, :title, or :name
         
     | 
| 
       655 
763 
     | 
    
         
             
                #   what - string or regexp
         
     | 
| 
       656 
764 
     | 
    
         
             
                #
         
     | 
| 
         @@ -665,8 +773,11 @@ module Vapir 
     | 
|
| 
       665 
773 
     | 
    
         
             
                  raise ArgumentError, "how should be one of: #{hows.keys.inspect} (was #{orig_how.inspect})" unless how
         
     | 
| 
       666 
774 
     | 
    
         
             
                  found_win=nil
         
     | 
| 
       667 
775 
     | 
    
         
             
                  self.class.each_browser_window_object do |win|
         
     | 
| 
       668 
     | 
    
         
            -
                     
     | 
| 
       669 
     | 
    
         
            -
                     
     | 
| 
      
 776 
     | 
    
         
            +
                    contentDocument = win.getBrowser.contentDocument rescue nil # this can result in a Javascript TypeError: this.docShell is null if the window isn't ready yet 
         
     | 
| 
      
 777 
     | 
    
         
            +
                    if contentDocument && Vapir::fuzzy_match(hows[how].call(contentDocument),what)
         
     | 
| 
      
 778 
     | 
    
         
            +
                      found_win=win 
         
     | 
| 
      
 779 
     | 
    
         
            +
                      # we don't break here if found_win is set because we want the last match if there are multiple. 
         
     | 
| 
      
 780 
     | 
    
         
            +
                    end
         
     | 
| 
       670 
781 
     | 
    
         
             
                  end
         
     | 
| 
       671 
782 
     | 
    
         
             
                  return found_win
         
     | 
| 
       672 
783 
     | 
    
         
             
                end
         
     | 
| 
         @@ -692,8 +803,8 @@ module Vapir 
     | 
|
| 
       692 
803 
     | 
    
         
             
                  channel = nil
         
     | 
| 
       693 
804 
     | 
    
         
             
                  ::Waiter.try_for(8, :exception => nil) do
         
     | 
| 
       694 
805 
     | 
    
         
             
                    channel=browser.browser_object.docShell.currentDocumentChannel
         
     | 
| 
       695 
     | 
    
         
            -
                    channel.is_a?( 
     | 
| 
       696 
     | 
    
         
            -
                  end || raise(RuntimeError, "expected currentDocumentChannel to exist and be a nsIHttpChannel but it wasn't; was #{channel.is_a?( 
     | 
| 
      
 806 
     | 
    
         
            +
                    channel.is_a?(JavascriptObject) && channel.instanceof(browser.firefox_socket.Components.interfaces.nsIHttpChannel) && channel.respond_to?(:responseStatus)
         
     | 
| 
      
 807 
     | 
    
         
            +
                  end || raise(RuntimeError, "expected currentDocumentChannel to exist and be a nsIHttpChannel but it wasn't; was #{channel.is_a?(JavascriptObject) ? channel.toString : channel.inspect}")
         
     | 
| 
       697 
808 
     | 
    
         
             
                  status = channel.responseStatus
         
     | 
| 
       698 
809 
     | 
    
         
             
                end
         
     | 
| 
       699 
810 
     | 
    
         | 
| 
         @@ -713,7 +824,7 @@ module Vapir 
     | 
|
| 
       713 
824 
     | 
    
         
             
                  unless options.is_a?(Hash)
         
     | 
| 
       714 
825 
     | 
    
         
             
                    raise ArgumentError, "given options should be a Hash, not #{options.inspect} (#{options.class})\nold conflicting arguments of no_sleep or last_url are gone"
         
     | 
| 
       715 
826 
     | 
    
         
             
                  end
         
     | 
| 
       716 
     | 
    
         
            -
                  options={:sleep => false, :last_url => nil, :timeout =>  
     | 
| 
      
 827 
     | 
    
         
            +
                  options={:sleep => false, :last_url => nil, :timeout => config.wait_timeout}.merge(options)
         
     | 
| 
       717 
828 
     | 
    
         
             
                  started=Time.now
         
     | 
| 
       718 
829 
     | 
    
         
             
                  ::Waiter.try_for(options[:timeout] - (Time.now - started), :exception => "Waiting for the document to finish loading timed out") do
         
     | 
| 
       719 
830 
     | 
    
         
             
                    browser_object.webProgress.isLoadingDocument==false
         
     | 
| 
         @@ -747,7 +858,7 @@ module Vapir 
     | 
|
| 
       747 
858 
     | 
    
         
             
                    end
         
     | 
| 
       748 
859 
     | 
    
         
             
                  end
         
     | 
| 
       749 
860 
     | 
    
         
             
                  ::Waiter.try_for(options[:timeout] - (Time.now - started), :exception => "Waiting for requests in progress to complete timed out.") do
         
     | 
| 
       750 
     | 
    
         
            -
                    @requests_in_progress.length<=@ 
     | 
| 
      
 861 
     | 
    
         
            +
                    @requests_in_progress.length<=@browser_objects[:unmatched_stopped_requests_count]
         
     | 
| 
       751 
862 
     | 
    
         
             
                  end
         
     | 
| 
       752 
863 
     | 
    
         
             
                  run_error_checks
         
     | 
| 
       753 
864 
     | 
    
         
             
                  return self
         
     | 
| 
         @@ -769,7 +880,7 @@ module Vapir 
     | 
|
| 
       769 
880 
     | 
    
         | 
| 
       770 
881 
     | 
    
         
             
                  if options[:dc] == :page
         
     | 
| 
       771 
882 
     | 
    
         
             
                    options[:format] ||= 'png'
         
     | 
| 
       772 
     | 
    
         
            -
                     
     | 
| 
      
 883 
     | 
    
         
            +
                    firefox_socket.call_function(:window => content_window_object, :options => options, :filename => File.expand_path(filename)) do
         
     | 
| 
       773 
884 
     | 
    
         
             
                    %q(
         
     | 
| 
       774 
885 
     | 
    
         
             
                      // this is adapted from Selenium's method Selenium.prototype.doCaptureEntirePageScreenshot
         
     | 
| 
       775 
886 
     | 
    
         
             
                      var document = window.document;
         
     |