pincers 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pincers/backend/base.rb +4 -0
- data/lib/pincers/backend/nokogiri.rb +4 -0
- data/lib/pincers/backend/webdriver.rb +19 -16
- data/lib/pincers/core/root_context.rb +9 -0
- data/lib/pincers/core/search_context.rb +4 -9
- data/lib/pincers/errors.rb +1 -1
- data/lib/pincers/factories/base.rb +36 -0
- data/lib/pincers/factories/nokogiri.rb +18 -0
- data/lib/pincers/factories/webdriver.rb +96 -0
- data/lib/pincers/factory.rb +19 -18
- data/lib/pincers/support/configuration.rb +5 -1
- data/lib/pincers/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58cb503232b2361b44d079c62928c24950e128a8
|
4
|
+
data.tar.gz: ea7d053337c7ca2d00d57bb0a87fa8a5c6f18134
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fafc923902254504e1fc18f42db4c088f7bbc8e587db1643e4400d18140845b9c9db86291cfed87b7aabae59d882b98a035f822ce8061fd00f3740e57d1ed2fb
|
7
|
+
data.tar.gz: 386cc875106ecd99a7ec55a454177b92954439fd1a00e5be4b861bce5387b68078fea9207fba98e84b4c675867e45160bbc676a006ad37d7cc9d2505c9ce46d8
|
data/lib/pincers/backend/base.rb
CHANGED
@@ -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
|
-
|
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
|
-
[
|
19
|
+
[driver]
|
21
20
|
end
|
22
21
|
|
23
22
|
def document_url
|
24
|
-
|
23
|
+
driver.current_url
|
25
24
|
end
|
26
25
|
|
27
26
|
def document_title
|
28
|
-
|
27
|
+
driver.title
|
29
28
|
end
|
30
29
|
|
31
30
|
def fetch_cookies
|
32
|
-
|
31
|
+
driver.manage.all_cookies
|
33
32
|
end
|
34
33
|
|
35
34
|
def navigate_to(_url)
|
36
|
-
|
35
|
+
driver.get _url
|
37
36
|
end
|
38
37
|
|
39
38
|
def navigate_forward(_steps)
|
40
|
-
_steps.times {
|
39
|
+
_steps.times { driver.navigate.forward }
|
41
40
|
end
|
42
41
|
|
43
42
|
def navigate_back(_steps)
|
44
|
-
_steps.times {
|
43
|
+
_steps.times { driver.navigate.back }
|
45
44
|
end
|
46
45
|
|
47
46
|
def refresh_document
|
48
|
-
|
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
|
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
|
-
|
128
|
+
driver.switch_to.frame _element
|
126
129
|
end
|
127
130
|
|
128
131
|
def switch_to_top_frame
|
129
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
data/lib/pincers/errors.rb
CHANGED
@@ -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
|
data/lib/pincers/factory.rb
CHANGED
@@ -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/
|
4
|
+
def for_webdriver(_driver=nil, _options={}, &_block)
|
5
|
+
require 'pincers/factories/webdriver'
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
if _driver.is_a? Hash
|
8
|
+
_options = _driver
|
9
|
+
_driver = nil
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
end
|
12
|
+
_options[:driver] = _driver || config.webdriver_bridge
|
15
13
|
|
16
|
-
|
17
|
-
require 'pincers/backend/nokogiri'
|
14
|
+
context = Factories::Webdriver.new_context _options
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
25
|
+
def for_nokogiri(_document, _options={})
|
26
|
+
require 'pincers/factories/nokogiri'
|
27
|
+
|
28
|
+
_options[:document] = _document
|
27
29
|
|
28
|
-
|
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|
|
data/lib/pincers/version.rb
CHANGED
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.
|
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-
|
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
|