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.
- data/CHANGES +19 -0
- data/VERSION +1 -1
- data/lib/watir/close_all.rb +2 -2
- data/lib/watir/container.rb +6 -4
- data/lib/watir/cookies.rb +80 -0
- data/lib/watir/core.rb +7 -3
- data/lib/watir/dialogs/file_field.rb +0 -4
- data/lib/watir/drag_and_drop_helper.rb +68 -0
- data/lib/watir/element.rb +58 -156
- data/lib/watir/element_collection.rb +109 -0
- data/lib/watir/form.rb +7 -14
- data/lib/watir/frame.rb +11 -26
- data/lib/watir/ie-class.rb +17 -307
- data/lib/watir/ie.rb +0 -9
- data/lib/watir/image.rb +8 -25
- data/lib/watir/input_elements.rb +32 -81
- data/lib/watir/link.rb +2 -17
- data/lib/watir/locator.rb +29 -25
- data/lib/watir/modal_dialog.rb +26 -40
- data/lib/watir/non_control_elements.rb +111 -79
- data/lib/watir/page-container.rb +12 -1
- data/lib/watir/supported_elements.rb +172 -0
- data/lib/watir/table.rb +61 -89
- data/lib/watir/win32ole.rb +2 -3
- data/lib/watir/win32ole/1.9.3/win32ole.so +0 -0
- data/lib/watir/xpath_locator.rb +52 -0
- data/rakefile.rb +1 -1
- data/unittests/checkbox_test.rb +22 -32
- data/unittests/css_selector_test.rb +1 -6
- data/unittests/css_test.rb +1 -4
- data/unittests/div_test.rb +3 -21
- data/unittests/document_standards.rb +0 -4
- data/unittests/element_collections_test.rb +2 -2
- data/unittests/element_test.rb +1 -1
- data/unittests/form_test.rb +0 -30
- data/unittests/frame_test.rb +8 -49
- data/unittests/ie_test.rb +5 -9
- data/unittests/images_test.rb +6 -6
- data/unittests/index_specifier_test.rb +0 -1
- data/unittests/js_events_test.rb +1 -1
- data/unittests/links_multi_test.rb +0 -14
- data/unittests/links_test.rb +8 -51
- data/unittests/lists_test.rb +0 -9
- data/unittests/navigate_test.rb +1 -1
- data/unittests/nbsp_xpath_test.rb +1 -1
- data/unittests/no_wait_test.rb +3 -3
- data/unittests/parent_child_test.rb +0 -17
- data/unittests/pre_test.rb +0 -3
- data/unittests/radios_test.rb +31 -42
- data/unittests/selectbox_test.rb +18 -21
- data/unittests/selectbox_xpath_test.rb +11 -26
- data/unittests/table_test.rb +14 -79
- data/unittests/textfields_test.rb +8 -47
- data/unittests/windows/attach_to_new_window_test.rb +0 -8
- data/unittests/windows/frame_links_test.rb +5 -5
- data/unittests/windows/ie-each_test.rb +1 -1
- data/unittests/windows/modal_dialog_test.rb +2 -2
- data/watir.gemspec +3 -3
- metadata +81 -126
- data/lib/watir/camel_case.rb +0 -67
- data/lib/watir/collections.rb +0 -48
- data/lib/watir/cookiemanager.rb +0 -56
- data/lib/watir/element_collections.rb +0 -81
- data/lib/watir/html_element.rb +0 -30
- data/unittests/defer_test.rb +0 -47
- data/unittests/multiple_specifiers_test.rb +0 -29
- data/unittests/table_and_tablerow_to_a_test.rb +0 -117
- 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
|
data/lib/watir/form.rb
CHANGED
@@ -1,41 +1,34 @@
|
|
1
1
|
module Watir
|
2
2
|
|
3
3
|
class Form < Element
|
4
|
-
|
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
|
-
|
9
|
+
attr_ole :action
|
17
10
|
|
18
11
|
def name
|
19
12
|
assert_exists
|
20
|
-
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
|
-
|
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
|
26
|
+
super
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
37
30
|
def locate
|
38
|
-
@o = @container.locator_for(FormLocator,
|
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.
|
data/lib/watir/frame.rb
CHANGED
@@ -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
|
-
|
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,
|
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(#{@
|
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
|
data/lib/watir/ie-class.rb
CHANGED
@@ -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(
|
496
|
-
rautomation.send_keys
|
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(
|
518
|
-
win = Window.new(self,
|
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(
|
524
|
-
self.class._find_all(
|
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
|
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(/ /, ' ')
|
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(/&/,'&')
|
905
|
-
str = str.gsub(/</,'<')
|
906
|
-
str = str.gsub(/>/,'>')
|
907
|
-
str = str.gsub(/"/, '"')
|
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
|