rautomation 0.6.3 → 0.7.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/.gitignore +34 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +24 -0
- data/History.rdoc +21 -0
- data/LICENSE +1 -1
- data/README.rdoc +8 -7
- data/Rakefile +22 -32
- data/VERSION +1 -1
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UiaDll.suo +0 -0
- data/ext/UiaDll/UiaDll/UiaDll.cpp +236 -10
- data/lib/rautomation/adapter/autoit/locators.rb +1 -1
- data/lib/rautomation/adapter/autoit/text_field.rb +10 -1
- data/lib/rautomation/adapter/autoit/window.rb +50 -23
- data/lib/rautomation/adapter/helper.rb +6 -6
- data/lib/rautomation/adapter/ms_uia.rb +22 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/button.rb +3 -2
- data/lib/rautomation/adapter/ms_uia/button_helper.rb +25 -0
- data/lib/rautomation/adapter/ms_uia/checkbox.rb +27 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/constants.rb +20 -5
- data/lib/rautomation/adapter/ms_uia/control.rb +180 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/functions.rb +24 -26
- data/lib/rautomation/adapter/ms_uia/keystroke_converter.rb +122 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/label.rb +3 -2
- data/lib/rautomation/adapter/ms_uia/list_box.rb +91 -0
- data/lib/rautomation/adapter/ms_uia/list_item.rb +49 -0
- data/lib/rautomation/adapter/ms_uia/locators.rb +23 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/radio.rb +2 -2
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/select_list.rb +41 -7
- data/lib/rautomation/adapter/ms_uia/table.rb +86 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/text_field.rb +5 -4
- data/lib/rautomation/adapter/ms_uia/uia_dll.rb +62 -0
- data/lib/rautomation/adapter/ms_uia/window.rb +364 -0
- data/lib/rautomation/adapter/win_32.rb +21 -0
- data/lib/rautomation/adapter/win_32/button.rb +14 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/button_helper.rb +1 -1
- data/lib/rautomation/adapter/win_32/checkbox.rb +14 -0
- data/lib/rautomation/adapter/win_32/constants.rb +68 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/control.rb +30 -23
- data/lib/rautomation/adapter/win_32/functions.rb +313 -0
- data/lib/rautomation/adapter/win_32/keys.rb +121 -0
- data/lib/rautomation/adapter/win_32/label.rb +10 -0
- data/lib/rautomation/adapter/win_32/list_box.rb +40 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/locators.rb +2 -2
- data/lib/rautomation/adapter/win_32/radio.rb +11 -0
- data/lib/rautomation/adapter/win_32/select_list.rb +97 -0
- data/lib/rautomation/adapter/win_32/table.rb +22 -0
- data/lib/rautomation/adapter/win_32/text_field.rb +42 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/window.rb +79 -62
- data/lib/rautomation/element_collections.rb +9 -1
- data/lib/rautomation/window.rb +17 -9
- data/rautomation.gemspec +24 -0
- data/spec/adapter/autoit/window_spec.rb +71 -0
- data/spec/adapter/{win_ffi → ms_uia}/button_spec.rb +1 -1
- data/spec/adapter/{win_ffi → ms_uia}/checkbox_spec.rb +9 -3
- data/spec/adapter/ms_uia/control_spec.rb +28 -0
- data/spec/adapter/ms_uia/keystroke_converter_spec.rb +50 -0
- data/spec/adapter/{win_ffi → ms_uia}/label_spec.rb +2 -2
- data/spec/adapter/ms_uia/list_item_spec.rb +14 -0
- data/spec/adapter/{win_ffi → ms_uia}/listbox_spec.rb +18 -5
- data/spec/adapter/{win_ffi → ms_uia}/radio_spec.rb +3 -1
- data/spec/adapter/ms_uia/select_list_spec.rb +109 -0
- data/spec/adapter/{win_ffi → ms_uia}/table_spec.rb +12 -1
- data/spec/adapter/{win_ffi → ms_uia}/text_field_spec.rb +2 -1
- data/spec/adapter/ms_uia/window_spec.rb +89 -0
- data/spec/adapter/win_32/button_spec.rb +30 -0
- data/spec/adapter/win_32/checkbox_spec.rb +48 -0
- data/spec/adapter/win_32/label_spec.rb +15 -0
- data/spec/adapter/win_32/listbox_spec.rb +42 -0
- data/spec/adapter/win_32/radio_spec.rb +32 -0
- data/spec/adapter/{win_ffi → win_32}/select_list_spec.rb +16 -16
- data/spec/adapter/win_32/table_spec.rb +28 -0
- data/spec/adapter/win_32/text_field_spec.rb +24 -0
- data/spec/adapter/{win_ffi → win_32}/window_spec.rb +19 -14
- data/spec/button_spec.rb +1 -0
- data/spec/buttons_spec.rb +4 -4
- data/spec/spec_helper.rb +30 -4
- data/spec/text_field_spec.rb +6 -7
- data/spec/window_spec.rb +12 -0
- data/spec/windows_spec.rb +19 -0
- metadata +116 -97
- data/lib/rautomation/adapter/win_ffi.rb +0 -21
- data/lib/rautomation/adapter/win_ffi/checkbox.rb +0 -19
- data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +0 -67
- data/lib/rautomation/adapter/win_ffi/list_box.rb +0 -60
- data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +0 -36
- data/lib/rautomation/adapter/win_ffi/table.rb +0 -57
- data/spec/adapter/win_ffi/keystroke_converter_spec.rb +0 -47
@@ -0,0 +1,121 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
class Keys
|
5
|
+
KEYS = {
|
6
|
+
# keycodes from http://msdn.microsoft.com/en-us/library/ms927178.aspx
|
7
|
+
:null => 0x00,
|
8
|
+
:cancel => 0x03,
|
9
|
+
:help => 0x2F,
|
10
|
+
:backspace => 0x08,
|
11
|
+
:tab => 0x09,
|
12
|
+
:clear => 0x0C,
|
13
|
+
:return => 0x0D,
|
14
|
+
:enter => 0x0D,
|
15
|
+
:shift => 0x10,
|
16
|
+
:left_shift => 0xA0,
|
17
|
+
:control => 0x11,
|
18
|
+
:left_control => 0xA2,
|
19
|
+
:alt => 0x12,
|
20
|
+
:left_alt => 0xA4,
|
21
|
+
:pause => 0x13,
|
22
|
+
:escape => 0x1B,
|
23
|
+
:space => 0x20,
|
24
|
+
:page_up => 0x21,
|
25
|
+
:page_down => 0x22,
|
26
|
+
:end => 0x23,
|
27
|
+
:home => 0x24,
|
28
|
+
:left => 0x25,
|
29
|
+
:arrow_left => 0x25,
|
30
|
+
:up => 0x26,
|
31
|
+
:arrow_up => 0x26,
|
32
|
+
:right => 0x27,
|
33
|
+
:arrow_right => 0x27,
|
34
|
+
:down => 0x28,
|
35
|
+
:arrow_down => 0x28,
|
36
|
+
:insert => 0x2D,
|
37
|
+
:delete => 0x2E,
|
38
|
+
:semicolon => 0x3B,
|
39
|
+
:equals => 0x3D,
|
40
|
+
:numpad0 => 0x60,
|
41
|
+
:numpad1 => 0x61,
|
42
|
+
:numpad2 => 0x62,
|
43
|
+
:numpad3 => 0x63,
|
44
|
+
:numpad4 => 0x64,
|
45
|
+
:numpad5 => 0x65,
|
46
|
+
:numpad6 => 0x66,
|
47
|
+
:numpad7 => 0x67,
|
48
|
+
:numpad8 => 0x68,
|
49
|
+
:numpad9 => 0x69,
|
50
|
+
:multiply => 0x6A,
|
51
|
+
:add => 0x6B,
|
52
|
+
:separator => 0x6C,
|
53
|
+
:subtract => 0x6D,
|
54
|
+
:decimal => 0x6E,
|
55
|
+
:divide => 0x6F,
|
56
|
+
:f1 => 0x70,
|
57
|
+
:f2 => 0x71,
|
58
|
+
:f3 => 0x72,
|
59
|
+
:f4 => 0x73,
|
60
|
+
:f5 => 0x74,
|
61
|
+
:f6 => 0x75,
|
62
|
+
:f7 => 0x76,
|
63
|
+
:f8 => 0x77,
|
64
|
+
:f9 => 0x78,
|
65
|
+
:f10 => 0x79,
|
66
|
+
:f11 => 0x7A,
|
67
|
+
:f12 => 0x7B,
|
68
|
+
}
|
69
|
+
|
70
|
+
SPECIAL_KEYS = {
|
71
|
+
"!" => 0x31,
|
72
|
+
"@" => 0x32,
|
73
|
+
"#" => 0x33,
|
74
|
+
"$" => 0x34,
|
75
|
+
"%" => 0x35,
|
76
|
+
"^" => 0x36,
|
77
|
+
"&" => 0x37,
|
78
|
+
"*" => 0x38,
|
79
|
+
"(" => 0x39,
|
80
|
+
")" => 0x30,
|
81
|
+
"_" => 0x2D,
|
82
|
+
"+" => 0x3D,
|
83
|
+
"{" => 0x5B,
|
84
|
+
"}" => 0x5D,
|
85
|
+
":" => 0x3B,
|
86
|
+
"\"" => 0x27,
|
87
|
+
"|" => 0x5C,
|
88
|
+
"?" => 0x2F,
|
89
|
+
">" => 0x2E,
|
90
|
+
"<" => 0x2C
|
91
|
+
}
|
92
|
+
|
93
|
+
def self.[](key)
|
94
|
+
KEYS[key] or raise "unsupported key #{key.inspect}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.encode(keys)
|
98
|
+
keys.reduce([]) do |converted, key|
|
99
|
+
if key.is_a?(Symbol)
|
100
|
+
converted << Keys[key]
|
101
|
+
elsif key.is_a?(Array)
|
102
|
+
converted << (key.map {|k| encode([k])} << Keys[:null]).flatten
|
103
|
+
else # key is a string
|
104
|
+
converted += encode_str(key)
|
105
|
+
end
|
106
|
+
converted
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.encode_str(keys)
|
111
|
+
keys.to_s.split("").map do |key|
|
112
|
+
key =~ /[a-z]/ ? key.upcase.unpack("c")[0] :
|
113
|
+
key =~ /[A-Z]/ || SPECIAL_KEYS[key] ? [Keys[:shift], SPECIAL_KEYS[key] || key.unpack("c")[0], Keys[:null]] :
|
114
|
+
key.unpack("c")[0]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
class ListBox < Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Default locators used for searching buttons.
|
9
|
+
DEFAULT_LOCATORS = {:class => /listbox/i}
|
10
|
+
|
11
|
+
def count
|
12
|
+
Functions.send_message(hwnd, Constants::LB_GETCOUNT, 0, nil)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :size, :count
|
16
|
+
|
17
|
+
def items
|
18
|
+
count.times.reduce([]) do |memo, i|
|
19
|
+
text_length = Functions.send_message(hwnd, Constants::LB_GETTEXTLEN, 0, nil) + 1
|
20
|
+
text = FFI::MemoryPointer.new :char, text_length
|
21
|
+
Functions.send_message(hwnd, Constants::LB_GETTEXT, i, text)
|
22
|
+
memo << text.read_string
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :strings, :items
|
27
|
+
|
28
|
+
def selected?(i)
|
29
|
+
Functions.send_message(hwnd, Constants::LB_GETSEL, i, nil) > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def select(i)
|
33
|
+
Functions.send_message(hwnd, Constants::LB_SETCURSEL, i, nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module RAutomation
|
2
2
|
module Adapter
|
3
|
-
module
|
3
|
+
module Win32
|
4
4
|
# @private
|
5
5
|
module Locators
|
6
6
|
|
@@ -14,7 +14,7 @@ module RAutomation
|
|
14
14
|
|
15
15
|
# control locator
|
16
16
|
locators = self.class::DEFAULT_LOCATORS.merge(locators) if self.class.const_defined?(:DEFAULT_LOCATORS)
|
17
|
-
@locators = locators
|
17
|
+
@locators = {:index => 0}.merge locators
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
class SelectList < Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Default locators used for searching buttons.
|
9
|
+
DEFAULT_LOCATORS = {:class => /combobox/i}
|
10
|
+
|
11
|
+
class SelectListOption
|
12
|
+
attr_accessor :text, :index
|
13
|
+
|
14
|
+
def initialize(select_list, text, index)
|
15
|
+
@select_list = select_list
|
16
|
+
@text = text
|
17
|
+
@index = index
|
18
|
+
end
|
19
|
+
|
20
|
+
def selected?
|
21
|
+
selected_idx = Functions.send_message(@select_list.hwnd, Constants::CB_GETCURSEL, 0, nil)
|
22
|
+
return false if selected_idx == Constants::CB_ERR
|
23
|
+
@text == Functions.retrieve_combobox_item_text(@select_list.hwnd, selected_idx)
|
24
|
+
end
|
25
|
+
|
26
|
+
def select
|
27
|
+
@select_list.send :assert_enabled
|
28
|
+
Functions.send_message(@select_list.hwnd, Constants::CB_SETCURSEL, @index, nil) != Constants::CB_ERR
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :set, :select
|
32
|
+
end
|
33
|
+
|
34
|
+
def options(options = {})
|
35
|
+
items = []
|
36
|
+
|
37
|
+
item_count.times do |item_no|
|
38
|
+
item = Functions.retrieve_combobox_item_text(hwnd, item_no)
|
39
|
+
|
40
|
+
if options[:text]
|
41
|
+
items.push(SelectListOption.new(self, item, item_no)) if options[:text] == item
|
42
|
+
else
|
43
|
+
items.push(SelectListOption.new(self, item, item_no))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
items
|
48
|
+
end
|
49
|
+
|
50
|
+
def value
|
51
|
+
selected_option = options.find { |option| option.selected? }
|
52
|
+
selected_option ? selected_option.text : ""
|
53
|
+
end
|
54
|
+
|
55
|
+
def option(options)
|
56
|
+
item_count.times do |item_no|
|
57
|
+
item = Functions.retrieve_combobox_item_text(hwnd, item_no)
|
58
|
+
return SelectListOption.new(self, item, item_no) if options[:text] == item
|
59
|
+
end
|
60
|
+
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def select(index)
|
65
|
+
Functions.send_message(hwnd, Constants::CB_SETCURSEL, index, nil) != Constants::CB_ERR
|
66
|
+
end
|
67
|
+
|
68
|
+
def set(text)
|
69
|
+
option(:text => text).set
|
70
|
+
end
|
71
|
+
|
72
|
+
def list_item_height
|
73
|
+
Functions.send_message(hwnd, Constants::CB_GETITEMHEIGHT, 0 ,nil)
|
74
|
+
end
|
75
|
+
|
76
|
+
def dropbox_boundary
|
77
|
+
boundary = FFI::MemoryPointer.new :long, 4
|
78
|
+
|
79
|
+
Functions.send_message(hwnd, Constants::CB_GETDROPPEDCONTROLRECT, 0 ,boundary)
|
80
|
+
|
81
|
+
boundary.read_array_of_long(4)
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_top_index
|
85
|
+
Functions.send_message(hwnd, Constants::CB_GETTOPINDEX, 0 ,nil)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def item_count
|
91
|
+
Functions.send_message(hwnd, Constants::CB_GETCOUNT, 0, nil)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
class Table < Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Default locators used for searching buttons.
|
9
|
+
DEFAULT_LOCATORS = {:class => /syslistview/i}
|
10
|
+
|
11
|
+
def select(row)
|
12
|
+
Functions.select_table_row(Window.oleacc_module_handle, Functions.control_hwnd(@window.hwnd, @locators), row)
|
13
|
+
end
|
14
|
+
|
15
|
+
def selected?(row)
|
16
|
+
state = Functions.get_table_row_state(Window.oleacc_module_handle, Functions.control_hwnd(@window.hwnd, @locators), row)
|
17
|
+
state & Constants::STATE_SYSTEM_SELECTED != 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
class TextField < Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Default locators used for searching text fields.
|
9
|
+
DEFAULT_LOCATORS = {:class => /edit/i}
|
10
|
+
|
11
|
+
# @see RAutomation::TextField#set
|
12
|
+
def set(text)
|
13
|
+
raise "Cannot set value on a disabled text field" if disabled?
|
14
|
+
|
15
|
+
wait_until do
|
16
|
+
hwnd = Functions.control_hwnd(@window.hwnd, @locators)
|
17
|
+
@window.activate
|
18
|
+
@window.active? &&
|
19
|
+
focus &&
|
20
|
+
Functions.set_control_text(hwnd, text) &&
|
21
|
+
value == text
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @see RAutomation::TextField#clear
|
26
|
+
def clear
|
27
|
+
raise "Cannot set value on a disabled text field" if disabled?
|
28
|
+
set ""
|
29
|
+
end
|
30
|
+
|
31
|
+
# @see RAutomation::Window#send_keys
|
32
|
+
def send_keys(*keys)
|
33
|
+
@window.container.wait_until_present
|
34
|
+
assert_enabled
|
35
|
+
@window.activate
|
36
|
+
focus
|
37
|
+
@window.send_keys(keys)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module RAutomation
|
2
2
|
module Adapter
|
3
|
-
module
|
4
|
-
autoload :UiaDll, File.dirname(__FILE__) + "/ms_uia/uia_dll"
|
5
|
-
|
3
|
+
module Win32
|
6
4
|
class Window
|
7
5
|
include WaitHelper
|
8
6
|
include Locators
|
@@ -20,6 +18,8 @@ module RAutomation
|
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
21
|
+
attr_reader :container
|
22
|
+
|
23
23
|
# Locators of the window.
|
24
24
|
attr_reader :locators
|
25
25
|
|
@@ -36,7 +36,8 @@ module RAutomation
|
|
36
36
|
# @option locators [String, Fixnum] :index 0-based index to specify n-th window if all other criteria match
|
37
37
|
# all other criteria match
|
38
38
|
# @see RAutomation::Window#initialize
|
39
|
-
def initialize(locators)
|
39
|
+
def initialize(container, locators)
|
40
|
+
@container = container
|
40
41
|
extract(locators)
|
41
42
|
end
|
42
43
|
|
@@ -57,12 +58,21 @@ module RAutomation
|
|
57
58
|
Functions.window_title(hwnd)
|
58
59
|
end
|
59
60
|
|
61
|
+
# @see RAutomation::Window#class_names
|
62
|
+
def class_names
|
63
|
+
classes = []
|
64
|
+
controls.each do |control|
|
65
|
+
classes << control.class_name
|
66
|
+
end
|
67
|
+
classes.sort
|
68
|
+
end
|
69
|
+
|
60
70
|
# @see RAutomation::Window#activate
|
61
71
|
def activate
|
62
72
|
return if !exists? || active?
|
63
73
|
restore if minimized?
|
64
74
|
Functions.activate_window(hwnd)
|
65
|
-
sleep 1
|
75
|
+
sleep 0.1
|
66
76
|
end
|
67
77
|
|
68
78
|
# @see RAutomation::Window#active?
|
@@ -111,29 +121,33 @@ module RAutomation
|
|
111
121
|
|
112
122
|
# Activates the window and sends keys to it.
|
113
123
|
#
|
114
|
-
#
|
124
|
+
# @example
|
125
|
+
# RAutomation::Window.new(:title => //).send_keys "hello!"
|
126
|
+
# RAutomation::Window.new(:title => //).send_keys [:control, "a"], "world!"
|
127
|
+
# Refer to Keys#KEYS for all the special keycodes.
|
115
128
|
# @see RAutomation::Window#send_keys
|
116
|
-
def send_keys(
|
117
|
-
|
118
|
-
KeystrokeConverter.convert(keys).each do |key|
|
129
|
+
def send_keys(args)
|
130
|
+
Keys.encode(args).each do |arg|
|
119
131
|
wait_until do
|
120
132
|
activate
|
121
133
|
active?
|
122
134
|
end
|
123
|
-
press_key key
|
124
|
-
|
125
|
-
if key == Constants::VK_LSHIFT
|
126
|
-
shift_pressed = true
|
127
|
-
next
|
128
|
-
end
|
129
135
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
136
|
+
if arg.is_a?(Array)
|
137
|
+
arg.reduce([]) do |pressed_keys, k|
|
138
|
+
if k == Keys[:null]
|
139
|
+
pressed_keys.each {|pressed_key| release_key pressed_key}
|
140
|
+
pressed_keys = []
|
141
|
+
else
|
142
|
+
pressed_keys << press_key(k)
|
143
|
+
end
|
144
|
+
pressed_keys
|
145
|
+
end
|
146
|
+
else
|
147
|
+
send_key arg
|
135
148
|
end
|
136
149
|
end
|
150
|
+
sleep 1
|
137
151
|
end
|
138
152
|
|
139
153
|
# @see RAutomation::Window#close
|
@@ -153,72 +167,75 @@ module RAutomation
|
|
153
167
|
TextField.new(self, locator)
|
154
168
|
end
|
155
169
|
|
156
|
-
|
157
|
-
|
170
|
+
# Redirects all method calls not part of the public API to the {Functions} directly.
|
171
|
+
# @see RAutomation::Window#method_missing
|
172
|
+
def method_missing(name, *args)
|
173
|
+
Functions.respond_to?(name) ? Functions.send(name, *args) : super
|
158
174
|
end
|
159
175
|
|
160
|
-
|
161
|
-
|
176
|
+
# Win32 adapter specific API methods
|
177
|
+
def label(locator={})
|
178
|
+
@container.wait_until_present
|
179
|
+
Label.new(self, locator)
|
162
180
|
end
|
163
181
|
|
164
|
-
def
|
165
|
-
|
182
|
+
def control(locator={})
|
183
|
+
@container.wait_until_present
|
184
|
+
Control.new(self, locator)
|
166
185
|
end
|
167
186
|
|
168
|
-
def list_box(locator)
|
187
|
+
def list_box(locator={})
|
188
|
+
@container.wait_until_present
|
169
189
|
ListBox.new(self, locator)
|
170
190
|
end
|
171
191
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
Functions.respond_to?(name) ? Functions.send(name, *args) : super
|
192
|
+
def select_list(locator={})
|
193
|
+
@container.wait_until_present
|
194
|
+
SelectList.new(self, locator)
|
176
195
|
end
|
177
196
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
RAutomation::Adapter::WinFfi::SelectList.new(@window, locator)
|
183
|
-
end
|
184
|
-
|
185
|
-
def checkbox(locator)
|
186
|
-
wait_until_exists
|
187
|
-
RAutomation::Adapter::WinFfi::Checkbox.new(@window, locator)
|
188
|
-
end
|
197
|
+
def checkbox(locator={})
|
198
|
+
@container.wait_until_present
|
199
|
+
Checkbox.new(self, locator)
|
200
|
+
end
|
189
201
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
202
|
+
def radio(locator={})
|
203
|
+
@container.wait_until_present
|
204
|
+
Radio.new(self, locator)
|
205
|
+
end
|
194
206
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
207
|
+
def table(locator={})
|
208
|
+
@container.wait_until_present
|
209
|
+
Table.new(self, locator)
|
210
|
+
end
|
199
211
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
212
|
+
# Creates the child window object.
|
213
|
+
# @note This is an Win32 adapter specific method, not part of the public API
|
214
|
+
# @example
|
215
|
+
# RAutomation::Window.new(:title => /Windows Internet Explorer/i).
|
216
|
+
# child(:title => /some popup/)
|
217
|
+
# @param (see Window#initialize)
|
218
|
+
# @return [RAutomation::Window] child window, popup or regular window.
|
219
|
+
def child(locators)
|
220
|
+
RAutomation::Window.new Functions.child_window_locators(hwnd, locators)
|
210
221
|
end
|
211
222
|
|
212
223
|
private
|
213
224
|
|
214
225
|
def press_key key
|
215
226
|
Functions.send_key(key, 0, 0, nil)
|
216
|
-
|
227
|
+
key
|
217
228
|
end
|
218
229
|
|
219
230
|
def release_key key
|
220
231
|
Functions.send_key(key, 0, Constants::KEYEVENTF_KEYUP, nil)
|
221
|
-
|
232
|
+
key
|
233
|
+
end
|
234
|
+
|
235
|
+
def send_key key
|
236
|
+
press_key key
|
237
|
+
release_key key
|
238
|
+
key
|
222
239
|
end
|
223
240
|
end
|
224
241
|
end
|