vapir-ie 1.7.2 → 1.8.0
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.
- data/lib/vapir-ie.rb +2 -26
- data/lib/vapir-ie/{ie-class.rb → browser.rb} +188 -294
- data/lib/vapir-ie/clear_tracks.rb +56 -0
- data/lib/vapir-ie/close_all.rb +1 -1
- data/lib/vapir-ie/config.rb +22 -0
- data/lib/vapir-ie/container.rb +5 -27
- data/lib/vapir-ie/element.rb +26 -16
- data/lib/vapir-ie/ie-process.rb +11 -21
- data/lib/vapir-ie/input_elements.rb +1 -10
- data/lib/vapir-ie/modal_dialog.rb +1 -119
- data/lib/vapir-ie/page_container.rb +4 -2
- data/lib/vapir-ie/process.rb +1 -1
- data/lib/vapir-ie/scripts/select_file.rb +1 -1
- data/lib/vapir-ie/version.rb +1 -1
- data/lib/vapir-ie/win32ole.rb +1 -1
- metadata +37 -42
@@ -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
|
data/lib/vapir-ie/close_all.rb
CHANGED
@@ -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
|
data/lib/vapir-ie/container.rb
CHANGED
@@ -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
|
-
|
28
|
+
base_handling_existence_failure(options, &block)
|
30
29
|
rescue WIN32OLERuntimeError, RuntimeError, NoMethodError, Vapir::Exception::ExistenceFailureException
|
31
|
-
|
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
|
data/lib/vapir-ie/element.rb
CHANGED
@@ -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
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
data/lib/vapir-ie/ie-process.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
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
|
-
#
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
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
|
-
|
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.
|
data/lib/vapir-ie/process.rb
CHANGED