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.
Files changed (88) hide show
  1. data/.gitignore +34 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +24 -0
  4. data/History.rdoc +21 -0
  5. data/LICENSE +1 -1
  6. data/README.rdoc +8 -7
  7. data/Rakefile +22 -32
  8. data/VERSION +1 -1
  9. data/ext/UiaDll/Release/UiaDll.dll +0 -0
  10. data/ext/UiaDll/UiaDll.suo +0 -0
  11. data/ext/UiaDll/UiaDll/UiaDll.cpp +236 -10
  12. data/lib/rautomation/adapter/autoit/locators.rb +1 -1
  13. data/lib/rautomation/adapter/autoit/text_field.rb +10 -1
  14. data/lib/rautomation/adapter/autoit/window.rb +50 -23
  15. data/lib/rautomation/adapter/helper.rb +6 -6
  16. data/lib/rautomation/adapter/ms_uia.rb +22 -0
  17. data/lib/rautomation/adapter/{win_ffi → ms_uia}/button.rb +3 -2
  18. data/lib/rautomation/adapter/ms_uia/button_helper.rb +25 -0
  19. data/lib/rautomation/adapter/ms_uia/checkbox.rb +27 -0
  20. data/lib/rautomation/adapter/{win_ffi → ms_uia}/constants.rb +20 -5
  21. data/lib/rautomation/adapter/ms_uia/control.rb +180 -0
  22. data/lib/rautomation/adapter/{win_ffi → ms_uia}/functions.rb +24 -26
  23. data/lib/rautomation/adapter/ms_uia/keystroke_converter.rb +122 -0
  24. data/lib/rautomation/adapter/{win_ffi → ms_uia}/label.rb +3 -2
  25. data/lib/rautomation/adapter/ms_uia/list_box.rb +91 -0
  26. data/lib/rautomation/adapter/ms_uia/list_item.rb +49 -0
  27. data/lib/rautomation/adapter/ms_uia/locators.rb +23 -0
  28. data/lib/rautomation/adapter/{win_ffi → ms_uia}/radio.rb +2 -2
  29. data/lib/rautomation/adapter/{win_ffi → ms_uia}/select_list.rb +41 -7
  30. data/lib/rautomation/adapter/ms_uia/table.rb +86 -0
  31. data/lib/rautomation/adapter/{win_ffi → ms_uia}/text_field.rb +5 -4
  32. data/lib/rautomation/adapter/ms_uia/uia_dll.rb +62 -0
  33. data/lib/rautomation/adapter/ms_uia/window.rb +364 -0
  34. data/lib/rautomation/adapter/win_32.rb +21 -0
  35. data/lib/rautomation/adapter/win_32/button.rb +14 -0
  36. data/lib/rautomation/adapter/{win_ffi → win_32}/button_helper.rb +1 -1
  37. data/lib/rautomation/adapter/win_32/checkbox.rb +14 -0
  38. data/lib/rautomation/adapter/win_32/constants.rb +68 -0
  39. data/lib/rautomation/adapter/{win_ffi → win_32}/control.rb +30 -23
  40. data/lib/rautomation/adapter/win_32/functions.rb +313 -0
  41. data/lib/rautomation/adapter/win_32/keys.rb +121 -0
  42. data/lib/rautomation/adapter/win_32/label.rb +10 -0
  43. data/lib/rautomation/adapter/win_32/list_box.rb +40 -0
  44. data/lib/rautomation/adapter/{win_ffi → win_32}/locators.rb +2 -2
  45. data/lib/rautomation/adapter/win_32/radio.rb +11 -0
  46. data/lib/rautomation/adapter/win_32/select_list.rb +97 -0
  47. data/lib/rautomation/adapter/win_32/table.rb +22 -0
  48. data/lib/rautomation/adapter/win_32/text_field.rb +42 -0
  49. data/lib/rautomation/adapter/{win_ffi → win_32}/window.rb +79 -62
  50. data/lib/rautomation/element_collections.rb +9 -1
  51. data/lib/rautomation/window.rb +17 -9
  52. data/rautomation.gemspec +24 -0
  53. data/spec/adapter/autoit/window_spec.rb +71 -0
  54. data/spec/adapter/{win_ffi → ms_uia}/button_spec.rb +1 -1
  55. data/spec/adapter/{win_ffi → ms_uia}/checkbox_spec.rb +9 -3
  56. data/spec/adapter/ms_uia/control_spec.rb +28 -0
  57. data/spec/adapter/ms_uia/keystroke_converter_spec.rb +50 -0
  58. data/spec/adapter/{win_ffi → ms_uia}/label_spec.rb +2 -2
  59. data/spec/adapter/ms_uia/list_item_spec.rb +14 -0
  60. data/spec/adapter/{win_ffi → ms_uia}/listbox_spec.rb +18 -5
  61. data/spec/adapter/{win_ffi → ms_uia}/radio_spec.rb +3 -1
  62. data/spec/adapter/ms_uia/select_list_spec.rb +109 -0
  63. data/spec/adapter/{win_ffi → ms_uia}/table_spec.rb +12 -1
  64. data/spec/adapter/{win_ffi → ms_uia}/text_field_spec.rb +2 -1
  65. data/spec/adapter/ms_uia/window_spec.rb +89 -0
  66. data/spec/adapter/win_32/button_spec.rb +30 -0
  67. data/spec/adapter/win_32/checkbox_spec.rb +48 -0
  68. data/spec/adapter/win_32/label_spec.rb +15 -0
  69. data/spec/adapter/win_32/listbox_spec.rb +42 -0
  70. data/spec/adapter/win_32/radio_spec.rb +32 -0
  71. data/spec/adapter/{win_ffi → win_32}/select_list_spec.rb +16 -16
  72. data/spec/adapter/win_32/table_spec.rb +28 -0
  73. data/spec/adapter/win_32/text_field_spec.rb +24 -0
  74. data/spec/adapter/{win_ffi → win_32}/window_spec.rb +19 -14
  75. data/spec/button_spec.rb +1 -0
  76. data/spec/buttons_spec.rb +4 -4
  77. data/spec/spec_helper.rb +30 -4
  78. data/spec/text_field_spec.rb +6 -7
  79. data/spec/window_spec.rb +12 -0
  80. data/spec/windows_spec.rb +19 -0
  81. metadata +116 -97
  82. data/lib/rautomation/adapter/win_ffi.rb +0 -21
  83. data/lib/rautomation/adapter/win_ffi/checkbox.rb +0 -19
  84. data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +0 -67
  85. data/lib/rautomation/adapter/win_ffi/list_box.rb +0 -60
  86. data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +0 -36
  87. data/lib/rautomation/adapter/win_ffi/table.rb +0 -57
  88. 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,10 @@
1
+ module RAutomation
2
+ module Adapter
3
+ module Win32
4
+ class Label < Control
5
+ include WaitHelper
6
+ include Locators
7
+ end
8
+ end
9
+ end
10
+ 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 WinFfi
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,11 @@
1
+ module RAutomation
2
+ module Adapter
3
+ module Win32
4
+ class Radio < Control
5
+ include WaitHelper
6
+ include Locators
7
+ include ButtonHelper
8
+ end
9
+ end
10
+ end
11
+ 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 WinFfi
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
- # Refer to KeystrokeConverter#convert_special_characters for the special keycodes.
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(keys)
117
- shift_pressed = false
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
- release_key key
131
-
132
- if shift_pressed
133
- shift_pressed = false
134
- release_key Constants::VK_LSHIFT
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
- def label(locator)
157
- Label.new(self, locator)
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
- def control(locator)
161
- Control.new(self, locator)
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 controls(locator)
165
- Controls.new(self, locator)
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
- # Redirects all method calls not part of the public API to the {Functions} directly.
173
- # @see RAutomation::Window#method_missing
174
- def method_missing(name, *args)
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
- # extend public API
179
- RAutomation::Window.class_eval do
180
- def select_list(locator)
181
- wait_until_exists
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
- def radio(locator)
191
- wait_until_exists
192
- RAutomation::Adapter::WinFfi::Radio.new(@window, locator)
193
- end
202
+ def radio(locator={})
203
+ @container.wait_until_present
204
+ Radio.new(self, locator)
205
+ end
194
206
 
195
- def table(locator)
196
- wait_until_exists
197
- RAutomation::Adapter::WinFfi::Table.new(@window, locator)
198
- end
207
+ def table(locator={})
208
+ @container.wait_until_present
209
+ Table.new(self, locator)
210
+ end
199
211
 
200
- # Creates the child window object.
201
- # @note This is an WinFfi adapter specific method, not part of the public API
202
- # @example
203
- # RAutomation::Window.new(:title => /Windows Internet Explorer/i).
204
- # child(:title => /some popup/)
205
- # @param (see Window#initialize)
206
- # @return [RAutomation::Window] child window, popup or regular window.
207
- def child(locators)
208
- RAutomation::Window.new Functions.child_window_locators(@window.hwnd, locators)
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
- sleep 0.01
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
- sleep 0.1
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