rautomation 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/History.rdoc +14 -0
  2. data/README.rdoc +1 -1
  3. data/VERSION +1 -1
  4. data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
  5. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +0 -6
  6. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +2 -0
  7. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.filters +3 -0
  8. data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.h +9 -3
  9. data/ext/IAccessibleDLL/IAccessibleDLL/table_support.cpp +282 -0
  10. data/ext/IAccessibleDLL/Release/IAccessibleDLL.dll +0 -0
  11. data/ext/ListViewExplorer/ListViewExplorer.sln +20 -0
  12. data/ext/ListViewExplorer/ListViewExplorer.suo +0 -0
  13. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.cpp +174 -0
  14. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj +95 -0
  15. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.filters +42 -0
  16. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.user +3 -0
  17. data/ext/ListViewExplorer/ListViewExplorer/ReadMe.txt +40 -0
  18. data/ext/ListViewExplorer/ListViewExplorer/stdafx.cpp +8 -0
  19. data/ext/ListViewExplorer/ListViewExplorer/stdafx.h +17 -0
  20. data/ext/ListViewExplorer/ListViewExplorer/table_support.cpp +250 -0
  21. data/ext/ListViewExplorer/ListViewExplorer/table_support.h +2 -0
  22. data/ext/ListViewExplorer/ListViewExplorer/targetver.h +8 -0
  23. data/ext/UiaDll/Release/UiaDll.dll +0 -0
  24. data/ext/UiaDll/UiaDll.sln +20 -0
  25. data/ext/UiaDll/UiaDll.suo +0 -0
  26. data/ext/UiaDll/UiaDll/ReadMe.txt +48 -0
  27. data/ext/UiaDll/UiaDll/UiaDll.cpp +205 -0
  28. data/ext/UiaDll/UiaDll/UiaDll.vcxproj +104 -0
  29. data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +42 -0
  30. data/ext/UiaDll/UiaDll/dllmain.cpp +39 -0
  31. data/ext/UiaDll/UiaDll/globals.h +3 -0
  32. data/ext/UiaDll/UiaDll/stdafx.cpp +8 -0
  33. data/ext/UiaDll/UiaDll/stdafx.h +19 -0
  34. data/ext/UiaDll/UiaDll/targetver.h +8 -0
  35. data/ext/WindowsForms/bin/WindowsForms.exe +0 -0
  36. data/ext/WindowsForms/src/WindowsForms/WindowsForms.suo +0 -0
  37. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +27 -7
  38. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.cs +1 -0
  39. data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +110 -11
  40. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Release/WindowsForms.exe +0 -0
  41. data/lib/rautomation.rb +2 -3
  42. data/lib/rautomation/adapter/autoit.rb +2 -2
  43. data/lib/rautomation/adapter/win_ffi.rb +4 -0
  44. data/lib/rautomation/adapter/win_ffi/button.rb +6 -0
  45. data/lib/rautomation/adapter/win_ffi/checkbox.rb +7 -0
  46. data/lib/rautomation/adapter/win_ffi/constants.rb +44 -3
  47. data/lib/rautomation/adapter/win_ffi/control.rb +36 -3
  48. data/lib/rautomation/adapter/win_ffi/functions.rb +37 -3
  49. data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +67 -0
  50. data/lib/rautomation/adapter/win_ffi/label.rb +21 -0
  51. data/lib/rautomation/adapter/win_ffi/list_box.rb +60 -0
  52. data/lib/rautomation/adapter/win_ffi/locators.rb +0 -1
  53. data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +36 -0
  54. data/lib/rautomation/adapter/win_ffi/radio.rb +7 -0
  55. data/lib/rautomation/adapter/win_ffi/select_list.rb +30 -7
  56. data/lib/rautomation/adapter/win_ffi/table.rb +42 -3
  57. data/lib/rautomation/adapter/win_ffi/text_field.rb +17 -1
  58. data/lib/rautomation/adapter/win_ffi/window.rb +47 -8
  59. data/lib/rautomation/button.rb +5 -0
  60. data/lib/rautomation/element_collections.rb +8 -5
  61. data/lib/rautomation/text_field.rb +10 -0
  62. data/lib/rautomation/window.rb +20 -14
  63. data/spec/adapter/win_ffi/button_spec.rb +41 -0
  64. data/spec/adapter/win_ffi/checkbox_spec.rb +19 -0
  65. data/spec/adapter/win_ffi/keystroke_converter_spec.rb +47 -0
  66. data/spec/adapter/win_ffi/label_spec.rb +21 -0
  67. data/spec/adapter/win_ffi/listbox_spec.rb +52 -0
  68. data/spec/adapter/win_ffi/radio_spec.rb +16 -0
  69. data/spec/adapter/win_ffi/select_list_spec.rb +29 -4
  70. data/spec/adapter/win_ffi/table_spec.rb +20 -1
  71. data/spec/adapter/win_ffi/text_field_spec.rb +23 -0
  72. data/spec/adapter/win_ffi/window_spec.rb +29 -0
  73. data/spec/button_spec.rb +1 -0
  74. data/spec/spec_helper.rb +4 -1
  75. data/spec/text_field_spec.rb +27 -15
  76. metadata +52 -34
  77. data/ext/IAccessibleDLL/Release/IAccessibleDLL.exp +0 -0
  78. data/ext/IAccessibleDLL/Release/IAccessibleDLL.lib +0 -0
  79. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.exe +0 -0
  80. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.pdb +0 -0
  81. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.vshost.exe +0 -0
  82. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.vshost.exe.manifest +0 -11
  83. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache +0 -0
  84. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache +0 -0
  85. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/GenerateResource.read.1.tlog +0 -0
  86. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/GenerateResource.write.1.tlog +0 -0
  87. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/ResolveAssemblyReference.cache +0 -0
  88. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.AboutBox.resources +0 -0
  89. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.DataEntryForm.resources +0 -0
  90. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.MainFormWindow.resources +0 -0
  91. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.PersonForm.resources +0 -0
  92. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.Properties.Resources.resources +0 -0
  93. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.SimpleElementsForm.resources +0 -0
  94. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.csproj.FileListAbsolute.txt +0 -25
  95. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.exe +0 -0
  96. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.pdb +0 -0
@@ -5,14 +5,53 @@ module RAutomation
5
5
  include WaitHelper
6
6
  include Locators
7
7
 
8
- private
8
+ def strings
9
+ rows = []
10
+ header_columns = []
11
+
12
+ raise "Not a list control" unless UiaDll::current_control_type(uia_control(@locators[:id])) == Constants::UIA_LIST_CONTROL_TYPE
13
+
14
+ children_count = count_children(uia_control(@locators[:id]))
15
+ children = FFI::MemoryPointer.new :pointer, children_count
16
+ UiaDll::find_children(uia_control(@locators[:id]), children)
17
+ children.read_array_of_pointer(children_count).each do |child|
18
+ grandchildren_count = count_children(child)
19
+ grandchildren = FFI::MemoryPointer.new :pointer, grandchildren_count
20
+ UiaDll::find_children(child, grandchildren)
21
+ grandchildren.read_array_of_pointer(grandchildren_count).each do |grandchild|
22
+ grandchild_name = FFI::MemoryPointer.new :char, UiaDll::get_name(grandchild, nil) + 1
23
+ UiaDll::get_name(grandchild, grandchild_name)
24
+ header_columns.push grandchild_name.read_string
25
+ end
26
+
27
+ rows.push header_columns
28
+ header_columns = []
29
+ end
30
+
31
+ rows
32
+ end
33
+
34
+ def select(row)
35
+ Functions.select_table_row(@window.oleacc_module_handle, Functions.control_hwnd(@window.hwnd, @locators), row)
36
+ end
37
+
38
+ def selected?(row)
39
+ state = Functions.get_table_row_state(@window.oleacc_module_handle, Functions.control_hwnd(@window.hwnd, @locators), row)
40
+ state & Constants::STATE_SYSTEM_SELECTED != 0
41
+ end
9
42
 
10
43
  def row_count
11
- Functions.send_message(Functions.control_hwnd(@window.hwnd, @locators), Constants::LVM_GETITEMCOUNT, 0, nil)
44
+ UiaDll::find_children(uia_control(@locators[:id]), nil)
45
+ end
46
+
47
+ private
48
+
49
+ def count_children(element)
50
+ UiaDll::find_children(element, nil)
12
51
  end
13
52
 
53
+
14
54
  end
15
55
  end
16
56
  end
17
57
  end
18
-
@@ -10,6 +10,8 @@ module RAutomation
10
10
 
11
11
  # @see RAutomation::TextField#set
12
12
  def set(text)
13
+ raise "Cannot set value on a disabled text field" if disabled?
14
+
13
15
  wait_until do
14
16
  hwnd = Functions.control_hwnd(@window.hwnd, @locators)
15
17
  @window.activate
@@ -22,14 +24,28 @@ module RAutomation
22
24
 
23
25
  # @see RAutomation::TextField#clear
24
26
  def clear
27
+ raise "Cannot set value on a disabled text field" if disabled?
25
28
  set ""
26
29
  end
27
30
 
28
31
  # @see RAutomation::TextField#value
29
32
  def value
30
- Functions.control_value(Functions.control_hwnd(@window.hwnd, @locators))
33
+ Functions.control_value(hwnd)
34
+ end
35
+
36
+ # @see RAutomation::TextField#hwnd
37
+ def hwnd
38
+ Functions.control_hwnd(@window.hwnd, @locators)
39
+ end
40
+
41
+ def exist?
42
+ @locators[:id].nil? ? super : super && matches_type(Constants::UIA_EDIT_CONTROL_TYPE)
31
43
  end
32
44
 
45
+ alias_method :exists?, :exist?
46
+
47
+
48
+
33
49
  end
34
50
  end
35
51
  end
@@ -4,6 +4,9 @@ module RAutomation
4
4
  class Window
5
5
  include WaitHelper
6
6
  include Locators
7
+ extend ElementCollections
8
+
9
+ has_many :controls
7
10
 
8
11
  class << self
9
12
  def initialize_com
@@ -109,19 +112,28 @@ module RAutomation
109
112
 
110
113
  # Activates the window and sends keys to it.
111
114
  #
112
- # Refer to MSDN documentation at http://msdn.microsoft.com/en-us/library/dd375731(v=VS.85).aspx
113
- # for the keycodes.
115
+ # Refer to KeystrokeConverter#convert_special_characters for the special keycodes.
114
116
  # @see RAutomation::Window#send_keys
115
- def send_keys(*keys)
116
- keys.each do |key|
117
+ def send_keys(keys)
118
+ shift_pressed = false
119
+ KeystrokeConverter.convert(keys).each do |key|
117
120
  wait_until do
118
121
  activate
119
122
  active?
120
123
  end
121
- Functions.send_key(0x12, 0, 0, nil)
122
- Functions.send_key(key, 0, 0, nil)
123
- Functions.send_key(0x12, 0, Constants::KEYEVENTF_KEYUP, nil)
124
- Functions.send_key(key, 0, Constants::KEYEVENTF_KEYUP, nil)
124
+ press_key key
125
+
126
+ if key == Constants::VK_LSHIFT
127
+ shift_pressed = true
128
+ next
129
+ end
130
+
131
+ release_key key
132
+
133
+ if shift_pressed
134
+ shift_pressed = false
135
+ release_key Constants::VK_LSHIFT
136
+ end
125
137
  end
126
138
  end
127
139
 
@@ -142,6 +154,22 @@ module RAutomation
142
154
  TextField.new(self, locator)
143
155
  end
144
156
 
157
+ def label(locator)
158
+ Label.new(self, locator)
159
+ end
160
+
161
+ def control(locator)
162
+ Control.new(self, locator)
163
+ end
164
+
165
+ def controls(locator)
166
+ Controls.new(self, locator)
167
+ end
168
+
169
+ def list_box(locator)
170
+ ListBox.new(self, locator)
171
+ end
172
+
145
173
  # Redirects all method calls not part of the public API to the {Functions} directly.
146
174
  # @see RAutomation::Window#method_missing
147
175
  def method_missing(name, *args)
@@ -182,6 +210,17 @@ module RAutomation
182
210
  end
183
211
  end
184
212
 
213
+ private
214
+
215
+ def press_key key
216
+ Functions.send_key(key, 0, 0, nil)
217
+ sleep 0.01
218
+ end
219
+
220
+ def release_key key
221
+ Functions.send_key(key, 0, Constants::KEYEVENTF_KEYUP, nil)
222
+ sleep 0.1
223
+ end
185
224
  end
186
225
  end
187
226
  end
@@ -39,6 +39,11 @@ module RAutomation
39
39
 
40
40
  alias_method :exist?, :exists?
41
41
 
42
+ # Allows to execute specific {Adapter} methods not part of the public API.
43
+ def method_missing(name, *args)
44
+ @button.send(name, *args)
45
+ end
46
+
42
47
  private
43
48
 
44
49
  def wait_until_exists
@@ -6,9 +6,12 @@ module RAutomation
6
6
  # and methods.
7
7
  def has_many(*elements)
8
8
  elements.each do |element|
9
- class_name = element.to_s.split("_").map {|e| e.capitalize}.join
10
- RAutomation.class_eval %Q{
11
- class #{class_name}
9
+ class_name_plural = element.to_s.split("_").map {|e| e.capitalize}.join
10
+ class_name = class_name_plural.chop
11
+ adapter_class = self.to_s.scan(/(.*)::/).to_s
12
+ clazz = RAutomation.constants.include?(class_name) ? RAutomation : class_eval(adapter_class)
13
+ clazz.class_eval %Q{
14
+ class #{class_name_plural}
12
15
  include Enumerable
13
16
 
14
17
  def initialize(window, locators)
@@ -20,7 +23,7 @@ module RAutomation
20
23
  i = -1
21
24
  while true
22
25
  args = [@window, @locators.merge(:index => i += 1)].compact
23
- object = RAutomation::#{class_name.chop}.new(*args)
26
+ object = #{clazz}::#{class_name}.new(*args)
24
27
  break unless object.exists?
25
28
  yield object
26
29
  end
@@ -35,7 +38,7 @@ module RAutomation
35
38
 
36
39
  class_eval %Q{
37
40
  def #{element}(locators = {})
38
- #{class_name}.new(@window, locators)
41
+ #{class_name_plural}.new(@window, locators)
39
42
  end
40
43
  }
41
44
  end
@@ -37,8 +37,18 @@ module RAutomation
37
37
  @text_field.exists?
38
38
  end
39
39
 
40
+ def hwnd
41
+ wait_until_exists
42
+ @text_field.hwnd
43
+ end
44
+
40
45
  alias_method :exist?, :exists?
41
46
 
47
+ # Allows to execute specific {Adapter} methods not part of the public API.
48
+ def method_missing(name, *args)
49
+ @text_field.send(name, *args)
50
+ end
51
+
42
52
  private
43
53
 
44
54
  def wait_until_exists
@@ -87,21 +87,21 @@ module RAutomation
87
87
  # @return [Fixnum] handle of the window which is used internally for other methods.
88
88
  # @raise [UnknownWindowException] if the window doesn't exist.
89
89
  def hwnd
90
- wait_until_exists
90
+ wait_until_present
91
91
  @window.hwnd
92
92
  end
93
93
 
94
94
  # @return [Fixnum] process identifier (PID) of the window.
95
95
  # @raise [UnknownWindowException] if the window doesn't exist.
96
96
  def pid
97
- wait_until_exists
97
+ wait_until_present
98
98
  @window.pid
99
99
  end
100
100
 
101
101
  # @return [String] title of the window.
102
102
  # @raise [UnknownWindowException] if the window doesn't exist.
103
103
  def title
104
- wait_until_exists
104
+ wait_until_present
105
105
  @window.title
106
106
  end
107
107
 
@@ -120,7 +120,7 @@ module RAutomation
120
120
  # @return [String] visible text of the window.
121
121
  # @raise [UnknownWindowException] if the window doesn't exist.
122
122
  def text
123
- wait_until_exists
123
+ wait_until_present
124
124
  @window.text
125
125
  end
126
126
 
@@ -150,14 +150,14 @@ module RAutomation
150
150
  # Maximizes the window.
151
151
  # @raise [UnknownWindowException] if the window doesn't exist.
152
152
  def maximize
153
- wait_until_exists
153
+ wait_until_present
154
154
  @window.maximize
155
155
  end
156
156
 
157
157
  # Minimizes the window.
158
158
  # @raise [UnknownWindowException] if the window doesn't exist.
159
159
  def minimize
160
- wait_until_exists
160
+ wait_until_present
161
161
  @window.minimize
162
162
  end
163
163
 
@@ -165,7 +165,7 @@ module RAutomation
165
165
  # @return [Boolean] true if window is minimized, false otherwise.
166
166
  # @raise [UnknownWindowException] if the window doesn't exist.
167
167
  def minimized?
168
- wait_until_exists
168
+ wait_until_present
169
169
  @window.minimized?
170
170
  end
171
171
 
@@ -173,15 +173,15 @@ module RAutomation
173
173
  # @note If the window is minimized, makes it visible again.
174
174
  # @raise [UnknownWindowException] if the window doesn't exist.
175
175
  def restore
176
- wait_until_exists
176
+ wait_until_present
177
177
  @window.restore
178
178
  end
179
179
 
180
180
  # Sends keyboard keys to the window. Refer to specific {Adapter} documentation for all possible values.
181
181
  # @raise [UnknownWindowException] if the window doesn't exist.
182
- def send_keys(*keys)
183
- wait_until_exists
184
- @window.send_keys(*keys)
182
+ def send_keys(keys)
183
+ wait_until_present
184
+ @window.send_keys(keys)
185
185
  end
186
186
 
187
187
  # Closes the window if it exists.
@@ -195,7 +195,7 @@ module RAutomation
195
195
  # @param [Hash] locators for the {Button}.
196
196
  # @raise [UnknownWindowException] if the window doesn't exist.
197
197
  def button(locators)
198
- wait_until_exists
198
+ wait_until_present
199
199
  Button.new(@window, locators)
200
200
  end
201
201
 
@@ -203,7 +203,7 @@ module RAutomation
203
203
  # @note Refer to specific {Adapter} documentation for possible _locators_ parameters.
204
204
  # @raise [UnknownWindowException] if the window doesn't exist.
205
205
  def text_field(locators)
206
- wait_until_exists
206
+ wait_until_present
207
207
  TextField.new(@window, locators)
208
208
  end
209
209
 
@@ -214,10 +214,16 @@ module RAutomation
214
214
 
215
215
  private
216
216
 
217
+ def wait_until_present
218
+ WaitHelper.wait_until {present?}
219
+ rescue WaitHelper::TimeoutError
220
+ raise UnknownWindowException, "Window with locator #{@window.locators.inspect} doesn't exist or is not visible!"
221
+ end
222
+
217
223
  def wait_until_exists
218
224
  WaitHelper.wait_until {exists?}
219
225
  rescue WaitHelper::TimeoutError
220
- raise UnknownWindowException, "Window with locator #{@window.locators.inspect} doesn't exist!" unless exists?
226
+ raise UnknownWindowException, "Window with locator #{@window.locators.inspect} doesn't exist!"
221
227
  end
222
228
 
223
229
  def normalize adapter
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe "WinFfi::Button", :if => SpecHelper.adapter == :win_ffi do
4
+ it "find by id" do
5
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window1_title])
6
+ window.button(:id => "aboutButton").should exist
7
+ end
8
+
9
+ it "check for button class" do
10
+ RAutomation::Window.new(:title => "MainFormWindow").button(:id => "textField").should_not exist
11
+ end
12
+
13
+
14
+ it "enabled/disabled" do
15
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window1_title])
16
+ window.button(:id => "enabledButton").should be_enabled
17
+ window.button(:id => "enabledButton").should_not be_disabled
18
+
19
+ window.button(:id => "disabledButton").should be_disabled
20
+ window.button(:id => "disabledButton").should_not be_enabled
21
+ end
22
+
23
+ it "#set_focus" do
24
+ button = RAutomation::Window.new(:title => SpecHelper::DATA[:window1_title]).button(:id => "enabledButton")
25
+ button.should_not have_focus
26
+
27
+ button.set_focus
28
+ button.should have_focus
29
+ end
30
+
31
+ it "cannot click disabled button" do
32
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window1_title])
33
+ lambda { window.button(:id => "disabledButton").click }.should raise_error
34
+ end
35
+
36
+ it "cannot set focus to disabled button" do
37
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window1_title])
38
+ lambda { window.button(:id => "disabledButton").set_focus }.should raise_error
39
+ end
40
+
41
+ end
@@ -9,6 +9,11 @@ describe "WinFfi::Checkbox", :if => SpecHelper.adapter == :win_ffi do
9
9
  to raise_exception(RAutomation::UnknownWindowException)
10
10
  end
11
11
 
12
+ it "check for checkbox class" do
13
+ RAutomation::Window.new(:title => "MainFormWindow").checkbox(:id => "textField").should_not exist
14
+ end
15
+
16
+
12
17
  it "#set? & #set" do
13
18
  checkbox = RAutomation::Window.new(:title => "MainFormWindow").checkbox(:value => "checkBox")
14
19
  checkbox.should_not be_set
@@ -26,4 +31,18 @@ describe "WinFfi::Checkbox", :if => SpecHelper.adapter == :win_ffi do
26
31
  checkbox.should_not be_set
27
32
  end
28
33
 
34
+ it "enabled/disabled" do
35
+ RAutomation::Window.new(:title => "MainFormWindow").checkbox(:id => "checkBox").should be_enabled
36
+ RAutomation::Window.new(:title => "MainFormWindow").checkbox(:id => "checkBox").should_not be_disabled
37
+
38
+ RAutomation::Window.new(:title => "MainFormWindow").checkbox(:id => "checkBoxDisabled").should_not be_enabled
39
+ RAutomation::Window.new(:title => "MainFormWindow").checkbox(:id => "checkBoxDisabled").should be_disabled
40
+ end
41
+
42
+ it "cannot check a disabled checkbox" do
43
+ lambda {
44
+ RAutomation::Window.new(:title => "MainFormWindow").checkbox(:id => "checkBoxDisabled").set
45
+ }.should raise_error
46
+ end
47
+
29
48
  end
@@ -0,0 +1,47 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'rautomation'
3
+ require 'rspec'
4
+
5
+ describe "KeystrokeConverter" do
6
+
7
+ it "converts plain ASCII" do
8
+ codes = RAutomation::Adapter::WinFfi::KeystrokeConverter.convert("abc")
9
+ converted_keys = convert_keys "abc"
10
+ codes.should == converted_keys
11
+ end
12
+
13
+ it "uses caps lock for entering downcase keys" do
14
+ codes = RAutomation::Adapter::WinFfi::KeystrokeConverter.convert("aBc")
15
+ converted_keys = convert_keys "abc"
16
+ converted_keys = converted_keys.insert(1, RAutomation::Adapter::WinFfi::Constants::VK_LSHIFT)
17
+ codes.should == converted_keys
18
+ end
19
+
20
+ it "converts special keys" do
21
+ codes = RAutomation::Adapter::WinFfi::KeystrokeConverter.convert("{tab}a{backspace}b{enter}c {left}d{right}ee{down}f{up}g{unsupported}")
22
+ expected_codes = [
23
+ RAutomation::Adapter::WinFfi::Constants::VK_TAB,
24
+ convert_keys("a"),
25
+ RAutomation::Adapter::WinFfi::Constants::VK_BACK,
26
+ convert_keys("b"),
27
+ RAutomation::Adapter::WinFfi::Constants::VK_RETURN,
28
+ convert_keys("c"),
29
+ RAutomation::Adapter::WinFfi::Constants::VK_SPACE,
30
+ RAutomation::Adapter::WinFfi::Constants::VK_LEFT,
31
+ convert_keys("d"),
32
+ RAutomation::Adapter::WinFfi::Constants::VK_RIGHT,
33
+ convert_keys("ee"),
34
+ RAutomation::Adapter::WinFfi::Constants::VK_DOWN,
35
+ convert_keys("f"),
36
+ RAutomation::Adapter::WinFfi::Constants::VK_UP,
37
+ convert_keys("g"),
38
+ convert_keys("unsupported")
39
+ ].flatten
40
+ codes.should == expected_codes
41
+ end
42
+
43
+ def convert_keys keys
44
+ keys.split("").map {|k| k.upcase.unpack("c")[0]}
45
+ end
46
+
47
+ end