watir 3.0.0.rc2 → 3.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGES +19 -0
  2. data/VERSION +1 -1
  3. data/lib/watir/close_all.rb +2 -2
  4. data/lib/watir/container.rb +6 -4
  5. data/lib/watir/cookies.rb +80 -0
  6. data/lib/watir/core.rb +7 -3
  7. data/lib/watir/dialogs/file_field.rb +0 -4
  8. data/lib/watir/drag_and_drop_helper.rb +68 -0
  9. data/lib/watir/element.rb +58 -156
  10. data/lib/watir/element_collection.rb +109 -0
  11. data/lib/watir/form.rb +7 -14
  12. data/lib/watir/frame.rb +11 -26
  13. data/lib/watir/ie-class.rb +17 -307
  14. data/lib/watir/ie.rb +0 -9
  15. data/lib/watir/image.rb +8 -25
  16. data/lib/watir/input_elements.rb +32 -81
  17. data/lib/watir/link.rb +2 -17
  18. data/lib/watir/locator.rb +29 -25
  19. data/lib/watir/modal_dialog.rb +26 -40
  20. data/lib/watir/non_control_elements.rb +111 -79
  21. data/lib/watir/page-container.rb +12 -1
  22. data/lib/watir/supported_elements.rb +172 -0
  23. data/lib/watir/table.rb +61 -89
  24. data/lib/watir/win32ole.rb +2 -3
  25. data/lib/watir/win32ole/1.9.3/win32ole.so +0 -0
  26. data/lib/watir/xpath_locator.rb +52 -0
  27. data/rakefile.rb +1 -1
  28. data/unittests/checkbox_test.rb +22 -32
  29. data/unittests/css_selector_test.rb +1 -6
  30. data/unittests/css_test.rb +1 -4
  31. data/unittests/div_test.rb +3 -21
  32. data/unittests/document_standards.rb +0 -4
  33. data/unittests/element_collections_test.rb +2 -2
  34. data/unittests/element_test.rb +1 -1
  35. data/unittests/form_test.rb +0 -30
  36. data/unittests/frame_test.rb +8 -49
  37. data/unittests/ie_test.rb +5 -9
  38. data/unittests/images_test.rb +6 -6
  39. data/unittests/index_specifier_test.rb +0 -1
  40. data/unittests/js_events_test.rb +1 -1
  41. data/unittests/links_multi_test.rb +0 -14
  42. data/unittests/links_test.rb +8 -51
  43. data/unittests/lists_test.rb +0 -9
  44. data/unittests/navigate_test.rb +1 -1
  45. data/unittests/nbsp_xpath_test.rb +1 -1
  46. data/unittests/no_wait_test.rb +3 -3
  47. data/unittests/parent_child_test.rb +0 -17
  48. data/unittests/pre_test.rb +0 -3
  49. data/unittests/radios_test.rb +31 -42
  50. data/unittests/selectbox_test.rb +18 -21
  51. data/unittests/selectbox_xpath_test.rb +11 -26
  52. data/unittests/table_test.rb +14 -79
  53. data/unittests/textfields_test.rb +8 -47
  54. data/unittests/windows/attach_to_new_window_test.rb +0 -8
  55. data/unittests/windows/frame_links_test.rb +5 -5
  56. data/unittests/windows/ie-each_test.rb +1 -1
  57. data/unittests/windows/modal_dialog_test.rb +2 -2
  58. data/watir.gemspec +3 -3
  59. metadata +81 -126
  60. data/lib/watir/camel_case.rb +0 -67
  61. data/lib/watir/collections.rb +0 -48
  62. data/lib/watir/cookiemanager.rb +0 -56
  63. data/lib/watir/element_collections.rb +0 -81
  64. data/lib/watir/html_element.rb +0 -30
  65. data/unittests/defer_test.rb +0 -47
  66. data/unittests/multiple_specifiers_test.rb +0 -29
  67. data/unittests/table_and_tablerow_to_a_test.rb +0 -117
  68. data/unittests/windows/iedialog_test.rb +0 -53
@@ -0,0 +1,109 @@
1
+ module Watir
2
+ # this class is the super class for the iterator classes (buttons, links, spans etc
3
+ # it would normally only be accessed by the iterator methods (spans, links etc) of IE
4
+ class ElementCollection
5
+ include Enumerable
6
+
7
+ # Super class for all the iterator classes
8
+ # * container - an instance of an IE object
9
+ def initialize(container, specifiers)
10
+ if specifiers[:index]
11
+ raise Exception::MissingWayOfFindingObjectException,
12
+ "#{self.class} does not support attribute :index in #{specifiers.inspect}"
13
+ end
14
+
15
+ @container = container
16
+ @specifiers = specifiers
17
+ @page_container = container.page_container
18
+ end
19
+
20
+ def length
21
+ count = 0
22
+ each {|element| count += 1 }
23
+ count
24
+ end
25
+
26
+ alias_method :size, :length
27
+
28
+ # iterate through each of the elements in the collection in turn
29
+ def each
30
+ @container.locator_for(TaggedElementLocator, @specifiers, element_class).each {|element| yield element}
31
+ end
32
+
33
+ # allows access to a specific item in the collection
34
+ def [](n)
35
+ number = n - Watir::IE.base_index
36
+ offset = Watir::IE.zero_based_indexing ? (length - 1) : length
37
+ non_existing_element = element_class.new(@container, @specifiers.merge(:index => n))
38
+ def non_existing_element.locate; nil end
39
+ iterator_object(number) || non_existing_element
40
+ end
41
+
42
+ def first
43
+ iterator_object(0)
44
+ end
45
+
46
+ def last
47
+ iterator_object(length - 1)
48
+ end
49
+
50
+ def to_s
51
+ map { |e| e.to_s }.join("\n")
52
+ end
53
+
54
+ def inspect
55
+ '#<%s:0x%x length=%s container=%s>' % [self.class, hash*2, length.inspect, @container.inspect]
56
+ end
57
+
58
+ private
59
+
60
+ def iterator_object(i)
61
+ count = 0
62
+ each do |e|
63
+ return e if (i >= 0 && count == i) || (i < 0 && count == length + i)
64
+ count += 1
65
+ end
66
+ end
67
+
68
+ def element_class
69
+ Watir.const_get self.class.name.split("::").last.scan(/(.*)Collection/).flatten.first
70
+ end
71
+
72
+ end
73
+
74
+ class TableElementCollection < ElementCollection
75
+ def initialize(container, specifiers, ole_collection=nil)
76
+ super container, specifiers
77
+ @ole_collection = ole_collection
78
+ end
79
+
80
+ def each
81
+ if @ole_collection
82
+ elements = []
83
+ @ole_collection.each {|element| elements << element_class.new(@container, :ole_object => element)}
84
+ super do |element|
85
+ yield element if elements.include?(element)
86
+ end
87
+ else
88
+ super
89
+ end
90
+ end
91
+ end
92
+
93
+ class TableRowCollection < TableElementCollection; end
94
+
95
+ class TableCellCollection < TableElementCollection; end
96
+
97
+ class InputElementCollection < ElementCollection
98
+ def each
99
+ @container.locator_for(InputElementLocator, @specifiers, element_class).each {|element| yield element}
100
+ end
101
+ end
102
+
103
+ class HTMLElementCollection < ElementCollection
104
+ def each
105
+ @container.locator_for(TaggedElementLocator, @specifiers, Element).each { |element| yield element }
106
+ end
107
+ end
108
+
109
+ end
@@ -1,41 +1,34 @@
1
1
  module Watir
2
2
 
3
3
  class Form < Element
4
- TAG = 'FORM'
5
-
6
- # * container - the containing object, normally an instance of IE
7
- # * how - symbol - how we access the form (:name, :id, :index, :action, :method)
8
- # * what - what we use to access the form
9
- def initialize(container, how, what)
10
- set_container container
11
- @how = how
12
- @what = what
4
+ def initialize(container, specifiers)
5
+ super
13
6
  copy_test_config container
14
7
  end
15
8
 
16
- def_wrap_guard :action
9
+ attr_ole :action
17
10
 
18
11
  def name
19
12
  assert_exists
20
- name = @o.getAttributeNode('name')
13
+ name = ole_object.getAttributeNode('name')
21
14
  name ? name.value : ''
22
15
  end
23
16
 
24
17
  def form_method
25
18
  assert_exists
26
- @o.invoke('method')
19
+ ole_object.invoke('method')
27
20
  end
28
21
 
29
22
  def method(arg = nil)
30
23
  if arg.nil?
31
24
  form_method
32
25
  else
33
- super(arg)
26
+ super
34
27
  end
35
28
  end
36
29
 
37
30
  def locate
38
- @o = @container.locator_for(FormLocator, [self.class::TAG], @how, @what, self.class).locate
31
+ @o = @container.locator_for(FormLocator, @specifiers, self.class).locate
39
32
  end
40
33
 
41
34
  # Submit the data -- equivalent to pressing Enter or Return to submit a form.
@@ -1,13 +1,19 @@
1
1
  module Watir
2
2
  class Frame < Element
3
3
  include PageContainer
4
- TAGS = ['FRAME', 'IFRAME']
5
-
6
4
  attr_accessor :document
7
5
 
8
- # Find the frame denoted by how and what in the container and return its ole_object
6
+ attr_ole :name
7
+ attr_ole :src
8
+
9
+ def initialize(container, specifiers)
10
+ super
11
+ copy_test_config container
12
+ end
13
+
14
+ # Find the frame denoted by specifiers in the container and return its ole_object
9
15
  def locate
10
- frame, document = @container.locator_for(FrameLocator, self.class::TAGS, @how, @what, self.class).locate
16
+ frame, document = @container.locator_for(FrameLocator, @specifiers, self.class).locate
11
17
  if frame && document
12
18
  @o = frame
13
19
  begin
@@ -24,13 +30,6 @@ module Watir
24
30
  document.body.all
25
31
  end
26
32
 
27
- def initialize(container, how, what)
28
- set_container container
29
- @how = how
30
- @what = what
31
- copy_test_config container
32
- end
33
-
34
33
  def document
35
34
  assert_exists
36
35
  if @document
@@ -40,22 +39,8 @@ module Watir
40
39
  end
41
40
  end
42
41
 
43
- def document_mode
44
- document.documentMode
45
- end
46
-
47
42
  def attach_command
48
- @container.page_container.attach_command + ".frame(#{@how.inspect}, #{@what.inspect})".gsub('"','\'')
49
- end
50
-
51
- def execute_script(source)
52
- document.parentWindow.eval(source.to_s)
53
- rescue WIN32OLERuntimeError, NoMethodError #if eval fails we need to use execScript(source.to_s) which does not return a value, hence the workaround
54
- escaped_src = source.to_s.gsub(/[\r\n']/) {|m| "\\#{m}"}
55
- wrapper = "_watir_helper_div_#{Time.now.to_i}"
56
- cmd = "var e = document.createElement('DIV'); e.style.display = 'none'; e.id='#{wrapper}'; e.innerHTML = eval('#{escaped_src}'); document.body.appendChild(e);"
57
- document.parentWindow.execScript(cmd)
58
- document.getElementById(wrapper).wrapper_obj.innerHTML
43
+ @container.page_container.attach_command + ".frame(#{@specifiers.inspect})".gsub('"','\'')
59
44
  end
60
45
 
61
46
  end
@@ -68,11 +68,6 @@ module Watir
68
68
  # The default color for highlighting objects as they are accessed.
69
69
  HIGHLIGHT_COLOR = 'yellow'
70
70
 
71
- # IE inserts some element whose tagName is empty and just acts as block level element
72
- # Probably some IE method of cleaning things
73
- # To pass the same to the xml parser we need to give some name to empty tagName
74
- EMPTY_TAG_NAME = "DUMMY"
75
-
76
71
  # The time, in seconds, it took for the new page to load after executing the
77
72
  # the last command
78
73
  attr_reader :down_load_time
@@ -361,13 +356,6 @@ module Watir
361
356
  @ie.document.title
362
357
  end
363
358
 
364
- # The document standards mode used by IE
365
- # can be overridden in the html with: <meta http-equiv="x-ua-compatible" content="IE=8">
366
- def document_mode
367
- @ie.document.documentMode.to_i
368
- end
369
-
370
-
371
359
  # Return the status of the window, typically from the status bar at the bottom.
372
360
  def status
373
361
  return @ie.statusText
@@ -411,17 +399,6 @@ module Watir
411
399
  '#<%s:0x%x url=%s title=%s>' % [self.class, hash*2, url.inspect, title.inspect]
412
400
  end
413
401
 
414
- # Execute the given JavaScript string
415
- def execute_script(source)
416
- document.parentWindow.eval(source.to_s)
417
- rescue WIN32OLERuntimeError, NoMethodError #if eval fails we need to use execScript(source.to_s) which does not return a value, hence the workaround
418
- escaped_src = source.to_s.gsub(/[\r\n']/) {|m| "\\#{m}"}
419
- wrapper = "_watir_helper_div_#{rand(100000)}"
420
- cmd = "var e = document.createElement('DIV'); e.style.display='none'; e.id='#{wrapper}'; e.innerHTML = eval('#{escaped_src}'); document.body.appendChild(e);"
421
- document.parentWindow.execScript(cmd)
422
- document.getElementById(wrapper).innerHTML
423
- end
424
-
425
402
  # clear the list of urls that we have visited
426
403
  def clear_url_list
427
404
  @url_list.clear
@@ -434,11 +411,11 @@ module Watir
434
411
  wait rescue nil
435
412
  chwnd = @ie.hwnd.to_i
436
413
  @ie.quit
437
- t = Time.now
414
+ t = ::Time.now
438
415
  while exists?
439
416
  # just in case to avoid possible endless loop if failing to close some
440
417
  # window or tab
441
- break if Time.now - t > 10
418
+ break if ::Time.now - t > 10
442
419
  sleep 0.3
443
420
  end
444
421
  end
@@ -492,8 +469,8 @@ module Watir
492
469
  # Refer to RAutomation::Adapter::WinFfi::KeystrokeConverter.convert_special_characters for
493
470
  # special characters conversion.
494
471
  # @see RAutomation::Window#send_keys
495
- def send_keys(key_string)
496
- rautomation.send_keys key_string
472
+ def send_keys(*keys)
473
+ rautomation.send_keys *keys
497
474
  end
498
475
 
499
476
  def dir
@@ -514,14 +491,18 @@ module Watir
514
491
  return @ie.LocationURL
515
492
  end
516
493
 
517
- def window(how={}, &blk)
518
- win = Window.new(self, how, &blk)
494
+ def window(specifiers={}, &blk)
495
+ win = Window.new(self, specifiers, &blk)
519
496
  win.use &blk if blk
520
497
  win
521
498
  end
522
499
 
523
- def windows(how={}, &blk)
524
- self.class._find_all(how.keys.first, how.values.first).map {|ie| Window.new(self, how, IE.bind(ie), &blk)}
500
+ def windows(specifiers={}, &blk)
501
+ self.class._find_all(specifiers.keys.first, specifiers.values.first).map {|ie| Window.new(self, specifiers, IE.bind(ie), &blk)}
502
+ end
503
+
504
+ def cookies
505
+ Cookies.new(self)
525
506
  end
526
507
 
527
508
  #
@@ -538,7 +519,7 @@ module Watir
538
519
  @xml_parser_doc = nil
539
520
  @down_load_time = 0.0
540
521
  interval = 0.05
541
- start_load_time = Time.now
522
+ start_load_time = ::Time.now
542
523
 
543
524
  Timeout::timeout(5*60) do
544
525
  begin
@@ -556,7 +537,7 @@ module Watir
556
537
 
557
538
  documents_to_wait_for = [@ie.document]
558
539
  rescue WIN32OLERuntimeError # IE window must have been closed
559
- @down_load_time = Time.now - start_load_time
540
+ @down_load_time = ::Time.now - start_load_time
560
541
  return @down_load_time
561
542
  end
562
543
 
@@ -577,7 +558,7 @@ module Watir
577
558
  end
578
559
  end
579
560
 
580
- @down_load_time = Time.now - start_load_time
561
+ @down_load_time = ::Time.now - start_load_time
581
562
  run_error_checks
582
563
  sleep @pause_after_wait unless no_sleep
583
564
  @down_load_time
@@ -751,15 +732,11 @@ module Watir
751
732
 
752
733
  # Gives focus to the frame
753
734
  def focus
754
- document.activeElement.blur
735
+ active_element = document.activeElement
736
+ active_element.blur unless active_element.tagName == "BODY"
755
737
  document.focus
756
738
  end
757
739
 
758
- # Functions written for using xpath for getting the elements.
759
- def xmlparser_document_object
760
- @xml_parser_doc ||= create_xml_parser_doc
761
- end
762
-
763
740
  def attach_command
764
741
  "Watir::IE.attach(:hwnd, #{hwnd})"
765
742
  end
@@ -784,272 +761,5 @@ module Watir
784
761
  @ie = ieTemp
785
762
  end
786
763
 
787
- # Create the Nokogiri object if it is nil. This method is private so can be called only
788
- # from xmlparser_document_object method.
789
- def create_xml_parser_doc
790
- require 'nokogiri'
791
- if @xml_parser_doc == nil
792
- htmlSource ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<HTML>\n"
793
- htmlSource = html_source(document.body,htmlSource," ")
794
- htmlSource += "\n</HTML>\n"
795
- # Angrez: Resolving Jira issue WTR-114
796
- htmlSource = htmlSource.gsub(/&nbsp;/, '&#160;')
797
- begin
798
- @xml_parser_doc = Nokogiri.parse(htmlSource)
799
- rescue => e
800
- output_xml_parser_doc("error.xml", htmlSource)
801
- raise e
802
- end
803
- end
804
- end
805
-
806
- def output_xml_parser_doc(name, text)
807
- file = File.open(name,"w")
808
- file.print(text)
809
- file.close
810
- end
811
-
812
- #Function Tokenizes the tag line and returns array of tokens.
813
- #Token could be either tagName or "=" or attribute name or attribute value
814
- #Attribute value could be either quoted string or single word
815
- def tokenize_tagline(outerHtml)
816
- outerHtml = outerHtml.gsub(/\n|\r/," ")
817
- #removing "< symbol", opening of current tag
818
- outerHtml =~ /^\s*<(.*)$/
819
- outerHtml = $1
820
- tokens = Array.new
821
- i = startOffset = 0
822
- length = outerHtml.length
823
- #puts outerHtml
824
- parsingValue = false
825
- while i < length do
826
- i +=1 while (i < length && outerHtml[i,1] =~ /\s/)
827
- next if i == length
828
- currentToken = outerHtml[i,1]
829
-
830
- #Either current tag has been closed or user has not closed the tag >
831
- # and we have received the opening of next element
832
- break if currentToken =~ /<|>/
833
-
834
- #parse quoted value
835
- if(currentToken == "\"" || currentToken == "'")
836
- parsingValue = false
837
- quote = currentToken
838
- startOffset = i
839
- i += 1
840
- i += 1 while (i < length && (outerHtml[i,1] != quote || outerHtml[i-1,1] == "\\"))
841
- if i == length
842
- tokens.push quote + outerHtml[startOffset..i-1]
843
- else
844
- tokens.push outerHtml[startOffset..i]
845
- end
846
- elsif currentToken == "="
847
- tokens.push "="
848
- parsingValue = true
849
- else
850
- startOffset = i
851
- i += 1 while (i < length && !(outerHtml[i,1] =~ /\s|=|<|>/)) if !parsingValue
852
- i += 1 while (i < length && !(outerHtml[i,1] =~ /\s|<|>/)) if parsingValue
853
- parsingValue = false
854
- i -= 1
855
- tokens.push outerHtml[startOffset..i]
856
- end
857
- i += 1
858
- end
859
- return tokens
860
- end
861
-
862
- # This function get and clean all the attributes of the tag.
863
- def all_tag_attributes(outerHtml)
864
- tokens = tokenize_tagline(outerHtml)
865
- #puts tokens
866
- tagLine = ""
867
- count = 1
868
- tokensLength = tokens.length
869
- expectedEqualityOP= false
870
- while count < tokensLength do
871
- if expectedEqualityOP == false
872
- #print Attribute Name
873
- # If attribute name is valid. Refer: http://www.w3.org/TR/REC-xml/#NT-Name
874
- if tokens[count] =~ /^(\w|_|:)(.*)$/
875
- tagLine += " #{tokens[count]}"
876
- expectedEqualityOP = true
877
- end
878
- elsif tokens[count] == "="
879
- count += 1
880
- if count == tokensLength
881
- tagLine += "=\"\""
882
- elsif(tokens[count][0,1] == "\"" || tokens[count][0,1] == "'")
883
- tagLine += "=#{tokens[count]}"
884
- else
885
- tagLine += "=\"#{tokens[count]}\""
886
- end
887
- expectedEqualityOP = false
888
- else
889
- #Opps! equality was expected but its not there.
890
- #Set value same as the attribute name e.g. selected="selected"
891
- tagLine += "=\"#{tokens[count-1]}\""
892
- expectedEqualityOP = false
893
- next
894
- end
895
- count += 1
896
- end
897
- tagLine += "=\"#{tokens[count-1]}\" " if expectedEqualityOP == true
898
- #puts tagLine
899
- return tagLine
900
- end
901
-
902
- # This function is used to escape the characters that are not valid XML data.
903
- def xml_escape(str)
904
- str = str.gsub(/&/,'&amp;')
905
- str = str.gsub(/</,'&lt;')
906
- str = str.gsub(/>/,'&gt;')
907
- str = str.gsub(/"/, '&quot;')
908
- str
909
- end
910
-
911
- # Returns HTML Source
912
- # Traverse the DOM tree rooted at body element
913
- # and generate the HTML source.
914
- # element: Represent Current element
915
- # htmlString:HTML Source
916
- # spaces:(Used for debugging). Helps in indentation
917
- def html_source(element, htmlString, spaceString)
918
- begin
919
- tagLine = ""
920
- outerHtml = ""
921
- tagName = ""
922
- begin
923
- tagName = element.tagName.downcase
924
- tagName = EMPTY_TAG_NAME if tagName == ""
925
- # If tag is a mismatched tag.
926
- if !(tagName =~ /^(\w|_|:)(.*)$/)
927
- return htmlString
928
- end
929
- rescue
930
- #handling text nodes
931
- if element.toString(0) == '[object Text]' #IE9 has a different method for getting text
932
- element_text = element.wholeText
933
- else
934
- element_text = element.toString(0)
935
- end
936
- htmlString += xml_escape(element_text)
937
- return htmlString
938
- end
939
- #Skip comment and script tag
940
- if tagName =~ /^!/ || tagName== "script" || tagName =="style"
941
- return htmlString
942
- end
943
- #tagLine += spaceString
944
- outerHtml = all_tag_attributes(element.outerHtml) if tagName != EMPTY_TAG_NAME
945
- tagLine += "<#{tagName} #{outerHtml}"
946
-
947
- canHaveChildren = element.canHaveChildren
948
- if canHaveChildren
949
- tagLine += ">"
950
- else
951
- tagLine += "/>" #self closing tag
952
- end
953
- #spaceString += spaceString
954
- htmlString += tagLine
955
- childElements = element.childnodes
956
- childElements.each do |child|
957
- htmlString = html_source(child,htmlString,spaceString)
958
- end
959
- if canHaveChildren
960
- #tagLine += spaceString
961
- tagLine ="</" + tagName + ">"
962
- htmlString += tagLine
963
- end
964
- return htmlString
965
- rescue => e
966
- puts e.to_s
967
- end
968
- return htmlString
969
- end
970
-
971
- # Method that iterates over IE DOM object and get the elements for the given
972
- # xpath.
973
- def element_by_absolute_xpath(xpath)
974
- curElem = nil
975
- xpath = xpath.scan(/^.*\/body\[?\d*\]?\/(.*)/).flatten.first
976
- return unless xpath
977
-
978
- arr = xpath.split("/")
979
- return nil if arr.length == 0
980
-
981
- doc = document
982
- curElem = doc.getElementsByTagName("body").item(0)
983
- lastTagName = arr.last.to_s.upcase
984
-
985
- # lastTagName is like tagName[number] or just tagName. For the first case we need to
986
- # separate tagName and number.
987
- lastTagName = lastTagName.scan(/(\w*)\[?\d*\]?/).flatten.first
988
-
989
- arr.each do |element|
990
- element =~ /(\w*)\[?(\d*)\]?/
991
- tagname = $1
992
- tagname = tagname.upcase
993
-
994
- if $2 != nil && $2 != ""
995
- index = $2
996
- index = "#{index}".to_i - 1
997
- else
998
- index = 0
999
- end
1000
-
1001
- allElemns = tagname == "FRAME" ? [curElem] : curElem.childnodes
1002
- next if allElemns == nil || allElemns.length == 0
1003
-
1004
- allElemns.each do |child|
1005
- begin
1006
- curTag = child.tagName
1007
- curTag = EMPTY_TAG_NAME if curTag.empty?
1008
- rescue
1009
- next
1010
- end
1011
-
1012
- if curTag == tagname
1013
- index -= 1
1014
- if index < 0
1015
- curElem = child
1016
- break
1017
- end
1018
- end
1019
- end
1020
- end
1021
-
1022
- curElem.tagName == lastTagName ? curElem : nil rescue nil
1023
- end
1024
-
1025
- # execute css selector and return an array of (ole object) elements
1026
- def elements_by_css(selector)
1027
- xmlparser_document_object # Needed to ensure Nokogiri has been loaded
1028
- xpath = Nokogiri::CSS.xpath_for(selector)[0]
1029
- elements_by_xpath(xpath)
1030
- end
1031
-
1032
- # return the first (ole object) element that matches the css selector
1033
- def element_by_css(selector)
1034
- elements_by_css(selector)[0]
1035
- end
1036
-
1037
- # return the first element that matches the xpath
1038
- def element_by_xpath(xpath)
1039
- elements_by_xpath(xpath)[0]
1040
- end
1041
-
1042
- # execute xpath and return an array of elements
1043
- def elements_by_xpath(xpath)
1044
- doc = xmlparser_document_object
1045
-
1046
- # strip any trailing slash from the xpath expression (as used in watir unit tests)
1047
- xpath.chop! if xpath =~ /\/$/
1048
-
1049
- doc.xpath(xpath).reduce([]) do |memo, element|
1050
- memo << element_by_absolute_xpath(element.path)
1051
- end.compact
1052
- end
1053
-
1054
764
  end # class IE
1055
765
  end