rautomation 0.9.1 → 0.9.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d60457345affb72ade2ec56f93991a918cb39cd8
4
- data.tar.gz: d136c890f577984d093d2831aa6f19559a54a271
3
+ metadata.gz: 748478d3036c775c96382a911bccd9e8253ef1ac
4
+ data.tar.gz: e7bf598b813dd955fcbea0c2d50f143159a06380
5
5
  SHA512:
6
- metadata.gz: 562a850a9175f49764a49927a6dd86666afc248065a1c9cee6e4ba739702f613777f71fbb354074b071af979b60399d4d59abe61ed3ce283bc4e188f43b3d7ca
7
- data.tar.gz: a26f7646d7b025c58584906fc9808bd0eeca4321f3b3caf53f2a8fd4ab8e02b2fc50cb8b69976e6dbfb6e0438226aeaac30ba61ef584a7bfc9fa699b79490484
6
+ metadata.gz: b391f11900769761f78426e9ba26029b08cad3e2c68723ab32cf64026611697db96e6dfdefb93e875ecc21045ba24005b56ddfc53b56e4e7215ea389b1e8d256
7
+ data.tar.gz: 623f4f71ac5c00c18524a1bb151a5b80e2a86a3745253f6887ba85ff929acb70f1eec5662acc86b469895ffde75b64811cdfd973528ec64a900fd5ef7bd7a2c0
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rautomation (0.9.1)
4
+ rautomation (0.9.2)
5
5
  ffi
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  diff-lcs (1.1.3)
11
- ffi (1.7.0-x86-mingw32)
11
+ ffi (1.8.1-x86-mingw32)
12
12
  rake (0.9.2.2)
13
13
  rspec (2.8.0)
14
14
  rspec-core (~> 2.8.0)
@@ -18,7 +18,7 @@ GEM
18
18
  rspec-expectations (2.8.0)
19
19
  diff-lcs (~> 1.1.2)
20
20
  rspec-mocks (2.8.0)
21
- yard (0.8.3)
21
+ yard (0.8.6.1)
22
22
 
23
23
  PLATFORMS
24
24
  x86-mingw32
data/History.rdoc CHANGED
@@ -1,6 +1,23 @@
1
- == 0.9.1
1
+ == 0.9.2 / 2013-05-19
2
+
3
+ === Win32 adapter
4
+
5
+ * Window#send_keys supports now :dash, :slash and :backslash. Closes #64.
2
6
 
3
7
  === MsUia adapter
8
+
9
+ * Ability to get and set the text of a multi-line text control that only supports the TextPattern.
10
+ * Add some caching to speed up locating controls.
11
+ * Fix issue #67 that happens when clicking on controls.
12
+
13
+ === AutoIt adapter
14
+
15
+ * Add deprecation warning.
16
+
17
+ == 0.9.1 / 2013-04-26
18
+
19
+ === MsUia adapter
20
+
4
21
  * Ability to interact with controls that do not have native window handles (for example WPF applications).
5
22
 
6
23
  == 0.9.0 / 2013-04-22
data/Rakefile CHANGED
@@ -37,7 +37,7 @@ end
37
37
  task :build => "build:all"
38
38
 
39
39
  namespace :spec do
40
- adapters = %w[win_32 autoit ms_uia]
40
+ adapters = %w[win_32 ms_uia]
41
41
 
42
42
  adapters.each do |adapter|
43
43
  desc "Run RSpec code examples against #{adapter} adapter"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.1
1
+ 0.9.2
Binary file
@@ -0,0 +1,22 @@
1
+ #include "StdAfx.h"
2
+ #include "AutomatedText.h"
3
+
4
+ String^ AutomatedText::Text::get() {
5
+ if( IsValuePattern ) {
6
+ return Value;
7
+ } else {
8
+ return AsTextPattern->DocumentRange->GetText(-1);
9
+ }
10
+ }
11
+
12
+ void AutomatedText::Text::set(String^ value) {
13
+ if( IsValuePattern ) {
14
+ Value = value;
15
+ } else {
16
+ _control->SetFocus();
17
+ SendKeys::SendWait("^{HOME}"); // Move to start of control
18
+ SendKeys::SendWait("^+{END}"); // Select everything
19
+ SendKeys::SendWait("{DEL}"); // Delete selection
20
+ SendKeys::SendWait(value);
21
+ }
22
+ }
@@ -0,0 +1,26 @@
1
+ #pragma once
2
+
3
+ #include "automationcontrol.h"
4
+
5
+ using namespace System::Windows::Automation;
6
+ using namespace System::Windows::Forms;
7
+
8
+ ref class AutomatedText : public AutomationControl
9
+ {
10
+ public:
11
+ AutomatedText(const HWND windowHandle) : AutomationControl(windowHandle) {}
12
+ AutomatedText(const FindInformation& finderInformation) : AutomationControl(finderInformation) {}
13
+
14
+ property String^ Text {
15
+ String^ get();
16
+ void set(String^ value);
17
+ }
18
+
19
+ private:
20
+ property TextPattern^ AsTextPattern {
21
+ TextPattern^ get() {
22
+ return dynamic_cast<TextPattern^>(_control->GetCurrentPattern(TextPattern::Pattern));
23
+ }
24
+ }
25
+ };
26
+
@@ -1,14 +1,21 @@
1
1
  #include "StdAfx.h"
2
2
  #include "AutomationClicker.h"
3
3
 
4
- void AutomationClicker::Click() {
5
- if( CanInvoke() ) {
6
- return Invoke();
7
- } else if( CanToggle() ) {
8
- return Toggle();
9
- } else if( CanSelect() ) {
10
- return Select();
11
- }
4
+ bool AutomationClicker::Click() {
5
+ try {
6
+ if( CanInvoke() ) {
7
+ Invoke();
8
+ } else if( CanToggle() ) {
9
+ Toggle();
10
+ } else if( CanSelect() ) {
11
+ Select();
12
+ }
13
+
14
+ return true;
15
+ } catch(Exception^ e) {
16
+ Console::WriteLine("AutomationClicker::Click - {0}", e->Message);
17
+ return false;
18
+ }
12
19
 
13
20
  throw gcnew Exception(gcnew String("AutomationElement did not support the InvokePattern, TogglePattern or the SelectionItemPattern"));
14
21
  }
@@ -10,7 +10,7 @@ ref class AutomationClicker : AutomationControl
10
10
  public:
11
11
  AutomationClicker(const HWND windowHandle) : AutomationControl(windowHandle) {}
12
12
  AutomationClicker(const FindInformation& findInformation) : AutomationControl(findInformation) {}
13
- void Click();
13
+ bool Click();
14
14
  void MouseClick();
15
15
 
16
16
  private:
@@ -25,4 +25,12 @@ void AutomationControl::Value::set(String^ value) {
25
25
 
26
26
  String^ AutomationControl::Value::get() {
27
27
  return AsValuePattern->Current.Value;
28
+ }
29
+
30
+ bool AutomationControl::IsValuePattern::get() {
31
+ try {
32
+ return nullptr != AsValuePattern;
33
+ } catch(Exception^ e) {
34
+ return false;
35
+ }
28
36
  }
@@ -51,6 +51,10 @@ public:
51
51
  bool get() { return nullptr != _control; }
52
52
  }
53
53
 
54
+ property bool IsValuePattern {
55
+ bool get();
56
+ }
57
+
54
58
  protected:
55
59
  AutomationElement^ _control;
56
60
 
@@ -0,0 +1,23 @@
1
+ #include "stdafx.h"
2
+ #include "AutomatedText.h"
3
+ #include "StringHelper.h"
4
+
5
+ extern "C" {
6
+ __declspec ( dllexport ) void Text_GetValue(const FindInformation& findInformation, char* theValue, const int maximumLength) {
7
+ try {
8
+ auto control = gcnew AutomatedText(findInformation);
9
+ StringHelper::CopyToUnmanagedString(control->Text, theValue, maximumLength);
10
+ } catch(Exception^ e) {
11
+ Console::WriteLine("Text_GetValue: {0}", e->Message);
12
+ }
13
+ }
14
+
15
+ __declspec ( dllexport ) void Text_SetValue(const FindInformation& findInformation, const char* theValue) {
16
+ try {
17
+ auto control = gcnew AutomatedText(findInformation);
18
+ control->Text = gcnew String(theValue);
19
+ } catch(Exception^ e) {
20
+ Console::WriteLine("Text_SetValue: {0}", e->Message);
21
+ }
22
+ }
23
+ }
@@ -19,6 +19,11 @@ extern "C" {
19
19
  return automationElement->Exists;
20
20
  }
21
21
 
22
+ __declspec ( dllexport ) int NativeWindowHandle(const FindInformation& findInformation) {
23
+ auto automationElement = gcnew AutomationControl(findInformation);
24
+ return automationElement->Exists ? automationElement->Element->Current.NativeWindowHandle : 0;
25
+ }
26
+
22
27
  __declspec ( dllexport ) int BoundingRectangle(const FindInformation& findInformation, long *rectangle) {
23
28
  try {
24
29
  auto automationElement = gcnew AutomationControl(findInformation);
@@ -312,13 +317,14 @@ extern "C" {
312
317
  return 1;
313
318
  }
314
319
 
315
- __declspec ( dllexport ) void RA_Click(const FindInformation& findInformation, char* errorInfo, const int errorInfoSize) {
320
+ __declspec ( dllexport ) bool RA_Click(const FindInformation& findInformation, char* errorInfo, const int errorInfoSize) {
316
321
  try {
317
322
  auto automationClicker = gcnew AutomationClicker(findInformation);
318
- automationClicker->Click();
323
+ return automationClicker->Click();
319
324
  } catch(Exception^ e) {
320
325
  if( errorInfo ) {
321
326
  StringHelper::CopyToUnmanagedString(e->ToString(), errorInfo, errorInfoSize);
327
+ return false;
322
328
  }
323
329
  }
324
330
  }
@@ -92,6 +92,7 @@
92
92
  <ClInclude Include="Stdafx.h" />
93
93
  <ClInclude Include="StringHelper.h" />
94
94
  <ClInclude Include="targetver.h" />
95
+ <ClInclude Include="AutomatedText.h" />
95
96
  <ClInclude Include="Toggle.h" />
96
97
  <ClInclude Include="UiaDll.h" />
97
98
  </ItemGroup>
@@ -116,6 +117,8 @@
116
117
  <ClCompile Include="StringHelper.cpp" />
117
118
  <ClCompile Include="StringMethods.cpp" />
118
119
  <ClCompile Include="TableMethods.cpp" />
120
+ <ClCompile Include="AutomatedText.cpp" />
121
+ <ClCompile Include="TextMethods.cpp" />
119
122
  <ClCompile Include="Toggle.cpp" />
120
123
  <ClCompile Include="UiaDll.cpp" />
121
124
  </ItemGroup>
@@ -49,6 +49,12 @@
49
49
  <Filter Include="Header Files\Control">
50
50
  <UniqueIdentifier>{90616ecb-ce19-48d6-88ac-a38a46e42687}</UniqueIdentifier>
51
51
  </Filter>
52
+ <Filter Include="Source Files\Text">
53
+ <UniqueIdentifier>{15a04b2b-04c7-44f4-8fdb-d83019eb3917}</UniqueIdentifier>
54
+ </Filter>
55
+ <Filter Include="Header Files\Text">
56
+ <UniqueIdentifier>{3b3c2b83-e423-4619-991a-ffd7f324ae62}</UniqueIdentifier>
57
+ </Filter>
52
58
  </ItemGroup>
53
59
  <ItemGroup>
54
60
  <ClInclude Include="UiaDll.h">
@@ -96,6 +102,9 @@
96
102
  <ClInclude Include="SelectionItem.h">
97
103
  <Filter>Header Files</Filter>
98
104
  </ClInclude>
105
+ <ClInclude Include="AutomatedText.h">
106
+ <Filter>Header Files\Text</Filter>
107
+ </ClInclude>
99
108
  </ItemGroup>
100
109
  <ItemGroup>
101
110
  <ClCompile Include="UiaDll.cpp">
@@ -155,6 +164,12 @@
155
164
  <ClCompile Include="SelectionItem.cpp">
156
165
  <Filter>Source Files</Filter>
157
166
  </ClCompile>
167
+ <ClCompile Include="TextMethods.cpp">
168
+ <Filter>Source Files\Text</Filter>
169
+ </ClCompile>
170
+ <ClCompile Include="AutomatedText.cpp">
171
+ <Filter>Source Files\Text</Filter>
172
+ </ClCompile>
158
173
  </ItemGroup>
159
174
  <ItemGroup>
160
175
  <None Include="ReadMe.txt" />
@@ -1,3 +1,5 @@
1
+ Kernel.warn "[WARN] RAutomation AutoIt adapter is DEPRECATED and will be removed in the future!"
2
+
1
3
  require "win32ole"
2
4
  require File.dirname(__FILE__) + "/autoit/locators"
3
5
  require File.dirname(__FILE__) + "/autoit/button"
@@ -19,6 +19,11 @@ module RAutomation
19
19
  extract(locators)
20
20
  end
21
21
 
22
+ def cached_hwnd
23
+ @cached_hwnd ||= UiaDll::cached_hwnd(UiaDll::SearchCriteria.from_locator(@window.hwnd, @locators))
24
+ @cached_hwnd == 0 ? nil : @cached_hwnd
25
+ end
26
+
22
27
  #todo - replace with UIA version
23
28
  def hwnd
24
29
  Functions.control_hwnd(@window.hwnd, @locators)
@@ -26,10 +31,11 @@ module RAutomation
26
31
 
27
32
  def search_information
28
33
  info = UiaDll::SearchCriteria.from_locator(@window.hwnd, @locators)
29
- if info.how == 0
34
+ if info.how == 0 || cached_hwnd
30
35
  info.how = :hwnd
31
- info.data = hwnd
36
+ info.data = cached_hwnd || hwnd
32
37
  end
38
+
33
39
  info
34
40
  end
35
41
 
@@ -12,7 +12,7 @@ module RAutomation
12
12
  # @see RAutomation::TextField#set
13
13
  def set(text)
14
14
  raise "Cannot set value on a disabled text field" if disabled?
15
- UiaDll::set_control_value(search_information, text)
15
+ UiaDll::set_text(search_information, text)
16
16
  end
17
17
 
18
18
  # @see RAutomation::TextField#clear
@@ -24,7 +24,7 @@ module RAutomation
24
24
  #todo - replace with UIA version
25
25
  # @see RAutomation::TextField#value
26
26
  def value
27
- UiaDll::get_control_value(search_information)
27
+ UiaDll::get_text(search_information)
28
28
  end
29
29
 
30
30
  def exist?
@@ -102,10 +102,13 @@ module RAutomation
102
102
  ffi_convention :stdcall
103
103
 
104
104
  # Generic Control methods
105
+ attach_function :cached_hwnd, :NativeWindowHandle, [SearchCriteria.by_ref], :long
105
106
  attach_function :ElementExists, [SearchCriteria.by_ref], :bool
106
107
  attach_function :process_id, :ProcessId, [SearchCriteria.by_ref], :int
107
108
  attach_function :Control_GetValue, [SearchCriteria.by_ref, :pointer, :int], :void
108
109
  attach_function :set_control_value, :Control_SetValue, [SearchCriteria.by_ref, :string], :void
110
+ attach_function :Text_GetValue, [SearchCriteria.by_ref, :pointer, :int], :void
111
+ attach_function :set_text, :Text_SetValue, [SearchCriteria.by_ref, :string], :void
109
112
  attach_function :BoundingRectangle, [SearchCriteria.by_ref, :pointer], :int
110
113
  attach_function :current_control_type, :ControlType, [SearchCriteria.by_ref], :int
111
114
  attach_function :Name, [SearchCriteria.by_ref, :pointer, :int], :void
@@ -130,6 +133,10 @@ module RAutomation
130
133
  string_from(:Control_GetValue, search_information)
131
134
  end
132
135
 
136
+ def self.get_text(search_information)
137
+ string_from(:Text_GetValue, search_information)
138
+ end
139
+
133
140
  def self.name(search_information)
134
141
  string_from(:Name, search_information)
135
142
  end
@@ -260,7 +267,7 @@ module RAutomation
260
267
  attach_function :collapse_by_index, :RA_CollapseItemByIndex,
261
268
  [SearchCriteria.by_ref, :int], :void
262
269
  attach_function :RA_Click,
263
- [SearchCriteria.by_ref, :pointer, :int], :void
270
+ [SearchCriteria.by_ref, :pointer, :int], :bool
264
271
  attach_function :control_mouse_click, :RA_PointAndClick,
265
272
  [:long, :pointer, :int], :void
266
273
 
@@ -286,10 +293,10 @@ module RAutomation
286
293
 
287
294
  def self.can_throw(method, *args)
288
295
  string_buffer = FFI::MemoryPointer.new :char, 1024
289
- send method, *(args << string_buffer << 1024)
296
+ result = send method, *(args << string_buffer << 1024)
290
297
  error_info = string_buffer.read_string
291
298
  raise error_info unless error_info.empty?
292
- true
299
+ result
293
300
  end
294
301
  end
295
302
  end
@@ -68,6 +68,9 @@ module RAutomation
68
68
  :f10 => 0x79,
69
69
  :f11 => 0x7A,
70
70
  :f12 => 0x7B,
71
+ :dash => 0xBD,
72
+ :slash => 0x6F,
73
+ :backslash => 0xDC
71
74
  }
72
75
 
73
76
  SPECIAL_KEYS = {
@@ -1,6 +1,5 @@
1
1
  require "spec_helper"
2
2
 
3
-
4
3
  describe "MsUia::Control", :if => SpecHelper.adapter == :ms_uia do
5
4
 
6
5
  it "control coordinates", :special => false do
@@ -25,4 +24,45 @@ describe "MsUia::Control", :if => SpecHelper.adapter == :ms_uia do
25
24
  control.control_class.should =~ /WindowsForms10.BUTTON.app.0.2bf8098_r1[0-9]_ad1/
26
25
  end
27
26
 
27
+ context RAutomation::Adapter::MsUia::UiaDll::SearchCriteria, :pure_unit => true do
28
+ let(:window) { double('RAutomation Window').as_null_object }
29
+ let(:locator) { {:id => 'someId'} }
30
+ let(:control) { RAutomation::Adapter::MsUia::Control.new(window, locator) }
31
+ let(:old_style_control) { RAutomation::Adapter::MsUia::Control.new(window, :class => 'someClass') }
32
+ let(:expect_a_handle) { RAutomation::Adapter::MsUia::UiaDll.should_receive(:cached_hwnd).once.and_return(456) }
33
+ let(:expect_no_handle) { RAutomation::Adapter::MsUia::UiaDll.should_receive(:cached_hwnd).once.and_return(0) }
34
+ subject { control.search_information }
35
+
36
+ before(:each) do
37
+ window.should_receive(:hwnd).at_least(:once).and_return(123)
38
+ RAutomation::Adapter::MsUia::Functions.stub(:control_hwnd)
39
+ end
40
+
41
+ it "uses the cached window handle if it has one" do
42
+ expect_a_handle
43
+ subject.how.should eq(:hwnd)
44
+ subject.data.should eq(456)
45
+ end
46
+
47
+ it "only asks for the window handle once" do
48
+ expect_a_handle
49
+ 2.times { control.search_information }
50
+ end
51
+
52
+ it "uses the locator specified when no window handle is present" do
53
+ expect_no_handle
54
+ subject.how.should eq(:id)
55
+ subject.data.should eq('someId')
56
+ end
57
+
58
+ it "tries the old way of locating the window handle if no UIA locator is provided" do
59
+ expect_no_handle
60
+ RAutomation::Adapter::MsUia::Functions.should_receive(:control_hwnd).with(window.hwnd, :index => 0, :class => 'someClass').and_return(789)
61
+ old_info = old_style_control.search_information
62
+ old_info.how.should eq(:hwnd)
63
+ old_info.data.should eq(789)
64
+ end
65
+
66
+ end
67
+
28
68
  end
@@ -28,4 +28,16 @@ describe "MsUia::TextField", :if => SpecHelper.adapter == :ms_uia do
28
28
  main_form.text_field(:id => "multiLineTextField").should exist
29
29
  end
30
30
 
31
+ it "can set the value of a multi line text field" do
32
+ text_field = main_form.text_field(:id => "multiLineTextField")
33
+
34
+ # initial
35
+ text_field.set "some dater'"
36
+ text_field.value.should eq("some dater'")
37
+
38
+ # overwrite
39
+ text_field.set "overwrite with this dater'"
40
+ text_field.value.should eq("overwrite with this dater'")
41
+ end
42
+
31
43
  end
data/spec/spec_helper.rb CHANGED
@@ -109,8 +109,10 @@ RSpec.configure do |config|
109
109
  config.before(:each) do
110
110
  RAutomation::Window.wait_timeout = 15
111
111
 
112
- @pid1 = IO.popen(SpecHelper::DATA[:window1]).pid
113
- RAutomation::WaitHelper.wait_until {RAutomation::Window.new(:pid => @pid1).present?}
112
+ unless example.metadata[:pure_unit]
113
+ @pid1 = IO.popen(SpecHelper::DATA[:window1]).pid
114
+ RAutomation::WaitHelper.wait_until { RAutomation::Window.new(:pid => @pid1).present? }
115
+ end
114
116
  end
115
117
 
116
118
  config.after(:each) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rautomation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarmo Pertman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-26 00:00:00.000000000 Z
11
+ date: 2013-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -111,6 +111,8 @@ files:
111
111
  - ext/UiaDll/UiaDll/AutomatedSelectList.h
112
112
  - ext/UiaDll/UiaDll/AutomatedTable.cpp
113
113
  - ext/UiaDll/UiaDll/AutomatedTable.h
114
+ - ext/UiaDll/UiaDll/AutomatedText.cpp
115
+ - ext/UiaDll/UiaDll/AutomatedText.h
114
116
  - ext/UiaDll/UiaDll/AutomationClicker.cpp
115
117
  - ext/UiaDll/UiaDll/AutomationClicker.h
116
118
  - ext/UiaDll/UiaDll/AutomationControl.cpp
@@ -131,6 +133,7 @@ files:
131
133
  - ext/UiaDll/UiaDll/StringHelper.h
132
134
  - ext/UiaDll/UiaDll/StringMethods.cpp
133
135
  - ext/UiaDll/UiaDll/TableMethods.cpp
136
+ - ext/UiaDll/UiaDll/TextMethods.cpp
134
137
  - ext/UiaDll/UiaDll/Toggle.cpp
135
138
  - ext/UiaDll/UiaDll/Toggle.h
136
139
  - ext/UiaDll/UiaDll/ToggleStateHelper.h