selenium_surfer 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,7 +25,7 @@ module SeleniumSurfer
25
25
  driver_name = SeleniumSurfer.config[:webdriver]
26
26
  raise ConfigurationError.new 'must provide a webdriver type' if driver_name.nil?
27
27
 
28
- @driver = case driver_name.to_sym
28
+ case driver_name.to_sym
29
29
  when :remote
30
30
  url = SeleniumSurfer.config[:remote_host]
31
31
 
@@ -36,6 +36,9 @@ module SeleniumSurfer
36
36
  @driver = Selenium::WebDriver.for :remote, :url => url, :http_client => client
37
37
  else
38
38
  @driver = Selenium::WebDriver.for driver_name.to_sym
39
+
40
+ # apply browser configuration to new driver
41
+ @driver.manage.window.resize_to(SeleniumSurfer.config[:window_width], SeleniumSurfer.config[:window_height]) rescue nil
39
42
  end
40
43
  end
41
44
 
@@ -66,12 +69,12 @@ module SeleniumSurfer
66
69
  end
67
70
 
68
71
  # unbinds the currently bound context.
69
- def unbind(_force_reset=false)
72
+ def unbind
70
73
  if @bound_ctx
71
74
  @bound_ctx.on_unbind if @bound_ctx.respond_to? :on_unbind
72
75
  @bound_ctx = nil
73
76
  end
74
- reset if _force_reset or @anonymous # reset bucket if required
77
+ reset if @anonymous # reset bucket if required
75
78
  end
76
79
  end
77
80
 
@@ -9,7 +9,19 @@ module SeleniumSurfer
9
9
  # Error thrown when a programming setup error is found
10
10
  class SetupError < StandardError; end
11
11
 
12
+ # Base class for context errors
13
+ class ContextError < StandardError
14
+
15
+ attr_reader :context, :source
16
+
17
+ def initialize(_msg, _context)
18
+ super _msg
19
+ @context = _context
20
+ @source = _context.root_context.page_source # cache page source for future reference
21
+ end
22
+ end
23
+
12
24
  # Error thrown when an element operation is attempted in an empty search result set
13
- class EmptySetError < StandardError; end
25
+ class EmptySetError < ContextError; end
14
26
 
15
27
  end
@@ -48,7 +48,10 @@ module SeleniumSurfer
48
48
  raise
49
49
  ensure
50
50
  force_reset = session_error or !keep_sessions
51
- @@loaded_buckets.each { |b| b.unbind(force_reset) }
51
+ @@loaded_buckets.each do |bucket|
52
+ bucket.unbind
53
+ bucket.reset if force_reset
54
+ end
52
55
  @@loaded_buckets = nil
53
56
  @all_buckets = temp unless keep_sessions
54
57
  end
@@ -86,7 +89,8 @@ module SeleniumSurfer
86
89
  begin
87
90
  return _block.call ctx
88
91
  ensure
89
- bucket.unbind _opt.fetch(:on_exit, :release) == :discard
92
+ bucket.unbind
93
+ bucket.reset if _opt.fetch(:on_exit, :release) == :discard
90
94
  end
91
95
  end
92
96
 
@@ -10,39 +10,54 @@ module SeleniumSurfer
10
10
  include Enumerable
11
11
  extend Forwardable
12
12
 
13
- def initialize(_elements)
13
+ def initialize(_elements, _parent)
14
14
  @elements = _elements
15
+ @parent = _parent
16
+ end
17
+
18
+ # return the context's root context
19
+ def root_context
20
+ return @parent.root_context if @parent
21
+ self
22
+ end
23
+
24
+ # return the context's parent context
25
+ def parent_context
26
+ @parent
15
27
  end
16
28
 
17
29
  # forward read-only array methods to context
18
30
  def_delegators :context, :each, :[], :length, :count, :empty?, :first, :last
19
31
 
32
+ # yield individual SearchContext for each element contained in this result
20
33
  def explode(&_block)
21
34
  return enum_for(__method__) if _block.nil?
22
35
  context.each do |el|
23
- _block.call SearchContext.new([el])
36
+ _block.call SearchContext.new([el], self)
24
37
  end
25
38
  end
26
39
 
40
+ # searches for elements that match a given selector
27
41
  def search(_selector=nil, _options={})
28
42
  _options[:css] = _selector if _selector
29
- SearchContext.new search_elements(_options)
43
+ SearchContext.new search_elements(_options), self
30
44
  end
31
45
 
46
+ # clears and sends_keys to this context main element
32
47
  def fill(_value)
33
- raise EmptySetError.new if empty?
48
+ raise EmptySetError.new('Cannot call \'fill\' on an empty set', self) if empty?
34
49
  context.first.clear
35
50
  context.first.send_keys _value
36
51
  end
37
52
 
38
- # Any methods missing are forwarded to the first element.
53
+ # Any methods missing are forwarded to the main element (first).
39
54
  def method_missing(_method, *_args, &_block)
40
55
  m = /^(.*)_all$/.match _method.to_s
41
56
  if m then
42
57
  return [] if empty?
43
58
  context.map { |e| e.send(m[1], *_args, &_block) }
44
59
  else
45
- raise EmptySetError.new if empty?
60
+ raise EmptySetError.new("Cannot call '#{_method}' on an empty set", self) if empty?
46
61
  context.first.send(_method, *_args, &_block)
47
62
  end
48
63
  end
@@ -54,7 +69,7 @@ module SeleniumSurfer
54
69
  return true if empty?
55
70
  context.first.respond_to? m[1], _include_all
56
71
  else
57
- raise EmptySetError.new if empty?
72
+ return true if empty?
58
73
  context.first.respond_to? _method, _include_all
59
74
  end
60
75
  end
@@ -3,6 +3,7 @@ module SeleniumSurfer
3
3
  # ### Base class for robot contexts
4
4
  #
5
5
  class SurfContext < SearchContext
6
+ extend Forwardable
6
7
 
7
8
  # add a macro attribute writer to context.
8
9
  #
@@ -36,8 +37,10 @@ module SeleniumSurfer
36
37
  macro_attr_accessor :max_retries
37
38
 
38
39
  def initialize(_bucket, _macro=nil, _stack=nil)
40
+ super nil, nil
41
+
39
42
  @bucket = _bucket
40
- @macro = _macro || {}
43
+ @macro = _macro || { max_retries: 5 }
41
44
  @stack = _stack || []
42
45
 
43
46
  @bucket.bind self
@@ -58,13 +61,24 @@ module SeleniumSurfer
58
61
  # ## Helpers
59
62
 
60
63
  # retrieves the current driver being used by this context
61
- def driver
62
- load_driver
64
+ def driver(_reset=false)
65
+ raise UnboundContextError.new if not bound?
66
+ @bucket.reset if _reset
67
+ @bucket.driver
63
68
  end
64
69
 
65
- # return the current page title
66
- def title
67
- load_driver.title
70
+ # delegate some stuff to driver
71
+ def_delegators 'driver', :title, :current_url, :page_source
72
+ def_delegators 'driver.navigate', :back, :forward, :refresh
73
+
74
+ # return the current page url as an URI
75
+ def current_uri
76
+ URI.parse driver.current_url
77
+ end
78
+
79
+ # return the current page cookies as a hash
80
+ def cookies
81
+ driver.manage.all_cookies
68
82
  end
69
83
 
70
84
  # navigate to a given url (uses the max_retries setting)
@@ -74,12 +88,12 @@ module SeleniumSurfer
74
88
 
75
89
  loop do
76
90
  begin
77
- load_driver(retries > 0).get(_url)
91
+ driver(retries > 0).get(_url)
78
92
  @stack = [] # clear stack after successfull navigation
79
93
  break
80
- rescue Timeout::Error, Selenium::WebDriver::Error::UnknownError
81
- trace "Error when opening #{_url}!"
82
- raise if retries >= @max_retries
94
+ rescue Timeout::Error #, Selenium::WebDriver::Error::UnknownError
95
+ # TODO: log this
96
+ raise if retries >= max_retries
83
97
  retries += 1
84
98
  sleep 1.0
85
99
  end
@@ -87,7 +101,7 @@ module SeleniumSurfer
87
101
  end
88
102
 
89
103
  # changes the context
90
- # TODO: this method may be unecesary...
104
+ # TODO: this method may be unnecesary...
91
105
  def step(_selector=nil, _options={})
92
106
  _options[:css] = _selector if _selector
93
107
  new_context = search_elements(_options)
@@ -110,15 +124,9 @@ module SeleniumSurfer
110
124
 
111
125
  # release and discard the current driver connection.
112
126
  def quit
113
- return false if not bound?
114
- @bucket.unbind true
115
- return true
116
- end
117
-
118
- # resets the current driver connection, does not release it.
119
- def reset
120
127
  return false if not bound?
121
128
  @bucket.reset
129
+ @bucket.unbind
122
130
  return true
123
131
  end
124
132
 
@@ -130,15 +138,9 @@ module SeleniumSurfer
130
138
 
131
139
  private
132
140
 
133
- def load_driver(_reset=false)
134
- raise UnboundContextError.new if not bound?
135
- @bucket.reset if _reset
136
- @bucket.driver
137
- end
138
-
139
141
  def context
140
142
  raise UnboundContextError.new if not bound?
141
- @stack.last || [load_driver]
143
+ @stack.last || [driver]
142
144
  end
143
145
 
144
146
  def observe
@@ -1,3 +1,3 @@
1
1
  module SeleniumSurfer
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -11,7 +11,9 @@ module SeleniumSurfer
11
11
  @@config = {
12
12
  :webdriver => nil,
13
13
  :remote_host => 'http://localhost:8080',
14
- :remote_timeout => 120
14
+ :remote_timeout => 120,
15
+ :window_width => 1500,
16
+ :window_height => 1000
15
17
  }
16
18
 
17
19
  # Configure through hash
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium_surfer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-13 00:00:00.000000000 Z
12
+ date: 2013-08-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: selenium-webdriver