rspec-html-matchers 发现 html 和 HTML 中的正文标签没有它们

rspec-html-matchers finds html and body tags in HTML without them

我有一个非常简单的目录,其中有一个 index.html 文件,我正在用 rspec-html-matchers.

进行测试

我在 spec_helper.rb 中这样配置它:

require "rspec-html-matchers"

RSpec.configure do |config|
  config.include RSpecHtmlMatchers

  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end

  config.shared_context_metadata_behavior = :apply_to_host_groups
end

测试大部分都按预期工作,但现在我正在测试 <html><body> 标签的存在并得到(我认为是)不正确的结果。

例子

这是一个我认为应该失败的非常简单的测试:

describe "index" do
  it "does something weird" do
    expect("<h1>just a header</h1>").to have_tag('html')
  end
end

该字符串显然 包含 <html> 标记,因此它应该失败。

本次测试:

我错过了什么?如何测试是否存在正确实施的 <html><body> 标签?

rspec-html-matchers' have_tag parses the document with Nokogiri's HTML parser,它添加了 HTML 标准所需的缺失标签。你可以在 irb 中看到这个:

irb(main):001:0> require 'nokogiri'
irb(main):002:0> Nokogiri::HTML '<p>Hi</p>'
=> #<Nokogiri::HTML::Document:0x3fedb1935a60 name="document" children=[
     #<Nokogiri::XML::DTD:0x3fedb19353f8 name="html">,
     #<Nokogiri::XML::Element:0x3fedb1934f84 name="html" children=[
       #<Nokogiri::XML::Element:0x3fedb1934a70 name="body" children=[
         #<Nokogiri::XML::Element:0x3fedb1934804 name="p" children=[
           #<Nokogiri::XML::Text:0x3fedb19344bc "Hi">]>]>]>]>

Capybara的have_selector匹配器也使用了Nokogiri::HTML,效果相同。

如果您的 HTML 是 XHTML,您可以在严格模式下使用 Nokogiri 的 XML 解析器测试 htmlbody 标签:

it "has html and body tags" do
  string = "<html><body><p>Hi</p></body></html>"
  # The following raises an error if the string contains unbalanced tags
  xml = Nokogiri::XML(string) { |config| config.options = Nokogiri::XML::ParseOptions::STRICT }
  htmls = xml.children.select { |child| child.name == 'html' }
  expect(htmls.length).to eq(1)
  bodys = htmls.first.children.select { |child| child.name == 'body' }
  expect(bodys.length).to eq(1)
end