如何对 JavaScript 响应执行功能测试?

发布于 2024-10-15 07:29:33 字数 603 浏览 7 评论 0原文

我注意到,在 Rails 中,为 js 请求渲染回文本,并将文本嵌入到 jquery 方法调用中以将其插入到 DOM 中是很常见的。

// javascript code
$.getScript("/some_url");

// rails partial code, to make things more clear I have added some simple html
$("#some_id").text(unescape_javascript('<div id="foo">bar</div>'))

我的问题是如何在对这样的响应文本进行功能测试时执行assert_select 或等效操作?

// 
class FooBarControllerTest < ...
  test "javascript response" do
     xhr :get, :new
     // how could I test the div here
     assert_select "#foo", "bar"  // this doesn't work
  end
end

** 更新了代码以使其更加清晰

I noticed that it is quite common in Rails to render back text for js requests with the text embedded within a jquery method call to insert it into the DOM.

// javascript code
$.getScript("/some_url");

// rails partial code, to make things more clear I have added some simple html
$("#some_id").text(unescape_javascript('<div id="foo">bar</div>'))

My question is how do you perform assert_select, or the equivalent, within a functional test on response text like this?

// 
class FooBarControllerTest < ...
  test "javascript response" do
     xhr :get, :new
     // how could I test the div here
     assert_select "#foo", "bar"  // this doesn't work
  end
end

** Updated code to make this more clear

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

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

发布评论

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

评论(3

傾城如夢未必闌珊 2024-10-22 07:29:33

经过一番摆弄后,这对我有用。最棘手的部分是在创建 HTML::Document 对象之前清理所有分隔字符,例如 \t、\n 和 \。

# wrapper method around the native assert_select method that extracts out the html
# from 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\" .../>")
#
# assert_js_select "input[type=?][name=?]", "text", "foo[bar]", :count => 1
# assert_js_select "textarea", "Some long text"
# assert_js_select "textarea[name=?]", "post_text", "Some long text"
# assert_js_select "textarea[name=?][class=?]", ["post_text", "css_class", "Some long text"
def assert_js_select(*args, &block)
  extracted_text = @response.body.match(/(\<.*\>)/)[0].
    gsub("\\n", "").gsub("\\t", "").gsub(/\\"/, '"').gsub("\\", '')
  if extracted_text.present?
    doc = HTML::Document.new(CGI::unescapeHTML(extracted_text)).root
    args.insert(0, doc)
    assert_select(*args, &block)
  else
    assert false, "Unable to extract any html from the js code."
  end
end

After some fiddling around this works for me. The trickiest part is cleaning up all of the delimited chars such as \t,\n and \ before creating the HTML::Document object.

# wrapper method around the native assert_select method that extracts out the html
# from 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\" .../>")
#
# assert_js_select "input[type=?][name=?]", "text", "foo[bar]", :count => 1
# assert_js_select "textarea", "Some long text"
# assert_js_select "textarea[name=?]", "post_text", "Some long text"
# assert_js_select "textarea[name=?][class=?]", ["post_text", "css_class", "Some long text"
def assert_js_select(*args, &block)
  extracted_text = @response.body.match(/(\<.*\>)/)[0].
    gsub("\\n", "").gsub("\\t", "").gsub(/\\"/, '"').gsub("\\", '')
  if extracted_text.present?
    doc = HTML::Document.new(CGI::unescapeHTML(extracted_text)).root
    args.insert(0, doc)
    assert_select(*args, &block)
  else
    assert false, "Unable to extract any html from the js code."
  end
end
舞袖。长 2024-10-22 07:29:33

我不知道你会如何从rails请求它,但是使用ajax和jquery会像这样:

$.ajax({
        type: 'POST',
        url: 'getstring.php',
        data: '',
        success: function(server_response){
            if(server_response){
                eval(server_response);
            }
            else{

            }
        }
    });

你需要的是eval,所以只需将你的字符串放在eval()内部作为javascript运行;

i dont know how would you request it from rails but with ajax and jquery would go like this:

$.ajax({
        type: 'POST',
        url: 'getstring.php',
        data: '',
        success: function(server_response){
            if(server_response){
                eval(server_response);
            }
            else{

            }
        }
    });

thing you need is eval, so just put your string that hawe to be runed as javascript inside of eval();

跨年 2024-10-22 07:29:33

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

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

  it "works" do
    xhr :get, :new
    @html = response.body # or wherever the response HTML comes from
    assert_select "#foo", "bar" # should work now
  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 "works" do
    xhr :get, :new
    @html = response.body # or wherever the response HTML comes from
    assert_select "#foo", "bar" # should work now
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文