rdp-rautomation 0.6.3.1

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 (120) hide show
  1. data/.document +5 -0
  2. data/.rspec +2 -0
  3. data/.yardopts +6 -0
  4. data/History.rdoc +103 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +114 -0
  7. data/Rakefile +43 -0
  8. data/VERSION +1 -0
  9. data/ext/AutoItX/AutoItX.chm +0 -0
  10. data/ext/AutoItX/AutoItX3.dll +0 -0
  11. data/ext/IAccessibleDLL/IAccessibleDLL.sln +20 -0
  12. data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
  13. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +30 -0
  14. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +102 -0
  15. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.filters +42 -0
  16. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.user +3 -0
  17. data/ext/IAccessibleDLL/IAccessibleDLL/ReadMe.txt +48 -0
  18. data/ext/IAccessibleDLL/IAccessibleDLL/dllmain.cpp +19 -0
  19. data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.cpp +8 -0
  20. data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.h +22 -0
  21. data/ext/IAccessibleDLL/IAccessibleDLL/table_support.cpp +282 -0
  22. data/ext/IAccessibleDLL/IAccessibleDLL/targetver.h +8 -0
  23. data/ext/IAccessibleDLL/Release/IAccessibleDLL.dll +0 -0
  24. data/ext/ListViewExplorer/ListViewExplorer.sln +20 -0
  25. data/ext/ListViewExplorer/ListViewExplorer.suo +0 -0
  26. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.cpp +174 -0
  27. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj +95 -0
  28. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.filters +42 -0
  29. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.user +3 -0
  30. data/ext/ListViewExplorer/ListViewExplorer/ReadMe.txt +40 -0
  31. data/ext/ListViewExplorer/ListViewExplorer/stdafx.cpp +8 -0
  32. data/ext/ListViewExplorer/ListViewExplorer/stdafx.h +17 -0
  33. data/ext/ListViewExplorer/ListViewExplorer/table_support.cpp +250 -0
  34. data/ext/ListViewExplorer/ListViewExplorer/table_support.h +2 -0
  35. data/ext/ListViewExplorer/ListViewExplorer/targetver.h +8 -0
  36. data/ext/UiaDll/Release/UiaDll.dll +0 -0
  37. data/ext/UiaDll/UiaDll.sln +20 -0
  38. data/ext/UiaDll/UiaDll.suo +0 -0
  39. data/ext/UiaDll/UiaDll/ReadMe.txt +48 -0
  40. data/ext/UiaDll/UiaDll/UiaDll.cpp +205 -0
  41. data/ext/UiaDll/UiaDll/UiaDll.vcxproj +104 -0
  42. data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +42 -0
  43. data/ext/UiaDll/UiaDll/dllmain.cpp +39 -0
  44. data/ext/UiaDll/UiaDll/globals.h +3 -0
  45. data/ext/UiaDll/UiaDll/stdafx.cpp +8 -0
  46. data/ext/UiaDll/UiaDll/stdafx.h +19 -0
  47. data/ext/UiaDll/UiaDll/targetver.h +8 -0
  48. data/ext/WindowsForms/bin/WindowsForms.exe +0 -0
  49. data/ext/WindowsForms/src/WindowsForms/WindowsForms.sln +20 -0
  50. data/ext/WindowsForms/src/WindowsForms/WindowsForms.suo +0 -0
  51. data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.Designer.cs +80 -0
  52. data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.cs +103 -0
  53. data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.resx +120 -0
  54. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +187 -0
  55. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.cs +46 -0
  56. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.resx +120 -0
  57. data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +377 -0
  58. data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.cs +78 -0
  59. data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.resx +120 -0
  60. data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.Designer.cs +119 -0
  61. data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.cs +34 -0
  62. data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.resx +120 -0
  63. data/ext/WindowsForms/src/WindowsForms/WindowsForms/Program.cs +21 -0
  64. data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/AssemblyInfo.cs +36 -0
  65. data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Resources.Designer.cs +71 -0
  66. data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Resources.resx +117 -0
  67. data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Settings.Designer.cs +30 -0
  68. data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Settings.settings +7 -0
  69. data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.Designer.cs +93 -0
  70. data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.cs +19 -0
  71. data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.resx +120 -0
  72. data/ext/WindowsForms/src/WindowsForms/WindowsForms/WindowsForms.csproj +123 -0
  73. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Release/WindowsForms.exe +0 -0
  74. data/lib/rautomation.rb +6 -0
  75. data/lib/rautomation/adapter/autoit.rb +5 -0
  76. data/lib/rautomation/adapter/autoit/button.rb +59 -0
  77. data/lib/rautomation/adapter/autoit/locators.rb +22 -0
  78. data/lib/rautomation/adapter/autoit/text_field.rb +61 -0
  79. data/lib/rautomation/adapter/autoit/window.rb +184 -0
  80. data/lib/rautomation/adapter/helper.rb +20 -0
  81. data/lib/rautomation/adapter/win_ffi.rb +21 -0
  82. data/lib/rautomation/adapter/win_ffi/button.rb +25 -0
  83. data/lib/rautomation/adapter/win_ffi/button_helper.rb +24 -0
  84. data/lib/rautomation/adapter/win_ffi/checkbox.rb +19 -0
  85. data/lib/rautomation/adapter/win_ffi/constants.rb +94 -0
  86. data/lib/rautomation/adapter/win_ffi/control.rb +79 -0
  87. data/lib/rautomation/adapter/win_ffi/functions.rb +333 -0
  88. data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +67 -0
  89. data/lib/rautomation/adapter/win_ffi/label.rb +21 -0
  90. data/lib/rautomation/adapter/win_ffi/list_box.rb +60 -0
  91. data/lib/rautomation/adapter/win_ffi/locators.rb +22 -0
  92. data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +36 -0
  93. data/lib/rautomation/adapter/win_ffi/radio.rb +19 -0
  94. data/lib/rautomation/adapter/win_ffi/select_list.rb +87 -0
  95. data/lib/rautomation/adapter/win_ffi/table.rb +57 -0
  96. data/lib/rautomation/adapter/win_ffi/text_field.rb +52 -0
  97. data/lib/rautomation/adapter/win_ffi/window.rb +226 -0
  98. data/lib/rautomation/button.rb +55 -0
  99. data/lib/rautomation/element_collections.rb +47 -0
  100. data/lib/rautomation/text_field.rb +60 -0
  101. data/lib/rautomation/wait_helper.rb +23 -0
  102. data/lib/rautomation/window.rb +234 -0
  103. data/spec/adapter/win_ffi/button_spec.rb +41 -0
  104. data/spec/adapter/win_ffi/checkbox_spec.rb +48 -0
  105. data/spec/adapter/win_ffi/keystroke_converter_spec.rb +47 -0
  106. data/spec/adapter/win_ffi/label_spec.rb +21 -0
  107. data/spec/adapter/win_ffi/listbox_spec.rb +52 -0
  108. data/spec/adapter/win_ffi/radio_spec.rb +37 -0
  109. data/spec/adapter/win_ffi/select_list_spec.rb +66 -0
  110. data/spec/adapter/win_ffi/table_spec.rb +39 -0
  111. data/spec/adapter/win_ffi/text_field_spec.rb +23 -0
  112. data/spec/adapter/win_ffi/window_spec.rb +43 -0
  113. data/spec/button_spec.rb +68 -0
  114. data/spec/buttons_spec.rb +21 -0
  115. data/spec/spec_helper.rb +96 -0
  116. data/spec/text_field_spec.rb +65 -0
  117. data/spec/text_fields_spec.rb +22 -0
  118. data/spec/window_spec.rb +122 -0
  119. data/spec/windows_spec.rb +55 -0
  120. metadata +207 -0
@@ -0,0 +1,55 @@
1
+ module RAutomation
2
+ class Button
3
+ # @private
4
+ # This constructor is meant to be accessed only through {Window#button} method.
5
+ def initialize(window, locators)
6
+ @window = window
7
+ @locators = locators
8
+ @button = @window.button(@locators)
9
+ end
10
+
11
+ # Performs a click on the button.
12
+ # By default click is considered successful if the button doesn't exist after clicking (e.g. window has closed)
13
+ # @yield [button] optional block specifying successful clicking condition.
14
+ # @yieldparam [Button] button which is being clicked on.
15
+ # @yieldreturn [Boolean] true if clicking on the button is successful, false otherwise.
16
+ # @raise [UnknownButtonException] if the button doesn't exist.
17
+ def click
18
+ wait_until_exists
19
+ if block_given?
20
+ @button.click {yield self}
21
+ else
22
+ @button.click
23
+ end
24
+ end
25
+
26
+ # Retrieves the value (text) of the button, usually the visible text.
27
+ # @return [String] the value (text) of the button.
28
+ # @raise [UnknownButtonException] if the button doesn't exist.
29
+ def value
30
+ wait_until_exists
31
+ @button.value
32
+ end
33
+
34
+ # Checks if the button exists.
35
+ # @return [Boolean] true if button exists, false otherwise.
36
+ def exists?
37
+ @button.exists?
38
+ end
39
+
40
+ alias_method :exist?, :exists?
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
+
47
+ private
48
+
49
+ def wait_until_exists
50
+ WaitHelper.wait_until {exists?}
51
+ rescue WaitHelper::TimeoutError
52
+ raise UnknownButtonException, "Button #{@locators.inspect} doesn't exist on window #{@window.locators.inspect}!"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,47 @@
1
+ module RAutomation
2
+ # @private
3
+ module ElementCollections
4
+ # Creates collection classes and methods for elements.
5
+ # @param [Array<Symbol>] elements for which to create collection classes
6
+ # and methods.
7
+ def has_many(*elements)
8
+ elements.each do |element|
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(/(.*)::/).flatten.first
12
+ clazz = RAutomation.constants.include?(class_name) ? RAutomation : class_eval(adapter_class)
13
+ clazz.class_eval %Q{
14
+ class #{class_name_plural}
15
+ include Enumerable
16
+
17
+ def initialize(window, locators)
18
+ @window = window
19
+ @locators = locators
20
+ end
21
+
22
+ def each
23
+ i = -1
24
+ while true
25
+ args = [@window, @locators.merge(:index => i += 1)].compact
26
+ object = #{clazz}::#{class_name}.new(*args)
27
+ break unless object.exists?
28
+ yield object
29
+ end
30
+ end
31
+
32
+ def method_missing(name, *args)
33
+ ary = self.to_a
34
+ ary.respond_to?(name) ? ary.send(name, *args) : super
35
+ end
36
+ end
37
+ }
38
+
39
+ class_eval %Q{
40
+ def #{element}(locators = {})
41
+ #{class_name_plural}.new(@window, locators)
42
+ end
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,60 @@
1
+ module RAutomation
2
+ class TextField
3
+ # @private
4
+ # This constructor is meant to be accessed only through {Window#text_field} method.
5
+ def initialize(window, locators) #:nodoc:
6
+ @window = window
7
+ @locators = locators
8
+ @text_field = @window.text_field(@locators)
9
+ end
10
+
11
+ # Sets text of the text field.
12
+ # @param [String] text of the field to set.
13
+ # @raise [UnknownTextFieldException] if the text field doesn't exist.
14
+ def set(text)
15
+ wait_until_exists
16
+ @text_field.set(text)
17
+ end
18
+
19
+ # Clears text field's text.
20
+ # @raise [UnknownTextFieldException] if the text field doesn't exist.
21
+ def clear
22
+ wait_until_exists
23
+ @text_field.clear
24
+ end
25
+
26
+ # Returns text field's current value (text).
27
+ # @return [String] the value (text) of the text field.
28
+ # @raise [UnknownTextFieldException] if the text field doesn't exist.
29
+ def value
30
+ wait_until_exists
31
+ @text_field.value
32
+ end
33
+
34
+ # Checks if the text field exists.
35
+ # @return [Boolean] true if text field exists, false otherwise.
36
+ def exists?
37
+ @text_field.exists?
38
+ end
39
+
40
+ def hwnd
41
+ wait_until_exists
42
+ @text_field.hwnd
43
+ end
44
+
45
+ alias_method :exist?, :exists?
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
+
52
+ private
53
+
54
+ def wait_until_exists
55
+ WaitHelper.wait_until {exists?}
56
+ rescue WaitHelper::TimeoutError
57
+ raise UnknownTextFieldException, "Text field #{@locators.inspect} doesn't exist on window #{@window.locators.inspect}!" unless exists?
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ module RAutomation
2
+ # Waiting with timeout
3
+ module WaitHelper
4
+ extend self
5
+
6
+ class TimeoutError < StandardError
7
+ end
8
+
9
+ # @private
10
+ # Wait until the block evaluates to true or times out.
11
+ def wait_until(timeout = Window.wait_timeout, &block)
12
+ end_time = ::Time.now + timeout
13
+
14
+ until ::Time.now > end_time
15
+ result = yield(self)
16
+ return result if result
17
+ sleep 0.5
18
+ end
19
+
20
+ raise TimeoutError, "timed out after #{timeout} seconds"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,234 @@
1
+ module RAutomation
2
+ class UnknownElementException < RuntimeError
3
+ end
4
+ class UnknownWindowException < UnknownElementException
5
+ end
6
+ class UnknownButtonException < UnknownElementException
7
+ end
8
+ class UnknownTextFieldException < UnknownElementException
9
+ end
10
+
11
+ class Window
12
+ include Adapter::Helper
13
+ extend ElementCollections
14
+
15
+ has_many :windows, :buttons, :text_fields
16
+
17
+ class << self
18
+ # @return [Windows] all windows.
19
+ def windows
20
+ Windows.new(nil, {})
21
+ end
22
+ end
23
+
24
+ # Retrieves all windows with similar locators to the current window.
25
+ # @param locators (see #initialize)
26
+ # @return [Windows] all windows matching current window's _locators_ if no
27
+ # explicit locators specified or windows matching the specified _locators_.
28
+ def windows(locators = @window.locators)
29
+ Windows.new(nil, locators)
30
+ end
31
+
32
+ # Currently used {Adapter}.
33
+ attr_reader :adapter
34
+
35
+ # Creates the window object.
36
+ #
37
+ # Possible window _locators_ may depend of the used platform and adapter, but
38
+ # following examples will use :title, :class and :hwnd.
39
+ #
40
+ # @example Use window with some title:
41
+ # RAutomation::Window.new(:title => "some title")
42
+ #
43
+ # @example Use window with Regexp title:
44
+ # RAutomation::Window.new(:title => /some title/i)
45
+ #
46
+ # @example Use window with handle (hwnd):
47
+ # RAutomation::Window.new(:hwnd => 123456)
48
+ #
49
+ # @example Use multiple locators, every locator will be matched (AND-ed) to the window:
50
+ # RAutomation::Window.new(:title => "some title", :class => "IEFrame")
51
+ #
52
+ # @note Refer to all possible _locators_ in each {Adapter} documentation.
53
+ #
54
+ # _locators_ may also include a key called :adapter to change default adapter,
55
+ # which is dependent of the platform, to automate windows and their controls.
56
+ #
57
+ # It is also possible to change the default adapter by using environment variable called
58
+ # __RAUTOMATION_ADAPTER__
59
+ #
60
+ # @note This constructor doesn't check for window's existance.
61
+ # @note Only visible windows are supported.
62
+ # @note If given _locators_ include :hwnd then every other possible _locator_ is ignored.
63
+ # @param [Hash] locators locators for the window.
64
+ def initialize(locators)
65
+ @adapter = locators.delete(:adapter) || ENV["RAUTOMATION_ADAPTER"] && ENV["RAUTOMATION_ADAPTER"].to_sym || default_adapter
66
+ @window = Adapter.const_get(normalize(@adapter)).const_get(:Window).new(locators)
67
+ end
68
+
69
+ class << self
70
+ # Timeout for waiting until object exists. If the timeout exceeds then an {WaitHelper::TimeoutError} is raised.
71
+ @@wait_timeout = 60
72
+
73
+ # Change the timeout to wait before {WaitHelper::TimeoutError} is raised.
74
+ # @param [Fixnum] timeout in seconds.
75
+ def wait_timeout=(timeout)
76
+ @@wait_timeout = timeout
77
+ end
78
+
79
+ # Retrieve current timeout in seconds to wait before {WaitHelper::TimeoutError} is raised.
80
+ # @return [Fixnum] timeout in seconds
81
+ def wait_timeout
82
+ @@wait_timeout
83
+ end
84
+
85
+ end
86
+
87
+ # @return [Fixnum] handle of the window which is used internally for other methods.
88
+ # @raise [UnknownWindowException] if the window doesn't exist.
89
+ def hwnd
90
+ wait_until_present
91
+ @window.hwnd
92
+ end
93
+
94
+ # @return [Fixnum] process identifier (PID) of the window.
95
+ # @raise [UnknownWindowException] if the window doesn't exist.
96
+ def pid
97
+ wait_until_present
98
+ @window.pid
99
+ end
100
+
101
+ # @return [String] title of the window.
102
+ # @raise [UnknownWindowException] if the window doesn't exist.
103
+ def title
104
+ wait_until_present
105
+ @window.title
106
+ end
107
+
108
+ # Activates the Window, e.g. brings it to the top of other windows.
109
+ def activate
110
+ @window.activate
111
+ end
112
+
113
+ # Checks if the window is active, e.g. on the top of other windows.
114
+ # @return [Boolean] true if the window is active, false otherwise.
115
+ def active?
116
+ @window.active?
117
+ end
118
+
119
+ # Returns visible text of the Window.
120
+ # @return [String] visible text of the window.
121
+ # @raise [UnknownWindowException] if the window doesn't exist.
122
+ def text
123
+ wait_until_present
124
+ @window.text
125
+ end
126
+
127
+ # Checks if the window exists (does have to be visible).
128
+ # @return [Boolean] true if the window exists, false otherwise.
129
+ def exists?
130
+ @window.exists?
131
+ end
132
+
133
+ alias_method :exist?, :exists?
134
+
135
+ # Checks if window is visible.
136
+ # @note Window is also visible, if it is behind other windows or minimized.
137
+ # @return [Boolean] true if window is visible, false otherwise.
138
+ # @raise [UnknownWindowException] if the window doesn't exist.
139
+ def visible?
140
+ wait_until_exists
141
+ @window.visible?
142
+ end
143
+
144
+ # Checks if the window exists and is visible.
145
+ # @return [Boolean] true if window exists and is visible, false otherwise
146
+ def present?
147
+ exists? && visible?
148
+ end
149
+
150
+ # Maximizes the window.
151
+ # @raise [UnknownWindowException] if the window doesn't exist.
152
+ def maximize
153
+ wait_until_present
154
+ @window.maximize
155
+ end
156
+
157
+ # Minimizes the window.
158
+ # @raise [UnknownWindowException] if the window doesn't exist.
159
+ def minimize
160
+ wait_until_present
161
+ @window.minimize
162
+ end
163
+
164
+ # Checks if window is minimized.
165
+ # @return [Boolean] true if window is minimized, false otherwise.
166
+ # @raise [UnknownWindowException] if the window doesn't exist.
167
+ def minimized?
168
+ wait_until_present
169
+ @window.minimized?
170
+ end
171
+
172
+ # Restores the window size and position.
173
+ # @note If the window is minimized, makes it visible again.
174
+ # @raise [UnknownWindowException] if the window doesn't exist.
175
+ def restore
176
+ wait_until_present
177
+ @window.restore
178
+ end
179
+
180
+ # Sends keyboard keys to the window. Refer to specific {Adapter} documentation for all possible values.
181
+ # @raise [UnknownWindowException] if the window doesn't exist.
182
+ def send_keys(keys)
183
+ wait_until_present
184
+ @window.send_keys(keys)
185
+ end
186
+
187
+ # Closes the window if it exists.
188
+ def close
189
+ return unless @window.exists?
190
+ @window.close
191
+ end
192
+
193
+ # Retrieves {Button} on the window.
194
+ # @note Refer to specific {Adapter} documentation for possible _locator_ parameters.
195
+ # @param [Hash] locators for the {Button}.
196
+ # @raise [UnknownWindowException] if the window doesn't exist.
197
+ def button(locators)
198
+ wait_until_present
199
+ Button.new(@window, locators)
200
+ end
201
+
202
+ # Retrieves {TextField} on the window.
203
+ # @note Refer to specific {Adapter} documentation for possible _locators_ parameters.
204
+ # @raise [UnknownWindowException] if the window doesn't exist.
205
+ def text_field(locators)
206
+ wait_until_present
207
+ TextField.new(@window, locators)
208
+ end
209
+
210
+ # Allows to execute specific {Adapter} methods not part of the public API.
211
+ def method_missing(name, *args)
212
+ @window.send(name, *args)
213
+ end
214
+
215
+ private
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
+
223
+ def wait_until_exists
224
+ WaitHelper.wait_until {exists?}
225
+ rescue WaitHelper::TimeoutError
226
+ raise UnknownWindowException, "Window with locator #{@window.locators.inspect} doesn't exist!"
227
+ end
228
+
229
+ def normalize adapter
230
+ adapter.to_s.split("_").map {|word| word.capitalize}.join
231
+ end
232
+
233
+ end
234
+ end
@@ -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