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
@@ -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