rautomation 0.6.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|