vapir-common 1.7.2 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ class Module
2
+ def alias_deprecated(to, from)
3
+ define_method to do |*args|
4
+ if !respond_to?(:config) || config.warn_deprecated
5
+ Kernel.warn_with_caller "DEPRECATION WARNING: #{self.class.name}\##{to} is deprecated. Please use #{self.class.name}\##{from}"
6
+ end
7
+ send(from, *args)
8
+ end
9
+ end
10
+ end
11
+
12
+ class String
13
+ if method_defined?(:ord)
14
+ alias vapir_ord ord
15
+ else
16
+ def vapir_ord
17
+ unpack("U*")[0] # assume it's unicode
18
+ end
19
+ end
20
+ end
21
+
22
+ unless :to_proc.respond_to?(:to_proc)
23
+ class Symbol
24
+ # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
25
+ #
26
+ # # The same as people.collect { |p| p.name }
27
+ # people.collect(&:name)
28
+ #
29
+ # # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
30
+ # people.select(&:manager?).collect(&:salary)
31
+ def to_proc
32
+ Proc.new { |*args| args[0].__send__(self, *args[1..-1]) }
33
+ end
34
+ end
35
+ end
36
+
37
+ module Kernel
38
+ # this is the Y-combinator, which allows anonymous recursive functions. for a simple example,
39
+ # to define a recursive function to return the length of an array:
40
+ #
41
+ # length = ycomb do |len|
42
+ # proc{|list| list == [] ? 0 : len.call(list[1..-1]) }
43
+ # end
44
+ #
45
+ # see https://secure.wikimedia.org/wikipedia/en/wiki/Fixed_point_combinator#Y_combinator
46
+ # and chapter 9 of the little schemer, available as the sample chapter at http://www.ccs.neu.edu/home/matthias/BTLS/
47
+ def ycomb
48
+ proc{|f| f.call(f) }.call(proc{|f| yield proc{|*x| f.call(f).call(*x) } })
49
+ end
50
+ module_function :ycomb
51
+
52
+ def warn_with_caller(message)
53
+ Kernel.warn "#{message}\ncalled from: #{caller[1..-1].map{|c|"\n\t"+c}}"
54
+ end
55
+ module_function :warn_with_caller
56
+ end
57
+
58
+ require 'enumerator'
59
+ module Vapir
60
+ Enumerator = Object.const_defined?('Enumerator') ? ::Enumerator : Enumerable::Enumerator
61
+ end
62
+
@@ -6,7 +6,7 @@
6
6
  def handle_options(given_options, default_options, other_allowed_keys=[])
7
7
  given_options=given_options.dup
8
8
  unless (unknown_keys=(given_options.keys-default_options.keys-other_allowed_keys)).empty?
9
- raise ArgumentError, "Unknown options: #{(given_options.keys-default_options.keys).map(&:inspect).join(', ')}. Known options are #{(default_options.keys+other_allowed_keys).map(&:inspect).join(', ')}"
9
+ raise ArgumentError, "Unknown options: #{unknown_keys.map(&:inspect).join(', ')}. Known options are #{(default_options.keys+other_allowed_keys).uniq.map(&:inspect).join(', ')}"
10
10
  end
11
11
  (default_options.keys-given_options.keys).each do |key|
12
12
  given_options[key]=default_options[key]
@@ -0,0 +1,135 @@
1
+ require 'vapir-common/external/core_extensions'
2
+ module Vapir
3
+ KeyCodes = (('0'..'9').to_a+('a'..'z').to_a).inject({}){|hash, char| hash.merge(char.to_sym => char.vapir_ord) }.merge(
4
+ {
5
+ :cancel => 3,
6
+ :help => 6,
7
+ :back_space => 8,
8
+ :tab => 9,
9
+ :clear => 12,
10
+ :return => 13,
11
+ :enter => 14,
12
+ :shift => 16,
13
+ :control => 17,
14
+ :alt => 18,
15
+ :pause => 19,
16
+ :caps_lock => 20,
17
+ :escape => 27,
18
+ :space => 32,
19
+ :page_up => 33,
20
+ :page_down => 34,
21
+ :end => 35,
22
+ :home => 36,
23
+ :left => 37,
24
+ :up => 38,
25
+ :right => 39,
26
+ :down => 40,
27
+ :printscreen => 44,
28
+ :insert => 45,
29
+ :delete => 46,
30
+ :semicolon => 59,
31
+ :equals => 61,
32
+ :context_menu => 93,
33
+ :numpad0 => 96,
34
+ :numpad1 => 97,
35
+ :numpad2 => 98,
36
+ :numpad3 => 99,
37
+ :numpad4 => 100,
38
+ :numpad5 => 101,
39
+ :numpad6 => 102,
40
+ :numpad7 => 103,
41
+ :numpad8 => 104,
42
+ :numpad9 => 105,
43
+ :multiply => 106,
44
+ :add => 107,
45
+ :separator => 108,
46
+ :subtract => 109,
47
+ :decimal => 110,
48
+ :divide => 111,
49
+ :f1 => 112,
50
+ :f2 => 113,
51
+ :f3 => 114,
52
+ :f4 => 115,
53
+ :f5 => 116,
54
+ :f6 => 117,
55
+ :f7 => 118,
56
+ :f8 => 119,
57
+ :f9 => 120,
58
+ :f10 => 121,
59
+ :f11 => 122,
60
+ :f12 => 123,
61
+ :f13 => 124,
62
+ :f14 => 125,
63
+ :f15 => 126,
64
+ :f16 => 127,
65
+ :f17 => 128,
66
+ :f18 => 129,
67
+ :f19 => 130,
68
+ :f20 => 131,
69
+ :f21 => 132,
70
+ :f22 => 133,
71
+ :f23 => 134,
72
+ :f24 => 135,
73
+ :num_lock => 144,
74
+ :scroll_lock => 145,
75
+ :comma => 188,
76
+ :dash => 189,
77
+ :period => 190,
78
+ :slash => 191,
79
+ :back_quote => 192,
80
+ :open_bracket => 219,
81
+ :back_slash => 220,
82
+ :close_bracket => 221,
83
+ :quote => 222,
84
+ :meta => 224,
85
+ })
86
+ PrintKeyCodes = (('0'..'9').to_a+('a'..'z').to_a).inject({}){|hash, char| hash.merge(char => char.to_sym) }.merge(
87
+ {
88
+ "\t" => :tab,
89
+ #"\n" => :return,
90
+ #"\n" => :enter,
91
+ ' ' => :space,
92
+ ';' => :semicolon,
93
+ '=' => :equals,
94
+ ',' => :comma,
95
+ '.' => :period,
96
+ '/' => :slash,
97
+ "`" => :back_quote,
98
+ '[' => :open_bracket,
99
+ "\\" => :back_slash,
100
+ ']' => :close_bracket,
101
+ "'" => :quote,
102
+ }).inject({}){|hash, (key, key_codes_key)| hash.merge(key => KeyCodes[key_codes_key]) }
103
+ ShiftPrintKeyCodes = ('A'..'Z').to_a.inject({}){|hash, char| hash.merge(char => char.downcase.to_sym) }.merge(
104
+ {
105
+ ')' => :'0',
106
+ '!' => :'1',
107
+ '@' => :'2',
108
+ '#' => :'3',
109
+ '$' => :'4',
110
+ '%' => :'5',
111
+ '^' => :'6',
112
+ '&' => :'7',
113
+ '*' => :'8',
114
+ '(' => :'9',
115
+ ':' => :semicolon,
116
+ '+' => :equals,
117
+ '<' => :comma,
118
+ '>' => :period,
119
+ '?' => :slash,
120
+ '~' => :back_quote,
121
+ '{' => :open_bracket,
122
+ '|' => :back_slash,
123
+ '}' => :close_bracket,
124
+ '"' => :quote,
125
+ }).inject({}){|hash, (key, key_codes_key)| hash.merge(key => KeyCodes[key_codes_key]) }
126
+ NumpadKeyCodes = ('0'..'9').inject({}){|hash, char| hash.merge(char => "numpad#{char}".to_sym) }.merge(
127
+ {
128
+ '*' => :multiply,
129
+ '+' => :add,
130
+ #? => :separator,
131
+ '-' => :subtract,
132
+ '.' => :decimal,
133
+ '/' => :divide,
134
+ }).inject({}){|hash, (key, key_codes_key)| hash.merge(key => KeyCodes[key_codes_key]) }
135
+ end
@@ -1,49 +1,16 @@
1
- require 'user-choices'
2
-
3
1
  module Vapir
4
- @@options_file = nil
5
- @@options = nil
6
2
  class << self
7
- # Specify the location of a yaml file containing Vapir options. Must be
8
- # specified before the options are parsed.
9
- def options_file= file
10
- @@options_file = file
3
+ def options_file=(file) # :nodoc:
4
+ raise NotImplementedError, "this method of specifying options is deprecated and gone. see documentation for Vapir.config"
11
5
  end
12
6
  def options_file
13
- @@options_file
7
+ raise NotImplementedError, "this method of specifying options is deprecated and gone. see documentation for Vapir.config"
14
8
  end
15
9
  def options= x
16
- @@options = x
10
+ raise NotImplementedError, "this method of specifying options is deprecated and gone. see documentation for Vapir.config"
17
11
  end
18
- # Return the Vapir options, as a hash. If they haven't been parsed yet,
19
- # they will be now.
20
12
  def options
21
- @@options ||= Vapir::Options.new.execute
13
+ raise NotImplementedError, "this method of specifying options is deprecated and gone. see documentation for Vapir.config"
22
14
  end
23
15
  end
24
-
25
- class Options < UserChoices::Command
26
- include UserChoices
27
- def add_sources builder
28
- builder.add_source EnvironmentSource, :with_prefix, 'watir_'
29
- if Vapir.options_file
30
- builder.add_source YamlConfigFileSource, :from_complete_path,
31
- Vapir.options_file
32
- end
33
- end
34
- def add_choices builder
35
- builder.add_choice :browser,
36
- :type => Vapir::Browser.browser_names,
37
- :default => Vapir::Browser.default
38
- builder.add_choice :speed,
39
- :type => ['slow', 'fast', 'zippy'],
40
- :default => 'fast'
41
- builder.add_choice :visible,
42
- :type => :boolean
43
- end
44
- def execute
45
- @user_choices[:speed] = @user_choices[:speed].to_sym
46
- @user_choices
47
- end
48
- end
49
16
  end
@@ -1,21 +1,26 @@
1
- module Vapir
2
- module PageContainer
3
- include Vapir::Container
4
- def containing_object
5
- document_object
6
- end
7
- def document_element
8
- document_object.documentElement || raise(Exception::ExistenceFailureException, "document_object.documentElement was nil")
9
- end
10
- def title
11
- document_object.title
12
- end
13
- # The url of the page object.
14
- def url
15
- document_object.location.href
16
- end
17
- def page_container
18
- self
19
- end
20
- end
21
- end
1
+ module Vapir
2
+ module PageContainer
3
+ include Vapir::Container
4
+ def containing_object
5
+ document_object
6
+ end
7
+ def document_element_object
8
+ document_object.documentElement || raise(Exception::ExistenceFailureException, "document_object.documentElement was nil")
9
+ end
10
+ alias document_element document_element_object
11
+
12
+ def title
13
+ document_object.title
14
+ end
15
+ # The url of the page object.
16
+ def url
17
+ document_object.location.href
18
+ end
19
+ def page_container
20
+ self
21
+ end
22
+ def active_element
23
+ base_element_class.new(nil, nil, extra_for_contained.merge(:candidates => proc{|container| [container.document_object.activeElement] })).to_subtype
24
+ end
25
+ end
26
+ end
@@ -50,7 +50,7 @@ module Vapir
50
50
 
51
51
  # this is a list of what users can specify (there are additional possible hows that may be given
52
52
  # to the Element constructor, but not generally for use by users, such as :element_object or :label
53
- HowList=[:attributes, :xpath, :custom, :element_object, :label]
53
+ HowList=[:attributes, :xpath, :css, :custom, :element_object, :label]
54
54
 
55
55
  # returns an Enumerable of element objects that _may_ match (note, not do match, necessarily)
56
56
  # the given specifiers on the given container. these are obtained from the container's containing_object
@@ -141,7 +141,7 @@ module Vapir
141
141
  unless specifiers_list.is_a?(Enumerable) && specifiers_list.all?{|spec| spec.is_a?(Hash)}
142
142
  raise ArgumentError, "specifiers_list should be a list of Hashes!"
143
143
  end
144
- if candidates.length != 0 && Object.const_defined?('JsshObject') && (candidates.is_a?(JsshObject) || candidates.all?{|c| c.is_a?(JsshObject)})
144
+ if Object.const_defined?('JsshObject') && (candidates.is_a?(JsshObject) || (candidates.length != 0 && candidates.all?{|c| c.is_a?(JsshObject)}))
145
145
  # optimize for JSSH by moving code to the other side of the socket, rather than talking across it a whole lot
146
146
  # this javascript should be exactly the same as the ruby in the else (minus WIN32OLE optimization) -
147
147
  # just written in javascript instead of ruby.
@@ -0,0 +1,5 @@
1
+ module Vapir
2
+ module Common
3
+ VERSION = '1.8.0'
4
+ end
5
+ end
@@ -1,100 +1,53 @@
1
1
  require 'vapir-common/exceptions'
2
2
 
3
3
  module Vapir
4
+ class Waiter # :nodoc:all
5
+ # How long to wait between each iteration through the wait_until
6
+ # loop. In seconds.
7
+ attr_accessor :polling_interval
4
8
 
5
- def wait_until(*args)
6
- Waiter.wait_until(*args) {yield}
7
- end
8
-
9
- class TimeKeeper
10
- attr_reader :sleep_time
11
- def initialize
12
- @sleep_time = 0.0
13
- end
14
- def sleep seconds
15
- @sleep_time += Kernel.sleep seconds
16
- end
17
- def now
18
- Time.now
19
- end
20
- end
21
-
22
- class Waiter
23
- # This is an interface to a TimeKeeper which proxies
24
- # calls to "sleep" and "Time.now".
25
- # Useful for unit testing Waiter.
26
- attr_accessor :timer
27
-
28
- # How long to wait between each iteration through the wait_until
29
- # loop. In seconds.
30
- attr_accessor :polling_interval
31
-
32
- # Timeout for wait_until.
33
- attr_accessor :timeout
9
+ # Timeout for wait_until.
10
+ attr_accessor :timeout
11
+
12
+ @@default_polling_interval = 0.5
13
+ @@default_timeout = 60.0
34
14
 
35
- @@default_polling_interval = 0.5
36
- @@default_timeout = 60.0
37
-
38
- def initialize(timeout=@@default_timeout,
39
- polling_interval=@@default_polling_interval)
40
- @timeout = timeout
41
- @polling_interval = polling_interval
42
- @timer = TimeKeeper.new
43
- end
44
-
45
- # Execute the provided block until either (1) it returns true, or
46
- # (2) the timeout (in seconds) has been reached. If the timeout is reached,
47
- # a TimeOutException will be raised. The block will always
48
- # execute at least once.
49
- #
50
- # waiter = Waiter.new(5)
51
- # waiter.wait_until {puts 'hello'}
52
- #
53
- # This code will print out "hello" for five seconds, and then raise a
54
- # Vapir::TimeOutException.
55
- def wait_until # block
56
- start_time = now
57
- until yield do
58
- if (duration = now - start_time) > @timeout
59
- raise Vapir::Exception::TimeOutException.new(duration, @timeout),
60
- "Timed out after #{duration} seconds."
15
+ def initialize(timeout=@@default_timeout, polling_interval=@@default_polling_interval)
16
+ @timeout = timeout
17
+ @polling_interval = polling_interval
18
+ end
19
+
20
+ module WaitUntil
21
+ public
22
+ # Execute the provided block until either (1) it returns true, or
23
+ # (2) the timeout (in seconds) has been reached. If the timeout is reached,
24
+ # a TimeOutException will be raised. The block will always
25
+ # execute at least once.
26
+ #
27
+ # waiter = Waiter.new(5)
28
+ # waiter.wait_until {puts 'hello'}
29
+ #
30
+ # This code will print out "hello" for five seconds, and then raise a
31
+ # Vapir::TimeOutException.
32
+ def wait_until(timeout=::Vapir::Waiter.send(:class_variable_get, '@@default_timeout'), polling_interval=::Vapir::Waiter.send(:class_variable_get, '@@default_polling_interval'), &block)
33
+ ::Waiter.try_for(timeout, :interval => polling_interval, &block)
61
34
  end
62
- sleep @polling_interval
63
35
  end
36
+ include ::Vapir::Waiter::WaitUntil
37
+ extend ::Vapir::Waiter::WaitUntil
64
38
  end
65
-
66
- # Execute the provided block until either (1) it returns true, or
67
- # (2) the timeout (in seconds) has been reached. If the timeout is reached,
68
- # a TimeOutException will be raised. The block will always
69
- # execute at least once.
70
- #
71
- # Waiter.wait_until(5) {puts 'hello'}
72
- #
73
- # This code will print out "hello" for five seconds, and then raise a
74
- # Vapir::TimeOutException.
75
-
76
- # IDEA: wait_until: remove defaults from Waiter.wait_until
77
- def self.wait_until(timeout=@@default_timeout,
78
- polling_interval=@@default_polling_interval)
79
- waiter = new(timeout, polling_interval)
80
- waiter.wait_until { yield }
81
- end
82
-
83
- private
84
- def sleep seconds
85
- @timer.sleep seconds
86
- end
87
- def now
88
- @timer.now
39
+ include ::Vapir::Waiter::WaitUntil
40
+ extend ::Vapir::Waiter::WaitUntil
41
+ class Browser
42
+ include ::Vapir::Waiter::WaitUntil
43
+ extend ::Vapir::Waiter::WaitUntil
89
44
  end
90
- end
91
-
92
45
  end # module
93
46
 
94
47
  require 'vapir-common/handle_options'
95
48
 
96
49
  class WaiterError < StandardError; end
97
- class Waiter
50
+ module Waiter
98
51
  # Tries for +time+ seconds to get the desired result from the given block. Stops when either:
99
52
  # 1. The :condition option (which should be a proc) returns true (that is, not false or nil)
100
53
  # 2. The block returns true (that is, anything but false or nil) if no :condition option is given
@@ -104,17 +57,18 @@ class Waiter
104
57
  #
105
58
  # Returns the value of the block, which can be handy for things that return nil on failure and some
106
59
  # other object on success, like Enumerable#detect for example:
107
- # found_thing=Waiter.try_for(30) { all_things().detect {|thing| thing.name=="Bill" } }
60
+ # found_thing=Waiter.try_for(30){ all_things().detect{|thing| thing.name=="Bill" } }
108
61
  #
109
62
  # Examples:
110
- # Waiter.try_for(30) do
111
- # Time.now.year == 2015
112
- # end
63
+ # Waiter.try_for(30) do
64
+ # Time.now.year == 2015
65
+ # end
113
66
  # Raises a WaiterError unless it is called between the last 30 seconds of December 31, 2014 and the end of 2015
114
67
  #
115
- # Waiter.try_for(365.242199*24*60*60, :interval => 0.1, :exception => nil, :condition => proc{ 2+2==5 }) do
116
- # STDERR.puts "any decisecond now ..."
117
- # end
68
+ # Waiter.try_for(365*24*60*60, :interval => 0.1, :exception => nil, :condition => proc{ 2+2==5 }) do
69
+ # STDERR.puts "any decisecond now ..."
70
+ # end
71
+ #
118
72
  # Complains to STDERR for one year, every tenth of a second, as long as 2+2 does not equal 5. Does not
119
73
  # raise an exception if 2+2 does not become equal to 5.
120
74
  def self.try_for(time, options={})