rspec-html-matchers 0.7.0 → 0.10.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 +5 -5
- data/CHANGELOG.md +79 -12
- data/README.md +63 -57
- data/features/step_definitions/steps.rb +3 -1
- data/features/support/env.rb +22 -3
- data/lib/rspec-html-matchers/have_tag.rb +290 -0
- data/lib/rspec-html-matchers/nokogiri_regexp_helper.rb +17 -0
- data/lib/rspec-html-matchers/nokogiri_text_helper.rb +24 -0
- data/lib/rspec-html-matchers/version.rb +5 -0
- data/lib/rspec-html-matchers.rb +167 -331
- data/spec/form_matchers_spec.rb +132 -130
- data/spec/have_empty_tag_spec.rb +31 -0
- data/spec/have_tag_spec.rb +281 -167
- data/spec/issues_spec.rb +17 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/asset_helpers.rb +5 -5
- data/spec/support/raise_spec_error_helper.rb +9 -7
- metadata +74 -36
data/lib/rspec-html-matchers.rb
CHANGED
@@ -1,240 +1,30 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rspec-html-matchers/nokogiri_regexp_helper'
|
5
|
+
require 'rspec-html-matchers/nokogiri_text_helper'
|
6
|
+
require 'rspec-html-matchers/have_tag'
|
7
|
+
|
8
|
+
# RSpec global configuration:
|
9
|
+
#
|
10
|
+
# RSpec.configure do |config|
|
11
|
+
# config.include RSpecHtmlMatchers
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# RSpec per-test configuration
|
15
|
+
#
|
16
|
+
# RSpec.describe "my view spec" do
|
17
|
+
# include RSpecHtmlMatchers
|
18
|
+
#
|
19
|
+
# it "has tags" do
|
20
|
+
# expect(rendered).to have_tag('div')
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Cucumber configuration:
|
25
|
+
#
|
26
|
+
# World RSpecHtmlMatchers
|
5
27
|
module RSpecHtmlMatchers
|
6
|
-
|
7
|
-
# @api
|
8
|
-
# @private
|
9
|
-
# for nokogiri regexp matching
|
10
|
-
class NokogiriRegexpHelper
|
11
|
-
def initialize(regex)
|
12
|
-
@regex = regex
|
13
|
-
end
|
14
|
-
|
15
|
-
def regexp node_set
|
16
|
-
node_set.find_all { |node| node.content =~ @regex }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# @api
|
21
|
-
# @private
|
22
|
-
class NokogiriTextHelper
|
23
|
-
NON_BREAKING_SPACE = "\u00a0"
|
24
|
-
|
25
|
-
def initialize text
|
26
|
-
@text = text
|
27
|
-
end
|
28
|
-
|
29
|
-
def content node_set
|
30
|
-
node_set.find_all do |node|
|
31
|
-
actual_content = node.content.gsub(NON_BREAKING_SPACE, ' ')
|
32
|
-
|
33
|
-
actual_content == @text
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# @api
|
39
|
-
# @private
|
40
|
-
class HaveTag
|
41
|
-
attr_reader :failure_message, :failure_message_when_negated
|
42
|
-
attr_reader :parent_scope, :current_scope
|
43
|
-
|
44
|
-
DESCRIPTIONS = {
|
45
|
-
:have_at_least_1 => %Q|have at least 1 element matching "%s"|,
|
46
|
-
:have_n => %Q|have %i element(s) matching "%s"|
|
47
|
-
}
|
48
|
-
|
49
|
-
MESSAGES = {
|
50
|
-
:expected_tag => %Q|expected following:\n%s\nto #{DESCRIPTIONS[:have_at_least_1]}, found 0.|,
|
51
|
-
:unexpected_tag => %Q|expected following:\n%s\nto NOT have element matching "%s", found %s.|,
|
52
|
-
|
53
|
-
:expected_count => %Q|expected following:\n%s\nto #{DESCRIPTIONS[:have_n]}, found %s.|,
|
54
|
-
:unexpected_count => %Q|expected following:\n%s\nto NOT have %i element(s) matching "%s", but found.|,
|
55
|
-
|
56
|
-
:expected_btw_count => %Q|expected following:\n%s\nto have at least %i and at most %i element(s) matching "%s", found %i.|,
|
57
|
-
:unexpected_btw_count => %Q|expected following:\n%s\nto NOT have at least %i and at most %i element(s) matching "%s", but found %i.|,
|
58
|
-
|
59
|
-
:expected_at_most => %Q|expected following:\n%s\nto have at most %i element(s) matching "%s", found %i.|,
|
60
|
-
:unexpected_at_most => %Q|expected following:\n%s\nto NOT have at most %i element(s) matching "%s", but found %i.|,
|
61
|
-
|
62
|
-
:expected_at_least => %Q|expected following:\n%s\nto have at least %i element(s) matching "%s", found %i.|,
|
63
|
-
:unexpected_at_least => %Q|expected following:\n%s\nto NOT have at least %i element(s) matching "%s", but found %i.|,
|
64
|
-
|
65
|
-
:expected_regexp => %Q|%s regexp expected within "%s" in following template:\n%s|,
|
66
|
-
:unexpected_regexp => %Q|%s regexp unexpected within "%s" in following template:\n%s\nbut was found.|,
|
67
|
-
|
68
|
-
:expected_text => %Q|"%s" expected within "%s" in following template:\n%s|,
|
69
|
-
:unexpected_text => %Q|"%s" unexpected within "%s" in following template:\n%s\nbut was found.|,
|
70
|
-
|
71
|
-
:wrong_count_error => %Q|:count with :minimum or :maximum has no sence!|,
|
72
|
-
:min_max_error => %Q|:minimum should be less than :maximum!|,
|
73
|
-
:bad_range_error => %Q|Your :count range(%s) has no sence!|,
|
74
|
-
}
|
75
|
-
|
76
|
-
|
77
|
-
def initialize tag, options={}, &block
|
78
|
-
@tag, @options, @block = tag.to_s, options, block
|
79
|
-
|
80
|
-
if with_attrs = @options.delete(:with)
|
81
|
-
if classes = with_attrs.delete(:class)
|
82
|
-
@tag << '.' + classes_to_selector(classes)
|
83
|
-
end
|
84
|
-
selector = with_attrs.inject('') do |html_attrs_string, (k, v)|
|
85
|
-
html_attrs_string << "[#{k}='#{v}']"
|
86
|
-
html_attrs_string
|
87
|
-
end
|
88
|
-
@tag << selector
|
89
|
-
end
|
90
|
-
|
91
|
-
if without_attrs = @options.delete(:without)
|
92
|
-
if classes = without_attrs.delete(:class)
|
93
|
-
@tag << ":not(.#{classes_to_selector(classes)})"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
validate_options!
|
98
|
-
end
|
99
|
-
|
100
|
-
def matches? document, &block
|
101
|
-
@block = block if block
|
102
|
-
|
103
|
-
document = document.html if defined?(Capybara::Session) && document.is_a?(Capybara::Session)
|
104
|
-
|
105
|
-
case document
|
106
|
-
when String
|
107
|
-
@parent_scope = @current_scope = Nokogiri::HTML(document).css(@tag)
|
108
|
-
@document = document
|
109
|
-
else
|
110
|
-
@parent_scope = document.current_scope
|
111
|
-
@current_scope = begin
|
112
|
-
document.parent_scope.css(@tag)
|
113
|
-
# on jruby this produce exception if css was not found:
|
114
|
-
# undefined method `decorate' for nil:NilClass
|
115
|
-
rescue NoMethodError
|
116
|
-
Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
|
117
|
-
end
|
118
|
-
@document = @parent_scope.to_html
|
119
|
-
end
|
120
|
-
|
121
|
-
if tag_presents? and text_right? and count_right?
|
122
|
-
@current_scope = @parent_scope
|
123
|
-
@block.call if @block
|
124
|
-
true
|
125
|
-
else
|
126
|
-
false
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def description
|
131
|
-
# TODO should it be more complicated?
|
132
|
-
if @options.has_key?(:count)
|
133
|
-
DESCRIPTIONS[:have_n] % [@options[:count],@tag]
|
134
|
-
else
|
135
|
-
DESCRIPTIONS[:have_at_least_1] % @tag
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
private
|
140
|
-
|
141
|
-
def classes_to_selector(classes)
|
142
|
-
case classes
|
143
|
-
when Array
|
144
|
-
classes.join('.')
|
145
|
-
when String
|
146
|
-
classes.gsub(/\s+/, '.')
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def tag_presents?
|
151
|
-
if @current_scope.first
|
152
|
-
@count = @current_scope.count
|
153
|
-
@failure_message_when_negated = MESSAGES[:unexpected_tag] % [@document, @tag, @count]
|
154
|
-
true
|
155
|
-
else
|
156
|
-
@failure_message = MESSAGES[:expected_tag] % [@document, @tag]
|
157
|
-
false
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def count_right?
|
162
|
-
case @options[:count]
|
163
|
-
when Integer
|
164
|
-
((@failure_message_when_negated=MESSAGES[:unexpected_count] % [@document,@count,@tag]) && @count == @options[:count]) || (@failure_message=MESSAGES[:expected_count] % [@document,@options[:count],@tag,@count]; false)
|
165
|
-
when Range
|
166
|
-
((@failure_message_when_negated=MESSAGES[:unexpected_btw_count] % [@document,@options[:count].min,@options[:count].max,@tag,@count]) && @options[:count].member?(@count)) || (@failure_message=MESSAGES[:expected_btw_count] % [@document,@options[:count].min,@options[:count].max,@tag,@count]; false)
|
167
|
-
when nil
|
168
|
-
if @options[:maximum]
|
169
|
-
((@failure_message_when_negated=MESSAGES[:unexpected_at_most] % [@document,@options[:maximum],@tag,@count]) && @count <= @options[:maximum]) || (@failure_message=MESSAGES[:expected_at_most] % [@document,@options[:maximum],@tag,@count]; false)
|
170
|
-
elsif @options[:minimum]
|
171
|
-
((@failure_message_when_negated=MESSAGES[:unexpected_at_least] % [@document,@options[:minimum],@tag,@count]) && @count >= @options[:minimum]) || (@failure_message=MESSAGES[:expected_at_least] % [@document,@options[:minimum],@tag,@count]; false)
|
172
|
-
else
|
173
|
-
true
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def text_right?
|
179
|
-
return true unless @options[:text]
|
180
|
-
|
181
|
-
case text=@options[:text]
|
182
|
-
when Regexp
|
183
|
-
new_scope = @current_scope.css(':regexp()',NokogiriRegexpHelper.new(text))
|
184
|
-
unless new_scope.empty?
|
185
|
-
@count = new_scope.count
|
186
|
-
@failure_message_when_negated = MESSAGES[:unexpected_regexp] % [text.inspect,@tag,@document]
|
187
|
-
true
|
188
|
-
else
|
189
|
-
@failure_message = MESSAGES[:expected_regexp] % [text.inspect,@tag,@document]
|
190
|
-
false
|
191
|
-
end
|
192
|
-
else
|
193
|
-
new_scope = @current_scope.css(':content()',NokogiriTextHelper.new(text))
|
194
|
-
unless new_scope.empty?
|
195
|
-
@count = new_scope.count
|
196
|
-
@failure_message_when_negated = MESSAGES[:unexpected_text] % [text,@tag,@document]
|
197
|
-
true
|
198
|
-
else
|
199
|
-
@failure_message = MESSAGES[:expected_text] % [text,@tag,@document]
|
200
|
-
false
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
protected
|
206
|
-
|
207
|
-
def validate_options!
|
208
|
-
raise 'wrong :count specified' unless [Range, NilClass].include?(@options[:count].class) or @options[:count].is_a?(Integer)
|
209
|
-
|
210
|
-
[:min, :minimum, :max, :maximum].each do |key|
|
211
|
-
raise MESSAGES[:wrong_count_error] if @options.has_key?(key) and @options.has_key?(:count)
|
212
|
-
end
|
213
|
-
|
214
|
-
begin
|
215
|
-
raise MESSAGES[:min_max_error] if @options[:minimum] > @options[:maximum]
|
216
|
-
rescue NoMethodError # nil > 4
|
217
|
-
rescue ArgumentError # 2 < nil
|
218
|
-
end
|
219
|
-
|
220
|
-
begin
|
221
|
-
begin
|
222
|
-
raise MESSAGES[:bad_range_error] % [@options[:count].to_s] if @options[:count] && @options[:count].is_a?(Range) && (@options[:count].min.nil? or @options[:count].min < 0)
|
223
|
-
rescue ArgumentError, "comparison of String with" # if @options[:count] == 'a'..'z'
|
224
|
-
raise MESSAGES[:bad_range_error] % [@options[:count].to_s]
|
225
|
-
end
|
226
|
-
rescue TypeError # fix for 1.8.7 for 'rescue ArgumentError, "comparison of String with"' stroke
|
227
|
-
raise MESSAGES[:bad_range_error] % [@options[:count].to_s]
|
228
|
-
end
|
229
|
-
|
230
|
-
@options[:minimum] ||= @options.delete(:min)
|
231
|
-
@options[:maximum] ||= @options.delete(:max)
|
232
|
-
|
233
|
-
@options[:text] = @options[:text].to_s if @options.has_key?(:text) && !@options[:text].is_a?(Regexp)
|
234
|
-
end
|
235
|
-
|
236
|
-
end
|
237
|
-
|
238
28
|
# tag assertion, this is the core of functionality, other matchers are shortcuts to this matcher
|
239
29
|
#
|
240
30
|
# @yield block where you should put with_tag, without_tag and/or other matchers
|
@@ -269,41 +59,60 @@ module RSpecHtmlMatchers
|
|
269
59
|
# </html>").to have_tag('body') { with_tag('h1', :text => 'some html document') }
|
270
60
|
# expect('<div class="one two">').to have_tag('div', :with => { :class => ['two', 'one'] })
|
271
61
|
# expect('<div class="one two">').to have_tag('div', :with => { :class => 'two one' })
|
272
|
-
def have_tag tag, options={}, &block
|
62
|
+
def have_tag tag, options = {}, &block
|
273
63
|
# for backwards compatibility with rpecs have tag:
|
274
|
-
options = { :text => options } if options.
|
64
|
+
options = { :text => options } if options.is_a?(String) || options.is_a?(Regexp)
|
275
65
|
@__current_scope_for_nokogiri_matcher = HaveTag.new(tag, options, &block)
|
276
66
|
end
|
277
67
|
|
68
|
+
# tests whether tag have any content inside
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# expect('<div></div>').to have_empty_tag('div') # success
|
72
|
+
# expect('<div>hi</div>').to have_empty_tag('div') # fail
|
73
|
+
def have_empty_tag tag, options = {}
|
74
|
+
have_tag(tag, options.merge(:blank => true))
|
75
|
+
end
|
76
|
+
|
278
77
|
def with_text text
|
279
78
|
raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher)
|
280
79
|
raise ArgumentError, 'this matcher does not accept block' if block_given?
|
80
|
+
|
281
81
|
tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag)
|
282
|
-
|
82
|
+
within_nested_tag do
|
83
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, :text => text)
|
84
|
+
end
|
283
85
|
end
|
284
86
|
|
285
87
|
def without_text text
|
286
88
|
raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher)
|
287
89
|
raise ArgumentError, 'this matcher does not accept block' if block_given?
|
90
|
+
|
288
91
|
tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag)
|
289
|
-
|
92
|
+
within_nested_tag do
|
93
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, :text => text)
|
94
|
+
end
|
290
95
|
end
|
291
|
-
alias
|
96
|
+
alias but_without_text without_text
|
292
97
|
|
293
98
|
# with_tag matcher
|
294
99
|
# @yield block where you should put other with_tag or without_tag
|
295
100
|
# @see #have_tag
|
296
101
|
# @note this should be used within block of have_tag matcher
|
297
|
-
def with_tag tag, options={}, &block
|
298
|
-
|
102
|
+
def with_tag tag, options = {}, &block
|
103
|
+
within_nested_tag do
|
104
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block)
|
105
|
+
end
|
299
106
|
end
|
300
107
|
|
301
108
|
# without_tag matcher
|
302
109
|
# @yield block where you should put other with_tag or without_tag
|
303
110
|
# @see #have_tag
|
304
111
|
# @note this should be used within block of have_tag matcher
|
305
|
-
def without_tag tag, options={}, &block
|
306
|
-
|
112
|
+
def without_tag tag, options = {}, &block
|
113
|
+
within_nested_tag do
|
114
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block)
|
115
|
+
end
|
307
116
|
end
|
308
117
|
|
309
118
|
# form assertion
|
@@ -312,248 +121,275 @@ module RSpecHtmlMatchers
|
|
312
121
|
# have_tag 'form', :with => { :action => action_url, :method => method ... }
|
313
122
|
# @yield block with with_<field>, see below
|
314
123
|
# @see #have_tag
|
315
|
-
def have_form action_url, method, options={}, &block
|
124
|
+
def have_form action_url, method, options = {}, &block
|
316
125
|
options[:with] ||= {}
|
317
126
|
id = options[:with].delete(:id)
|
318
|
-
tag = 'form'; tag
|
127
|
+
tag = 'form'; tag += '#' + id if id
|
319
128
|
options[:with].merge!(:action => action_url)
|
320
129
|
options[:with].merge!(:method => method.to_s)
|
321
130
|
have_tag tag, options, &block
|
322
131
|
end
|
323
132
|
|
324
|
-
#TODO fix code duplications
|
133
|
+
# @TODO fix code duplications
|
325
134
|
|
326
|
-
def with_hidden_field name, value=nil
|
327
|
-
options = form_tag_options('hidden',name,value)
|
135
|
+
def with_hidden_field name, value = nil
|
136
|
+
options = form_tag_options('hidden', name, value)
|
328
137
|
should_have_input(options)
|
329
138
|
end
|
330
139
|
|
331
|
-
def without_hidden_field name, value=nil
|
332
|
-
options = form_tag_options('hidden',name,value)
|
140
|
+
def without_hidden_field name, value = nil
|
141
|
+
options = form_tag_options('hidden', name, value)
|
333
142
|
should_not_have_input(options)
|
334
143
|
end
|
335
144
|
|
336
|
-
def with_text_field name, value=nil
|
337
|
-
options = form_tag_options('text',name,value)
|
145
|
+
def with_text_field name, value = nil
|
146
|
+
options = form_tag_options('text', name, value)
|
338
147
|
should_have_input(options)
|
339
148
|
end
|
340
149
|
|
341
|
-
def without_text_field name, value=nil
|
342
|
-
options = form_tag_options('text',name,value)
|
150
|
+
def without_text_field name, value = nil
|
151
|
+
options = form_tag_options('text', name, value)
|
343
152
|
should_not_have_input(options)
|
344
153
|
end
|
345
154
|
|
346
|
-
def with_email_field name, value=nil
|
347
|
-
options = form_tag_options('email',name,value)
|
155
|
+
def with_email_field name, value = nil
|
156
|
+
options = form_tag_options('email', name, value)
|
348
157
|
should_have_input(options)
|
349
158
|
end
|
350
159
|
|
351
|
-
def without_email_field name, value=nil
|
352
|
-
options = form_tag_options('email',name,value)
|
160
|
+
def without_email_field name, value = nil
|
161
|
+
options = form_tag_options('email', name, value)
|
353
162
|
should_not_have_input(options)
|
354
163
|
end
|
355
164
|
|
356
|
-
def with_url_field name, value=nil
|
357
|
-
options = form_tag_options('url',name,value)
|
165
|
+
def with_url_field name, value = nil
|
166
|
+
options = form_tag_options('url', name, value)
|
358
167
|
should_have_input(options)
|
359
168
|
end
|
360
169
|
|
361
|
-
def without_url_field name, value=nil
|
362
|
-
options = form_tag_options('url',name,value)
|
170
|
+
def without_url_field name, value = nil
|
171
|
+
options = form_tag_options('url', name, value)
|
363
172
|
should_not_have_input(options)
|
364
173
|
end
|
365
174
|
|
366
|
-
def with_number_field name, value=nil
|
367
|
-
options = form_tag_options('number',name,value)
|
175
|
+
def with_number_field name, value = nil
|
176
|
+
options = form_tag_options('number', name, value)
|
368
177
|
should_have_input(options)
|
369
178
|
end
|
370
179
|
|
371
|
-
def without_number_field name, value=nil
|
372
|
-
options = form_tag_options('number',name,value)
|
180
|
+
def without_number_field name, value = nil
|
181
|
+
options = form_tag_options('number', name, value)
|
373
182
|
should_not_have_input(options)
|
374
183
|
end
|
375
184
|
|
376
|
-
def with_range_field name, min, max, options={}
|
377
|
-
options = { :with => { :name => name, :type => 'range', :min => min.to_s, :max => max.to_s }.merge(options.delete(:with)||{}) }
|
185
|
+
def with_range_field name, min, max, options = {}
|
186
|
+
options = { :with => { :name => name, :type => 'range', :min => min.to_s, :max => max.to_s }.merge(options.delete(:with) || {}) }
|
378
187
|
should_have_input(options)
|
379
188
|
end
|
380
189
|
|
381
|
-
def without_range_field name, min=nil, max=nil, options={}
|
382
|
-
options = { :with => { :name => name, :type => 'range' }.merge(options.delete(:with)||{}) }
|
190
|
+
def without_range_field name, min = nil, max = nil, options = {}
|
191
|
+
options = { :with => { :name => name, :type => 'range' }.merge(options.delete(:with) || {}) }
|
383
192
|
options[:with].merge!(:min => min.to_s) if min
|
384
193
|
options[:with].merge!(:max => max.to_s) if max
|
385
194
|
should_not_have_input(options)
|
386
195
|
end
|
387
196
|
|
388
|
-
DATE_FIELD_TYPES = %w
|
197
|
+
DATE_FIELD_TYPES = %w[date month week time datetime datetime-local].freeze
|
389
198
|
|
390
|
-
def with_date_field date_field_type, name=nil, options={}
|
199
|
+
def with_date_field date_field_type, name = nil, options = {}
|
391
200
|
date_field_type = date_field_type.to_s
|
392
201
|
raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type)
|
393
|
-
|
202
|
+
|
203
|
+
options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with) || {}) }
|
394
204
|
options[:with].merge!(:name => name.to_s) if name
|
395
205
|
should_have_input(options)
|
396
206
|
end
|
397
207
|
|
398
|
-
def without_date_field date_field_type, name=nil, options={}
|
208
|
+
def without_date_field date_field_type, name = nil, options = {}
|
399
209
|
date_field_type = date_field_type.to_s
|
400
210
|
raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type)
|
401
|
-
|
211
|
+
|
212
|
+
options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with) || {}) }
|
402
213
|
options[:with].merge!(:name => name.to_s) if name
|
403
214
|
should_not_have_input(options)
|
404
215
|
end
|
405
216
|
|
406
|
-
|
407
|
-
|
408
|
-
options = form_tag_options('password',name,value)
|
217
|
+
def with_password_field name, value = nil
|
218
|
+
# TODO: add ability to explicitly say that value should be empty
|
219
|
+
options = form_tag_options('password', name, value)
|
409
220
|
should_have_input(options)
|
410
221
|
end
|
411
222
|
|
412
|
-
def without_password_field name, value=nil
|
413
|
-
options = form_tag_options('password',name,value)
|
223
|
+
def without_password_field name, value = nil
|
224
|
+
options = form_tag_options('password', name, value)
|
414
225
|
should_not_have_input(options)
|
415
226
|
end
|
416
227
|
|
417
|
-
def with_file_field name, value=nil
|
418
|
-
options = form_tag_options('file',name,value)
|
228
|
+
def with_file_field name, value = nil
|
229
|
+
options = form_tag_options('file', name, value)
|
419
230
|
should_have_input(options)
|
420
231
|
end
|
421
232
|
|
422
|
-
def without_file_field name, value=nil
|
423
|
-
options = form_tag_options('file',name,value)
|
233
|
+
def without_file_field name, value = nil
|
234
|
+
options = form_tag_options('file', name, value)
|
424
235
|
should_not_have_input(options)
|
425
236
|
end
|
426
237
|
|
427
|
-
def with_text_area name
|
428
|
-
#
|
238
|
+
def with_text_area name
|
239
|
+
# TODO, should be: with_text_area name, text=nil
|
240
|
+
# options = form_tag_options('text',name,value)
|
429
241
|
options = { :with => { :name => name } }
|
430
|
-
|
242
|
+
within_nested_tag do
|
243
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag('textarea', options)
|
244
|
+
end
|
431
245
|
end
|
432
246
|
|
433
|
-
def without_text_area name
|
434
|
-
#
|
247
|
+
def without_text_area name
|
248
|
+
# TODO, should be: without_text_area name, text=nil
|
249
|
+
# options = form_tag_options('text',name,value)
|
435
250
|
options = { :with => { :name => name } }
|
436
|
-
|
251
|
+
within_nested_tag do
|
252
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('textarea', options)
|
253
|
+
end
|
437
254
|
end
|
438
255
|
|
439
|
-
def with_checkbox name, value=nil
|
440
|
-
options = form_tag_options('checkbox',name,value)
|
256
|
+
def with_checkbox name, value = nil
|
257
|
+
options = form_tag_options('checkbox', name, value)
|
441
258
|
should_have_input(options)
|
442
259
|
end
|
443
260
|
|
444
|
-
def without_checkbox name, value=nil
|
445
|
-
options = form_tag_options('checkbox',name,value)
|
261
|
+
def without_checkbox name, value = nil
|
262
|
+
options = form_tag_options('checkbox', name, value)
|
446
263
|
should_not_have_input(options)
|
447
264
|
end
|
448
265
|
|
449
266
|
def with_radio_button name, value
|
450
|
-
options = form_tag_options('radio',name,value)
|
267
|
+
options = form_tag_options('radio', name, value)
|
451
268
|
should_have_input(options)
|
452
269
|
end
|
453
270
|
|
454
271
|
def without_radio_button name, value
|
455
|
-
options = form_tag_options('radio',name,value)
|
272
|
+
options = form_tag_options('radio', name, value)
|
456
273
|
should_not_have_input(options)
|
457
274
|
end
|
458
275
|
|
459
|
-
def with_select name, options={}, &block
|
276
|
+
def with_select name, options = {}, &block
|
460
277
|
options[:with] ||= {}
|
461
278
|
id = options[:with].delete(:id)
|
462
|
-
tag='select'; tag
|
279
|
+
tag = 'select'; tag += '#' + id if id
|
463
280
|
options[:with].merge!(:name => name)
|
464
|
-
|
281
|
+
within_nested_tag do
|
282
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block)
|
283
|
+
end
|
465
284
|
end
|
466
285
|
|
467
|
-
def without_select name, options={}, &block
|
286
|
+
def without_select name, options = {}, &block
|
468
287
|
options[:with] ||= {}
|
469
288
|
id = options[:with].delete(:id)
|
470
|
-
tag='select'; tag
|
289
|
+
tag = 'select'; tag += '#' + id if id
|
471
290
|
options[:with].merge!(:name => name)
|
472
|
-
|
291
|
+
within_nested_tag do
|
292
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block)
|
293
|
+
end
|
473
294
|
end
|
474
295
|
|
475
|
-
def with_option text, value=nil, options={}
|
296
|
+
def with_option text, value = nil, options = {}
|
476
297
|
options[:with] ||= {}
|
477
298
|
if value.is_a?(Hash)
|
478
299
|
options.merge!(value)
|
479
|
-
value=nil
|
300
|
+
value = nil
|
480
301
|
end
|
481
|
-
tag='option'
|
302
|
+
tag = 'option'
|
482
303
|
options[:with].merge!(:value => value.to_s) if value
|
483
|
-
if options[:selected]
|
484
|
-
options[:with].merge!(:selected => "selected")
|
485
|
-
end
|
304
|
+
options[:with].merge!(:selected => 'selected') if options[:selected]
|
486
305
|
options.delete(:selected)
|
487
306
|
options.merge!(:text => text) if text
|
488
|
-
|
307
|
+
within_nested_tag do
|
308
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options)
|
309
|
+
end
|
489
310
|
end
|
490
311
|
|
491
|
-
def without_option text, value=nil, options={}
|
312
|
+
def without_option text, value = nil, options = {}
|
492
313
|
options[:with] ||= {}
|
493
314
|
if value.is_a?(Hash)
|
494
315
|
options.merge!(value)
|
495
|
-
value=nil
|
316
|
+
value = nil
|
496
317
|
end
|
497
|
-
tag='option'
|
318
|
+
tag = 'option'
|
498
319
|
options[:with].merge!(:value => value.to_s) if value
|
499
|
-
if options[:selected]
|
500
|
-
options[:with].merge!(:selected => "selected")
|
501
|
-
end
|
320
|
+
options[:with].merge!(:selected => 'selected') if options[:selected]
|
502
321
|
options.delete(:selected)
|
503
322
|
options.merge!(:text => text) if text
|
504
|
-
|
323
|
+
within_nested_tag do
|
324
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options)
|
325
|
+
end
|
505
326
|
end
|
506
327
|
|
507
|
-
def with_button text, value=nil, options={}
|
328
|
+
def with_button text, value = nil, options = {}
|
508
329
|
options[:with] ||= {}
|
509
330
|
if value.is_a?(Hash)
|
510
331
|
options.merge!(value)
|
511
|
-
value=nil
|
332
|
+
value = nil
|
512
333
|
end
|
513
334
|
options[:with].merge!(:value => value.to_s) if value
|
514
335
|
options.merge!(:text => text) if text
|
515
|
-
|
336
|
+
within_nested_tag do
|
337
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag('button', options)
|
338
|
+
end
|
516
339
|
end
|
517
340
|
|
518
|
-
def without_button text, value=nil, options={}
|
341
|
+
def without_button text, value = nil, options = {}
|
519
342
|
options[:with] ||= {}
|
520
343
|
if value.is_a?(Hash)
|
521
344
|
options.merge!(value)
|
522
|
-
value=nil
|
345
|
+
value = nil
|
523
346
|
end
|
524
347
|
options[:with].merge!(:value => value.to_s) if value
|
525
348
|
options.merge!(:text => text) if text
|
526
|
-
|
349
|
+
within_nested_tag do
|
350
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('button', options)
|
351
|
+
end
|
527
352
|
end
|
528
353
|
|
529
354
|
def with_submit value
|
530
355
|
options = { :with => { :type => 'submit', :value => value } }
|
531
|
-
#options = form_tag_options('text',name,value)
|
356
|
+
# options = form_tag_options('text',name,value)
|
532
357
|
should_have_input(options)
|
533
358
|
end
|
534
359
|
|
535
360
|
def without_submit value
|
536
|
-
#options = form_tag_options('text',name,value)
|
361
|
+
# options = form_tag_options('text',name,value)
|
537
362
|
options = { :with => { :type => 'submit', :value => value } }
|
538
363
|
should_not_have_input(options)
|
539
364
|
end
|
540
365
|
|
541
366
|
private
|
542
367
|
|
543
|
-
def should_have_input
|
544
|
-
|
368
|
+
def should_have_input options
|
369
|
+
within_nested_tag do
|
370
|
+
expect(@__current_scope_for_nokogiri_matcher).to have_tag('input', options)
|
371
|
+
end
|
545
372
|
end
|
546
373
|
|
547
|
-
def should_not_have_input
|
548
|
-
|
374
|
+
def should_not_have_input options
|
375
|
+
within_nested_tag do
|
376
|
+
expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('input', options)
|
377
|
+
end
|
549
378
|
end
|
550
379
|
|
551
380
|
# form_tag in method name name mean smth. like input, submit, tags that should appear in a form
|
552
|
-
def form_tag_options form_tag_type, form_tag_name, form_tag_value=nil
|
381
|
+
def form_tag_options form_tag_type, form_tag_name, form_tag_value = nil
|
553
382
|
options = { :with => { :name => form_tag_name, :type => form_tag_type } }
|
554
383
|
# .to_s if value is a digit or smth. else, see issue#10
|
555
384
|
options[:with].merge!(:value => form_tag_value.to_s) if form_tag_value
|
556
|
-
|
385
|
+
options
|
557
386
|
end
|
558
387
|
|
388
|
+
def within_nested_tag &block
|
389
|
+
raise 'block needed' unless block_given?
|
390
|
+
|
391
|
+
parent_scope = @__current_scope_for_nokogiri_matcher
|
392
|
+
block.call
|
393
|
+
@__current_scope_for_nokogiri_matcher = parent_scope
|
394
|
+
end
|
559
395
|
end
|