pincers 0.4.0 → 0.4.1

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: 94c141298bd94fe5be1c1facece4c4c3b3833601
4
- data.tar.gz: e747e9e4e8eb54e8703fb2763ae718ccc9cdddf2
3
+ metadata.gz: 58cb503232b2361b44d079c62928c24950e128a8
4
+ data.tar.gz: ea7d053337c7ca2d00d57bb0a87fa8a5c6f18134
5
5
  SHA512:
6
- metadata.gz: 01cc35baece47af8cbdfbbc0a1633287d1205c9bd81a1f6b69b07854c21662ead2b72acbedf477ae3e8ddb4779bf05b9dadd4c4898720d073531913a1245cfb4
7
- data.tar.gz: b216663dab188b2ea1f37b6e635c7fe290a63900cf8282f402e2a53a9eabb19bcbcdb4a570dcde348de7c57f909dd51b7dc9fa1acad1a4ccae52be7131227e47
6
+ metadata.gz: fafc923902254504e1fc18f42db4c088f7bbc8e587db1643e4400d18140845b9c9db86291cfed87b7aabae59d882b98a035f822ce8061fd00f3740e57d1ed2fb
7
+ data.tar.gz: 386cc875106ecd99a7ec55a454177b92954439fd1a00e5be4b861bce5387b68078fea9207fba98e84b4c675867e45160bbc676a006ad37d7cc9d2505c9ce46d8
@@ -44,6 +44,10 @@ module Pincers::Backend
44
44
  ensure_implementation :refresh_document
45
45
  end
46
46
 
47
+ def close_document
48
+ ensure_implementation :close_document
49
+ end
50
+
47
51
  def search_by_css(_element, _selector, _limit)
48
52
  ensure_implementation :search_by_css
49
53
  end
@@ -13,6 +13,10 @@ module Pincers::Backend
13
13
  document.title
14
14
  end
15
15
 
16
+ def close_document
17
+ # no closing needed
18
+ end
19
+
16
20
  def search_by_css(_element, _selector, _limit)
17
21
  # nokogiri does not do any query level optimization when searching just one node
18
22
  _element.css _selector
@@ -5,11 +5,10 @@ module Pincers::Backend
5
5
 
6
6
  class Webdriver < Base
7
7
 
8
- attr_reader :driver
8
+ alias :driver :document
9
9
 
10
10
  def initialize(_driver)
11
11
  super _driver
12
- @driver = _driver
13
12
  end
14
13
 
15
14
  def javascript_enabled?
@@ -17,35 +16,39 @@ module Pincers::Backend
17
16
  end
18
17
 
19
18
  def document_root
20
- [@driver]
19
+ [driver]
21
20
  end
22
21
 
23
22
  def document_url
24
- @driver.current_url
23
+ driver.current_url
25
24
  end
26
25
 
27
26
  def document_title
28
- @driver.title
27
+ driver.title
29
28
  end
30
29
 
31
30
  def fetch_cookies
32
- @driver.manage.all_cookies
31
+ driver.manage.all_cookies
33
32
  end
34
33
 
35
34
  def navigate_to(_url)
36
- @driver.get _url
35
+ driver.get _url
37
36
  end
38
37
 
39
38
  def navigate_forward(_steps)
40
- _steps.times { @driver.navigate.forward }
39
+ _steps.times { driver.navigate.forward }
41
40
  end
42
41
 
43
42
  def navigate_back(_steps)
44
- _steps.times { @driver.navigate.back }
43
+ _steps.times { driver.navigate.back }
45
44
  end
46
45
 
47
46
  def refresh_document
48
- @driver.navigate.refresh
47
+ driver.navigate.refresh
48
+ end
49
+
50
+ def close_document
51
+ driver.quit rescue nil
49
52
  end
50
53
 
51
54
  def search_by_css(_element, _selector, _limit)
@@ -67,7 +70,7 @@ module Pincers::Backend
67
70
  end
68
71
 
69
72
  def extract_element_html(_element)
70
- return @driver.page_source if _element == @driver
73
+ return driver.page_source if _element == driver
71
74
  _element.attribute 'outerHTML'
72
75
  end
73
76
 
@@ -122,11 +125,11 @@ module Pincers::Backend
122
125
  end
123
126
 
124
127
  def switch_to_frame(_element)
125
- @driver.switch_to.frame _element
128
+ driver.switch_to.frame _element
126
129
  end
127
130
 
128
131
  def switch_to_top_frame
129
- @driver.switch_to.default_content
132
+ driver.switch_to.default_content
130
133
  end
131
134
 
132
135
  def check_visible(_elements)
@@ -156,7 +159,7 @@ module Pincers::Backend
156
159
  end
157
160
 
158
161
  def actions
159
- @driver.action
162
+ driver.action
160
163
  end
161
164
 
162
165
  def click_with_modifiers(_element, _modifiers)
@@ -168,13 +171,13 @@ module Pincers::Backend
168
171
  end
169
172
 
170
173
  def assert_has_input_devices_for(_name)
171
- unless @driver.kind_of? Selenium::WebDriver::DriverExtensions::HasInputDevices
174
+ unless driver.kind_of? Selenium::WebDriver::DriverExtensions::HasInputDevices
172
175
  raise MissingFeatureError, _name
173
176
  end
174
177
  end
175
178
 
176
179
  def ensure_element(_element)
177
- return @driver.find_element tag_name: 'html' if _element == @driver
180
+ return driver.find_element tag_name: 'html' if _element == driver
178
181
  _element
179
182
  end
180
183
 
@@ -20,6 +20,10 @@ module Pincers::Core
20
20
  true
21
21
  end
22
22
 
23
+ def document
24
+ @backend.document
25
+ end
26
+
23
27
  def backend
24
28
  @backend
25
29
  end
@@ -72,6 +76,11 @@ module Pincers::Core
72
76
  self
73
77
  end
74
78
 
79
+ def close
80
+ wrap_errors { backend.close_document }
81
+ self
82
+ end
83
+
75
84
  def default_timeout
76
85
  @config[:wait_timeout]
77
86
  end
@@ -38,10 +38,6 @@ module Pincers::Core
38
38
  root.backend
39
39
  end
40
40
 
41
- def document
42
- backend.document
43
- end
44
-
45
41
  def elements
46
42
  reload_elements :all
47
43
  @elements
@@ -53,7 +49,7 @@ module Pincers::Core
53
49
  end
54
50
 
55
51
  def element!
56
- wait?(:present) unless frozen? or advanced_mode?
52
+ wait(:present) unless frozen? or advanced_mode?
57
53
  raise Pincers::EmptySetError.new self if empty?
58
54
  element
59
55
  end
@@ -184,7 +180,7 @@ module Pincers::Core
184
180
  end
185
181
  end
186
182
 
187
- def wait(_condition, _options)
183
+ def wait(_condition, _options={})
188
184
  raise Pincers::ConditionTimeoutError.new self, _condition unless wait?(_condition, _options)
189
185
  return self
190
186
  end
@@ -210,14 +206,13 @@ module Pincers::Core
210
206
  rescue Pincers::Error
211
207
  raise
212
208
  rescue Exception => exc
213
- raise Pincers::BackendError.new self, exc
209
+ raise Pincers::BackendError.new(self, exc)
214
210
  end
215
211
  end
216
212
 
217
213
  def perform_action
218
214
  wrap_errors do
219
- wait?(:actionable) unless advanced_mode?
220
- raise Pincers::EmptySetError.new self if empty?
215
+ wait(:actionable) unless advanced_mode?
221
216
  yield elements.first
222
217
  end
223
218
  self
@@ -56,7 +56,7 @@ module Pincers
56
56
  attr_reader :original
57
57
 
58
58
  def initialize(_context, _exc)
59
- super _context, "Backend error: #{_exc.message}"
59
+ super _context, "#{_exc.class.to_s}: #{_exc.message}"
60
60
  @document = _context.document
61
61
  @original = _exc
62
62
  end
@@ -0,0 +1,36 @@
1
+ require 'pincers/core/root_context'
2
+
3
+ module Pincers::Factories
4
+
5
+ class Base
6
+
7
+ def self.new_context(_options)
8
+ self.new(_options).new_context
9
+ end
10
+
11
+ def initialize(_options)
12
+ @context_options = extract_context_options _options
13
+ @backend_options = _options
14
+ end
15
+
16
+ def new_context
17
+ backend = load_backend @backend_options
18
+ ::Pincers::Core::RootContext.new backend, @context_options
19
+ end
20
+
21
+ def load_backend(_options)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ private
26
+
27
+ def extract_context_options(_options)
28
+ [:wait_interval, :wait_timeout, :advanced_mode].inject({}) do |opt, key|
29
+ opt[key] = _options.delete key if _options.key? key
30
+ opt
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,18 @@
1
+ require 'pincers/factories/base'
2
+ require 'pincers/backend/nokogiri'
3
+
4
+ module Pincers::Factories
5
+ class Nokogiri < Base
6
+
7
+ def load_backend(_options)
8
+ document = _options.delete(:document)
9
+
10
+ unless document.is_a? ::Nokogiri::HTML::Document
11
+ document = ::Nokogiri::HTML document, _options[:url], _options[:encoding], _options[:flags]
12
+ end
13
+
14
+ ::Pincers::Backend::Nokogiri.new document
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,96 @@
1
+ require 'pincers/factories/base'
2
+ require 'pincers/backend/webdriver'
3
+
4
+ module Pincers::Factories
5
+ class Webdriver < Base
6
+
7
+ DEFAULT_SETUP = {
8
+ page_timeout: 60000
9
+ }
10
+
11
+ def load_backend(_options)
12
+ driver = _options.delete(:driver)
13
+
14
+ unless driver.is_a? Selenium::WebDriver::Driver
15
+ driver = create_driver driver, _options
16
+ else
17
+ setup_driver driver, _options
18
+ end
19
+
20
+ ::Pincers::Backend::Webdriver.new driver
21
+ end
22
+
23
+ private
24
+
25
+ def create_driver(_name, _user={})
26
+ setup_options = extract_setup_options _user
27
+ build_options = recommended_settings_for _name
28
+ build_options = apply_custom_options build_options, _user
29
+
30
+ driver = Selenium::WebDriver::Driver.for _name, build_options
31
+ setup_fresh_driver driver, setup_options
32
+ driver
33
+ end
34
+
35
+ def setup_fresh_driver(_driver, _options)
36
+ _driver.manage.window.resize_to 1280, 1024 # ensure desktop form factor
37
+ setup_driver _driver, DEFAULT_SETUP.merge(_options)
38
+ end
39
+
40
+ def setup_driver(_driver, _options)
41
+ _driver.manage.timeouts.implicit_wait = _options[:implicit_timeout] if _options.key? :implicit_timeout
42
+ _driver.manage.timeouts.page_load = _options[:page_timeout] if _options.key? :page_timeout
43
+ _driver.manage.timeouts.script_timeout = _options[:script_timeout] if _options.key? :script_timeout
44
+ end
45
+
46
+ def recommended_settings_for(_name)
47
+ case _name
48
+ when :phantomjs
49
+ {
50
+ desired_capabilities: phantomjs_capabilities
51
+ }
52
+ when :chrome
53
+ {
54
+ detach: false, # ensure browser is shut down on exit
55
+ desired_capabilities: chrome_capabilities
56
+ }
57
+ when :firefox
58
+ {
59
+ desired_capabilities: firefox_capabitilies
60
+ }
61
+ else {} end
62
+ end
63
+
64
+ def apply_custom_options(_options, _user)
65
+ if _user.key? :proxy
66
+ proxy = _user.delete(:proxy)
67
+ proxy = Selenium::WebDriver::Proxy.new http: proxy, ssl: proxy if proxy.is_a? String
68
+ _options.desired_capabilities.proxy = proxy
69
+ end
70
+
71
+ _options.merge _user
72
+ end
73
+
74
+ def extract_setup_options(_user)
75
+ [:implicit_timeout, :page_timeout, :script_timeout].inject({}) do |opt, key|
76
+ opt[key] = _user.delete key if _user.key? key
77
+ opt
78
+ end
79
+ end
80
+
81
+ def phantomjs_capabilities
82
+ Selenium::WebDriver::Remote::Capabilities.phantomjs({
83
+ 'phantomjs.cli.args' => ['--ssl-protocol=any', '--web-security=false', '--ignore-ssl-errors=true', '--load-images=false']
84
+ })
85
+ end
86
+
87
+ def chrome_capabilities
88
+ Selenium::WebDriver::Remote::Capabilities.chrome
89
+ end
90
+
91
+ def firefox_capabitilies
92
+ Selenium::WebDriver::Remote::Capabilities.firefox
93
+ end
94
+
95
+ end
96
+ end
@@ -1,32 +1,33 @@
1
- require 'pincers/core/root_context'
2
-
3
1
  module Pincers
4
2
  module Factory
5
3
 
6
- def for_webdriver(_driver, _options={})
7
- require 'pincers/backend/webdriver'
4
+ def for_webdriver(_driver=nil, _options={}, &_block)
5
+ require 'pincers/factories/webdriver'
8
6
 
9
- unless _driver.is_a? Selenium::WebDriver::Driver
10
- _driver = Selenium::WebDriver::Driver.for _driver, _options
7
+ if _driver.is_a? Hash
8
+ _options = _driver
9
+ _driver = nil
11
10
  end
12
11
 
13
- context Backend::Webdriver.new _driver
14
- end
12
+ _options[:driver] = _driver || config.webdriver_bridge
15
13
 
16
- def for_nokogiri(_document, _options={})
17
- require 'pincers/backend/nokogiri'
14
+ context = Factories::Webdriver.new_context _options
18
15
 
19
- unless _document.is_a? ::Nokogiri::HTML::Document
20
- _document = ::Nokogiri::HTML _document, _options[:url], _options[:encoding], _options[:flags]
21
- end
22
-
23
- context Backend::Nokogiri.new _document
16
+ if _block
17
+ begin
18
+ yield context
19
+ ensure
20
+ context.close
21
+ end
22
+ else context end
24
23
  end
25
24
 
26
- private
25
+ def for_nokogiri(_document, _options={})
26
+ require 'pincers/factories/nokogiri'
27
+
28
+ _options[:document] = _document
27
29
 
28
- def context(_backend)
29
- Core::RootContext.new _backend
30
+ Factories::Nokogiri.new_context _options
30
31
  end
31
32
 
32
33
  end
@@ -6,7 +6,11 @@ module Pincers::Support
6
6
  FIELDS = [
7
7
  [:wait_timeout, 10.0],
8
8
  [:wait_interval, 0.2],
9
- [:advanced_mode, false]
9
+ [:advanced_mode, false],
10
+
11
+ # webdriver defaults
12
+ [:webdriver_bridge, :firefox],
13
+ [:webdriver_options, {}]
10
14
  ];
11
15
 
12
16
  FIELDS.each do |field|
@@ -1,3 +1,3 @@
1
1
  module Pincers
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pincers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ignacio Baixas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-25 00:00:00.000000000 Z
11
+ date: 2015-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -222,6 +222,9 @@ files:
222
222
  - lib/pincers/extension/actions.rb
223
223
  - lib/pincers/extension/labs.rb
224
224
  - lib/pincers/extension/queries.rb
225
+ - lib/pincers/factories/base.rb
226
+ - lib/pincers/factories/nokogiri.rb
227
+ - lib/pincers/factories/webdriver.rb
225
228
  - lib/pincers/factory.rb
226
229
  - lib/pincers/support/configuration.rb
227
230
  - lib/pincers/support/cookie_jar.rb