pincers 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/pincers/backend/base.rb +27 -3
- data/lib/pincers/backend/nokogiri.rb +4 -2
- data/lib/pincers/backend/webdriver.rb +82 -18
- data/lib/pincers/core/root_context.rb +10 -1
- data/lib/pincers/core/search_context.rb +134 -38
- data/lib/pincers/errors.rb +8 -0
- data/lib/pincers/support/configuration.rb +2 -1
- data/lib/pincers/support/query.rb +31 -0
- data/lib/pincers/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 88daefd24fb535d60be1252cb33ca632d6466c0f
|
|
4
|
+
data.tar.gz: abe5bde9ae30c13d6a424268e85606b383179d42
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2726362f0e0d4dd95bf87c50f795f557ef670007b80990c22f1425a955d23d93796623433b50e0344075fd96260ddfbfbe88988edea541c19caf863894744985
|
|
7
|
+
data.tar.gz: 7d66fd52f27ceb87085d643cb8f0df8aeda19747e23cf69b9bb2811b610c5283aa87d9bfa6cd9f45017303ef6e9b477c56da57a6aeb7e10e4fec5098822605d9
|
data/lib/pincers/backend/base.rb
CHANGED
|
@@ -8,6 +8,10 @@ module Pincers::Backend
|
|
|
8
8
|
@document = _document
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def javascript_enabled?
|
|
12
|
+
false
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
def document_root
|
|
12
16
|
ensure_implementation :document_root
|
|
13
17
|
end
|
|
@@ -40,11 +44,11 @@ module Pincers::Backend
|
|
|
40
44
|
ensure_implementation :refresh_document
|
|
41
45
|
end
|
|
42
46
|
|
|
43
|
-
def search_by_css(_element, _selector)
|
|
47
|
+
def search_by_css(_element, _selector, _limit)
|
|
44
48
|
ensure_implementation :search_by_css
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
def search_by_xpath(_element, _selector)
|
|
51
|
+
def search_by_xpath(_element, _selector, _limit)
|
|
48
52
|
ensure_implementation :search_by_xpath
|
|
49
53
|
end
|
|
50
54
|
|
|
@@ -68,14 +72,34 @@ module Pincers::Backend
|
|
|
68
72
|
ensure_implementation :clear_input
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
def element_is_actionable?(_element)
|
|
76
|
+
return true
|
|
77
|
+
end
|
|
78
|
+
|
|
71
79
|
def set_element_text(_element, _value)
|
|
72
80
|
ensure_implementation :set_element_text
|
|
73
81
|
end
|
|
74
82
|
|
|
75
|
-
def click_on_element(_element)
|
|
83
|
+
def click_on_element(_element, _modifiers)
|
|
76
84
|
ensure_implementation :click_on_element
|
|
77
85
|
end
|
|
78
86
|
|
|
87
|
+
def right_click_on_element(_element)
|
|
88
|
+
ensure_implementation :right_click_on_element
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def double_click_on_element(_element)
|
|
92
|
+
ensure_implementation :double_click_on_element
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def hover_over_element(_element)
|
|
96
|
+
ensure_implementation :hover_over_element
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def drag_and_drop(_element, _into)
|
|
100
|
+
ensure_implementation :drag_and_drop
|
|
101
|
+
end
|
|
102
|
+
|
|
79
103
|
def switch_to_frame(_element)
|
|
80
104
|
ensure_implementation :switch_to_frame
|
|
81
105
|
end
|
|
@@ -12,11 +12,13 @@ module Pincers::Backend
|
|
|
12
12
|
document.title
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def search_by_css(_element, _selector)
|
|
15
|
+
def search_by_css(_element, _selector, _limit)
|
|
16
|
+
# nokogiri does not do any query level optimization when searching just one node
|
|
16
17
|
_element.css _selector
|
|
17
18
|
end
|
|
18
19
|
|
|
19
|
-
def search_by_xpath(_element, _selector)
|
|
20
|
+
def search_by_xpath(_element, _selector, _limit)
|
|
21
|
+
# nokogiri does not do any query level optimization when searching just one node
|
|
20
22
|
_element.xpath _selector
|
|
21
23
|
end
|
|
22
24
|
|
|
@@ -11,6 +11,10 @@ module Pincers::Backend
|
|
|
11
11
|
@driver = _driver
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def javascript_enabled?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
14
18
|
def document_root
|
|
15
19
|
[@driver]
|
|
16
20
|
end
|
|
@@ -43,12 +47,12 @@ module Pincers::Backend
|
|
|
43
47
|
@driver.navigate.refresh
|
|
44
48
|
end
|
|
45
49
|
|
|
46
|
-
def search_by_css(_element, _selector)
|
|
47
|
-
_element
|
|
50
|
+
def search_by_css(_element, _selector, _limit)
|
|
51
|
+
search _element, { css: _selector }, _limit
|
|
48
52
|
end
|
|
49
53
|
|
|
50
|
-
def search_by_xpath(_element, _selector)
|
|
51
|
-
_element
|
|
54
|
+
def search_by_xpath(_element, _selector, _limit)
|
|
55
|
+
search _element, { xpath: _selector }, _limit
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
def extract_element_tag(_element)
|
|
@@ -71,37 +75,61 @@ module Pincers::Backend
|
|
|
71
75
|
_element[_name]
|
|
72
76
|
end
|
|
73
77
|
|
|
78
|
+
def element_is_actionable?(_element)
|
|
79
|
+
# this is the base requisite in webdriver for actionable elements:
|
|
80
|
+
# non displayed items will always error on action
|
|
81
|
+
_element.displayed?
|
|
82
|
+
end
|
|
83
|
+
|
|
74
84
|
def set_element_text(_element, _value)
|
|
75
|
-
_element =
|
|
85
|
+
_element = ensure_ready_for_input _element
|
|
76
86
|
_element.clear
|
|
77
87
|
_element.send_keys _value
|
|
78
88
|
end
|
|
79
89
|
|
|
80
|
-
def click_on_element(_element)
|
|
81
|
-
_element =
|
|
82
|
-
|
|
90
|
+
def click_on_element(_element, _modifiers)
|
|
91
|
+
_element = ensure_ready_for_input _element
|
|
92
|
+
if _modifiers.length == 0
|
|
93
|
+
_element.click
|
|
94
|
+
else
|
|
95
|
+
click_with_modifiers(_element, _modifiers)
|
|
96
|
+
end
|
|
83
97
|
end
|
|
84
98
|
|
|
85
|
-
def
|
|
86
|
-
|
|
99
|
+
def right_click_on_element(_element)
|
|
100
|
+
assert_has_input_devices_for :right_click_on_element
|
|
101
|
+
_element = ensure_ready_for_input _element
|
|
102
|
+
actions.context_click(_element).perform
|
|
87
103
|
end
|
|
88
104
|
|
|
89
|
-
def
|
|
90
|
-
|
|
105
|
+
def double_click_on_element(_element)
|
|
106
|
+
assert_has_input_devices_for :double_click_on_element
|
|
107
|
+
_element = ensure_ready_for_input _element
|
|
108
|
+
actions.double_click(_element).perform
|
|
91
109
|
end
|
|
92
110
|
|
|
93
|
-
|
|
111
|
+
def hover_over_element(_element)
|
|
112
|
+
assert_has_input_devices_for :hover_over_element
|
|
113
|
+
_element = ensure_ready_for_input _element
|
|
114
|
+
actions.move_to(_element).perform
|
|
115
|
+
end
|
|
94
116
|
|
|
95
|
-
def
|
|
96
|
-
|
|
117
|
+
def drag_and_drop(_element, _on)
|
|
118
|
+
assert_has_input_devices_for :drag_and_drop
|
|
119
|
+
_element = ensure_input_element _element
|
|
120
|
+
actions.drag_and_drop(_element, _on).perform
|
|
97
121
|
end
|
|
98
122
|
|
|
99
|
-
def
|
|
100
|
-
|
|
123
|
+
def switch_to_frame(_element)
|
|
124
|
+
@driver.switch_to.frame _element
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def switch_to_top_frame
|
|
128
|
+
@driver.switch_to.default_content
|
|
101
129
|
end
|
|
102
130
|
|
|
103
131
|
def check_visible(_elements)
|
|
104
|
-
|
|
132
|
+
_elements.first.displayed?
|
|
105
133
|
end
|
|
106
134
|
|
|
107
135
|
def check_enabled(_elements)
|
|
@@ -114,11 +142,47 @@ module Pincers::Backend
|
|
|
114
142
|
|
|
115
143
|
private
|
|
116
144
|
|
|
145
|
+
def search(_element, _query, _limit)
|
|
146
|
+
if _limit == 1
|
|
147
|
+
begin
|
|
148
|
+
[_element.find_element(_query)]
|
|
149
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError
|
|
150
|
+
[]
|
|
151
|
+
end
|
|
152
|
+
else
|
|
153
|
+
_element.find_elements _query
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def actions
|
|
158
|
+
@driver.action
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def click_with_modifiers(_element, _modifiers)
|
|
162
|
+
assert_has_input_devices_for :click_with_modifiers
|
|
163
|
+
_modifiers.each { |m| actions.key_down m }
|
|
164
|
+
actions.click _element
|
|
165
|
+
_modifiers.each { |m| actions.key_up m }
|
|
166
|
+
actions.perform
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def assert_has_input_devices_for(_name)
|
|
170
|
+
unless @driver.kind_of? Selenium::WebDriver::DriverExtensions::HasInputDevices
|
|
171
|
+
raise MissingFeatureError, _name
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
117
175
|
def ensure_element(_element)
|
|
118
176
|
return @driver.find_element tag_name: 'html' if _element == @driver
|
|
119
177
|
_element
|
|
120
178
|
end
|
|
121
179
|
|
|
180
|
+
def ensure_ready_for_input(_element)
|
|
181
|
+
_element = ensure_element _element
|
|
182
|
+
Selenium::WebDriver::Wait.new.until { _element.displayed? }
|
|
183
|
+
_element
|
|
184
|
+
end
|
|
185
|
+
|
|
122
186
|
end
|
|
123
187
|
|
|
124
188
|
end
|
|
@@ -7,7 +7,7 @@ module Pincers::Core
|
|
|
7
7
|
attr_reader :config
|
|
8
8
|
|
|
9
9
|
def initialize(_backend, _config={})
|
|
10
|
-
super _backend.document_root, nil
|
|
10
|
+
super _backend.document_root, nil, nil
|
|
11
11
|
@backend = _backend
|
|
12
12
|
@config = Pincers.config.values.merge _config
|
|
13
13
|
end
|
|
@@ -76,8 +76,17 @@ module Pincers::Core
|
|
|
76
76
|
@config[:wait_interval]
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
def advanced_mode?
|
|
80
|
+
@config[:advanced_mode]
|
|
81
|
+
end
|
|
82
|
+
|
|
79
83
|
private
|
|
80
84
|
|
|
85
|
+
def wrap_siblings(_elements)
|
|
86
|
+
# root node siblings behave like childs
|
|
87
|
+
SearchContext.new _elements, self, nil
|
|
88
|
+
end
|
|
89
|
+
|
|
81
90
|
def goto_url(_url)
|
|
82
91
|
_url = "http://#{_url}" unless /^(https?|file|ftp):\/\// === _url
|
|
83
92
|
backend.navigate_to _url
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'pincers/extension/queries'
|
|
2
2
|
require 'pincers/extension/actions'
|
|
3
|
+
require 'pincers/support/query'
|
|
3
4
|
|
|
4
5
|
module Pincers::Core
|
|
5
6
|
class SearchContext
|
|
@@ -8,13 +9,19 @@ module Pincers::Core
|
|
|
8
9
|
include Pincers::Extension::Queries
|
|
9
10
|
include Pincers::Extension::Actions
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
attr_reader :parent, :query
|
|
12
13
|
|
|
13
14
|
def_delegators :elements, :length, :count, :empty?
|
|
14
15
|
|
|
15
|
-
def initialize(_elements, _parent)
|
|
16
|
+
def initialize(_elements, _parent, _query)
|
|
16
17
|
@elements = _elements
|
|
18
|
+
@scope = if @elements.nil? then nil else :all end
|
|
17
19
|
@parent = _parent
|
|
20
|
+
@query = _query
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def frozen?
|
|
24
|
+
!backend.javascript_enabled? || @query.nil?
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
def root
|
|
@@ -29,17 +36,31 @@ module Pincers::Core
|
|
|
29
36
|
backend.document
|
|
30
37
|
end
|
|
31
38
|
|
|
39
|
+
def elements
|
|
40
|
+
reload_elements :all
|
|
41
|
+
@elements
|
|
42
|
+
end
|
|
43
|
+
|
|
32
44
|
def element
|
|
33
|
-
|
|
45
|
+
reload_elements :single
|
|
46
|
+
@elements.first
|
|
34
47
|
end
|
|
35
48
|
|
|
36
49
|
def element!
|
|
50
|
+
wait?(:present) unless frozen? or advanced_mode?
|
|
37
51
|
raise Pincers::EmptySetError.new self if empty?
|
|
38
52
|
element
|
|
39
53
|
end
|
|
40
54
|
|
|
55
|
+
def reload
|
|
56
|
+
raise Pincers::FrozenSetError.new self if frozen?
|
|
57
|
+
parent.reload if parent_needs_reload?
|
|
58
|
+
wrap_errors { reload_elements }
|
|
59
|
+
self
|
|
60
|
+
end
|
|
61
|
+
|
|
41
62
|
def each
|
|
42
|
-
elements.each { |el| yield
|
|
63
|
+
elements.each { |el| yield wrap_siblings [el] }
|
|
43
64
|
end
|
|
44
65
|
|
|
45
66
|
def [](*args)
|
|
@@ -48,31 +69,33 @@ module Pincers::Core
|
|
|
48
69
|
backend.extract_element_attribute element!, args[0]
|
|
49
70
|
end
|
|
50
71
|
else
|
|
51
|
-
|
|
72
|
+
wrap_siblings Array(elements.send(:[],*args))
|
|
52
73
|
end
|
|
53
74
|
end
|
|
54
75
|
|
|
55
76
|
def first
|
|
56
|
-
if
|
|
77
|
+
if element.nil? then nil else wrap_siblings [element] end
|
|
57
78
|
end
|
|
58
79
|
|
|
59
80
|
def first!
|
|
60
|
-
|
|
81
|
+
wrap_siblings [element!]
|
|
61
82
|
end
|
|
62
83
|
|
|
63
84
|
def last
|
|
64
|
-
if elements.last.nil? then nil else
|
|
85
|
+
if elements.last.nil? then nil else wrap_siblings [elements.last] end
|
|
65
86
|
end
|
|
66
87
|
|
|
67
88
|
def css(_selector, _options={})
|
|
68
|
-
|
|
69
|
-
|
|
89
|
+
wrap_errors do
|
|
90
|
+
query = Pincers::Support::Query.new backend, :css, _selector, _options[:limit]
|
|
91
|
+
wrap_childs query
|
|
70
92
|
end
|
|
71
93
|
end
|
|
72
94
|
|
|
73
95
|
def xpath(_selector, _options={})
|
|
74
|
-
|
|
75
|
-
|
|
96
|
+
wrap_errors do
|
|
97
|
+
query = Pincers::Support::Query.new backend, :xpath, _selector, _options[:limit]
|
|
98
|
+
wrap_childs query
|
|
76
99
|
end
|
|
77
100
|
end
|
|
78
101
|
|
|
@@ -84,7 +107,7 @@ module Pincers::Core
|
|
|
84
107
|
|
|
85
108
|
def text
|
|
86
109
|
wrap_errors do
|
|
87
|
-
backend.extract_element_text
|
|
110
|
+
elements.map { |e| backend.extract_element_text e }.join
|
|
88
111
|
end
|
|
89
112
|
end
|
|
90
113
|
|
|
@@ -94,18 +117,38 @@ module Pincers::Core
|
|
|
94
117
|
end
|
|
95
118
|
end
|
|
96
119
|
|
|
97
|
-
#
|
|
120
|
+
# input related
|
|
98
121
|
|
|
99
122
|
def set_text(_value)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
123
|
+
perform_action { |el| backend.set_element_text el, _value }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def click(*_modifiers)
|
|
127
|
+
perform_action { |el| backend.click_on_element el, _modifiers }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def right_click
|
|
131
|
+
perform_action { |el| backend.right_click_on_element el }
|
|
103
132
|
end
|
|
104
133
|
|
|
105
|
-
def
|
|
134
|
+
def double_click
|
|
135
|
+
perform_action { |el| backend.double_click_on_element el }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def hover
|
|
139
|
+
perform_action { |el| backend.hover_over_element el }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def drag_to(_element)
|
|
106
143
|
wrap_errors do
|
|
107
|
-
|
|
144
|
+
if advanced_mode?
|
|
145
|
+
wait_actionable
|
|
146
|
+
_element.wait_actionable
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
backend.drag_and_drop element!, _element.element!
|
|
108
150
|
end
|
|
151
|
+
self
|
|
109
152
|
end
|
|
110
153
|
|
|
111
154
|
# context related
|
|
@@ -114,8 +157,43 @@ module Pincers::Core
|
|
|
114
157
|
root.goto frame: self
|
|
115
158
|
end
|
|
116
159
|
|
|
160
|
+
# waiting
|
|
161
|
+
|
|
162
|
+
def wait?(_condition, _options={}, &_block)
|
|
163
|
+
poll_until(_condition, _options) do
|
|
164
|
+
case _condition
|
|
165
|
+
when :present
|
|
166
|
+
ensure_present
|
|
167
|
+
when :actionable
|
|
168
|
+
ensure_present and ensure_actionable
|
|
169
|
+
else
|
|
170
|
+
check_method = "check_#{_condition}"
|
|
171
|
+
raise Pincers::MissingFeatureError.new check_method unless backend.respond_to? check_method
|
|
172
|
+
ensure_present and check_method.call(elements)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def wait(_condition, _options)
|
|
178
|
+
raise Pincers::ConditionTimeoutError.new self, _condition unless wait?(_condition, _options)
|
|
179
|
+
return self
|
|
180
|
+
end
|
|
181
|
+
|
|
117
182
|
private
|
|
118
183
|
|
|
184
|
+
def advanced_mode?
|
|
185
|
+
root.advanced_mode?
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def ensure_present
|
|
189
|
+
reload if element.nil?
|
|
190
|
+
not element.nil?
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def ensure_actionable
|
|
194
|
+
backend.element_is_actionable? element
|
|
195
|
+
end
|
|
196
|
+
|
|
119
197
|
def wrap_errors
|
|
120
198
|
begin
|
|
121
199
|
yield
|
|
@@ -126,39 +204,57 @@ module Pincers::Core
|
|
|
126
204
|
end
|
|
127
205
|
end
|
|
128
206
|
|
|
129
|
-
def
|
|
130
|
-
SearchContext.new _elements, self
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def search_with_options(_options, &_block)
|
|
207
|
+
def perform_action
|
|
134
208
|
wrap_errors do
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
209
|
+
wait?(:actionable) unless advanced_mode?
|
|
210
|
+
raise Pincers::EmptySetError.new self if empty?
|
|
211
|
+
yield elements.first
|
|
138
212
|
end
|
|
213
|
+
self
|
|
139
214
|
end
|
|
140
215
|
|
|
141
|
-
def
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
216
|
+
def wrap_siblings(_elements)
|
|
217
|
+
SearchContext.new _elements, parent, nil
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def wrap_childs(_query)
|
|
221
|
+
child_elements = if advanced_mode? then _query.execute(elements) else nil end
|
|
222
|
+
SearchContext.new child_elements, self, _query
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def parent_needs_reload?
|
|
226
|
+
!parent.frozen? && parent.elements.count == 0
|
|
145
227
|
end
|
|
146
228
|
|
|
147
|
-
def
|
|
148
|
-
|
|
149
|
-
|
|
229
|
+
def reload_elements(_scope=nil)
|
|
230
|
+
case _scope
|
|
231
|
+
when :all
|
|
232
|
+
return if @scope == :all
|
|
233
|
+
@scope = :all
|
|
234
|
+
when :single
|
|
235
|
+
return unless @scope.nil?
|
|
236
|
+
@scope = :single
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
if @scope == :single
|
|
240
|
+
@elements = @query.execute parent.elements, 1 # force single record
|
|
241
|
+
else
|
|
242
|
+
@elements = @query.execute parent.elements
|
|
243
|
+
@scope = :all if @scope.nil?
|
|
244
|
+
end
|
|
245
|
+
end
|
|
150
246
|
|
|
247
|
+
def poll_until(_description, _options={})
|
|
151
248
|
timeout = _options.fetch :timeout, root.default_timeout
|
|
152
249
|
interval = _options.fetch :interval, root.default_interval
|
|
153
250
|
end_time = Time.now + timeout
|
|
154
251
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
return new_elements if backend.send check_method, new_elements
|
|
252
|
+
while Time.now <= end_time
|
|
253
|
+
return true if !!yield
|
|
158
254
|
sleep interval
|
|
159
255
|
end
|
|
160
256
|
|
|
161
|
-
|
|
257
|
+
return false
|
|
162
258
|
end
|
|
163
259
|
|
|
164
260
|
end
|
data/lib/pincers/errors.rb
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Pincers::Support
|
|
2
|
+
class Query
|
|
3
|
+
|
|
4
|
+
attr_reader :lang, :query, :limit
|
|
5
|
+
|
|
6
|
+
def initialize(_backend, _lang, _query, _limit)
|
|
7
|
+
@backend = _backend
|
|
8
|
+
@lang = _lang
|
|
9
|
+
@query = _query
|
|
10
|
+
@limit = _limit
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute(_elements, _force_limit=nil)
|
|
14
|
+
fun = case @lang
|
|
15
|
+
when :xpath then :search_by_xpath
|
|
16
|
+
else :search_by_css end
|
|
17
|
+
|
|
18
|
+
explode_elements _elements, fun, _force_limit || @limit
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def explode_elements(_elements, _fun, _limit)
|
|
22
|
+
_elements.inject([]) do |r, element|
|
|
23
|
+
limit = _limit.nil? ? nil : _limit - r.count
|
|
24
|
+
r = r + @backend.send(_fun, element, @query, limit)
|
|
25
|
+
break r if !_limit.nil? && r.length >= _limit
|
|
26
|
+
next r
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
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
|
+
version: 0.3.0
|
|
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-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: selenium-webdriver
|
|
@@ -224,6 +224,7 @@ files:
|
|
|
224
224
|
- lib/pincers/factory.rb
|
|
225
225
|
- lib/pincers/support/configuration.rb
|
|
226
226
|
- lib/pincers/support/cookie_jar.rb
|
|
227
|
+
- lib/pincers/support/query.rb
|
|
227
228
|
- lib/pincers/version.rb
|
|
228
229
|
- lib/pincers.rb
|
|
229
230
|
homepage: https://github.com/platanus/pincers
|