module RSpecHtmlMatchers
RSpec global configuration:
RSpec.configure do |config| config.include RSpecHtmlMatchers end
RSpec per-test configuration
RSpec.describe "my view spec" do include RSpecHtmlMatchers it "has tags" do expect(rendered).to have_tag('div') end end
Cucumber configuration:
World RSpecHtmlMatchers
Constants
- DATE_FIELD_TYPES
- VERSION
Public Instance Methods
tests whether tag have any content inside
@example
expect('<div></div>').to have_empty_tag('div') # success expect('<div>hi</div>').to have_empty_tag('div') # fail
# File lib/rspec-html-matchers.rb, line 73 def have_empty_tag tag, options = {} have_tag(tag, options.merge(:blank => true)) end
form assertion
it is a shortcut to
have_tag 'form', :with => { :action => action_url, :method => method ... }
@yield block with with_<field>, see below @see have_tag
# File lib/rspec-html-matchers.rb, line 124 def have_form action_url, method, options = {}, &block options[:with] ||= {} id = options[:with].delete(:id) tag = 'form'; tag += '#' + id if id options[:with].merge!(:action => action_url) options[:with].merge!(:method => method.to_s) have_tag tag, options, &block end
tag assertion, this is the core of functionality, other matchers are shortcuts to this matcher
@yield block where you should put with_tag
, without_tag
and/or other matchers
@param [String] tag css selector for tag you want to match, e.g. ‘div’, ‘section#my’, ‘article.red’ @param [Hash] options options hash(see below) @option options [Hash] :with hash with html attributes, within this, :class option have special meaning, you may specify it as array of expected classes or string of classes separated by spaces, order does not matter @option options [Fixnum] :count for tag count matching(ATTENTION: do not use :count with :minimum(:min) or :maximum(:max)) @option options [Range] :count not strict tag count matching, count of tags should be in specified range @option options [Fixnum] :minimum minimum count of elements to match @option options [Fixnum] :min same as :minimum @option options [Fixnum] :maximum maximum count of elements to match @option options [Fixnum] :max same as :maximum @option options [String/Regexp] :text to match tag content, could be either String or Regexp
@example
expect(rendered).to have_tag('div') expect(rendered).to have_tag('h1.header') expect(rendered).to have_tag('div#footer') expect(rendered).to have_tag('input#email', :with => { :name => 'user[email]', :type => 'email' } ) expect(rendered).to have_tag('div', :count => 3) # matches exactly 3 'div' tags expect(rendered).to have_tag('div', :count => 3..7) # shortcut for have_tag('div', :minimum => 3, :maximum => 7) expect(rendered).to have_tag('div', :minimum => 3) # matches more(or equal) than 3 'div' tags expect(rendered).to have_tag('div', :maximum => 3) # matches less(or equal) than 3 'div' tags expect(rendered).to have_tag('p', :text => 'some content') # will match "<p>some content</p>" expect(rendered).to have_tag('p', :text => /some content/i) # will match "<p>sOme cOntEnt</p>" expect(rendered).to have_tag('textarea', :with => {:name => 'user[description]'}, :text => "I like pie") expect("<html> <body> <h1>some html document</h1> </body> </html>").to have_tag('body') { with_tag('h1', :text => 'some html document') } expect('<div class="one two">').to have_tag('div', :with => { :class => ['two', 'one'] }) expect('<div class="one two">').to have_tag('div', :with => { :class => 'two one' })
# File lib/rspec-html-matchers.rb, line 62 def have_tag tag, options = {}, &block # for backwards compatibility with rpecs have tag: options = { :text => options } if options.is_a?(String) || options.is_a?(Regexp) @__current_scope_for_nokogiri_matcher = HaveTag.new(tag, options, &block) end
# File lib/rspec-html-matchers.rb, line 256 def with_checkbox name, value = nil options = form_tag_options('checkbox', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 199 def with_date_field date_field_type, name = nil, options = {} date_field_type = date_field_type.to_s raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type) options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with) || {}) } options[:with].merge!(:name => name.to_s) if name should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 155 def with_email_field name, value = nil options = form_tag_options('email', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 228 def with_file_field name, value = nil options = form_tag_options('file', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 175 def with_number_field name, value = nil options = form_tag_options('number', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 296 def with_option text, value = nil, options = {} options[:with] ||= {} if value.is_a?(Hash) options.merge!(value) value = nil end tag = 'option' options[:with].merge!(:value => value.to_s) if value options[:with].merge!(:selected => 'selected') if options[:selected] options.delete(:selected) options.merge!(:text => text) if text within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options) end end
# File lib/rspec-html-matchers.rb, line 217 def with_password_field name, value = nil # TODO: add ability to explicitly say that value should be empty options = form_tag_options('password', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 185 def with_range_field name, min, max, options = {} options = { :with => { :name => name, :type => 'range', :min => min.to_s, :max => max.to_s }.merge(options.delete(:with) || {}) } should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 276 def with_select name, options = {}, &block options[:with] ||= {} id = options[:with].delete(:id) tag = 'select'; tag += '#' + id if id options[:with].merge!(:name => name) within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block) end end
# File lib/rspec-html-matchers.rb, line 354 def with_submit value options = { :with => { :type => 'submit', :value => value } } # options = form_tag_options('text',name,value) should_have_input(options) end
with_tag
matcher @yield block where you should put other with_tag
or without_tag
@see have_tag
@note this should be used within block of have_tag
matcher
# File lib/rspec-html-matchers.rb, line 102 def with_tag tag, options = {}, &block within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block) end end
# File lib/rspec-html-matchers.rb, line 77 def with_text text raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher) raise ArgumentError, 'this matcher does not accept block' if block_given? tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag) within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, :text => text) end end
# File lib/rspec-html-matchers.rb, line 238 def with_text_area name # TODO, should be: with_text_area name, text=nil # options = form_tag_options('text',name,value) options = { :with => { :name => name } } within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to have_tag('textarea', options) end end
# File lib/rspec-html-matchers.rb, line 145 def with_text_field name, value = nil options = form_tag_options('text', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 165 def with_url_field name, value = nil options = form_tag_options('url', name, value) should_have_input(options) end
# File lib/rspec-html-matchers.rb, line 261 def without_checkbox name, value = nil options = form_tag_options('checkbox', name, value) should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 208 def without_date_field date_field_type, name = nil, options = {} date_field_type = date_field_type.to_s raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type) options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with) || {}) } options[:with].merge!(:name => name.to_s) if name should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 160 def without_email_field name, value = nil options = form_tag_options('email', name, value) should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 233 def without_file_field name, value = nil options = form_tag_options('file', name, value) should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 180 def without_number_field name, value = nil options = form_tag_options('number', name, value) should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 312 def without_option text, value = nil, options = {} options[:with] ||= {} if value.is_a?(Hash) options.merge!(value) value = nil end tag = 'option' options[:with].merge!(:value => value.to_s) if value options[:with].merge!(:selected => 'selected') if options[:selected] options.delete(:selected) options.merge!(:text => text) if text within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options) end end
# File lib/rspec-html-matchers.rb, line 223 def without_password_field name, value = nil options = form_tag_options('password', name, value) should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 190 def without_range_field name, min = nil, max = nil, options = {} options = { :with => { :name => name, :type => 'range' }.merge(options.delete(:with) || {}) } options[:with].merge!(:min => min.to_s) if min options[:with].merge!(:max => max.to_s) if max should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 286 def without_select name, options = {}, &block options[:with] ||= {} id = options[:with].delete(:id) tag = 'select'; tag += '#' + id if id options[:with].merge!(:name => name) within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block) end end
# File lib/rspec-html-matchers.rb, line 360 def without_submit value # options = form_tag_options('text',name,value) options = { :with => { :type => 'submit', :value => value } } should_not_have_input(options) end
without_tag
matcher @yield block where you should put other with_tag
or without_tag
@see have_tag
@note this should be used within block of have_tag
matcher
# File lib/rspec-html-matchers.rb, line 112 def without_tag tag, options = {}, &block within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block) end end
# File lib/rspec-html-matchers.rb, line 87 def without_text text raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher) raise ArgumentError, 'this matcher does not accept block' if block_given? tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag) within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, :text => text) end end
# File lib/rspec-html-matchers.rb, line 247 def without_text_area name # TODO, should be: without_text_area name, text=nil # options = form_tag_options('text',name,value) options = { :with => { :name => name } } within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('textarea', options) end end
# File lib/rspec-html-matchers.rb, line 150 def without_text_field name, value = nil options = form_tag_options('text', name, value) should_not_have_input(options) end
# File lib/rspec-html-matchers.rb, line 170 def without_url_field name, value = nil options = form_tag_options('url', name, value) should_not_have_input(options) end
Private Instance Methods
form_tag in method name name mean smth. like input, submit, tags that should appear in a form
# File lib/rspec-html-matchers.rb, line 381 def form_tag_options form_tag_type, form_tag_name, form_tag_value = nil options = { :with => { :name => form_tag_name, :type => form_tag_type } } # .to_s if value is a digit or smth. else, see issue#10 options[:with].merge!(:value => form_tag_value.to_s) if form_tag_value options end
# File lib/rspec-html-matchers.rb, line 368 def should_have_input options within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to have_tag('input', options) end end
# File lib/rspec-html-matchers.rb, line 374 def should_not_have_input options within_nested_tag do expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('input', options) end end
# File lib/rspec-html-matchers.rb, line 388 def within_nested_tag &block raise 'block needed' unless block_given? parent_scope = @__current_scope_for_nokogiri_matcher block.call @__current_scope_for_nokogiri_matcher = parent_scope end