rautomation 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,21 +0,0 @@
1
- begin
2
- gem "ffi"
3
- rescue Gem::LoadError
4
- raise Gem::LoadError, "Unable to load FFI gem. Install it with:\n\tgem install ffi"
5
- end
6
- require "ffi"
7
- require File.dirname(__FILE__) + "/win_ffi/constants"
8
- require File.dirname(__FILE__) + "/win_ffi/keystroke_converter"
9
- require File.dirname(__FILE__) + "/win_ffi/functions"
10
- require File.dirname(__FILE__) + "/win_ffi/locators"
11
- require File.dirname(__FILE__) + "/win_ffi/window"
12
- require File.dirname(__FILE__) + "/win_ffi/button_helper"
13
- require File.dirname(__FILE__) + "/win_ffi/control"
14
- require File.dirname(__FILE__) + "/win_ffi/button"
15
- require File.dirname(__FILE__) + "/win_ffi/checkbox"
16
- require File.dirname(__FILE__) + "/win_ffi/radio"
17
- require File.dirname(__FILE__) + "/win_ffi/text_field"
18
- require File.dirname(__FILE__) + "/win_ffi/select_list"
19
- require File.dirname(__FILE__) + "/win_ffi/table"
20
- require File.dirname(__FILE__) + "/win_ffi/label"
21
- require File.dirname(__FILE__) + "/win_ffi/list_box"
@@ -1,19 +0,0 @@
1
- module RAutomation
2
- module Adapter
3
- module WinFfi
4
- class Checkbox < Control
5
- include WaitHelper
6
- include Locators
7
- include ButtonHelper
8
-
9
-
10
- def exist?
11
- @locators[:id].nil? ? super : super && matches_type(Constants::UIA_CHECKBOX_CONTROL_TYPE)
12
- end
13
-
14
- alias_method :exists?, :exist?
15
-
16
- end
17
- end
18
- end
19
- end
@@ -1,67 +0,0 @@
1
- module RAutomation
2
- module Adapter
3
- module WinFfi
4
- class KeystrokeConverter
5
- class << self
6
- def convert(str)
7
- special_characters = ""
8
-
9
- str.split(/([{}])/).inject([]) do |converted_keys, str|
10
- if str == "}"
11
- converted_keys << convert_special_characters(special_characters << str)
12
- special_characters = ""
13
- elsif str == "{" || !special_characters.empty?
14
- special_characters << str
15
- else
16
- converted_keys += convert_characters(str)
17
- end
18
- converted_keys
19
- end.flatten
20
- end
21
-
22
- private
23
-
24
- def convert_special_characters chars
25
- case chars.downcase
26
- when "{tab}"
27
- Constants::VK_TAB
28
- when "{backspace}"
29
- Constants::VK_BACK
30
- when "{enter}"
31
- Constants::VK_RETURN
32
- when "{left}"
33
- Constants::VK_LEFT
34
- when "{right}"
35
- Constants::VK_RIGHT
36
- when "{down}"
37
- Constants::VK_DOWN
38
- when "{up}"
39
- Constants::VK_UP
40
- else
41
- # unsupported special tag, ignore the tag itself, but convert the
42
- # characters inside the tag
43
- convert_characters(chars.gsub(/[{}]/, ""))
44
- end
45
- end
46
-
47
- private
48
-
49
- def convert_characters(element)
50
- element.split(//).inject([]) do |chars, char|
51
- char_code = char.upcase.unpack("c")[0]
52
- if char =~ /[A-Z]/
53
- chars += in_upcase(char_code)
54
- else
55
- chars << char_code
56
- end
57
- end
58
- end
59
-
60
- def in_upcase(char_code)
61
- [Constants::VK_LSHIFT, char_code]
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,60 +0,0 @@
1
- module RAutomation
2
- module Adapter
3
- module WinFfi
4
-
5
- class ListBox < Control
6
- include WaitHelper
7
- include Locators
8
-
9
- def count
10
- UiaDll::find_children(uia_control(@locators[:id]), nil)
11
- end
12
-
13
- def items
14
- list_items = []
15
- children = FFI::MemoryPointer.new :pointer, self.count
16
- length = UiaDll::find_children(uia_control(@locators[:id]), children)
17
- children.read_array_of_pointer(length).each do |child|
18
- child_name = FFI::MemoryPointer.new :char, UiaDll::get_name(child, nil) + 1
19
- UiaDll::get_name(child, child_name)
20
- list_items.push child_name.read_string
21
- end
22
- list_items
23
- end
24
-
25
- def exist?
26
- @locators[:id].nil? ? super : super && matches_type(Constants::UIA_LIST_CONTROL_TYPE)
27
- end
28
-
29
- alias_method :exists?, :exist?
30
-
31
- def selected?(index)
32
- children = FFI::MemoryPointer.new :pointer, self.count
33
- length = UiaDll::find_children(uia_control(@locators[:id]), children)
34
- target_element = children.read_array_of_pointer(length)[index]
35
- is_selected = FFI::MemoryPointer.new :int, 1
36
-
37
- if UiaDll::get_is_selected(target_element, is_selected) == 1
38
- return is_selected.read_int == 1
39
- else
40
- return false
41
- end
42
- end
43
-
44
- def select(index)
45
- children = FFI::MemoryPointer.new :pointer, self.count
46
-
47
- length = UiaDll::find_children(uia_control(@locators[:id]), children)
48
- target_element = children.read_array_of_pointer(length)[index]
49
-
50
- UiaDll::select(target_element)
51
- end
52
-
53
- alias_method :strings, :items
54
-
55
-
56
- end
57
- end
58
- end
59
- end
60
-
@@ -1,36 +0,0 @@
1
- module RAutomation
2
- module Adapter
3
- module WinFfi
4
- # @private
5
- module UiaDll
6
- extend FFI::Library
7
-
8
- ffi_lib File.dirname(__FILE__) + '/../../../../../ext/UiaDll/Release/UiaDll.dll'
9
- ffi_convention :stdcall
10
-
11
- attach_function :find_window, :RA_FindWindow,
12
- [:string], :pointer
13
- attach_function :is_offscreen, :RA_IsOffscreen,
14
- [:pointer], :bool
15
- attach_function :element_from_handle, :RA_ElementFromHandle,
16
- [:long], :pointer
17
- attach_function :find_child_by_id, :RA_FindChildById,
18
- [:pointer, :string], :pointer
19
- attach_function :current_native_window_handle, :RA_CurrentNativeWindowHandle,
20
- [:pointer], :long
21
- attach_function :set_focus, :RA_SetFocus,
22
- [:pointer], :bool
23
- attach_function :current_control_type, :RA_GetCurrentControlType,
24
- [:pointer], :int
25
- attach_function :find_children, :RA_FindChildren,
26
- [:pointer, :pointer], :int
27
- attach_function :get_name, :RA_GetName,
28
- [:pointer, :pointer], :int
29
- attach_function :get_is_selected, :RA_GetIsSelected,
30
- [:pointer, :pointer], :int
31
- attach_function :select, :RA_Select,
32
- [:pointer], :int
33
- end
34
- end
35
- end
36
- end
@@ -1,57 +0,0 @@
1
- module RAutomation
2
- module Adapter
3
- module WinFfi
4
- class Table < Control
5
- include WaitHelper
6
- include Locators
7
-
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
42
-
43
- def row_count
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)
51
- end
52
-
53
-
54
- end
55
- end
56
- end
57
- end
@@ -1,47 +0,0 @@
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