vapir-firefox 1.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,144 @@
1
+ require 'vapir-firefox/window'
2
+ require 'vapir-common/modal_dialog'
3
+ require 'vapir-firefox/page_container'
4
+
5
+ module Vapir
6
+ # represents a window which is modal to a parent window
7
+ class Firefox::ModalDialog
8
+ include Vapir::ModalDialog
9
+ include Firefox::Window
10
+ def locate
11
+ candidates=[]
12
+ Vapir::Firefox.each_window_object do |win|
13
+ opener=win.attr(:opener)
14
+ opener=nil unless opener.type=='object'
15
+ content=win.attr(:content)
16
+ if content.type=='object'
17
+ content_opener=content.attr(:opener)
18
+ content_opener=nil unless content_opener.type=='object'
19
+ end
20
+ if [@browser.browser_window_object, @browser.content_window_object].any?{|_w| [opener, content_opener].compact.include?(_w) }
21
+ candidates << win
22
+ end
23
+ end
24
+ if candidates.size==0
25
+ nil
26
+ elsif candidates.size==1
27
+ @modal_window=candidates.first
28
+ else
29
+ raise "Multiple windows found which this is a parent of - cannot determine which is the expected modal dialog"
30
+ end
31
+ end
32
+
33
+ def exists?
34
+ # jssh_socket may be nil if the window has closed
35
+ @modal_window && @browser.jssh_socket && @browser.jssh_socket.object('getWindows()').to_js_array.include(@modal_window)
36
+ end
37
+
38
+ def text
39
+ assert_exists
40
+ @modal_window.document.documentElement.textContent
41
+ end
42
+
43
+ def set_text_field(value)
44
+ assert_exists
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def click_button(button_text, options={})
49
+ assert_exists
50
+ options=handle_options(options, :timeout => nil) # we don't actually use timeout here. maybe should error on it?
51
+ # raise if no anonymous nodes are found (this is where the buttons are)
52
+ anonymous_dialog_nodes=@modal_window.document.getAnonymousNodes(@modal_window.document.documentElement) || raise("Could not find anonymous nodes on which to look for buttons")
53
+ xul_buttons=[]
54
+ anonymous_dialog_nodes.to_array.each do |node|
55
+ xul_buttons+=node.getElementsByTagName('xul:button').to_array.select do |button|
56
+ Vapir::fuzzy_match(button.label, button_text)
57
+ end
58
+ end
59
+ raise("Found #{xul_buttons.size} buttons which match #{button_text} - expected to find 1") unless xul_buttons.size==1
60
+ xul_button=xul_buttons.first
61
+ xul_button.disabled=false # get around firefox's stupid thing where the default button is disabled for a few seconds or something, god knows why
62
+ xul_button.click
63
+ end
64
+
65
+ def close
66
+ @modal_window.close
67
+ end
68
+
69
+ def document
70
+ assert_exists
71
+ Firefox::ModalDialogDocument.new(self)
72
+ end
73
+ def browser_window_object
74
+ assert_exists
75
+ modal_window
76
+ end
77
+ def mozilla_window_class_name
78
+ 'MozillaDialogClass'
79
+ end
80
+ end
81
+
82
+ # this module is for objects that can launch modal dialogs of their own.
83
+ # such things are a Firefox Browser, and a Firefox::ModalDialogDocument.
84
+ module Firefox::ModalDialogContainer
85
+ # returns a Firefox::ModalDialog.
86
+ #
87
+ # you may specify an options hash. keys supported are those supported by the second argument
88
+ # to Firefox::ModalDialog#initialize, except that :error is overridden to false (use #modal_dialog!)
89
+ # if you want an exception to raise)
90
+ def modal_dialog(options={})
91
+ modal=Firefox::ModalDialog.new(self, options.merge(:error => false))
92
+ modal.exists? ? modal : nil
93
+ end
94
+
95
+ # returns #modal_dialog if it exists; otherwise, errors. use this with the expectation that the dialog does exist.
96
+ # use #modal_dialog when you will check if it exists.
97
+ def modal_dialog!(options={})
98
+ Firefox::ModalDialog.new(self, options.merge(:error => true))
99
+ end
100
+ end
101
+
102
+ # this represents a document contained within a modal dialog (a Firefox::ModalDialog)
103
+ # which was opened, generally, via a call to window.showModalDialog.
104
+ class Firefox::ModalDialogDocument
105
+ include Firefox::PageContainer
106
+ include Firefox::ModalDialogContainer
107
+
108
+ def initialize(containing_modal_dialog, options={})
109
+ options=handle_options(options, :timeout => ModalDialog::DEFAULT_TIMEOUT, :error => true)
110
+ @jssh_socket=containing_modal_dialog.browser.jssh_socket
111
+ @browser_object=containing_modal_dialog.modal_window.getBrowser
112
+
113
+ @containing_modal_dialog=containing_modal_dialog
114
+ end
115
+ attr_reader :containing_modal_dialog
116
+ attr_reader :browser_object
117
+
118
+ def document_object
119
+ browser_object.contentDocument
120
+ end
121
+ def content_window_object
122
+ browser_object.contentWindow
123
+ end
124
+ def browser_window_object
125
+ containing_modal_dialog.modal_window
126
+ end
127
+ def locate!(options={})
128
+ exists? || raise(Vapir::Exception::NoMatchingWindowFoundException, "The modal dialog seems to have stopped existing.")
129
+ end
130
+
131
+ def exists?
132
+ # todo/fix: will the document object change / become invalid / need to be relocated?
133
+ @containing_modal_dialog.exists? && document_object
134
+ end
135
+
136
+ def wait(options=nil)
137
+ ::Waiter.try_for(Firefox::ARBITRARY_TIMEOUT) do
138
+ !browser_object.webProgress.isLoadingDocument
139
+ end
140
+ end
141
+
142
+ attr_reader :jssh_socket
143
+ end
144
+ end
@@ -0,0 +1,91 @@
1
+ require 'vapir-firefox/container'
2
+
3
+ module Vapir
4
+ module Firefox::PageContainer
5
+ def containing_object
6
+ document_object
7
+ end
8
+ include Firefox::Container
9
+ def url
10
+ document_object.location.href
11
+ end
12
+ def title
13
+ document_object.title
14
+ end
15
+ def document_element
16
+ document_object.documentElement
17
+ end
18
+ #def content_window_object
19
+ # document_object.parentWindow
20
+ #end
21
+ def text
22
+ document_element.textContent
23
+ end
24
+
25
+ def page_container
26
+ self
27
+ end
28
+
29
+ # returns nil or raises an error if the given javascript errors.
30
+ #
31
+ # todo/fix: this should return the last evaluated value, like ie's?
32
+ def execute_script(javascript)
33
+ jssh_socket.value_json("(function()
34
+ { with(#{content_window_object.ref})
35
+ { #{javascript} }
36
+ return null;
37
+ })()")
38
+ #sandbox=jssh_socket.Components.utils.Sandbox(content_window_object)
39
+ #sandbox.window=content_window_object
40
+ #sandbox.document=content_window_object.document
41
+ #return jssh_socket.Components.utils.evalInSandbox(javascript, sandbox)
42
+ end
43
+
44
+ # Returns the html of the document
45
+ def html
46
+ jssh_socket.value_json("(function(document){
47
+ var temp_el=document.createElement('div');
48
+ var orig_childs=[];
49
+ while(document.childNodes.length > 0)
50
+ { orig_childs.push(document.childNodes[0]);
51
+ document.removeChild(document.childNodes[0]);
52
+ /* we remove each childNode here because doing appendChild on temp_el removes it
53
+ * from document anyway (at least when appendChild works), so we just remove all
54
+ * childNodes so that adding them back in the right order is simpler (using orig_childs)
55
+ */
56
+ }
57
+ for(var i in orig_childs)
58
+ { try
59
+ { temp_el.appendChild(orig_childs[i]);
60
+ }
61
+ catch(e)
62
+ {}
63
+ }
64
+ retval=temp_el.innerHTML;
65
+ while(orig_childs.length > 0)
66
+ { document.appendChild(orig_childs.shift());
67
+ }
68
+ return retval;
69
+ })(#{document_object.ref})")
70
+ =begin
71
+ temp_el=document_object.createElement('div') # make a temporary element
72
+ orig_childs=jssh_socket.object('[]').store_rand_object_key(@browser_jssh_objects)
73
+ while document_object.childNodes.length > 0
74
+ orig_childs.push(document_object.childNodes[0])
75
+ document_object.removeChild(document_object.childNodes[0])
76
+ end
77
+ orig_childs.to_array.each do |child|
78
+ begin
79
+ temp_el.appendChild(child)
80
+ rescue JsshError
81
+ end
82
+ end
83
+ result=temp_el.innerHTML
84
+ while orig_childs.length > 0
85
+ document_object.appendChild(orig_childs.shift())
86
+ end
87
+ return result
88
+ =end
89
+ end
90
+ end
91
+ end