xpath 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce787a09ca48f5c96580cbced2533d00b741a0e3
4
- data.tar.gz: c4310006453b0029c593077b225d36e79dfd35af
3
+ metadata.gz: ae41f677ac864edf9c7689365012dc5f73731f61
4
+ data.tar.gz: 63f10b70109aa842ac464b8491071a286b583f4c
5
5
  SHA512:
6
- metadata.gz: 83b64861c13aecd52661c7cbc598f90c4a17aeb71c86936f0bec36d97ffe4248fc8302cad434742b95074b6aded1de563c33a3f82df12e4baf42d10c42d132ac
7
- data.tar.gz: bc2e7c29f1240475904601bc7f8ad2ecda2978536b97e1ab407bc855ec16b7f64b48cc49400a501833bb8ac643bcc8b1e2052d4a05974c3df7ca0355ac26fe4e
6
+ metadata.gz: 7683342805b10e97fcb6593148c0beedb6ad43b7087915697b4a87b4127d88d1669e9e3d6a630a019a500c2203eff4a8b6c702e8bedb313ee41ca1ad726be446
7
+ data.tar.gz: 4d9146f6cd818e364b94b95f219d40a70571c33a01faa58af9feccb7d3f40d7f0e1b0d9093ef1aec4aae2429859001fa15e341a032a4248575804886e0fd8344
@@ -5,7 +5,6 @@ require 'xpath/expression'
5
5
  require 'xpath/literal'
6
6
  require 'xpath/union'
7
7
  require 'xpath/renderer'
8
- require 'xpath/html'
9
8
 
10
9
  module XPath
11
10
  extend XPath::DSL
@@ -68,7 +68,7 @@ module XPath
68
68
 
69
69
  METHODS = [
70
70
  # node set
71
- :count, :id, :local_name, :namespace_uri, :name,
71
+ :count, :id, :local_name, :namespace_uri,
72
72
  # string
73
73
  :string, :concat, :starts_with, :contains, :substring_before,
74
74
  :substring_after, :substring, :string_length, :normalize_space,
@@ -86,8 +86,13 @@ module XPath
86
86
  end
87
87
  end
88
88
 
89
+ def qname
90
+ method(:name)
91
+ end
92
+
89
93
  alias_method :inverse, :not
90
94
  alias_method :~, :not
95
+ alias_method :!, :not
91
96
  alias_method :normalize, :normalize_space
92
97
  alias_method :n, :normalize_space
93
98
 
@@ -95,6 +100,7 @@ module XPath
95
100
  [:equals, :"=", :==],
96
101
  [:or, :or, :|],
97
102
  [:and, :and, :&],
103
+ [:not_equals, :!=, :!=],
98
104
  [:lte, :<=, :<=],
99
105
  [:lt, :<, :<],
100
106
  [:gte, :>=, :>=],
@@ -128,6 +134,10 @@ module XPath
128
134
 
129
135
  alias_method :self_axis, :self
130
136
 
137
+ def contains_word(word)
138
+ function(:concat, " ", current.normalize_space, " ").contains(" #{word} ")
139
+ end
140
+
131
141
  def one_of(*expressions)
132
142
  expressions.map do |e|
133
143
  current.equals(e)
@@ -1,3 +1,3 @@
1
1
  module XPath
2
- VERSION = '2.1.0'
2
+ VERSION = '3.0.0'
3
3
  end
@@ -17,7 +17,7 @@
17
17
 
18
18
  <div id="woo" title="wooDiv" data="id">
19
19
  <ul><li>A list</li></ul>
20
- <p title="gorilla">Bax</p>
20
+ <p class="cat fish dog" title="gorilla">Bax</p>
21
21
  <p>Bax</p>
22
22
  <p id="wooDiv">Blah</p>
23
23
  </div>
@@ -26,7 +26,7 @@
26
26
 
27
27
  <div id="preference">
28
28
  <p id="is-fuzzy">allamas</p>
29
- <p id="is-exact">llama</p>
29
+ <p class="fish" id="is-exact">llama</p>
30
30
  </div>
31
31
 
32
32
  <p id="whitespace">
@@ -37,7 +37,7 @@
37
37
  </p>
38
38
 
39
39
  <div id="moar">
40
- <p id="impchay">chimp</p>
40
+ <p class="catfish" id="impchay">chimp</p>
41
41
  <div id="elephantay">elephant</div>
42
42
  <p id="amingoflay">flamingo</p>
43
43
  </div>
@@ -9,7 +9,7 @@ describe XPath::Union do
9
9
  @expr1 = XPath.generate { |x| x.descendant(:p) }
10
10
  @expr2 = XPath.generate { |x| x.descendant(:div) }
11
11
  @collection = XPath::Union.new(@expr1, @expr2)
12
- @collection.expressions.should == [@expr1, @expr2]
12
+ @collection.expressions.should eq [@expr1, @expr2]
13
13
  end
14
14
  end
15
15
 
@@ -20,7 +20,7 @@ describe XPath::Union do
20
20
  @collection = XPath::Union.new(@expr1, @expr2)
21
21
  exprs = []
22
22
  @collection.each { |expr| exprs << expr }
23
- exprs.should == [@expr1, @expr2]
23
+ exprs.should eq [@expr1, @expr2]
24
24
  end
25
25
  end
26
26
 
@@ -29,7 +29,7 @@ describe XPath::Union do
29
29
  @expr1 = XPath.generate { |x| x.descendant(:p) }
30
30
  @expr2 = XPath.generate { |x| x.descendant(:div) }
31
31
  @collection = XPath::Union.new(@expr1, @expr2)
32
- @collection.map { |expr| expr.expression }.should == [:descendant, :descendant]
32
+ @collection.map { |expr| expr.expression }.should eq [:descendant, :descendant]
33
33
  end
34
34
  end
35
35
 
@@ -39,9 +39,9 @@ describe XPath::Union do
39
39
  @expr2 = XPath.generate { |x| x.descendant(:div).where(x.attr(:id) == 'foo') }
40
40
  @collection = XPath::Union.new(@expr1, @expr2)
41
41
  @results = doc.xpath(@collection.to_xpath)
42
- @results[0][:title].should == 'fooDiv'
43
- @results[1].text.should == 'Blah'
44
- @results[2].text.should == 'Bax'
42
+ @results[0][:title].should eq 'fooDiv'
43
+ @results[1].text.should eq 'Blah'
44
+ @results[2].text.should eq 'Bax'
45
45
  end
46
46
  end
47
47
 
@@ -54,9 +54,9 @@ describe XPath::Union do
54
54
  @xpath1 = @collection.where(XPath.attr(:id) == 'foo').to_xpath
55
55
  @xpath2 = @collection.where(XPath.attr(:id) == 'fooDiv').to_xpath
56
56
  @results = doc.xpath(@xpath1)
57
- @results[0][:title].should == 'fooDiv'
57
+ @results[0][:title].should eq 'fooDiv'
58
58
  @results = doc.xpath(@xpath2)
59
- @results[0][:id].should == 'fooDiv'
59
+ @results[0][:id].should eq 'fooDiv'
60
60
  end
61
61
  end
62
62
 
@@ -20,14 +20,14 @@ describe XPath do
20
20
 
21
21
  it "should work as a mixin" do
22
22
  xpath = Thingy.new.foo_div.to_xpath
23
- doc.xpath(xpath).first[:title].should == 'fooDiv'
23
+ doc.xpath(xpath).first[:title].should eq 'fooDiv'
24
24
  end
25
25
 
26
26
  describe '#descendant' do
27
27
  it "should find nodes that are nested below the current node" do
28
28
  @results = xpath { |x| x.descendant(:p) }
29
- @results[0].text.should == "Blah"
30
- @results[1].text.should == "Bax"
29
+ @results[0].text.should eq "Blah"
30
+ @results[1].text.should eq "Bax"
31
31
  end
32
32
 
33
33
  it "should not find nodes outside the context" do
@@ -40,22 +40,22 @@ describe XPath do
40
40
 
41
41
  it "should find multiple kinds of nodes" do
42
42
  @results = xpath { |x| x.descendant(:p, :ul) }
43
- @results[0].text.should == 'Blah'
44
- @results[3].text.should == 'A list'
43
+ @results[0].text.should eq 'Blah'
44
+ @results[3].text.should eq 'A list'
45
45
  end
46
46
 
47
47
  it "should find all nodes when no arguments given" do
48
48
  @results = xpath { |x| x.descendant[x.attr(:id) == 'foo'].descendant }
49
- @results[0].text.should == 'Blah'
50
- @results[4].text.should == 'A list'
49
+ @results[0].text.should eq 'Blah'
50
+ @results[4].text.should eq 'A list'
51
51
  end
52
52
  end
53
53
 
54
54
  describe '#child' do
55
55
  it "should find nodes that are nested directly below the current node" do
56
56
  @results = xpath { |x| x.descendant(:div).child(:p) }
57
- @results[0].text.should == "Blah"
58
- @results[1].text.should == "Bax"
57
+ @results[0].text.should eq "Blah"
58
+ @results[1].text.should eq "Bax"
59
59
  end
60
60
 
61
61
  it "should not find nodes that are nested further down below the current node" do
@@ -65,46 +65,46 @@ describe XPath do
65
65
 
66
66
  it "should find multiple kinds of nodes" do
67
67
  @results = xpath { |x| x.descendant(:div).child(:p, :ul) }
68
- @results[0].text.should == 'Blah'
69
- @results[3].text.should == 'A list'
68
+ @results[0].text.should eq 'Blah'
69
+ @results[3].text.should eq 'A list'
70
70
  end
71
71
 
72
72
  it "should find all nodes when no arguments given" do
73
73
  @results = xpath { |x| x.descendant[x.attr(:id) == 'foo'].child }
74
- @results[0].text.should == 'Blah'
75
- @results[3].text.should == 'A list'
74
+ @results[0].text.should eq 'Blah'
75
+ @results[3].text.should eq 'A list'
76
76
  end
77
77
  end
78
78
 
79
79
  describe '#axis' do
80
80
  it "should find nodes given the xpath axis" do
81
81
  @results = xpath { |x| x.axis(:descendant, :p) }
82
- @results[0].text.should == "Blah"
82
+ @results[0].text.should eq "Blah"
83
83
  end
84
84
 
85
85
  it "should find nodes given the xpath axis without a specific tag" do
86
86
  @results = xpath { |x| x.descendant(:div)[x.attr(:id) == 'foo'].axis(:descendant) }
87
- @results[0][:id].should == "fooDiv"
87
+ @results[0][:id].should eq "fooDiv"
88
88
  end
89
89
  end
90
90
 
91
91
  describe '#next_sibling' do
92
92
  it "should find nodes which are immediate siblings of the current node" do
93
- xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:p) }.first.text.should == 'Bax'
94
- xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :p) }.first.text.should == 'Bax'
95
- xpath { |x| x.descendant(:p)[x.attr(:title) == 'monkey'].next_sibling(:ul, :p) }.first.text.should == 'A list'
93
+ xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:p) }.first.text.should eq 'Bax'
94
+ xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :p) }.first.text.should eq 'Bax'
95
+ xpath { |x| x.descendant(:p)[x.attr(:title) == 'monkey'].next_sibling(:ul, :p) }.first.text.should eq 'A list'
96
96
  xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :li) }.first.should be_nil
97
- xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling }.first.text.should == 'Bax'
97
+ xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling }.first.text.should eq 'Bax'
98
98
  end
99
99
  end
100
100
 
101
101
  describe '#previous_sibling' do
102
102
  it "should find nodes which are exactly preceding the current node" do
103
- xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:p) }.first.text.should == 'Bax'
104
- xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :p) }.first.text.should == 'Bax'
105
- xpath { |x| x.descendant(:p)[x.attr(:title) == 'gorilla'].previous_sibling(:ul, :p) }.first.text.should == 'A list'
103
+ xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:p) }.first.text.should eq 'Bax'
104
+ xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :p) }.first.text.should eq 'Bax'
105
+ xpath { |x| x.descendant(:p)[x.attr(:title) == 'gorilla'].previous_sibling(:ul, :p) }.first.text.should eq 'A list'
106
106
  xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :li) }.first.should be_nil
107
- xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling }.first.text.should == 'Bax'
107
+ xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling }.first.text.should eq 'Bax'
108
108
  end
109
109
  end
110
110
 
@@ -114,7 +114,7 @@ describe XPath do
114
114
  foo_div = x.anywhere(:div).where(x.attr(:id) == 'foo')
115
115
  x.descendant(:p).where(x.attr(:id) == foo_div.attr(:title))
116
116
  end
117
- @results[0].text.should == "Blah"
117
+ @results[0].text.should eq "Blah"
118
118
  end
119
119
 
120
120
  it "should find multiple kinds of nodes regardless of the context" do
@@ -123,10 +123,10 @@ describe XPath do
123
123
  context.anywhere(:p, :ul)
124
124
  end
125
125
 
126
- @results[0].text.should == 'Blah'
127
- @results[3].text.should == 'A list'
128
- @results[4].text.should == 'A list'
129
- @results[6].text.should == 'Bax'
126
+ @results[0].text.should eq 'Blah'
127
+ @results[3].text.should eq 'A list'
128
+ @results[4].text.should eq 'A list'
129
+ @results[6].text.should eq 'Bax'
130
130
  end
131
131
 
132
132
  it "should find all nodes when no arguments given regardless of the context" do
@@ -134,13 +134,13 @@ describe XPath do
134
134
  context=x.descendant(:div).where(x.attr(:id)=='woo')
135
135
  context.anywhere
136
136
  end
137
- @results[0].name.should == 'html'
138
- @results[1].name.should == 'head'
139
- @results[2].name.should == 'body'
140
- @results[6].text.should == 'Blah'
141
- @results[10].text.should == 'A list'
142
- @results[13].text.should == 'A list'
143
- @results[15].text.should == 'Bax'
137
+ @results[0].name.should eq 'html'
138
+ @results[1].name.should eq 'head'
139
+ @results[2].name.should eq 'body'
140
+ @results[6].text.should eq 'Blah'
141
+ @results[10].text.should eq 'A list'
142
+ @results[13].text.should eq 'A list'
143
+ @results[15].text.should eq 'Bax'
144
144
  end
145
145
 
146
146
  end
@@ -150,7 +150,7 @@ describe XPath do
150
150
  @results = xpath do |x|
151
151
  x.descendant(:div).where(x.attr(:title).contains('ooD'))
152
152
  end
153
- @results[0][:id].should == "foo"
153
+ @results[0][:id].should eq "foo"
154
154
  end
155
155
 
156
156
  it "should find nodes that contain the given expression" do
@@ -158,7 +158,18 @@ describe XPath do
158
158
  expression = x.anywhere(:div).where(x.attr(:title) == 'fooDiv').attr(:id)
159
159
  x.descendant(:div).where(x.attr(:title).contains(expression))
160
160
  end
161
- @results[0][:id].should == "foo"
161
+ @results[0][:id].should eq "foo"
162
+ end
163
+ end
164
+
165
+ describe "#contains_word" do
166
+ it "should find nodes that contain the given word in its entirety" do
167
+ @results = xpath do |x|
168
+ x.descendant.where(x.attr(:class).contains_word('fish'))
169
+ end
170
+ @results[0].text.should eq "Bax"
171
+ @results[1].text.should eq "llama"
172
+ @results.length.should eq 2
162
173
  end
163
174
  end
164
175
 
@@ -167,9 +178,9 @@ describe XPath do
167
178
  @results = xpath do |x|
168
179
  x.descendant(:*).where(x.attr(:id).starts_with('foo'))
169
180
  end
170
- @results.size.should == 2
171
- @results[0][:id].should == "foo"
172
- @results[1][:id].should == "fooDiv"
181
+ @results.size.should eq 2
182
+ @results[0][:id].should eq "foo"
183
+ @results[1][:id].should eq "fooDiv"
173
184
  end
174
185
 
175
186
  it "should find nodes that contain the given expression" do
@@ -177,17 +188,17 @@ describe XPath do
177
188
  expression = x.anywhere(:div).where(x.attr(:title) == 'fooDiv').attr(:id)
178
189
  x.descendant(:div).where(x.attr(:title).starts_with(expression))
179
190
  end
180
- @results[0][:id].should == "foo"
191
+ @results[0][:id].should eq "foo"
181
192
  end
182
193
  end
183
194
 
184
195
  describe '#text' do
185
196
  it "should select a node's text" do
186
197
  @results = xpath { |x| x.descendant(:p).where(x.text == 'Bax') }
187
- @results[0].text.should == 'Bax'
188
- @results[1][:title].should == 'monkey'
198
+ @results[0].text.should eq 'Bax'
199
+ @results[1][:title].should eq 'monkey'
189
200
  @results = xpath { |x| x.descendant(:div).where(x.descendant(:p).text == 'Bax') }
190
- @results[0][:title].should == 'fooDiv'
201
+ @results[0][:title].should eq 'fooDiv'
191
202
  end
192
203
  end
193
204
 
@@ -195,14 +206,14 @@ describe XPath do
195
206
  context "when called with one argument" do
196
207
  it "should select the part of a string after the specified character" do
197
208
  @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "substring").text.substring(7) }
198
- @results.should == "there"
209
+ @results.should eq "there"
199
210
  end
200
211
  end
201
212
 
202
213
  context "when called with two arguments" do
203
214
  it "should select the part of a string after the specified character, up to the given length" do
204
215
  @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "substring").text.substring(2, 4) }
205
- @results.should == "ello"
216
+ @results.should eq "ello"
206
217
  end
207
218
  end
208
219
  end
@@ -210,63 +221,78 @@ describe XPath do
210
221
  describe '#function' do
211
222
  it "should call the given xpath function" do
212
223
  @results = xpath { |x| x.function(:boolean, x.function(:true) == x.function(:false)) }
213
- @results.should == false
224
+ @results.should eq false
214
225
  end
215
226
  end
216
227
 
217
228
  describe '#method' do
218
229
  it "should call the given xpath function with the current node as the first argument" do
219
230
  @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "string-length").text.method(:"string-length") }
220
- @results.should == 11
231
+ @results.should eq 11
221
232
  end
222
233
  end
223
234
 
224
235
  describe '#string_length' do
225
236
  it "should return the length of a string" do
226
237
  @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "string-length").text.string_length }
227
- @results.should == 11
238
+ @results.should eq 11
228
239
  end
229
240
  end
230
241
 
231
242
  describe '#where' do
232
243
  it "should limit the expression to find only certain nodes" do
233
- xpath { |x| x.descendant(:div).where(:"@id = 'foo'") }.first[:title].should == "fooDiv"
244
+ xpath { |x| x.descendant(:div).where(:"@id = 'foo'") }.first[:title].should eq "fooDiv"
234
245
  end
235
246
 
236
247
  it "should be aliased as []" do
237
- xpath { |x| x.descendant(:div)[:"@id = 'foo'"] }.first[:title].should == "fooDiv"
248
+ xpath { |x| x.descendant(:div)[:"@id = 'foo'"] }.first[:title].should eq "fooDiv"
238
249
  end
239
250
  end
240
251
 
241
252
  describe '#inverse' do
242
253
  it "should invert the expression" do
243
- xpath { |x| x.descendant(:p).where(x.attr(:id).equals('fooDiv').inverse) }.first.text.should == 'Bax'
254
+ xpath { |x| x.descendant(:p).where(x.attr(:id).equals('fooDiv').inverse) }.first.text.should eq 'Bax'
244
255
  end
245
256
 
246
257
  it "should be aliased as the unary tilde" do
247
- xpath { |x| x.descendant(:p).where(~x.attr(:id).equals('fooDiv')) }.first.text.should == 'Bax'
258
+ xpath { |x| x.descendant(:p).where(~x.attr(:id).equals('fooDiv')) }.first.text.should eq 'Bax'
259
+ end
260
+
261
+ it "should be aliased as the unary bang" do
262
+ xpath { |x| x.descendant(:p).where(!x.attr(:id).equals('fooDiv')) }.first.text.should eq 'Bax'
248
263
  end
249
264
  end
250
265
 
251
266
  describe '#equals' do
252
267
  it "should limit the expression to find only certain nodes" do
253
- xpath { |x| x.descendant(:div).where(x.attr(:id).equals('foo')) }.first[:title].should == "fooDiv"
268
+ xpath { |x| x.descendant(:div).where(x.attr(:id).equals('foo')) }.first[:title].should eq "fooDiv"
254
269
  end
255
270
 
256
271
  it "should be aliased as ==" do
257
- xpath { |x| x.descendant(:div).where(x.attr(:id) == 'foo') }.first[:title].should == "fooDiv"
272
+ xpath { |x| x.descendant(:div).where(x.attr(:id) == 'foo') }.first[:title].should eq "fooDiv"
258
273
  end
259
274
  end
260
275
 
276
+ describe '#not_equals' do
277
+ it "should match only when not equal" do
278
+ xpath { |x| x.descendant(:div).where(x.attr(:id).not_equals('bar')) }.first[:title].should eq "fooDiv"
279
+ end
280
+
281
+ it "should be aliased as !=" do
282
+ xpath { |x| x.descendant(:div).where(x.attr(:id) != 'bar') }.first[:title].should eq "fooDiv"
283
+ end
284
+ end
285
+
286
+
261
287
  describe '#is' do
262
288
  it "uses equality when :exact given" do
263
- xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title].should == "fooDiv"
289
+ xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title].should eq "fooDiv"
264
290
  xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first.should be_nil
265
291
  end
266
292
 
267
293
  it "uses substring matching otherwise" do
268
- xpath { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title].should == "fooDiv"
269
- xpath { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first[:title].should == "fooDiv"
294
+ xpath { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title].should eq "fooDiv"
295
+ xpath { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first[:title].should eq "fooDiv"
270
296
  end
271
297
  end
272
298
 
@@ -276,9 +302,9 @@ describe XPath do
276
302
  p = x.anywhere(:div).where(x.attr(:id) == 'foo').attr(:title)
277
303
  x.descendant(:*).where(x.attr(:id).one_of('foo', p, 'baz'))
278
304
  end
279
- @results[0][:title].should == "fooDiv"
280
- @results[1].text.should == "Blah"
281
- @results[2][:title].should == "bazDiv"
305
+ @results[0][:title].should eq "fooDiv"
306
+ @results[1].text.should eq "Blah"
307
+ @results[2][:title].should eq "bazDiv"
282
308
  end
283
309
  end
284
310
 
@@ -287,14 +313,14 @@ describe XPath do
287
313
  @results = xpath do |x|
288
314
  x.descendant(:*).where(x.contains('Bax').and(x.attr(:title).equals('monkey')))
289
315
  end
290
- @results[0][:title].should == "monkey"
316
+ @results[0][:title].should eq "monkey"
291
317
  end
292
318
 
293
319
  it "should be aliased as ampersand (&)" do
294
320
  @results = xpath do |x|
295
321
  x.descendant(:*).where(x.contains('Bax') & x.attr(:title).equals('monkey'))
296
322
  end
297
- @results[0][:title].should == "monkey"
323
+ @results[0][:title].should eq "monkey"
298
324
  end
299
325
  end
300
326
 
@@ -303,57 +329,57 @@ describe XPath do
303
329
  @results = xpath do |x|
304
330
  x.descendant(:*).where(x.attr(:id).equals('foo').or(x.attr(:id).equals('fooDiv')))
305
331
  end
306
- @results[0][:title].should == "fooDiv"
307
- @results[1].text.should == "Blah"
332
+ @results[0][:title].should eq "fooDiv"
333
+ @results[1].text.should eq "Blah"
308
334
  end
309
335
 
310
336
  it "should be aliased as pipe (|)" do
311
337
  @results = xpath do |x|
312
338
  x.descendant(:*).where(x.attr(:id).equals('foo') | x.attr(:id).equals('fooDiv'))
313
339
  end
314
- @results[0][:title].should == "fooDiv"
315
- @results[1].text.should == "Blah"
340
+ @results[0][:title].should eq "fooDiv"
341
+ @results[1].text.should eq "Blah"
316
342
  end
317
343
  end
318
344
 
319
345
  describe '#attr' do
320
346
  it "should be an attribute" do
321
347
  @results = xpath { |x| x.descendant(:div).where(x.attr(:id)) }
322
- @results[0][:title].should == "barDiv"
323
- @results[1][:title].should == "fooDiv"
348
+ @results[0][:title].should eq "barDiv"
349
+ @results[1][:title].should eq "fooDiv"
324
350
  end
325
351
  end
326
352
 
327
353
  describe '#css' do
328
354
  it "should find nodes by the given CSS selector" do
329
355
  @results = xpath { |x| x.css('#preference p') }
330
- @results[0].text.should == 'allamas'
331
- @results[1].text.should == 'llama'
356
+ @results[0].text.should eq 'allamas'
357
+ @results[1].text.should eq 'llama'
332
358
  end
333
359
 
334
360
  it "should respect previous expression" do
335
361
  @results = xpath { |x| x.descendant[x.attr(:id) == 'moar'].css('p') }
336
- @results[0].text.should == 'chimp'
337
- @results[1].text.should == 'flamingo'
362
+ @results[0].text.should eq 'chimp'
363
+ @results[1].text.should eq 'flamingo'
338
364
  end
339
365
 
340
366
  it "should be composable" do
341
367
  @results = xpath { |x| x.css('#moar').descendant(:p) }
342
- @results[0].text.should == 'chimp'
343
- @results[1].text.should == 'flamingo'
368
+ @results[0].text.should eq 'chimp'
369
+ @results[1].text.should eq 'flamingo'
344
370
  end
345
371
 
346
372
  it "should allow comma separated selectors" do
347
373
  @results = xpath { |x| x.descendant[x.attr(:id) == 'moar'].css('div, p') }
348
- @results[0].text.should == 'chimp'
349
- @results[1].text.should == 'elephant'
350
- @results[2].text.should == 'flamingo'
374
+ @results[0].text.should eq 'chimp'
375
+ @results[1].text.should eq 'elephant'
376
+ @results[2].text.should eq 'flamingo'
351
377
  end
352
378
  end
353
379
 
354
- describe '#name' do
380
+ describe '#qname' do
355
381
  it "should match the node's name" do
356
- xpath { |x| x.descendant(:*).where(x.name == 'ul') }.first.text.should == "A list"
382
+ xpath { |x| x.descendant(:*).where(x.qname == 'ul') }.first.text.should eq "A list"
357
383
  end
358
384
  end
359
385
 
@@ -365,9 +391,9 @@ describe XPath do
365
391
  @xpath1 = @collection.where(XPath.attr(:id) == 'foo').to_xpath
366
392
  @xpath2 = @collection.where(XPath.attr(:id) == 'fooDiv').to_xpath
367
393
  @results = doc.xpath(@xpath1)
368
- @results[0][:title].should == 'fooDiv'
394
+ @results[0][:title].should eq 'fooDiv'
369
395
  @results = doc.xpath(@xpath2)
370
- @results[0][:id].should == 'fooDiv'
396
+ @results[0][:id].should eq 'fooDiv'
371
397
  end
372
398
 
373
399
  it "should be aliased as +" do
@@ -377,119 +403,119 @@ describe XPath do
377
403
  @xpath1 = @collection.where(XPath.attr(:id) == 'foo').to_xpath
378
404
  @xpath2 = @collection.where(XPath.attr(:id) == 'fooDiv').to_xpath
379
405
  @results = doc.xpath(@xpath1)
380
- @results[0][:title].should == 'fooDiv'
406
+ @results[0][:title].should eq 'fooDiv'
381
407
  @results = doc.xpath(@xpath2)
382
- @results[0][:id].should == 'fooDiv'
408
+ @results[0][:id].should eq 'fooDiv'
383
409
  end
384
410
  end
385
411
 
386
412
  describe "#last" do
387
413
  it "returns the number of elements in the context" do
388
414
  @results = xpath { |x| x.descendant(:p)[XPath.position() == XPath.last()] }
389
- @results[0].text.should == "Bax"
390
- @results[1].text.should == "Blah"
391
- @results[2].text.should == "llama"
415
+ @results[0].text.should eq "Bax"
416
+ @results[1].text.should eq "Blah"
417
+ @results[2].text.should eq "llama"
392
418
  end
393
419
  end
394
420
 
395
421
  describe "#position" do
396
422
  it "returns the position of elements in the context" do
397
423
  @results = xpath { |x| x.descendant(:p)[XPath.position() == 2] }
398
- @results[0].text.should == "Bax"
399
- @results[1].text.should == "Bax"
424
+ @results[0].text.should eq "Bax"
425
+ @results[1].text.should eq "Bax"
400
426
  end
401
427
  end
402
428
 
403
429
  describe "#count" do
404
430
  it "counts the number of occurrences" do
405
431
  @results = xpath { |x| x.descendant(:div)[x.descendant(:p).count == 2] }
406
- @results[0][:id].should == "preference"
432
+ @results[0][:id].should eq "preference"
407
433
  end
408
434
  end
409
435
 
410
436
  describe "#lte" do
411
437
  it "checks lesser than or equal" do
412
438
  @results = xpath { |x| x.descendant(:p)[XPath.position() <= 2] }
413
- @results[0].text.should == "Blah"
414
- @results[1].text.should == "Bax"
415
- @results[2][:title].should == "gorilla"
416
- @results[3].text.should == "Bax"
439
+ @results[0].text.should eq "Blah"
440
+ @results[1].text.should eq "Bax"
441
+ @results[2][:title].should eq "gorilla"
442
+ @results[3].text.should eq "Bax"
417
443
  end
418
444
  end
419
445
 
420
446
  describe "#lt" do
421
447
  it "checks lesser than" do
422
448
  @results = xpath { |x| x.descendant(:p)[XPath.position() < 2] }
423
- @results[0].text.should == "Blah"
424
- @results[1][:title].should == "gorilla"
449
+ @results[0].text.should eq "Blah"
450
+ @results[1][:title].should eq "gorilla"
425
451
  end
426
452
  end
427
453
 
428
454
  describe "#gte" do
429
455
  it "checks greater than or equal" do
430
456
  @results = xpath { |x| x.descendant(:p)[XPath.position() >= 2] }
431
- @results[0].text.should == "Bax"
432
- @results[1][:title].should == "monkey"
433
- @results[2].text.should == "Bax"
434
- @results[3].text.should == "Blah"
457
+ @results[0].text.should eq "Bax"
458
+ @results[1][:title].should eq "monkey"
459
+ @results[2].text.should eq "Bax"
460
+ @results[3].text.should eq "Blah"
435
461
  end
436
462
  end
437
463
 
438
464
  describe "#gt" do
439
465
  it "checks greater than" do
440
466
  @results = xpath { |x| x.descendant(:p)[XPath.position() > 2] }
441
- @results[0][:title].should == "monkey"
442
- @results[1].text.should == "Blah"
467
+ @results[0][:title].should eq "monkey"
468
+ @results[1].text.should eq "Blah"
443
469
  end
444
470
  end
445
471
 
446
472
  describe "#plus" do
447
473
  it "adds stuff" do
448
474
  @results = xpath { |x| x.descendant(:p)[XPath.position().plus(1) == 2] }
449
- @results[0][:id].should == "fooDiv"
450
- @results[1][:title].should == "gorilla"
475
+ @results[0][:id].should eq "fooDiv"
476
+ @results[1][:title].should eq "gorilla"
451
477
  end
452
478
  end
453
479
 
454
480
  describe "#minus" do
455
481
  it "subtracts stuff" do
456
482
  @results = xpath { |x| x.descendant(:p)[XPath.position().minus(1) == 0] }
457
- @results[0][:id].should == "fooDiv"
458
- @results[1][:title].should == "gorilla"
483
+ @results[0][:id].should eq "fooDiv"
484
+ @results[1][:title].should eq "gorilla"
459
485
  end
460
486
  end
461
487
 
462
488
  describe "#multiply" do
463
489
  it "multiplies stuff" do
464
490
  @results = xpath { |x| x.descendant(:p)[XPath.position() * 3 == 3] }
465
- @results[0][:id].should == "fooDiv"
466
- @results[1][:title].should == "gorilla"
491
+ @results[0][:id].should eq "fooDiv"
492
+ @results[1][:title].should eq "gorilla"
467
493
  end
468
494
  end
469
495
 
470
496
  describe "#divide" do
471
497
  it "divides stuff" do
472
498
  @results = xpath { |x| x.descendant(:p)[XPath.position() / 2 == 1] }
473
- @results[0].text.should == "Bax"
474
- @results[1].text.should == "Bax"
499
+ @results[0].text.should eq "Bax"
500
+ @results[1].text.should eq "Bax"
475
501
  end
476
502
  end
477
503
 
478
504
  describe "#mod" do
479
505
  it "take modulo" do
480
506
  @results = xpath { |x| x.descendant(:p)[XPath.position() % 2 == 1] }
481
- @results[0].text.should == "Blah"
482
- @results[1][:title].should == "monkey"
483
- @results[2][:title].should == "gorilla"
507
+ @results[0].text.should eq "Blah"
508
+ @results[1][:title].should eq "monkey"
509
+ @results[2][:title].should eq "gorilla"
484
510
  end
485
511
  end
486
512
 
487
513
  describe "#ancestor" do
488
514
  it "finds ancestor nodes" do
489
515
  @results = xpath { |x| x.descendant(:p)[1].ancestor }
490
- @results[0].node_name.should == "html"
491
- @results[1].node_name.should == "body"
492
- @results[2][:id].should == "foo"
516
+ @results[0].node_name.should eq "html"
517
+ @results[1].node_name.should eq "body"
518
+ @results[2][:id].should eq "foo"
493
519
  end
494
520
  end
495
521
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xpath
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - gem-public_cert.pem
12
- date: 2017-05-25 00:00:00.000000000 Z
12
+ date: 2017-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.3'
20
+ version: '1.8'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.3'
27
+ version: '1.8'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rspec
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -92,7 +92,6 @@ files:
92
92
  - lib/xpath.rb
93
93
  - lib/xpath/dsl.rb
94
94
  - lib/xpath/expression.rb
95
- - lib/xpath/html.rb
96
95
  - lib/xpath/literal.rb
97
96
  - lib/xpath/renderer.rb
98
97
  - lib/xpath/union.rb
@@ -100,7 +99,6 @@ files:
100
99
  - spec/fixtures/form.html
101
100
  - spec/fixtures/simple.html
102
101
  - spec/fixtures/stuff.html
103
- - spec/html_spec.rb
104
102
  - spec/spec_helper.rb
105
103
  - spec/union_spec.rb
106
104
  - spec/xpath_spec.rb
@@ -116,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
114
  requirements:
117
115
  - - ">="
118
116
  - !ruby/object:Gem::Version
119
- version: 1.9.3
117
+ version: '2.2'
120
118
  required_rubygems_version: !ruby/object:Gem::Requirement
121
119
  requirements:
122
120
  - - ">="
@@ -124,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
122
  version: '0'
125
123
  requirements: []
126
124
  rubyforge_project:
127
- rubygems_version: 2.5.2
125
+ rubygems_version: 2.6.13
128
126
  signing_key:
129
127
  specification_version: 4
130
128
  summary: Generate XPath expressions from Ruby
@@ -1,175 +0,0 @@
1
- module XPath
2
- module HTML
3
- include XPath::DSL
4
- extend self
5
-
6
- # Match an `a` link element.
7
- #
8
- # @param [String] locator
9
- # Text, id, title, or image alt attribute of the link
10
- #
11
- def link(locator)
12
- locator = locator.to_s
13
- link = descendant(:a)[attr(:href)]
14
- link[attr(:id).equals(locator) | string.n.is(locator) | attr(:title).is(locator) | descendant(:img)[attr(:alt).is(locator)]]
15
- end
16
-
17
- # Match a `submit`, `image`, or `button` element.
18
- #
19
- # @param [String] locator
20
- # Value, title, id, or image alt attribute of the button
21
- #
22
- def button(locator)
23
- locator = locator.to_s
24
- button = descendant(:input)[attr(:type).one_of('submit', 'reset', 'image', 'button')][attr(:id).equals(locator) | attr(:value).is(locator) | attr(:title).is(locator)]
25
- button += descendant(:button)[attr(:id).equals(locator) | attr(:value).is(locator) | string.n.is(locator) | attr(:title).is(locator)]
26
- button += descendant(:input)[attr(:type).equals('image')][attr(:alt).is(locator)]
27
- end
28
-
29
-
30
- # Match anything returned by either {#link} or {#button}.
31
- #
32
- # @param [String] locator
33
- # Text, id, title, or image alt attribute of the link or button
34
- #
35
- def link_or_button(locator)
36
- link(locator) + button(locator)
37
- end
38
-
39
-
40
- # Match any `fieldset` element.
41
- #
42
- # @param [String] locator
43
- # Legend or id of the fieldset
44
- #
45
- def fieldset(locator)
46
- locator = locator.to_s
47
- descendant(:fieldset)[attr(:id).equals(locator) | child(:legend)[string.n.is(locator)]]
48
- end
49
-
50
-
51
- # Match any `input`, `textarea`, or `select` element that doesn't have a
52
- # type of `submit`, `image`, or `hidden`.
53
- #
54
- # @param [String] locator
55
- # Label, id, or name of field to match
56
- #
57
- def field(locator)
58
- locator = locator.to_s
59
- xpath = descendant(:input, :textarea, :select)[~attr(:type).one_of('submit', 'image', 'hidden')]
60
- xpath = locate_field(xpath, locator)
61
- xpath
62
- end
63
-
64
-
65
- # Match any `input` or `textarea` element that can be filled with text.
66
- # This excludes any inputs with a type of `submit`, `image`, `radio`,
67
- # `checkbox`, `hidden`, or `file`.
68
- #
69
- # @param [String] locator
70
- # Label, id, or name of field to match
71
- #
72
- def fillable_field(locator)
73
- locator = locator.to_s
74
- xpath = descendant(:input, :textarea)[~attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')]
75
- xpath = locate_field(xpath, locator)
76
- xpath
77
- end
78
-
79
-
80
- # Match any `select` element.
81
- #
82
- # @param [String] locator
83
- # Label, id, or name of the field to match
84
- #
85
- def select(locator)
86
- locator = locator.to_s
87
- locate_field(descendant(:select), locator)
88
- end
89
-
90
-
91
- # Match any `input` element of type `checkbox`.
92
- #
93
- # @param [String] locator
94
- # Label, id, or name of the checkbox to match
95
- #
96
- def checkbox(locator)
97
- locator = locator.to_s
98
- locate_field(descendant(:input)[attr(:type).equals('checkbox')], locator)
99
- end
100
-
101
-
102
- # Match any `input` element of type `radio`.
103
- #
104
- # @param [String] locator
105
- # Label, id, or name of the radio button to match
106
- #
107
- def radio_button(locator)
108
- locator = locator.to_s
109
- locate_field(descendant(:input)[attr(:type).equals('radio')], locator)
110
- end
111
-
112
-
113
- # Match any `input` element of type `file`.
114
- #
115
- # @param [String] locator
116
- # Label, id, or name of the file field to match
117
- #
118
- def file_field(locator)
119
- locator = locator.to_s
120
- locate_field(descendant(:input)[attr(:type).equals('file')], locator)
121
- end
122
-
123
-
124
- # Match an `optgroup` element.
125
- #
126
- # @param [String] name
127
- # Label for the option group
128
- #
129
- def optgroup(locator)
130
- locator = locator.to_s
131
- descendant(:optgroup)[attr(:label).is(locator)]
132
- end
133
-
134
-
135
- # Match an `option` element.
136
- #
137
- # @param [String] name
138
- # Visible text of the option
139
- #
140
- def option(locator)
141
- locator = locator.to_s
142
- descendant(:option)[string.n.is(locator)]
143
- end
144
-
145
-
146
- # Match any `table` element.
147
- #
148
- # @param [String] locator
149
- # Caption or id of the table to match
150
- # @option options [Array] :rows
151
- # Content of each cell in each row to match
152
- #
153
- def table(locator)
154
- locator = locator.to_s
155
- descendant(:table)[attr(:id).equals(locator) | descendant(:caption).is(locator)]
156
- end
157
-
158
- # Match any 'dd' element.
159
- #
160
- # @param [String] locator
161
- # Id of the 'dd' element or text from preciding 'dt' element content
162
- def definition_description(locator)
163
- locator = locator.to_s
164
- descendant(:dd)[attr(:id).equals(locator) | previous_sibling(:dt)[string.n.equals(locator)] ]
165
- end
166
-
167
- protected
168
-
169
- def locate_field(xpath, locator)
170
- locate_field = xpath[attr(:id).equals(locator) | attr(:name).equals(locator) | attr(:placeholder).equals(locator) | attr(:id).equals(anywhere(:label)[string.n.is(locator)].attr(:for))]
171
- locate_field += descendant(:label)[string.n.is(locator)].descendant(xpath)
172
- locate_field
173
- end
174
- end
175
- end
@@ -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
- let(:type) { |example| example.metadata[:type] }
9
-
10
- def get(*args)
11
- all(*args).first
12
- end
13
-
14
- def all(*args)
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