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.
- data/.gitignore +34 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +24 -0
- data/History.rdoc +21 -0
- data/LICENSE +1 -1
- data/README.rdoc +8 -7
- data/Rakefile +22 -32
- data/VERSION +1 -1
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UiaDll.suo +0 -0
- data/ext/UiaDll/UiaDll/UiaDll.cpp +236 -10
- data/lib/rautomation/adapter/autoit/locators.rb +1 -1
- data/lib/rautomation/adapter/autoit/text_field.rb +10 -1
- data/lib/rautomation/adapter/autoit/window.rb +50 -23
- data/lib/rautomation/adapter/helper.rb +6 -6
- data/lib/rautomation/adapter/ms_uia.rb +22 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/button.rb +3 -2
- data/lib/rautomation/adapter/ms_uia/button_helper.rb +25 -0
- data/lib/rautomation/adapter/ms_uia/checkbox.rb +27 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/constants.rb +20 -5
- data/lib/rautomation/adapter/ms_uia/control.rb +180 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/functions.rb +24 -26
- data/lib/rautomation/adapter/ms_uia/keystroke_converter.rb +122 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/label.rb +3 -2
- data/lib/rautomation/adapter/ms_uia/list_box.rb +91 -0
- data/lib/rautomation/adapter/ms_uia/list_item.rb +49 -0
- data/lib/rautomation/adapter/ms_uia/locators.rb +23 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/radio.rb +2 -2
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/select_list.rb +41 -7
- data/lib/rautomation/adapter/ms_uia/table.rb +86 -0
- data/lib/rautomation/adapter/{win_ffi → ms_uia}/text_field.rb +5 -4
- data/lib/rautomation/adapter/ms_uia/uia_dll.rb +62 -0
- data/lib/rautomation/adapter/ms_uia/window.rb +364 -0
- data/lib/rautomation/adapter/win_32.rb +21 -0
- data/lib/rautomation/adapter/win_32/button.rb +14 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/button_helper.rb +1 -1
- data/lib/rautomation/adapter/win_32/checkbox.rb +14 -0
- data/lib/rautomation/adapter/win_32/constants.rb +68 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/control.rb +30 -23
- data/lib/rautomation/adapter/win_32/functions.rb +313 -0
- data/lib/rautomation/adapter/win_32/keys.rb +121 -0
- data/lib/rautomation/adapter/win_32/label.rb +10 -0
- data/lib/rautomation/adapter/win_32/list_box.rb +40 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/locators.rb +2 -2
- data/lib/rautomation/adapter/win_32/radio.rb +11 -0
- data/lib/rautomation/adapter/win_32/select_list.rb +97 -0
- data/lib/rautomation/adapter/win_32/table.rb +22 -0
- data/lib/rautomation/adapter/win_32/text_field.rb +42 -0
- data/lib/rautomation/adapter/{win_ffi → win_32}/window.rb +79 -62
- data/lib/rautomation/element_collections.rb +9 -1
- data/lib/rautomation/window.rb +17 -9
- data/rautomation.gemspec +24 -0
- data/spec/adapter/autoit/window_spec.rb +71 -0
- data/spec/adapter/{win_ffi → ms_uia}/button_spec.rb +1 -1
- data/spec/adapter/{win_ffi → ms_uia}/checkbox_spec.rb +9 -3
- data/spec/adapter/ms_uia/control_spec.rb +28 -0
- data/spec/adapter/ms_uia/keystroke_converter_spec.rb +50 -0
- data/spec/adapter/{win_ffi → ms_uia}/label_spec.rb +2 -2
- data/spec/adapter/ms_uia/list_item_spec.rb +14 -0
- data/spec/adapter/{win_ffi → ms_uia}/listbox_spec.rb +18 -5
- data/spec/adapter/{win_ffi → ms_uia}/radio_spec.rb +3 -1
- data/spec/adapter/ms_uia/select_list_spec.rb +109 -0
- data/spec/adapter/{win_ffi → ms_uia}/table_spec.rb +12 -1
- data/spec/adapter/{win_ffi → ms_uia}/text_field_spec.rb +2 -1
- data/spec/adapter/ms_uia/window_spec.rb +89 -0
- data/spec/adapter/win_32/button_spec.rb +30 -0
- data/spec/adapter/win_32/checkbox_spec.rb +48 -0
- data/spec/adapter/win_32/label_spec.rb +15 -0
- data/spec/adapter/win_32/listbox_spec.rb +42 -0
- data/spec/adapter/win_32/radio_spec.rb +32 -0
- data/spec/adapter/{win_ffi → win_32}/select_list_spec.rb +16 -16
- data/spec/adapter/win_32/table_spec.rb +28 -0
- data/spec/adapter/win_32/text_field_spec.rb +24 -0
- data/spec/adapter/{win_ffi → win_32}/window_spec.rb +19 -14
- data/spec/button_spec.rb +1 -0
- data/spec/buttons_spec.rb +4 -4
- data/spec/spec_helper.rb +30 -4
- data/spec/text_field_spec.rb +6 -7
- data/spec/window_spec.rb +12 -0
- data/spec/windows_spec.rb +19 -0
- metadata +116 -97
- data/lib/rautomation/adapter/win_ffi.rb +0 -21
- data/lib/rautomation/adapter/win_ffi/checkbox.rb +0 -19
- data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +0 -67
- data/lib/rautomation/adapter/win_ffi/list_box.rb +0 -60
- data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +0 -36
- data/lib/rautomation/adapter/win_ffi/table.rb +0 -57
- 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
|