有没有办法在某些自定义 html 文本上使用assert_select?

发布于 2024-10-12 16:31:51 字数 2168 浏览 5 评论 0原文

我正在尝试让assert_select 处理一些原始文本。以下是我所拥有的,但是当我执行选择时,它说没有匹配项。我还附加了来自assert_select方法的片段,该片段表明接受HTML::Node对象是可行的(我还尝试将提取的html包装在html/body标签中)

# Controller test
test "edit form contains all required fields" do
  group = groups(:a_group)
  user = users(:group_member)
  post = create_post(user, :group_ids => group.id)

  xhr :get, :edit, {:id => post.id}, {:user_id => user.id}
  node = convert_js_to_node(@response.body, "form")
  puts node.inspect
  assert_select node, "form"
  assert_select node, "input[type=text]"
end


# test_helper.rb method
def convert_js_to_node(js, enclosing_tag)
  regex = Regexp.new("(\<#{enclosing_tag}.*#{enclosing_tag}\>)")
  HTML::Node.new( js.match(regex)[0] )
end

## Test output
Loaded suite functional/posts_controller_test
Started
#<HTML::Node:0x1050e6040 @line=0, @children=[], @parent="<form accept-charset=\\\"UTF-8\\\" action=\\\"/posts/1023110311\\\" class=\\\"edit_post\\\" data-post-id=\\\"1023110311\\\" data-remote=\\\"true\\\" id=\\\"edit_post_1023110311\\\" method=\\\"post\\\"><div style=\\\"margin:0;padding:0;display:inline\\\"><input name=\\\"utf8\\\" type=\\\"hidden\\\" value=\\\"&#x2713;\\\" /><input name=\\\"_method\\\" type=\\\"hidden\\\" value=\\\"put\\\" /><\\/div>\\n\t\t<h3>Edit post<\\/h3>\\n\t\t<h5><img alt=\\\"Contact\\\" class=\\\"icon\\\" height=\\\"16\\\" src=\\\"/images/contact.png?1288409655\\\" width=\\\"16\\\" /> in some where<\\/h5>\\n\t\t\t\\n\t\t<div id=\\\"post_content\\\" class=\\\"clearfix clear\\\"

  1) Failure:
test_edit_form_contains_all_required_fields(PostsControllerTest)
    []:
Expected at least 1 element matching "form", found 0.
<false> is not true.

# File actionpack/lib/action_controller/assertions/selector_assertions.rb, line 201
def assert_select(*args, &block)
  # Start with optional element followed by mandatory selector.
  arg = args.shift

  if arg.is_a?(HTML::Node)
    # First argument is a node (tag or text, but also HTML root),
    # so we know what we're selecting from.
    root = arg
    arg = args.shift
  elsif arg == nil
    ...

I am trying to get assert_select to work on some raw text. Below is what I have, but when I perform the select it says there are no matches. I have also attached a snippet from the assert_select method which shows that accepting an HTML::Node object is doable (I have also tried wrapping the extracted html in html/body tags)

# Controller test
test "edit form contains all required fields" do
  group = groups(:a_group)
  user = users(:group_member)
  post = create_post(user, :group_ids => group.id)

  xhr :get, :edit, {:id => post.id}, {:user_id => user.id}
  node = convert_js_to_node(@response.body, "form")
  puts node.inspect
  assert_select node, "form"
  assert_select node, "input[type=text]"
end


# test_helper.rb method
def convert_js_to_node(js, enclosing_tag)
  regex = Regexp.new("(\<#{enclosing_tag}.*#{enclosing_tag}\>)")
  HTML::Node.new( js.match(regex)[0] )
end

## Test output
Loaded suite functional/posts_controller_test
Started
#<HTML::Node:0x1050e6040 @line=0, @children=[], @parent="<form accept-charset=\\\"UTF-8\\\" action=\\\"/posts/1023110311\\\" class=\\\"edit_post\\\" data-post-id=\\\"1023110311\\\" data-remote=\\\"true\\\" id=\\\"edit_post_1023110311\\\" method=\\\"post\\\"><div style=\\\"margin:0;padding:0;display:inline\\\"><input name=\\\"utf8\\\" type=\\\"hidden\\\" value=\\\"✓\\\" /><input name=\\\"_method\\\" type=\\\"hidden\\\" value=\\\"put\\\" /><\\/div>\\n\t\t<h3>Edit post<\\/h3>\\n\t\t<h5><img alt=\\\"Contact\\\" class=\\\"icon\\\" height=\\\"16\\\" src=\\\"/images/contact.png?1288409655\\\" width=\\\"16\\\" /> in some where<\\/h5>\\n\t\t\t\\n\t\t<div id=\\\"post_content\\\" class=\\\"clearfix clear\\\"

  1) Failure:
test_edit_form_contains_all_required_fields(PostsControllerTest)
    []:
Expected at least 1 element matching "form", found 0.
<false> is not true.

# File actionpack/lib/action_controller/assertions/selector_assertions.rb, line 201
def assert_select(*args, &block)
  # Start with optional element followed by mandatory selector.
  arg = args.shift

  if arg.is_a?(HTML::Node)
    # First argument is a node (tag or text, but also HTML root),
    # so we know what we're selecting from.
    root = arg
    arg = args.shift
  elsif arg == nil
    ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倚栏听风 2024-10-19 16:31:51

这是我整理的。它并不完美,但它满足了我的需要。

# allows for a method similar the native assert_select method to be performed
# on raw html text that is embedded within javascript code.
# ex.
#   $('body').append("<div id=\"edit_post_form_container\" class=\"active modal_form_container\">
#     <a href=\"#\" class=\"close\">
#       <img alt=\"Close\" height=\"16\" src=\"/images/close.png?1293730609\" width=\"16\" />
#     <\/a>
#     <form accept-charset=\"UTF-8\" action=\"/posts/1023110335\" .../>")
#
# To test for the closing link image:
# => assert_js_select("img[alt=Close]")
# To be more specific you can include a parent tag:
# => assert_js_select("img[alt=Close]", "a")
#
# Note: The parent_tag parameter cannot include any attribute or style selectors since
#       the initial extraction of the html section is done using a regular expression.
def assert_js_select(tag, content=nil, options={})
  text = options[:text] || @response.body
  parent_tag = options[:parent_tag] || ""
  regex = Regexp.new("(\<#{parent_tag}.*#{parent_tag}\>)")
  extracted_text = text.match(regex)[0].gsub(/\\/, "")
  if extracted_text.present?
    doc = HTML::Document.new(CGI::unescapeHTML(extracted_text)).root
    assert_select(doc, tag, content)
  else
    assert false, "Missing #{tag} tag"
  end
end

This is what I put together. It isn't perfect but it does what I need it to.

# allows for a method similar the native assert_select method to be performed
# on raw html text that is embedded within javascript code.
# ex.
#   $('body').append("<div id=\"edit_post_form_container\" class=\"active modal_form_container\">
#     <a href=\"#\" class=\"close\">
#       <img alt=\"Close\" height=\"16\" src=\"/images/close.png?1293730609\" width=\"16\" />
#     <\/a>
#     <form accept-charset=\"UTF-8\" action=\"/posts/1023110335\" .../>")
#
# To test for the closing link image:
# => assert_js_select("img[alt=Close]")
# To be more specific you can include a parent tag:
# => assert_js_select("img[alt=Close]", "a")
#
# Note: The parent_tag parameter cannot include any attribute or style selectors since
#       the initial extraction of the html section is done using a regular expression.
def assert_js_select(tag, content=nil, options={})
  text = options[:text] || @response.body
  parent_tag = options[:parent_tag] || ""
  regex = Regexp.new("(\<#{parent_tag}.*#{parent_tag}\>)")
  extracted_text = text.match(regex)[0].gsub(/\\/, "")
  if extracted_text.present?
    doc = HTML::Document.new(CGI::unescapeHTML(extracted_text)).root
    assert_select(doc, tag, content)
  else
    assert false, "Missing #{tag} tag"
  end
end
弥枳 2024-10-19 16:31:51

对于 Rails 4.x,这对我有用(技巧是在规范/测试期间覆盖“document_root_element”方法):

context "with assert_select" do
  def document_root_element
    Nokogiri::HTML::Document.parse(@html).root
  end

  it "selects" do
    @html = "<html></html>"
    assert_select("html", count: 1) # should work!
  end
end

With Rails 4.x, this works for me (the trick is to override the "document_root_element" method during the spec/test):

context "with assert_select" do
  def document_root_element
    Nokogiri::HTML::Document.parse(@html).root
  end

  it "selects" do
    @html = "<html></html>"
    assert_select("html", count: 1) # should work!
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文