rautomation 0.3.0 → 0.4.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/History.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ === Version 0.4.0 / 2010-12-23
2
+
3
+ * allow to search windows without text (like empty Notepad window for example).
4
+ * added possibility to use block for #click to specify successful clicking condition.
5
+ * renamed :ffi adapter to :win_ffi because FFI may be used on other platforms too.
6
+
1
7
  === Version 0.3.0 / 2010-12-18
2
8
 
3
9
  * added Ffi adapter specific method Window#child which searches for child windows and popups
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
File without changes
@@ -27,7 +27,7 @@ module RAutomation
27
27
  extract(locators)
28
28
  end
29
29
 
30
- # @see RAutomation::Button#click
30
+ # @see RAutomation::Button#click
31
31
  def click
32
32
  clicked = false
33
33
  wait_until do
@@ -37,7 +37,7 @@ module RAutomation
37
37
  Window.autoit.ControlClick(@window.locator_hwnd, "", @locators) == 1 &&
38
38
  clicked = true # is clicked at least once
39
39
 
40
- clicked && !exists?
40
+ block_given? ? yield : clicked && !exists?
41
41
  end
42
42
  end
43
43
 
@@ -53,4 +53,4 @@ module RAutomation
53
53
  end
54
54
  end
55
55
  end
56
- end
56
+ end
@@ -51,11 +51,11 @@ module RAutomation
51
51
  end
52
52
 
53
53
  # Retrieves handle of the window.
54
- # @note Searches only for visible windows with having some text at all.
54
+ # @note Searches only for visible windows.
55
55
  # @see RAutomation::Window#hwnd
56
56
  def hwnd
57
57
  @hwnd ||= @@autoit.WinList(@locators, @locator_text).pop.compact.
58
- find {|handle| w = self.class.new(:hwnd => handle.hex); w.visible? && !w.text.empty?}.
58
+ find {|handle| self.class.new(:hwnd => handle.hex).visible?}.
59
59
  hex rescue nil
60
60
  end
61
61
 
@@ -165,4 +165,4 @@ module RAutomation
165
165
  end
166
166
  end
167
167
  end
168
- end
168
+ end
@@ -1,7 +1,7 @@
1
1
  module RAutomation
2
2
  module Adapter
3
3
  autoload :Autoit, File.dirname(__FILE__) + "/autoit.rb"
4
- autoload :Ffi, File.dirname(__FILE__) + "/ffi.rb"
4
+ autoload :WinFfi, File.dirname(__FILE__) + "/win_ffi.rb"
5
5
 
6
6
  module Helper
7
7
  extend self
@@ -11,7 +11,7 @@ module RAutomation
11
11
  def default_adapter
12
12
  case RUBY_PLATFORM
13
13
  when /mswin|msys|mingw32/
14
- :ffi
14
+ :win_ffi
15
15
  else
16
16
  raise "unsupported platform for RAutomation: #{RUBY_PLATFORM}"
17
17
  end
@@ -0,0 +1,12 @@
1
+ begin
2
+ gem "ffi", "0.6.3"
3
+ rescue Gem::LoadError
4
+ raise Gem::LoadError, "Unable to load FFI gem. Install it with:\n\tgem install ffi -v 0.6.3"
5
+ end
6
+ require "ffi"
7
+ require File.dirname(__FILE__) + "/win_ffi/constants"
8
+ require File.dirname(__FILE__) + "/win_ffi/functions"
9
+ require File.dirname(__FILE__) + "/win_ffi/locators"
10
+ require File.dirname(__FILE__) + "/win_ffi/window"
11
+ require File.dirname(__FILE__) + "/win_ffi/button"
12
+ require File.dirname(__FILE__) + "/win_ffi/text_field"
@@ -1,6 +1,6 @@
1
1
  module RAutomation
2
2
  module Adapter
3
- module Ffi
3
+ module WinFfi
4
4
  class Button
5
5
  include WaitHelper
6
6
  include Locators
@@ -29,7 +29,8 @@ module RAutomation
29
29
  Functions.set_control_focus(hwnd) &&
30
30
  Functions.control_click(hwnd) &&
31
31
  clicked = true # is clicked at least once
32
- clicked && !exists?
32
+
33
+ block_given? ? yield : clicked && !exists?
33
34
  end
34
35
  end
35
36
 
@@ -46,4 +47,4 @@ module RAutomation
46
47
  end
47
48
  end
48
49
  end
49
- end
50
+ end
@@ -1,6 +1,6 @@
1
1
  module RAutomation
2
2
  module Adapter
3
- module Ffi
3
+ module WinFfi
4
4
  # @private
5
5
  module Constants
6
6
  WM_GETTEXT = 0xD
@@ -1,6 +1,6 @@
1
1
  module RAutomation
2
2
  module Adapter
3
- module Ffi
3
+ module WinFfi
4
4
  # @private
5
5
  module Functions
6
6
  extend FFI::Library
@@ -90,8 +90,7 @@ module RAutomation
90
90
 
91
91
  def window_hwnd(locators)
92
92
  find_hwnd(locators) do |hwnd|
93
- window_visible(hwnd) && !window_text(hwnd).empty? &&
94
- locators_match?(locators, window_properties(hwnd, locators))
93
+ window_visible(hwnd) && locators_match?(locators, window_properties(hwnd, locators))
95
94
  end
96
95
  end
97
96
 
@@ -246,4 +245,4 @@ module RAutomation
246
245
  end
247
246
  end
248
247
  end
249
- end
248
+ end
@@ -1,6 +1,6 @@
1
1
  module RAutomation
2
2
  module Adapter
3
- module Ffi
3
+ module WinFfi
4
4
  # @private
5
5
  module Locators
6
6
 
@@ -1,6 +1,6 @@
1
1
  module RAutomation
2
2
  module Adapter
3
- module Ffi
3
+ module WinFfi
4
4
  class TextField
5
5
  include WaitHelper
6
6
  include Locators
@@ -1,6 +1,6 @@
1
1
  module RAutomation
2
2
  module Adapter
3
- module Ffi
3
+ module WinFfi
4
4
  class Window
5
5
  include WaitHelper
6
6
  include Locators
@@ -26,7 +26,7 @@ module RAutomation
26
26
  end
27
27
 
28
28
  # Retrieves handle of the window.
29
- # @note Searches only for visible windows with having some text at all.
29
+ # @note Searches only for visible windows.
30
30
  # @see RAutomation::Window#hwnd
31
31
  def hwnd
32
32
  @hwnd ||= Functions.window_hwnd(@locators)
@@ -134,7 +134,10 @@ module RAutomation
134
134
  end
135
135
 
136
136
  # Creates the child window object.
137
- # @note This is an Ffi adapter specific method, not part of the public API
137
+ # @note This is an WinFfi adapter specific method, not part of the public API
138
+ # @example
139
+ # RAutomation::Window.new(:title => /Windows Internet Explorer/i).
140
+ # child(:title => /some popup/)
138
141
  # @param (see Window#initialize)
139
142
  # @return [RAutomation::Window] child window, popup or regular window.
140
143
  def child(locators)
@@ -144,4 +147,4 @@ module RAutomation
144
147
  end
145
148
  end
146
149
  end
147
- end
150
+ end
@@ -8,11 +8,19 @@ module RAutomation
8
8
  @button = @window.button(@locators)
9
9
  end
10
10
 
11
- # Performs a click on the Button.
11
+ # Performs a click on the button.
12
+ # By default click is considered successful if the button doesn't exist after clicking (e.g. window has closed)
13
+ # @yield [button] optional block specifying successful clicking condition.
14
+ # @yieldparam [Button] button which is being clicked on.
15
+ # @yieldreturn [Boolean] true if clicking on the button is successful, false otherwise.
12
16
  # @raise [UnknownButtonException] if the button doesn't exist.
13
17
  def click
14
18
  wait_until_exists
15
- @button.click
19
+ if block_given?
20
+ @button.click {yield self}
21
+ else
22
+ @button.click
23
+ end
16
24
  end
17
25
 
18
26
  # Retrieves the value (text) of the button, usually the visible text.
@@ -34,9 +42,9 @@ module RAutomation
34
42
  private
35
43
 
36
44
  def wait_until_exists
37
- WaitHelper.wait_until(RAutomation::Window.wait_timeout) {exists?}
45
+ WaitHelper.wait_until {exists?}
38
46
  rescue WaitHelper::TimeoutError
39
47
  raise UnknownButtonException, "Button #{@locators.inspect} doesn't exist on window #{@window.locators.inspect}!"
40
48
  end
41
49
  end
42
- end
50
+ end
@@ -42,9 +42,9 @@ module RAutomation
42
42
  private
43
43
 
44
44
  def wait_until_exists
45
- WaitHelper.wait_until(RAutomation::Window.wait_timeout) {exists?}
45
+ WaitHelper.wait_until {exists?}
46
46
  rescue WaitHelper::TimeoutError
47
47
  raise UnknownTextFieldException, "Text field #{@locators.inspect} doesn't exist on window #{@window.locators.inspect}!" unless exists?
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -8,7 +8,7 @@ module RAutomation
8
8
 
9
9
  # @private
10
10
  # Wait until the block evaluates to true or times out.
11
- def wait_until(timeout = 60, &block)
11
+ def wait_until(timeout = Window.wait_timeout, &block)
12
12
  end_time = ::Time.now + timeout
13
13
 
14
14
  until ::Time.now > end_time
@@ -20,4 +20,4 @@ module RAutomation
20
20
  raise TimeoutError, "timed out after #{timeout} seconds"
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -37,8 +37,8 @@ module RAutomation
37
37
  # It is also possible to change the default adapter by using environment variable called
38
38
  # __RAUTOMATION_ADAPTER__
39
39
  #
40
- # @note This constructor doesn't ensure window's existance.
41
- # @note Window to be searched for has to be visible.
40
+ # @note This constructor doesn't check for window's existance.
41
+ # @note Only visible Windows are supported.
42
42
  # @param [Hash] locators for the window.
43
43
  def initialize(locators)
44
44
  @adapter = locators.delete(:adapter) || ENV["RAUTOMATION_ADAPTER"] && ENV["RAUTOMATION_ADAPTER"].to_sym || default_adapter
@@ -191,7 +191,7 @@ module RAutomation
191
191
  private
192
192
 
193
193
  def wait_until_exists
194
- WaitHelper.wait_until(RAutomation::Window.wait_timeout) {exists?}
194
+ WaitHelper.wait_until {exists?}
195
195
  rescue WaitHelper::TimeoutError
196
196
  raise UnknownWindowException, "Window with locator #{@window.locators.inspect} doesn't exist!" unless exists?
197
197
  end
@@ -201,4 +201,4 @@ module RAutomation
201
201
  end
202
202
 
203
203
  end
204
- end
204
+ end
data/rautomation.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rautomation}
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jarmo Pertman"]
12
- s.date = %q{2010-12-18}
12
+ s.date = %q{2010-12-23}
13
13
  s.description = %q{RAutomation is a small and easy to use library for helping out to automate windows and their controls
14
14
  for automated testing.
15
15
 
@@ -35,25 +35,26 @@ RAutomation provides:
35
35
  "VERSION",
36
36
  "ext/AutoItX/AutoItX.chm",
37
37
  "ext/AutoItX/AutoItX3.dll",
38
- "lib/rautomation.rb",
38
+ "lib/RAutomation.rb",
39
39
  "lib/rautomation/adapter/autoit.rb",
40
40
  "lib/rautomation/adapter/autoit/button.rb",
41
41
  "lib/rautomation/adapter/autoit/locators.rb",
42
42
  "lib/rautomation/adapter/autoit/text_field.rb",
43
43
  "lib/rautomation/adapter/autoit/window.rb",
44
- "lib/rautomation/adapter/ffi.rb",
45
- "lib/rautomation/adapter/ffi/button.rb",
46
- "lib/rautomation/adapter/ffi/constants.rb",
47
- "lib/rautomation/adapter/ffi/functions.rb",
48
- "lib/rautomation/adapter/ffi/locators.rb",
49
- "lib/rautomation/adapter/ffi/text_field.rb",
50
- "lib/rautomation/adapter/ffi/window.rb",
51
44
  "lib/rautomation/adapter/helper.rb",
45
+ "lib/rautomation/adapter/win_ffi.rb",
46
+ "lib/rautomation/adapter/win_ffi/button.rb",
47
+ "lib/rautomation/adapter/win_ffi/constants.rb",
48
+ "lib/rautomation/adapter/win_ffi/functions.rb",
49
+ "lib/rautomation/adapter/win_ffi/locators.rb",
50
+ "lib/rautomation/adapter/win_ffi/text_field.rb",
51
+ "lib/rautomation/adapter/win_ffi/window.rb",
52
52
  "lib/rautomation/button.rb",
53
53
  "lib/rautomation/text_field.rb",
54
54
  "lib/rautomation/wait_helper.rb",
55
55
  "lib/rautomation/window.rb",
56
56
  "rautomation.gemspec",
57
+ "spec/adapter/win_ffi/window_spec.rb",
57
58
  "spec/button_spec.rb",
58
59
  "spec/spec_helper.rb",
59
60
  "spec/test.html",
@@ -66,7 +67,8 @@ RAutomation provides:
66
67
  s.rubygems_version = %q{1.3.7}
67
68
  s.summary = %q{Automate windows and their controls through user-friendly API with Ruby}
68
69
  s.test_files = [
69
- "spec/button_spec.rb",
70
+ "spec/adapter/win_ffi/window_spec.rb",
71
+ "spec/button_spec.rb",
70
72
  "spec/spec_helper.rb",
71
73
  "spec/text_field_spec.rb",
72
74
  "spec/window_spec.rb"
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe "WinFfi::Window", :if => SpecHelper.adapter == :win_ffi do
4
+ before :all do
5
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window1_title])
6
+ RAutomation::WaitHelper.wait_until {window.present?}
7
+
8
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window2_title])
9
+ RAutomation::WaitHelper.wait_until {window.present?}
10
+ end
11
+
12
+ it "#child" do
13
+ window = RAutomation::Window.new(:title => /Internet Explorer$/i)
14
+ window.should exist
15
+ child = window.child(:title => SpecHelper::DATA[:window2_title])
16
+ child.should exist
17
+ child.title.should == SpecHelper::DATA[:window2_title]
18
+ child.text.should include(SpecHelper::DATA[:window2_text])
19
+ end
20
+ end
data/spec/button_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe RAutomation::Button do
4
4
  it "#button" do
@@ -31,10 +31,29 @@ describe RAutomation::Button do
31
31
  expect {window.button(:value => "non-existent-button").click}.
32
32
  to raise_exception(RAutomation::UnknownButtonException)
33
33
 
34
+ RAutomation::Window.wait_timeout = 60
34
35
  button = window.button(:value => SpecHelper::DATA[:window2_button_text])
35
36
  button.should exist
36
37
  button.click
37
38
  button.should_not exist
38
39
  window.should_not exist
39
40
  end
40
- end
41
+
42
+ it "#click with a block for defining successful click" do
43
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window2_title])
44
+ RAutomation::Window.wait_timeout = 5
45
+ button = window.button(:value => SpecHelper::DATA[:window2_button_text])
46
+ expect {button.click {false}}.
47
+ to raise_exception(RAutomation::WaitHelper::TimeoutError)
48
+ button.should_not exist
49
+ window.should_not exist
50
+
51
+ RAutomation::Window.wait_timeout = 10
52
+ window = RAutomation::Window.new(:title => SpecHelper::DATA[:window2_title])
53
+ button = window.button(:value => SpecHelper::DATA[:window2_button_text])
54
+ button.should exist
55
+ button.click {|button| !button.exists? && !window.exists?}
56
+ button.should_not exist
57
+ window.should_not exist
58
+ end
59
+ end
data/spec/spec_helper.rb CHANGED
@@ -42,7 +42,7 @@ module SpecHelper
42
42
  :title_proc => lambda {|win| win.WinGetTitle("[TITLE:Explorer User Prompt]")}
43
43
  },
44
44
  # This adapter needs Windows OS with Internet Explorer installed into 'c:\program files\internet explorer'.
45
- :ffi => {
45
+ :win_ffi => {
46
46
  # Path to some binary, which opens up a window, what can be
47
47
  # minimized, maximized, activated, closed and etc.
48
48
  :window1 => "mspaint",
data/spec/test.html CHANGED
@@ -3,11 +3,13 @@
3
3
  <title>RAutomation testing page</title>
4
4
  <script type="text/javascript">
5
5
  function showPrompt() {
6
- prompt("Where do you want to go today?");
6
+ if (prompt("Where do you want to go today?")) {
7
+ showPrompt();
8
+ }
7
9
  }
8
10
  </script>
9
11
  </head>
10
12
  <body onload="setTimeout(showPrompt, 1000)">
11
13
  <h1>RAutomation testing page</h1>
12
14
  </body>
13
- </html>
15
+ </html>
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe RAutomation::TextField do
4
4
  it "#text_field" do
@@ -50,4 +50,4 @@ describe RAutomation::TextField do
50
50
  field.should exist
51
51
  window.text_field(:class => "non-existent-field").should_not exist
52
52
  end
53
- end
53
+ end
data/spec/window_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe RAutomation::Window do
4
4
  before :all do
@@ -102,15 +102,6 @@ describe RAutomation::Window do
102
102
  to raise_exception(RAutomation::UnknownWindowException)
103
103
  end
104
104
 
105
- it "#child", :if => SpecHelper.adapter == :ffi do
106
- window = RAutomation::Window.new(:title => /Windows Internet Explorer/i)
107
- window.should exist
108
- child = window.child(:title => SpecHelper::DATA[:window2_title])
109
- child.should exist
110
- child.title.should == SpecHelper::DATA[:window2_title]
111
- child.text.should include(SpecHelper::DATA[:window2_text])
112
- end
113
-
114
105
  it "#method_missing" do
115
106
  win = RAutomation::Window.new(:title => SpecHelper::DATA[:window2_title])
116
107
  SpecHelper::DATA[:title_proc].call(win).should == SpecHelper::DATA[:window2_title]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rautomation
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jarmo Pertman
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-18 00:00:00 +02:00
18
+ date: 2010-12-23 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -62,25 +62,26 @@ files:
62
62
  - VERSION
63
63
  - ext/AutoItX/AutoItX.chm
64
64
  - ext/AutoItX/AutoItX3.dll
65
- - lib/rautomation.rb
65
+ - lib/RAutomation.rb
66
66
  - lib/rautomation/adapter/autoit.rb
67
67
  - lib/rautomation/adapter/autoit/button.rb
68
68
  - lib/rautomation/adapter/autoit/locators.rb
69
69
  - lib/rautomation/adapter/autoit/text_field.rb
70
70
  - lib/rautomation/adapter/autoit/window.rb
71
- - lib/rautomation/adapter/ffi.rb
72
- - lib/rautomation/adapter/ffi/button.rb
73
- - lib/rautomation/adapter/ffi/constants.rb
74
- - lib/rautomation/adapter/ffi/functions.rb
75
- - lib/rautomation/adapter/ffi/locators.rb
76
- - lib/rautomation/adapter/ffi/text_field.rb
77
- - lib/rautomation/adapter/ffi/window.rb
78
71
  - lib/rautomation/adapter/helper.rb
72
+ - lib/rautomation/adapter/win_ffi.rb
73
+ - lib/rautomation/adapter/win_ffi/button.rb
74
+ - lib/rautomation/adapter/win_ffi/constants.rb
75
+ - lib/rautomation/adapter/win_ffi/functions.rb
76
+ - lib/rautomation/adapter/win_ffi/locators.rb
77
+ - lib/rautomation/adapter/win_ffi/text_field.rb
78
+ - lib/rautomation/adapter/win_ffi/window.rb
79
79
  - lib/rautomation/button.rb
80
80
  - lib/rautomation/text_field.rb
81
81
  - lib/rautomation/wait_helper.rb
82
82
  - lib/rautomation/window.rb
83
83
  - rautomation.gemspec
84
+ - spec/adapter/win_ffi/window_spec.rb
84
85
  - spec/button_spec.rb
85
86
  - spec/spec_helper.rb
86
87
  - spec/test.html
@@ -121,6 +122,7 @@ signing_key:
121
122
  specification_version: 3
122
123
  summary: Automate windows and their controls through user-friendly API with Ruby
123
124
  test_files:
125
+ - spec/adapter/win_ffi/window_spec.rb
124
126
  - spec/button_spec.rb
125
127
  - spec/spec_helper.rb
126
128
  - spec/text_field_spec.rb
@@ -1,12 +0,0 @@
1
- begin
2
- gem "ffi", "0.6.3"
3
- rescue Gem::LoadError
4
- raise Gem::LoadError, "Unable to load FFI gem. Install it with:\n\tgem install ffi -v 0.6.3"
5
- end
6
- require "ffi"
7
- require File.dirname(__FILE__) + "/ffi/constants"
8
- require File.dirname(__FILE__) + "/ffi/functions"
9
- require File.dirname(__FILE__) + "/ffi/locators"
10
- require File.dirname(__FILE__) + "/ffi/window"
11
- require File.dirname(__FILE__) + "/ffi/button"
12
- require File.dirname(__FILE__) + "/ffi/text_field"