Class: FireWatir::Firefox

Inherits:
Object
  • Object
show all
Includes:
Container
Defined in:
lib/firewatir/firefox.rb,
lib/firewatir/version.rb

Constant Summary collapse

FIRST_ORDERED_NODE_TYPE =

XPath Result type. Return only first node that matches the xpath expression. More details: “developer.mozilla.org/en/docs/DOM:document.evaluate

9
VERSION =
'1.6.5'

Constants included from Container

Container::DEFAULT_HIGHLIGHT_COLOR, Container::MACHINE_IP

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Container

#button, #cell, #checkbox, #dd, #dl, #dt, #file_field, #form, #frame, #hidden, #image, #link, #radio, #row, #select_list, #show_all_objects, #table, #text_field

Methods included from JsshSocket

#js_eval, #js_eval_method, #jssh_socket, #read_socket

Constructor Details

#initialize(options = {}) ⇒ Firefox

TODO: Start the firefox version given by user.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/firewatir/firefox.rb', line 27

def initialize(options = {})
  if(options.kind_of?(Integer))
    options = {:waitTime => options}
  end

  # check for jssh not running, firefox may be open but not with -jssh
  # if its not open at all, regardless of the :suppress_launch_process option start it
  # error if running without jssh, we don't want to kill their current window (mac only)
  jssh_down = false
  begin
    set_defaults()
  rescue Watir::Exception::UnableToStartJSShException
    jssh_down = true
  end

  if current_os == :macosx && !%x{ps x | grep firefox-bin | grep -v grep}.empty?
    raise "Firefox is running without -jssh" if jssh_down
    open_window unless options[:suppress_launch_process]
  elsif not options[:suppress_launch_process]
    launch_browser(options)
  end

  set_defaults()
  get_window_number()
  set_browser_document()
end

Class Method Details

.attach(how, what) ⇒ Object

Class method to return a browser object if a window matches for how and what. Window can be referenced by url or title. The second argument can be either a string or a regular expression. Watir::Browser.attach(:url, ‘www.google.com’) Watir::Browser.attach(:title, ‘Google’)



284
285
286
287
288
# File 'lib/firewatir/firefox.rb', line 284

def self.attach how, what
  br = new :suppress_launch_process => true # don't create window
  br.attach(how, what)
  br
end

.start(url) ⇒ Object

Creates a new instance of Firefox. Loads the URL and return the instance. Input:

url - url of the page to be loaded.


80
81
82
83
84
# File 'lib/firewatir/firefox.rb', line 80

def self.start(url)
  ff = Firefox.new
  ff.goto(url)
  return ff
end

Instance Method Details

#add_checker(checker) ⇒ Object

Add an error checker that gets called on every page load.

  • checker - a Proc object



498
499
500
# File 'lib/firewatir/firefox.rb', line 498

def add_checker(checker)
  @error_checkers << checker
end

#attach(how, what) ⇒ Object

Used for attaching pop up window to an existing Firefox window, either by url or title.

ff.attach(:url, 'http://www.google.com')
ff.attach(:title, 'Google')

Output:

Instance of newly attached window.


265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/firewatir/firefox.rb', line 265

def attach(how, what)

  $stderr.puts("warning: #{self.class}.attach is experimental") if $VERBOSE
  window_number = find_window(how, what)

  if(window_number.nil?)
    raise NoMatchingWindowFoundException.new("Unable to locate window, using #{how} and #{what}")
  elsif(window_number >= 0)
    @window_index = window_number
    set_browser_document()
  end
  self
end

#backObject

Loads the previous page (if there is any) in the browser. Waits for the page to get loaded.



118
119
120
121
# File 'lib/firewatir/firefox.rb', line 118

def back()
  js_eval "if(#{browser_var}.canGoBack) #{browser_var}.goBack()"
  wait()
end

#body_varObject

unfinished



210
211
212
# File 'lib/firewatir/firefox.rb', line 210

def body_var # unfinished
  "body"
end

#browser_varObject

private



204
205
206
# File 'lib/firewatir/firefox.rb', line 204

def browser_var
  "browser"
end

#closeObject

Closes the window.



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/firewatir/firefox.rb', line 216

def close

  if js_eval("getWindows().length").to_i == 1
    js_eval("getWindows()[0].close()")

    if current_os == :macosx
      %x{ osascript -e 'tell application "Firefox" to quit' }
    end

    # wait for the app to close properly
    @t.join if @t
  else
    # Check if window exists, because there may be the case that it has been closed by click event on some element.
    # For e.g: Close Button, Close this Window link etc.
    window_number = find_window(:url, @window_url)

    # If matching window found. Close the window.
    if window_number > 0
      js_eval "getWindows()[#{window_number}].close()"
    end

  end
end

#close_allObject

Closes all firefox windows



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/firewatir/firefox.rb', line 241

def close_all
    total_windows = js_eval("getWindows().length").to_i

    # start from last window  
    while(total_windows > 0) do
        js_eval "getWindows()[#{total_windows - 1}].close()"
        total_windows = total_windows - 1
    end    

    if current_os == :macosx
        %x{ osascript -e 'tell application "Firefox" to quit' }
    end  

    if current_os == :windows
        system("taskkill /im firefox.exe /f /t >nul 2>&1")
    end
end

#contains_text(target) ⇒ Object

Description:

Matches the given text with the current text shown in the browser.

Input:

target - Text to match. Can be a string or regex

Output:

Returns the index if the specified text was found.
Returns matchdata object if the specified regexp was found.


367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/firewatir/firefox.rb', line 367

def contains_text(target)
  #puts "Text to match is : #{match_text}"
  #puts "Html is : #{self.text}"
  case target
    when Regexp
    self.text.match(target)
    when String
    self.text.index(target)
  else
    raise TypeError, "Argument #{target} should be a string or regexp."
  end
end

#disable_checker(checker) ⇒ Object

Disable an error checker

  • checker - a Proc object that is to be disabled



504
505
506
# File 'lib/firewatir/firefox.rb', line 504

def disable_checker(checker)
  @error_checkers.delete(checker)
end

#documentObject

Returns the document element of the page currently loaded in the browser.



620
621
622
# File 'lib/firewatir/firefox.rb', line 620

def document
  Document.new(self)
end

#document_varObject

unfinished



207
208
209
# File 'lib/firewatir/firefox.rb', line 207

def document_var # unfinished
  "document"
end

#element_by_xpath(xpath) ⇒ Object

Returns the first element that matches the given xpath expression or query.



625
626
627
628
629
# File 'lib/firewatir/firefox.rb', line 625

def element_by_xpath(xpath)
  temp = Element.new(nil, self)
  element_name = temp.element_by_xpath(self, xpath)
  return element_factory(element_name)
end

#elements_by_xpath(xpath) ⇒ Object

Description:

Returns the array of elements that matches the xpath query.

Input:

Xpath expression or query.

Output:

Array of elements matching xpath query.


717
718
719
720
721
# File 'lib/firewatir/firefox.rb', line 717

def elements_by_xpath(xpath)
  element = Element.new(nil, self)
  elem_names = element.elements_by_xpath(self, xpath)
  elem_names.inject([]) {|elements,name| elements << element_factory(name)}
end

#execute_script(source) ⇒ Object

Executes the given JavaScript string



136
137
138
139
140
141
# File 'lib/firewatir/firefox.rb', line 136

def execute_script(source)
  result = js_eval source.to_s
  wait()

  result
end

#forwardObject

Loads the next page (if there is any) in the browser. Waits for the page to get loaded.



124
125
126
127
# File 'lib/firewatir/firefox.rb', line 124

def forward()
  js_eval "if(#{browser_var}.canGoForward) #{browser_var}.goForward()"
  wait()
end

#get_popup_textObject

Description:

Returns text of javascript pop up in case it comes.

Output:

Text shown in javascript pop up.


612
613
614
615
616
617
# File 'lib/firewatir/firefox.rb', line 612

def get_popup_text()
  return_value = js_eval "popuptext"
  # reset the variable
  js_eval "popuptext = ''"
  return return_value
end

#goto(url) ⇒ Object

Loads the given url in the browser. Waits for the page to get loaded.



110
111
112
113
114
115
# File 'lib/firewatir/firefox.rb', line 110

def goto(url)
  get_window_number()
  set_browser_document()
  js_eval "#{browser_var}.loadURI(\"#{url}\")"
  wait()
end

#htmlObject

Returns the html of the page currently loaded in the browser.



402
403
404
405
# File 'lib/firewatir/firefox.rb', line 402

def html
  result = js_eval("var htmlelem = #{document_var}.getElementsByTagName('html')[0]; htmlelem.innerHTML")
  return "<html>" + result + "</html>"
end

#inspectObject



54
55
56
# File 'lib/firewatir/firefox.rb', line 54

def inspect
  '#<%s:0x%x url=%s title=%s>' % [self.class, hash*2, url.inspect, title.inspect]
end

#maximizeObject

Maximize the current browser window.



413
414
415
# File 'lib/firewatir/firefox.rb', line 413

def maximize()
  js_eval "#{window_var}.maximize()"
end

#minimizeObject

Minimize the current browser window.



418
419
420
# File 'lib/firewatir/firefox.rb', line 418

def minimize()
  js_eval "#{window_var}.minimize()"
end

#refreshObject

Reloads the current page in the browser. Waits for the page to get loaded.



130
131
132
133
# File 'lib/firewatir/firefox.rb', line 130

def refresh()
  js_eval "#{browser_var}.reload()"
  wait()
end

#run_error_checksObject

Run the predefined error checks. This is automatically called on every page load.



509
510
511
# File 'lib/firewatir/firefox.rb', line 509

def run_error_checks
  @error_checkers.each { |e| e.call(self) }
end

#show_divsObject Also known as: showDivs

Description:

Show all the divs available on the page.

Output:

Name, id, class and index of all the divs available on the page.


792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/firewatir/firefox.rb', line 792

def show_divs
  divs = Document.new(self).get_divs
  puts "There are #{divs.length} divs"
  index = 1
  divs.each do |l|
    puts "div:   name: #{l.name}"
    puts "         id: #{l.id}"
    puts "      class: #{l.className}"
    puts "      index: #{index}"
    index += 1
  end
end

#show_formsObject Also known as: showForms

Description:

Show all the forms available on the page.

Output:

Name, id, method and action of all the forms available on the page.


730
731
732
733
734
735
736
737
738
739
740
# File 'lib/firewatir/firefox.rb', line 730

def show_forms
  forms = Document.new(self).get_forms()
  count = forms.length
  puts "There are #{count} forms"
  for i in 0..count - 1 do
    puts "Form name: " + forms[i].name
    puts "       id: " + forms[i].id
    puts "   method: " + forms[i].attribute_value("method")
    puts "   action: " + forms[i].action
  end
end

#show_framesObject Also known as: showFrames

Description:

Show all the frames available on the page. Doesn't show nested frames.

Output:

Name, and index of all the frames available on the page.


896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
# File 'lib/firewatir/firefox.rb', line 896

def show_frames
  jssh_command = "var frameset = #{window_var}.frames;
                        var elements_frames = new Array();
                        for(var i = 0; i < frameset.length; i++)
                        {
                            var frames = frameset[i].frames;
                            for(var j = 0; j < frames.length; j++)
                            {
                                elements_frames.push(frames[j].frameElement);
                            }
                        }
                        elements_frames.length;"

  length = js_eval(jssh_command).to_i

  puts "There are #{length} frames"

  frames = Array.new(length)
  for i in 0..length - 1 do
    frames[i] = Frame.new(self, :jssh_name, "elements_frames[#{i}]")
  end

  for i in 0..length - 1 do
    puts "frame: name: #{frames[i].name}"
    puts "      index: #{i+1}"
  end
end

#show_imagesObject Also known as: showImages

Description:

Show all the images available on the page.

Output:

Name, id, src and index of all the images available on the page.


750
751
752
753
754
755
756
757
758
759
760
761
# File 'lib/firewatir/firefox.rb', line 750

def show_images
  images = Document.new(self).get_images
  puts "There are #{images.length} images"
  index = 1
  images.each do |l|
    puts "image: name: #{l.name}"
    puts "         id: #{l.id}"
    puts "        src: #{l.src}"
    puts "      index: #{index}"
    index += 1
  end
end

#show_labelsObject Also known as: showLabels

Description:

Show all the labels available on the page.

Output:

Name, id, for and index of all the labels available on the page.


875
876
877
878
879
880
881
882
883
884
885
886
# File 'lib/firewatir/firefox.rb', line 875

def show_labels
  labels = Document.new(self).get_labels
  puts "There are #{labels.length} labels"
  index = 1
  labels.each do |l|
    puts "label: name: #{l.name}"
    puts "         id: #{l.id}"
    puts "        for: #{l.for}"
    puts "      index: #{index}"
    index += 1
  end
end

Description:

Show all the links available on the page.

Output:

Name, id, href and index of all the links available on the page.


771
772
773
774
775
776
777
778
779
780
781
782
# File 'lib/firewatir/firefox.rb', line 771

def show_links
  links = Document.new(self).get_links
  puts "There are #{links.length} links"
  index = 1
  links.each do |l|
    puts "link:  name: #{l.name}"
    puts "         id: #{l.id}"
    puts "       href: #{l.href}"
    puts "      index: #{index}"
    index += 1
  end
end

#show_presObject Also known as: showPres

Description:

Show all the pre elements available on the page.

Output:

Id, name and index of all the pre elements available on the page.


834
835
836
837
838
839
840
841
842
843
844
# File 'lib/firewatir/firefox.rb', line 834

def show_pres
  pres = Document.new(self).get_pres
  puts "There are #{pres.length} pres"
  index = 1
  pres.each do |l|
    puts "pre:     id: #{l.id}"
    puts "       name: #{l.name}"
    puts "      index: #{index}"
    index += 1
  end
end

#show_spansObject Also known as: showSpans

Description:

Show all the spans available on the page.

Output:

Name, id, class and index of all the spans available on the page.


854
855
856
857
858
859
860
861
862
863
864
865
# File 'lib/firewatir/firefox.rb', line 854

def show_spans
  spans = Document.new(self).get_spans
  puts "There are #{spans.length} spans"
  index = 1
  spans.each do |l|
    puts "span:  name: #{l.name}"
    puts "         id: #{l.id}"
    puts "      class: #{l.className}"
    puts "      index: #{index}"
    index += 1
  end
end

#show_tablesObject Also known as: showTables

Description:

Show all the tables available on the page.

Output:

Id, row count, column count (only first row) and index of all the tables available on the page.


813
814
815
816
817
818
819
820
821
822
823
824
# File 'lib/firewatir/firefox.rb', line 813

def show_tables
  tables = Document.new(self).get_tables
  puts "There are #{tables.length} tables"
  index = 1
  tables.each do |l|
    puts "table:   id: #{l.id}"
    puts "       rows: #{l.row_count}"
    puts "    columns: #{l.column_count}"
    puts "      index: #{index}"
    index += 1
  end
end

#startClicker(button, waitTime = 1, userInput = nil, text = nil) ⇒ Object

Description:

Tells FireWatir to click javascript button in case one comes after performing some action on an element. Matches
text of pop up with one if supplied as parameter. If text matches clicks the button else stop script execution until
pop up is dismissed by manual intervention.

Input:

button      - JavaScript button to be clicked. Values can be OK or Cancel
waitTime    - Time to wait for pop up to come. Not used just for compatibility with Watir.
userInput   - Not used just for compatibility with Watir
text        - Text that should appear on pop up.


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
# File 'lib/firewatir/firefox.rb', line 549

def startClicker(button, waitTime = 1, userInput = nil, text = nil)
  jssh_command = "var win = #{browser_var}.contentWindow;"
  if(button =~ /ok/i)
    jssh_command << "var popuptext = '';
                             var old_alert = win.alert;
                             var old_confirm = win.confirm;
                             win.alert = function(param) {"
    if(text != nil)
      jssh_command <<          "if(param == \"#{text}\") {
                                            popuptext = param;
                                            return true;
                                          }
                                          else {
                                            popuptext = param;
                                            win.alert = old_alert;
                                            win.alert(param);
                                          }"
    else
      jssh_command <<          "popuptext = param; return true;"
    end
    jssh_command << "};
                             win.confirm = function(param) {"
    if(text != nil)
      jssh_command <<          "if(param == \"#{text}\") {
                                            popuptext = param;
                                            return true;
                                          }
                                          else {
                                            win.confirm = old_confirm;
                                            win.confirm(param);
                                          }"
    else
      jssh_command <<          "popuptext = param; return true;"
    end
    jssh_command << "};"

  elsif(button =~ /cancel/i)
    jssh_command = "var old_confirm = win.confirm;
                                          win.confirm = function(param) {"
    if(text != nil)
      jssh_command <<          "if(param == \"#{text}\") {
                                            popuptext = param;
                                            return false;
                                          }
                                          else {
                                            win.confirm = old_confirm;
                                            win.confirm(param);
                                          }"
    else
      jssh_command <<          "popuptext = param; return false;"
    end
    jssh_command << "};"
  end
  js_eval jssh_command
end

#statusObject

Returns the Status of the page currently loaded in the browser from statusbar.

Output:

Status of the page.


395
396
397
398
# File 'lib/firewatir/firefox.rb', line 395

def status
  js_status = js_eval("#{window_var}.status")
  js_status.empty? ? js_eval("#{window_var}.XULBrowserWindow.statusText;") : js_status
end

#textObject

Returns the text of the page currently loaded in the browser.



408
409
410
# File 'lib/firewatir/firefox.rb', line 408

def text
  js_eval("#{body_var}.textContent").strip
end

#titleObject

Returns the title of the page currently loaded in the browser.



386
387
388
# File 'lib/firewatir/firefox.rb', line 386

def title
  @window_title = js_eval "#{document_var}.title"
end

#urlObject

Returns the url of the page currently loaded in the browser.



381
382
383
# File 'lib/firewatir/firefox.rb', line 381

def url
  @window_url = js_eval "#{document_var}.URL"
end

#wait(last_url = nil) ⇒ Object

Waits for the page to get loaded.



423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
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
488
489
490
491
492
493
494
# File 'lib/firewatir/firefox.rb', line 423

def wait(last_url = nil)
  #puts "In wait function "
  isLoadingDocument = ""
  start = Time.now

  while isLoadingDocument != "false"
    isLoadingDocument = js_eval("#{browser_var}=#{window_var}.getBrowser(); #{browser_var}.webProgress.isLoadingDocument;")
    #puts "Is browser still loading page: #{isLoadingDocument}"

    # Raise an exception if the page fails to load
    if (Time.now - start) > 300
      raise "Page Load Timeout"
    end
  end
  # If the redirect is to a download attachment that does not reload this page, this
  # method will loop forever. Therefore, we need to ensure that if this method is called
  # twice with the same URL, we simply accept that we're done.
  url = js_eval("#{browser_var}.contentDocument.URL")

  if(url != last_url)
    # Check for Javascript redirect. As we are connected to Firefox via JSSh. JSSh
    # doesn't detect any javascript redirects so check it here.
    # If page redirects to itself that this code will enter in infinite loop.
    # So we currently don't wait for such a page.
    # wait variable in JSSh tells if we should wait more for the page to get loaded
    # or continue. -1 means page is not redirected. Anyother positive values means wait.
    jssh_command = "var wait = -1; var meta = null; meta = #{browser_var}.contentDocument.getElementsByTagName('meta');
                            if(meta != null)
                            {
                                var doc_url = #{browser_var}.contentDocument.URL;
                                for(var i=0; i< meta.length;++i)
                                {
		    			var content = meta[i].content;
			    		var regex = new RegExp(\"^refresh$\", \"i\");
				    	if(regex.test(meta[i].httpEquiv))
					    {
						    var arrContent = content.split(';');
										var redirect_url = null;
 									if(arrContent.length > 0)
  								{
   								if(arrContent.length > 1)
    								redirect_url = arrContent[1];

			    				if(redirect_url != null)
		    					{
				    				regex = new RegExp(\"^.*\" + redirect_url + \"$\");
					    			if(!regex.test(doc_url))
						    		{
							    		wait = arrContent[0];
								    }
							    }
							    break;
						    }
					    }
				    }
                            }
                            wait;"
    wait_time = js_eval(jssh_command).to_i
    begin
      if(wait_time != -1)
        sleep(wait_time)
        # Call wait again. In case there are multiple redirects.
        js_eval "#{browser_var} = #{window_var}.getBrowser()"
        wait(url)
      end
    rescue
    end
  end
  set_browser_document()
  run_error_checks()
  return self
end

#window_varObject



200
201
202
# File 'lib/firewatir/firefox.rb', line 200

def window_var
  "window"
end