vapir-firefox 1.7.0.rc1

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.
@@ -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