xpath 2.0.0 → 3.2.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 +7 -0
- data/README.md +6 -64
- data/lib/xpath/dsl.rb +141 -79
- data/lib/xpath/expression.rb +4 -2
- data/lib/xpath/literal.rb +2 -0
- data/lib/xpath/renderer.rb +34 -82
- data/lib/xpath/union.rb +4 -2
- data/lib/xpath/version.rb +3 -1
- data/lib/xpath.rb +4 -4
- data/spec/fixtures/simple.html +11 -3
- data/spec/spec_helper.rb +7 -0
- data/spec/union_spec.rb +15 -16
- data/spec/xpath_spec.rb +336 -123
- metadata +50 -80
- data/lib/xpath/html.rb +0 -175
- data/spec/html_spec.rb +0 -308
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
data/spec/html_spec.rb
DELETED
@@ -1,308 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'nokogiri'
|
3
|
-
|
4
|
-
describe XPath::HTML do
|
5
|
-
let(:template) { 'form' }
|
6
|
-
let(:template_path) { File.read(File.expand_path("fixtures/#{template}.html", File.dirname(__FILE__))) }
|
7
|
-
let(:doc) { Nokogiri::HTML(template_path) }
|
8
|
-
|
9
|
-
def get(*args)
|
10
|
-
all(*args).first
|
11
|
-
end
|
12
|
-
|
13
|
-
def all(*args)
|
14
|
-
type = example.metadata[:type]
|
15
|
-
doc.xpath(XPath::HTML.send(subject, *args).to_xpath(type)).map { |node| node[:data] }
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '#link' do
|
19
|
-
subject { :link }
|
20
|
-
|
21
|
-
it("finds links by id") { get('some-id').should == 'link-id' }
|
22
|
-
it("finds links by content") { get('An awesome link').should == 'link-text' }
|
23
|
-
it("finds links by content regardless of whitespace") { get('My whitespaced link').should == 'link-whitespace' }
|
24
|
-
it("finds links with child tags by content") { get('An emphatic link').should == 'link-children' }
|
25
|
-
it("finds links by the content of their child tags") { get('emphatic').should == 'link-children' }
|
26
|
-
it("finds links by approximate content") { get('awesome').should == 'link-text' }
|
27
|
-
it("finds links by title") { get('My title').should == 'link-title' }
|
28
|
-
it("finds links by approximate title") { get('title').should == 'link-title' }
|
29
|
-
it("finds links by image's alt attribute") { get('Alt link').should == 'link-img' }
|
30
|
-
it("finds links by image's approximate alt attribute") { get('Alt').should == 'link-img' }
|
31
|
-
it("does not find links without href attriutes") { get('Wrong Link').should be_nil }
|
32
|
-
it("casts to string") { get(:'some-id').should == 'link-id' }
|
33
|
-
|
34
|
-
context "with exact match", :type => :exact do
|
35
|
-
it("finds links by content") { get('An awesome link').should == 'link-text' }
|
36
|
-
it("does not find links by approximate content") { get('awesome').should be_nil }
|
37
|
-
it("finds links by title") { get('My title').should == 'link-title' }
|
38
|
-
it("does not find links by approximate title") { get('title').should be_nil }
|
39
|
-
it("finds links by image's alt attribute") { get('Alt link').should == 'link-img' }
|
40
|
-
it("does not find links by image's approximate alt attribute") { get('Alt').should be_nil }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe '#button' do
|
45
|
-
subject { :button }
|
46
|
-
|
47
|
-
context "with submit type" do
|
48
|
-
it("finds buttons by id") { get('submit-with-id').should == 'id-submit' }
|
49
|
-
it("finds buttons by value") { get('submit-with-value').should == 'value-submit' }
|
50
|
-
it("finds buttons by approximate value") { get('mit-with-val').should == 'value-submit' }
|
51
|
-
it("finds buttons by title") { get('My submit title').should == 'title-submit' }
|
52
|
-
it("finds buttons by approximate title") { get('submit title').should == 'title-submit' }
|
53
|
-
|
54
|
-
context "with exact match", :type => :exact do
|
55
|
-
it("finds buttons by value") { get('submit-with-value').should == 'value-submit' }
|
56
|
-
it("does not find buttons by approximate value") { get('mit-with-val').should be_nil }
|
57
|
-
it("finds buttons by title") { get('My submit title').should == 'title-submit' }
|
58
|
-
it("does not find buttons by approximate title") { get('submit title').should be_nil }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context "with reset type" do
|
63
|
-
it("finds buttons by id") { get('reset-with-id').should == 'id-reset' }
|
64
|
-
it("finds buttons by value") { get('reset-with-value').should == 'value-reset' }
|
65
|
-
it("finds buttons by approximate value") { get('set-with-val').should == 'value-reset' }
|
66
|
-
it("finds buttons by title") { get('My reset title').should == 'title-reset' }
|
67
|
-
it("finds buttons by approximate title") { get('reset title').should == 'title-reset' }
|
68
|
-
|
69
|
-
context "with exact match", :type => :exact do
|
70
|
-
it("finds buttons by value") { get('reset-with-value').should == 'value-reset' }
|
71
|
-
it("does not find buttons by approximate value") { get('set-with-val').should be_nil }
|
72
|
-
it("finds buttons by title") { get('My reset title').should == 'title-reset' }
|
73
|
-
it("does not find buttons by approximate title") { get('reset title').should be_nil }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context "with button type" do
|
78
|
-
it("finds buttons by id") { get('button-with-id').should == 'id-button' }
|
79
|
-
it("finds buttons by value") { get('button-with-value').should == 'value-button' }
|
80
|
-
it("finds buttons by approximate value") { get('ton-with-val').should == 'value-button' }
|
81
|
-
it("finds buttons by title") { get('My button title').should == 'title-button' }
|
82
|
-
it("finds buttons by approximate title") { get('button title').should == 'title-button' }
|
83
|
-
|
84
|
-
context "with exact match", :type => :exact do
|
85
|
-
it("finds buttons by value") { get('button-with-value').should == 'value-button' }
|
86
|
-
it("does not find buttons by approximate value") { get('ton-with-val').should be_nil }
|
87
|
-
it("finds buttons by title") { get('My button title').should == 'title-button' }
|
88
|
-
it("does not find buttons by approximate title") { get('button title').should be_nil }
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "with image type" do
|
93
|
-
it("finds buttons by id") { get('imgbut-with-id').should == 'id-imgbut' }
|
94
|
-
it("finds buttons by value") { get('imgbut-with-value').should == 'value-imgbut' }
|
95
|
-
it("finds buttons by approximate value") { get('gbut-with-val').should == 'value-imgbut' }
|
96
|
-
it("finds buttons by alt attribute") { get('imgbut-with-alt').should == 'alt-imgbut' }
|
97
|
-
it("finds buttons by approximate alt attribute") { get('mgbut-with-al').should == 'alt-imgbut' }
|
98
|
-
it("finds buttons by title") { get('My imgbut title').should == 'title-imgbut' }
|
99
|
-
it("finds buttons by approximate title") { get('imgbut title').should == 'title-imgbut' }
|
100
|
-
|
101
|
-
context "with exact match", :type => :exact do
|
102
|
-
it("finds buttons by value") { get('imgbut-with-value').should == 'value-imgbut' }
|
103
|
-
it("does not find buttons by approximate value") { get('gbut-with-val').should be_nil }
|
104
|
-
it("finds buttons by alt attribute") { get('imgbut-with-alt').should == 'alt-imgbut' }
|
105
|
-
it("does not find buttons by approximate alt attribute") { get('mgbut-with-al').should be_nil }
|
106
|
-
it("finds buttons by title") { get('My imgbut title').should == 'title-imgbut' }
|
107
|
-
it("does not find buttons by approximate title") { get('imgbut title').should be_nil }
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context "with button tag" do
|
112
|
-
it("finds buttons by id") { get('btag-with-id').should == 'id-btag' }
|
113
|
-
it("finds buttons by value") { get('btag-with-value').should == 'value-btag' }
|
114
|
-
it("finds buttons by approximate value") { get('tag-with-val').should == 'value-btag' }
|
115
|
-
it("finds buttons by text") { get('btag-with-text').should == 'text-btag' }
|
116
|
-
it("finds buttons by text ignoring whitespace") { get('My whitespaced button').should == 'btag-with-whitespace' }
|
117
|
-
it("finds buttons by approximate text ") { get('tag-with-tex').should == 'text-btag' }
|
118
|
-
it("finds buttons with child tags by text") { get('An emphatic button').should == 'btag-with-children' }
|
119
|
-
it("finds buttons by text of their children") { get('emphatic').should == 'btag-with-children' }
|
120
|
-
it("finds buttons by title") { get('My btag title').should == 'title-btag' }
|
121
|
-
it("finds buttons by approximate title") { get('btag title').should == 'title-btag' }
|
122
|
-
|
123
|
-
context "with exact match", :type => :exact do
|
124
|
-
it("finds buttons by value") { get('btag-with-value').should == 'value-btag' }
|
125
|
-
it("does not find buttons by approximate value") { get('tag-with-val').should be_nil }
|
126
|
-
it("finds buttons by text") { get('btag-with-text').should == 'text-btag' }
|
127
|
-
it("does not find buttons by approximate text ") { get('tag-with-tex').should be_nil }
|
128
|
-
it("finds buttons by title") { get('My btag title').should == 'title-btag' }
|
129
|
-
it("does not find buttons by approximate title") { get('btag title').should be_nil }
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
context "with unkown type" do
|
134
|
-
it("does not find the button") { get('schmoo button').should be_nil }
|
135
|
-
end
|
136
|
-
|
137
|
-
it("casts to string") { get(:'tag-with-tex').should == 'text-btag' }
|
138
|
-
end
|
139
|
-
|
140
|
-
describe '#fieldset' do
|
141
|
-
subject { :fieldset }
|
142
|
-
|
143
|
-
it("finds fieldsets by id") { get('some-fieldset-id').should == 'fieldset-id' }
|
144
|
-
it("finds fieldsets by legend") { get('Some Legend').should == 'fieldset-legend' }
|
145
|
-
it("finds fieldsets by legend child tags") { get('Span Legend').should == 'fieldset-legend-span' }
|
146
|
-
it("accepts approximate legends") { get('Legend').should == 'fieldset-legend' }
|
147
|
-
it("finds nested fieldsets by legend") { get('Inner legend').should == 'fieldset-inner' }
|
148
|
-
it("casts to string") { get(:'Inner legend').should == 'fieldset-inner' }
|
149
|
-
|
150
|
-
context "with exact match", :type => :exact do
|
151
|
-
it("finds fieldsets by legend") { get('Some Legend').should == 'fieldset-legend' }
|
152
|
-
it("does not find by approximate legends") { get('Legend').should be_nil }
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
describe '#field' do
|
157
|
-
subject { :field }
|
158
|
-
|
159
|
-
context "by id" do
|
160
|
-
it("finds inputs with no type") { get('input-with-id').should == 'input-with-id-data' }
|
161
|
-
it("finds inputs with text type") { get('input-text-with-id').should == 'input-text-with-id-data' }
|
162
|
-
it("finds inputs with password type") { get('input-password-with-id').should == 'input-password-with-id-data' }
|
163
|
-
it("finds inputs with custom type") { get('input-custom-with-id').should == 'input-custom-with-id-data' }
|
164
|
-
it("finds textareas") { get('textarea-with-id').should == 'textarea-with-id-data' }
|
165
|
-
it("finds select boxes") { get('select-with-id').should == 'select-with-id-data' }
|
166
|
-
it("does not find submit buttons") { get('input-submit-with-id').should be_nil }
|
167
|
-
it("does not find image buttons") { get('input-image-with-id').should be_nil }
|
168
|
-
it("does not find hidden fields") { get('input-hidden-with-id').should be_nil }
|
169
|
-
end
|
170
|
-
|
171
|
-
context "by name" do
|
172
|
-
it("finds inputs with no type") { get('input-with-name').should == 'input-with-name-data' }
|
173
|
-
it("finds inputs with text type") { get('input-text-with-name').should == 'input-text-with-name-data' }
|
174
|
-
it("finds inputs with password type") { get('input-password-with-name').should == 'input-password-with-name-data' }
|
175
|
-
it("finds inputs with custom type") { get('input-custom-with-name').should == 'input-custom-with-name-data' }
|
176
|
-
it("finds textareas") { get('textarea-with-name').should == 'textarea-with-name-data' }
|
177
|
-
it("finds select boxes") { get('select-with-name').should == 'select-with-name-data' }
|
178
|
-
it("does not find submit buttons") { get('input-submit-with-name').should be_nil }
|
179
|
-
it("does not find image buttons") { get('input-image-with-name').should be_nil }
|
180
|
-
it("does not find hidden fields") { get('input-hidden-with-name').should be_nil }
|
181
|
-
end
|
182
|
-
|
183
|
-
context "by placeholder" do
|
184
|
-
it("finds inputs with no type") { get('input-with-placeholder').should == 'input-with-placeholder-data' }
|
185
|
-
it("finds inputs with text type") { get('input-text-with-placeholder').should == 'input-text-with-placeholder-data' }
|
186
|
-
it("finds inputs with password type") { get('input-password-with-placeholder').should == 'input-password-with-placeholder-data' }
|
187
|
-
it("finds inputs with custom type") { get('input-custom-with-placeholder').should == 'input-custom-with-placeholder-data' }
|
188
|
-
it("finds textareas") { get('textarea-with-placeholder').should == 'textarea-with-placeholder-data' }
|
189
|
-
it("does not find hidden fields") { get('input-hidden-with-placeholder').should be_nil }
|
190
|
-
end
|
191
|
-
|
192
|
-
context "by referenced label" do
|
193
|
-
it("finds inputs with no type") { get('Input with label').should == 'input-with-label-data' }
|
194
|
-
it("finds inputs with text type") { get('Input text with label').should == 'input-text-with-label-data' }
|
195
|
-
it("finds inputs with password type") { get('Input password with label').should == 'input-password-with-label-data' }
|
196
|
-
it("finds inputs with custom type") { get('Input custom with label').should == 'input-custom-with-label-data' }
|
197
|
-
it("finds textareas") { get('Textarea with label').should == 'textarea-with-label-data' }
|
198
|
-
it("finds select boxes") { get('Select with label').should == 'select-with-label-data' }
|
199
|
-
it("does not find submit buttons") { get('Input submit with label').should be_nil }
|
200
|
-
it("does not find image buttons") { get('Input image with label').should be_nil }
|
201
|
-
it("does not find hidden fields") { get('Input hidden with label').should be_nil }
|
202
|
-
end
|
203
|
-
|
204
|
-
context "by parent label" do
|
205
|
-
it("finds inputs with no type") { get('Input with parent label').should == 'input-with-parent-label-data' }
|
206
|
-
it("finds inputs with text type") { get('Input text with parent label').should == 'input-text-with-parent-label-data' }
|
207
|
-
it("finds inputs with password type") { get('Input password with parent label').should == 'input-password-with-parent-label-data' }
|
208
|
-
it("finds inputs with custom type") { get('Input custom with parent label').should == 'input-custom-with-parent-label-data' }
|
209
|
-
it("finds textareas") { get('Textarea with parent label').should == 'textarea-with-parent-label-data' }
|
210
|
-
it("finds select boxes") { get('Select with parent label').should == 'select-with-parent-label-data' }
|
211
|
-
it("does not find submit buttons") { get('Input submit with parent label').should be_nil }
|
212
|
-
it("does not find image buttons") { get('Input image with parent label').should be_nil }
|
213
|
-
it("does not find hidden fields") { get('Input hidden with parent label').should be_nil }
|
214
|
-
end
|
215
|
-
|
216
|
-
it("casts to string") { get(:'select-with-id').should == 'select-with-id-data' }
|
217
|
-
end
|
218
|
-
|
219
|
-
describe '#fillable_field' do
|
220
|
-
subject{ :fillable_field }
|
221
|
-
context "by parent label" do
|
222
|
-
it("finds inputs with text type") { get('Label text').should == 'id-text' }
|
223
|
-
it("finds inputs where label has problem chars") { get("Label text's got an apostrophe").should == 'id-problem-text' }
|
224
|
-
end
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
describe '#select' do
|
229
|
-
subject{ :select }
|
230
|
-
it("finds selects by id") { get('select-with-id').should == 'select-with-id-data' }
|
231
|
-
it("finds selects by name") { get('select-with-name').should == 'select-with-name-data' }
|
232
|
-
it("finds selects by label") { get('Select with label').should == 'select-with-label-data' }
|
233
|
-
it("finds selects by parent label") { get('Select with parent label').should == 'select-with-parent-label-data' }
|
234
|
-
it("casts to string") { get(:'Select with parent label').should == 'select-with-parent-label-data' }
|
235
|
-
end
|
236
|
-
|
237
|
-
describe '#checkbox' do
|
238
|
-
subject{ :checkbox }
|
239
|
-
it("finds checkboxes by id") { get('input-checkbox-with-id').should == 'input-checkbox-with-id-data' }
|
240
|
-
it("finds checkboxes by name") { get('input-checkbox-with-name').should == 'input-checkbox-with-name-data' }
|
241
|
-
it("finds checkboxes by label") { get('Input checkbox with label').should == 'input-checkbox-with-label-data' }
|
242
|
-
it("finds checkboxes by parent label") { get('Input checkbox with parent label').should == 'input-checkbox-with-parent-label-data' }
|
243
|
-
it("casts to string") { get(:'Input checkbox with parent label').should == 'input-checkbox-with-parent-label-data' }
|
244
|
-
end
|
245
|
-
|
246
|
-
describe '#radio_button' do
|
247
|
-
subject{ :radio_button }
|
248
|
-
it("finds radio buttons by id") { get('input-radio-with-id').should == 'input-radio-with-id-data' }
|
249
|
-
it("finds radio buttons by name") { get('input-radio-with-name').should == 'input-radio-with-name-data' }
|
250
|
-
it("finds radio buttons by label") { get('Input radio with label').should == 'input-radio-with-label-data' }
|
251
|
-
it("finds radio buttons by parent label") { get('Input radio with parent label').should == 'input-radio-with-parent-label-data' }
|
252
|
-
it("casts to string") { get(:'Input radio with parent label').should == 'input-radio-with-parent-label-data' }
|
253
|
-
end
|
254
|
-
|
255
|
-
describe '#file_field' do
|
256
|
-
subject{ :file_field }
|
257
|
-
it("finds file fields by id") { get('input-file-with-id').should == 'input-file-with-id-data' }
|
258
|
-
it("finds file fields by name") { get('input-file-with-name').should == 'input-file-with-name-data' }
|
259
|
-
it("finds file fields by label") { get('Input file with label').should == 'input-file-with-label-data' }
|
260
|
-
it("finds file fields by parent label") { get('Input file with parent label').should == 'input-file-with-parent-label-data' }
|
261
|
-
it("casts to string") { get(:'Input file with parent label').should == 'input-file-with-parent-label-data' }
|
262
|
-
end
|
263
|
-
|
264
|
-
describe "#optgroup" do
|
265
|
-
subject { :optgroup }
|
266
|
-
it("finds optgroups by label") { get('Group A').should == 'optgroup-a' }
|
267
|
-
it("finds optgroups by approximate label") { get('oup A').should == 'optgroup-a' }
|
268
|
-
it("casts to string") { get(:'Group A').should == 'optgroup-a' }
|
269
|
-
|
270
|
-
context "with exact match", :type => :exact do
|
271
|
-
it("finds by label") { get('Group A').should == 'optgroup-a' }
|
272
|
-
it("does not find by approximate label") { get('oup A').should be_nil }
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
describe '#option' do
|
277
|
-
subject{ :option }
|
278
|
-
it("finds by text") { get('Option with text').should == 'option-with-text-data' }
|
279
|
-
it("finds by approximate text") { get('Option with').should == 'option-with-text-data' }
|
280
|
-
it("casts to string") { get(:'Option with text').should == 'option-with-text-data' }
|
281
|
-
|
282
|
-
context "with exact match", :type => :exact do
|
283
|
-
it("finds by text") { get('Option with text').should == 'option-with-text-data' }
|
284
|
-
it("does not find by approximate text") { get('Option with').should be_nil }
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
describe "#table" do
|
289
|
-
subject {:table}
|
290
|
-
it("finds by id") { get('table-with-id').should == 'table-with-id-data' }
|
291
|
-
it("finds by caption") { get('Table with caption').should == 'table-with-caption-data' }
|
292
|
-
it("finds by approximate caption") { get('Table with').should == 'table-with-caption-data' }
|
293
|
-
it("casts to string") { get(:'Table with caption').should == 'table-with-caption-data' }
|
294
|
-
|
295
|
-
context "with exact match", :type => :exact do
|
296
|
-
it("finds by caption") { get('Table with caption').should == 'table-with-caption-data' }
|
297
|
-
it("does not find by approximate caption") { get('Table with').should be_nil }
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
describe "#definition_description" do
|
302
|
-
subject {:definition_description}
|
303
|
-
let(:template) {'stuff'}
|
304
|
-
it("find definition description by id") { get('latte').should == "with-id" }
|
305
|
-
it("find definition description by term") { get("Milk").should == "with-dt" }
|
306
|
-
it("casts to string") { get(:"Milk").should == "with-dt" }
|
307
|
-
end
|
308
|
-
end
|
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Q�יִ.�C�����hiΑj�5hg/�Ϋ!7�z�4� <X��Yn�W�o��A��U����W�]?��5S�,�mj�/Iqp<��|�~��Q�ݺS���ޟD-��@�x�oɶT� K~o{���qΣT���J���F{� �za�=�չ��36���+;SC������1�S&�/I�d���O�8�Nz�`F�4��Y�c�X��G�S�rj4�U�7D�(�{���AO�k�k�u���xa���;��vG�
|