vapir-ie 1.7.2 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ require 'vapir-ie/browser.rb'
2
+
3
+ module Vapir
4
+ class IE
5
+ module ClearTracks
6
+ History = 1 << 0
7
+ Cookies = 1 << 1
8
+ # ?? = 1 << 2
9
+ TemporaryFiles = 1 << 3
10
+ FormData = 1 << 4
11
+ StoredPasswords = 1 << 5
12
+ # ?? = 1 << 6
13
+ # ?? = 1 << 7
14
+ All = (1 << 8)-1 # this is called 'All' by such references as exist, despite higher bits being meaningful too.
15
+ FilesAndSettingsStoredByAddOns = 1 << 12 # don't know what happened to any of bits 6 through 11. also this only seems to be documented anywhere as 4351 = 1000011111111 (= All | FilesAndSettingsStoredByAddOns)
16
+ # apparently 1 << 13 is also meaningful, but I have no idea what it is. I have seen ClearMyTracksByProcess called with the argument 8651 = 10000111001011 (so bits 0, 1, 3, 6, 7, 8, 13)
17
+
18
+ # Clears tracks according to the given argument, which should be one of the constants of
19
+ # this module, or any number of those constants bitwise-OR'd together.
20
+ #
21
+ # ClearTracks.clear_tracks(ClearTracks::FormData)
22
+ # ClearTracks.clear_tracks(ClearTracks::History | ClearTracks::StoredPasswords)
23
+ def self.clear_tracks(what)
24
+ unless const_defined?('InetCpl')
25
+ require 'ffi'
26
+ define_const('InetCpl', Module.new)
27
+ InetCpl.extend(FFI::Library)
28
+ InetCpl.ffi_lib 'InetCpl.cpl'
29
+ InetCpl.ffi_convention :stdcall
30
+ InetCpl.attach_function :ClearMyTracksByProcess, :ClearMyTracksByProcessW, [:int], :void
31
+ end
32
+ InetCpl.ClearMyTracksByProcess(what)
33
+ end
34
+ end
35
+ module ClearTracksMethods
36
+ # Clear the history of sites that have been visited from the browser
37
+ def clear_history
38
+ ClearTracks.clear_tracks(ClearTracks::History)
39
+ end
40
+ # Clear all cookies from the browser
41
+ def clear_cookies
42
+ ClearTracks.clear_tracks(ClearTracks::Cookies)
43
+ end
44
+ # Clear temporary copies of web pages, images, and media that are saved
45
+ def clear_temporary_files
46
+ ClearTracks.clear_tracks(ClearTracks::TemporaryFiles)
47
+ end
48
+ # Clear all history, cookies, temporary files, form data, and passwords from the browser
49
+ def clear_all_tracks
50
+ ClearTracks.clear_tracks(ClearTracks::All)
51
+ end
52
+ end
53
+ include ClearTracksMethods
54
+ extend ClearTracksMethods
55
+ end
56
+ end
@@ -1,4 +1,4 @@
1
- require 'vapir-ie/ie-class'
1
+ require 'vapir-ie/browser'
2
2
 
3
3
  module Vapir
4
4
  class IE
@@ -0,0 +1,22 @@
1
+ require 'vapir-common/config'
2
+ require 'vapir-ie' # need the class to be set first
3
+
4
+ module Vapir
5
+ # if vapir-ie is required before any other browser-specific library, then set the default browser to ie
6
+ @base_configuration.default_browser = :ie unless @base_configuration.locally_defined_key?(:default_browser)
7
+
8
+ # add ie-specific stuff to base, and then bring them in from env and yaml
9
+ @base_configuration.create_update(:ie_launch_new_process, false, :validator => :boolean)
10
+ @base_configuration.create_update(:browser_visible, true, :validator => :boolean)
11
+ if defined?($HIDE_IE)
12
+ if config.warn_deprecated
13
+ Kernel.warn "WARNING: The $HIDE_IE global is gone. Please use the new config framework, and unset that global to silence this warning."
14
+ end
15
+ Vapir.config.browser_visible=false
16
+ end
17
+ @configurations.update_from_source
18
+ class IE
19
+ @configuration_parent = Vapir.config
20
+ extend Configurable
21
+ end
22
+ end
@@ -23,41 +23,19 @@ module Vapir
23
23
 
24
24
  public
25
25
  # see documentation for the common Vapir::Container#handling_existence_failure
26
- def handling_existence_failure(options={})
27
- options=handle_options(options, :handle => :ignore)
26
+ def handling_existence_failure(options={}, &block)
28
27
  begin
29
- yield
28
+ base_handling_existence_failure(options, &block)
30
29
  rescue WIN32OLERuntimeError, RuntimeError, NoMethodError, Vapir::Exception::ExistenceFailureException
31
- raise if $!.class==RuntimeError && $!.message !~ /HRESULT/ # sometimes WIN32OLE raises a RuntimeError instead of a WIN32OLERuntimeError. only catch a RuntimeError if it's from WIN32OLE, indicated by HRESULT in the error message.
30
+ if [WIN32OLERuntimeError, RuntimeError, NoMethodError].any?{|klass| $!.is_a?(klass) } && $!.message !~ Vapir::IE::ExistenceFailureCodesRE
31
+ raise
32
+ end
32
33
  handle_existence_failure($!, options)
33
34
  end
34
35
  end
35
- public
36
- # Note: @container is the container of this object, i.e. the container
37
- # of this container.
38
- # In other words, for ie.table().this_thing().text_field().set,
39
- # container of this_thing is the table.
40
-
41
- # This is used to change the typing speed when entering text on a page.
42
- attr_accessor :typingspeed
43
- attr_accessor :type_keys
44
-
45
- def copy_test_config(container) # only used by form and frame
46
- @typingspeed = container.typingspeed
47
- @type_keys = container.type_keys
48
- end
49
- private :copy_test_config
50
-
51
36
  # Write the specified string to the log.
52
37
  def log(what)
53
38
  @container.logger.debug(what) if @logger
54
39
  end
55
-
56
- # def set_container container
57
- # @container = container
58
- # @page_container = container.page_container
59
- # end
60
-
61
- private
62
40
  end # module
63
41
  end
@@ -41,15 +41,33 @@ module Vapir
41
41
  # Return the outer html of the object - see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/outerhtml.asp?frame=true
42
42
  dom_attr :outerHTML => :outer_html
43
43
 
44
- # return the text before the element
45
- def before_text
46
- element_object.getAdjacentText("afterEnd")
47
- end
48
-
49
- # return the text after the element
50
- def after_text
44
+ # text immediately before this element
45
+ #
46
+ # http://msdn.microsoft.com/en-us/library/ms536427(VS.85).aspx
47
+ def text_before_begin
51
48
  element_object.getAdjacentText("beforeBegin")
52
49
  end
50
+ # text after the start of the element but before all other content in the element
51
+ #
52
+ # http://msdn.microsoft.com/en-us/library/ms536427(VS.85).aspx
53
+ def text_after_begin
54
+ element_object.getAdjacentText("afterBegin")
55
+ end
56
+ # text immediately before the end of the element but after all other content in the element
57
+ #
58
+ # http://msdn.microsoft.com/en-us/library/ms536427(VS.85).aspx
59
+ def text_before_end
60
+ element_object.getAdjacentText("beforeEnd")
61
+ end
62
+ # text immediately before this element
63
+ #
64
+ # http://msdn.microsoft.com/en-us/library/ms536427(VS.85).aspx
65
+ def text_after_end
66
+ element_object.getAdjacentText("afterEnd")
67
+ end
68
+ # strange, counterintuitive aliases from watir
69
+ alias before_text text_after_end
70
+ alias after_text text_before_begin
53
71
 
54
72
  # Returns the text content of the element.
55
73
  dom_attr :innerText => :text
@@ -71,13 +89,6 @@ module Vapir
71
89
  source_index > other.source_index
72
90
  end
73
91
 
74
- def typingspeed
75
- @container.typingspeed
76
- end
77
- def type_keys
78
- @type_keys || @container.type_keys
79
- end
80
-
81
92
  private
82
93
  # for use with events' button property
83
94
  MouseButtonCodes=
@@ -111,7 +122,7 @@ module Vapir
111
122
  :shiftLeft => false,
112
123
  }
113
124
 
114
- if %w(onclick onmousedown onmouseup ondblclick onmouseover onmouseout).include?(event_type)
125
+ if %w(onclick onmousedown onmouseup ondblclick onmouseover onmouseout onmousemove).include?(event_type)
115
126
  client_center=self.client_center
116
127
 
117
128
  button_code=options[:button_code] ||
@@ -181,7 +192,6 @@ module Vapir
181
192
  actions.each do |action|
182
193
  # javascript stuff responding to previous events can cause self to stop existing, so check at every subsequent step
183
194
  handling_existence_failure(:handle => proc{ return result }) do
184
- assert_exists :force => true
185
195
  result=action.call
186
196
  end
187
197
  end
@@ -1,5 +1,4 @@
1
- require 'win32/process'
2
- require 'vapir-ie/ie-class'
1
+ require 'vapir-ie/browser'
3
2
 
4
3
  module Vapir
5
4
  class IE
@@ -18,10 +17,9 @@ module Vapir
18
17
  @@ie_version_parts ||= IE.version.split('.').map{|part| part.to_i }
19
18
  end
20
19
  class Process
21
- # Vapir::IE::Process.start is called by Vapir::IE.new_process and does not start a new process correctly in IE8.
22
- # Calling IE8 with the -nomerge option correctly starts a new process, so call Process.create with this option if
23
- # IE's version is 8
20
+ # start a new IE process and return a new Vapir::IE::Process object representing it.
24
21
  def self.start
22
+ require 'win32/process'
25
23
  program_files = ENV['ProgramFiles'] || "c:\\Program Files"
26
24
  startup_command = "#{program_files}\\Internet Explorer\\iexplore.exe"
27
25
  startup_command << " -nomerge" if ::Vapir::IE.version_parts.first==8
@@ -31,30 +29,22 @@ module Vapir
31
29
  new process_id
32
30
  end
33
31
 
32
+ # takes a process id
34
33
  def initialize process_id
35
34
  @process_id = process_id
36
35
  end
37
36
  attr_reader :process_id
38
37
 
39
- def window
40
- Waiter.wait_until do
41
- IE.each do | ie |
42
- window = ie.ie
43
- hwnd = ie.hwnd
44
- process_id = Process.process_id_from_hwnd hwnd
45
- return window if process_id == @process_id
38
+ # returns the browser object corresponding to the process id
39
+ def browser_object(options={})
40
+ options=handle_options(options, :timeout => 32)
41
+ Vapir.require_winwindow
42
+ ::Waiter.try_for(options[:timeout], :exception => RuntimeError.new("Could not find a browser for process #{self.inspect}")) do
43
+ Vapir::IE.browser_objects.detect do |browser_object|
44
+ @process_id == WinWindow.new(Vapir::IE.fix_win32ole_hwnd(browser_object.hwnd)).process_id
46
45
  end
47
46
  end
48
47
  end
49
-
50
- # Returns the process id for the specifed hWnd.
51
- def self.process_id_from_hwnd hwnd
52
- pid_info = ' ' * 32
53
- Win32API.new('user32', 'GetWindowThreadProcessId', 'ip', 'i').
54
- call(hwnd, pid_info)
55
- process_id = pid_info.unpack("L")[0]
56
- end
57
-
58
48
  end
59
49
  end
60
50
  end
@@ -87,15 +87,6 @@ module Vapir
87
87
  end
88
88
  end
89
89
  alias_deprecated :dragContentsTo, :drag_contents_to
90
-
91
- def requires_typing
92
- @type_keys = true
93
- self
94
- end
95
- def abhors_typing
96
- @type_keys = false
97
- self
98
- end
99
90
  end
100
91
 
101
92
  # this class can be used to access hidden field objects
@@ -122,7 +113,7 @@ module Vapir
122
113
  # of this browser, this process will handle the former, and we'll spawn another to do the
123
114
  # latter.
124
115
  require 'win32/process'
125
- require 'vapir-common/win_window'
116
+ Vapir.require_winwindow
126
117
  rubyw_exe= File.join(Config::CONFIG['bindir'], 'rubyw')
127
118
  error_file_name=File.expand_path(File.join(File.dirname(__FILE__), 'scripts', 'select_file_error_status.marshal_dump'))
128
119
  select_file_script=File.expand_path(File.join(File.dirname(__FILE__), 'scripts', 'select_file.rb'))
@@ -1,7 +1,5 @@
1
- require 'vapir-common/win_window'
2
1
  require 'vapir-common/modal_dialog'
3
2
  require 'vapir-ie/page_container'
4
- require 'Win32API'
5
3
 
6
4
  module Vapir
7
5
  class IE::ModalDialog
@@ -61,6 +59,7 @@ module Vapir
61
59
  @@iedialog_file = (File.expand_path(File.dirname(__FILE__) + '/..') + "/vapir-ie/IEDialog/Release/IEDialog.dll").gsub('/', '\\')
62
60
 
63
61
  def get_unknown(*args)
62
+ require 'Win32API'
64
63
  @@get_unknown ||= Win32API.new(@@iedialog_file, 'GetUnknown', ['l', 'p'], 'v')
65
64
  @@get_unknown.call(*args)
66
65
  end
@@ -104,120 +103,3 @@ module Vapir
104
103
  end
105
104
  end
106
105
  end
107
- =begin
108
- module Watir
109
- class IE::ModalDialog
110
- include IE::Container
111
- include IE::PageContainer
112
- include Win32
113
-
114
- # Return the current window handle
115
- attr_reader :hwnd
116
-
117
- def find_modal_from_window
118
- # Use handle of our parent window to see if we have any currently
119
- # enabled popup.
120
- hwnd = @container.hwnd
121
- hwnd_modal = 0
122
- begin
123
- Watir::until_with_timeout do
124
- hwnd_modal, arr = GetWindow.call(hwnd, GW_ENABLEDPOPUP) # GW_ENABLEDPOPUP = 6
125
- hwnd_modal > 0
126
- end
127
- rescue TimeOutException
128
- return nil
129
- end
130
- if hwnd_modal == hwnd || hwnd_modal == 0
131
- hwnd_modal = nil
132
- end
133
- @hwnd = hwnd_modal
134
- end
135
- private :find_modal_from_window
136
-
137
- def locate
138
- how = @how
139
- what = @what
140
-
141
- case how
142
- when nil
143
- unless find_modal_from_window
144
- raise NoMatchingWindowFoundException,
145
- "Modal Dialog not found. Timeout = #{Watir::IE.attach_timeout}"
146
- end
147
- when :title
148
- case what.class.to_s
149
- # TODO: re-write like WET's so we can select on regular expressions too.
150
- when "String"
151
- begin
152
- Watir::until_with_timeout do
153
- title = "#{what} -- Web Page Dialog"
154
- @hwnd, arr = FindWindowEx.call(0, 0, nil, title)
155
- @hwnd > 0
156
- end
157
- rescue TimeOutException
158
- raise NoMatchingWindowFoundException,
159
- "Modal Dialog with title #{what} not found. Timeout = #{Watir::IE.attach_timeout}"
160
- end
161
- else
162
- raise ArgumentError, "Title value must be String"
163
- end
164
- else
165
- raise ArgumentError, "Only null and :title methods are supported"
166
- end
167
-
168
- intUnknown = 0
169
- begin
170
- Watir::until_with_timeout do
171
- intPointer = " " * 4 # will contain the int value of the IUnknown*
172
- GetUnknown.call(@hwnd, intPointer)
173
- intArray = intPointer.unpack('L')
174
- intUnknown = intArray.first
175
- intUnknown > 0
176
- end
177
- rescue TimeOutException => e
178
- raise NoMatchingWindowFoundException,
179
- "Unable to attach to Modal Window #{what.inspect} after #{e.duration} seconds."
180
- end
181
-
182
- copy_test_config @parent_container
183
- @document = WIN32OLE.connect_unknown(intUnknown)
184
- end
185
-
186
- def initialize(container, how, what=nil)
187
- set_container container
188
- @how = how
189
- @what = what
190
- @parent_container = container
191
- # locate our modal dialog's Document object and save it
192
- begin
193
- locate
194
- rescue NoMethodError => e
195
- message =
196
- "IE#modal_dialog not supported with the current version of Ruby (#{RUBY_VERSION}).\n" +
197
- "See http://jira.openqa.org/browse/WTR-2 for details.\n" +
198
- e.message
199
- raise NoMethodError.new(message)
200
- end
201
- end
202
-
203
- def document
204
- @document
205
- end
206
-
207
- # Return the title of the document
208
- def title
209
- document.title
210
- end
211
-
212
- def wait(options={})
213
- end
214
-
215
- # Return true if the modal exists. Mostly this is useful for testing whether
216
- # a modal has closed.
217
- def exists?
218
- Watir::Win32::window_exists? @hwnd
219
- end
220
- alias :exist? :exists?
221
- end
222
- end
223
- =end
@@ -101,11 +101,13 @@ module Vapir
101
101
  if respond_to?(:browser_object)
102
102
  ::Waiter.try_for(options[:timeout]-(Time.now-start_load_time), :interval => options[:interval], :exception => "The browser was still busy after #{options[:timeout]} seconds") do
103
103
  return unless exists?
104
- !browser_object.busy
104
+ handling_existence_failure(:handle => proc { false }) { !browser_object.busy }
105
105
  end
106
106
  ::Waiter.try_for(options[:timeout]-(Time.now-start_load_time), :interval => options[:interval], :exception => "The browser's readyState was still not ready for interaction after #{options[:timeout]} seconds") do
107
107
  return unless exists?
108
- [WebBrowserReadyState::Interactive, WebBrowserReadyState::Complete].include?(browser_object.readyState)
108
+ handling_existence_failure(:handle => proc { false }) do
109
+ [WebBrowserReadyState::Interactive, WebBrowserReadyState::Complete].include?(browser_object.readyState)
110
+ end
109
111
  end
110
112
  end
111
113
  # if the document object is gone, then we want to just return.
@@ -1,4 +1,4 @@
1
- require 'vapir-ie/ie-class'
1
+ require 'vapir-ie/browser'
2
2
 
3
3
  module Vapir
4
4
  module Process