java - HtmlUnit 的 HtmlPage.getElementById 似乎在多次调用后重新初始化 JavaScript

标签 java javascript html scala htmlunit

我有一个简单的 HTML 页面 ( ratings.html),我正在尝试使用 HtmlUnit 对其进行测试。当我将其加载到浏览器中并手动执行时,我正在测试的操作会起作用。但是,当我尝试使用 HtmlUnit 对其进行测试时,似乎对 getElementById(或 getInputByName)的调用过多会导致页面上的 JavaScript 重新初始化。

在 AddRating.scala 测试中,对 page.addRating 的前两次调用有效,但第三次调用失败,因为它在页面上找不到“rating3”元素。经过大量调试后,我发现 ratingCount 由于某种原因重置回 0。

请参阅下面我的评论(在 //****** 部分之间)以了解问题所在。

还有其他人经历过这种行为或对如何处理它有任何建议吗?谢谢!

ratings.html(添加“评级”的 HTML 页面):

<html>
  <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
      <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
  </head>
  <body>
    <form name="new-rating" method="post" action="/add-rating">
      <table>
        <tr>
          <td valign="top">Ratings:</td>
          <td>
            Should be ordered from best to worst.<br>
            <a id="add-rating" href="#">add rating</a></td>
        </tr>
        <tr>
          <td></td>
          <td>
            <button name="submit-button" type="submit">Add Rating</button>
          </td>
        </tr>
      </table>
    </form>
    <h2>All Ratings</h2>

    <ul id="ratings">
    </ul>

    <script>
      $(window).load(function(){   
          // display ratings
          $.getJSON("/ratings", function(data)
          {
              var items = $.map(data, function(el) {
                var ratingsTable = "";
                if (el.ratings.length > 0)
                {
                  $.tmpl("<li><table><tr><th>Rating</th></tr>{{each ratings }}<tr><td>${$value.label}</td></tr>{{/each}}</table></li>", el).appendTo("#ratings");
                }
              });
          });

          // add rating action
          // ***********
          var ratingCount = 0; // THIS GETS RE-INITIALIZED TO 0 AFTER TOO MANY getElementById or getElementByName calls.
          // ***********
          $('#add-rating').click(function()
          {
              ratingCount += 1;
              $('#remove-rating').show();
              $.tmpl("<span id='rating${ratingId}'><input name='rating${ratingId}'><br></span>",
                     {ratingId: ratingCount}).insertBefore('#add-rating');
              if(ratingCount >= 5) { $('#add-rating').hide(); }
          });
      });
    </script>
  </body>
</html>

RatingsPage.scala(Scala 接口(interface)到 HTML 页面):

package portal

import com.gargoylesoftware.htmlunit.WebClient
import com.gargoylesoftware.htmlunit.html._

import infrastructure.SuperHtmlUnitConversions._

import infrastructure.WaitFor

class RatingsPage(page: HtmlPage)
{
    val newRatingForm: HtmlForm = page.getFormByName("new-rating")

    var ratingCount = 0

    def submit(): RatingsPage =
    {
        val page = newRatingForm.getButtonByName("submit-button").click[HtmlPage]()
        ratingCount = 0
        new RatingsPage(page)
    }

    def addRating(rating: String)
    {
        page.getElementById("add-rating").click()
        ratingCount += 1
        newRatingForm.getInputByName("rating" + ratingCount).asInstanceOf[HtmlInput].setValueAttribute(rating)
    }

    def asText(): String = page.asText
    def asXml():  String = page.asXml
}

AddRating.scala(Scala HtmlUnit 测试失败):

package portal

import java.util.Date
import org.scalatest.FunSuite
import org.scalatest.junit.JUnitRunner
import org.junit.runner.RunWith
import org.scalatest.matchers.ShouldMatchers
import com.gargoylesoftware.htmlunit.WebClient
import com.gargoylesoftware.htmlunit.html._
import infrastructure.WaitFor

@RunWith(classOf[JUnitRunner])
class AddRating extends FunSuite with ShouldMatchers
{
    test("add ratings")
    {
        val client = new WebClient()
        val index = new PortalIndexPage(client)
        var page = index.goToRatingsPage()

        page.addRating("Buy") // WORKS
        page.addRating("Sell") // WORKS
        // *********
        page.addRating("Sell") // FAILS! Can't find element with "rating3" name!
        // *********
        page = page.submit()
        WaitFor("rating to show up", ()=>page.asXml.contains("Sell"))

        page.asText should include ("Buy")

        client.closeAllWindows()
    }
}

最佳答案

我的猜测是,您需要让 anchor 击处理程序“返回 false”。

这应该可以防止浏览器重新加载页面的行为。

关于java - HtmlUnit 的 HtmlPage.getElementById 似乎在多次调用后重新初始化 JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6364675/

相关文章:

html - 无法跨浏览器获得像素完美高度

html - 从 Bootstrap Accordion 控件中删除边框

Java - Swing 计时器开始显示的时间比预期晚一些

java - JPanel 导致侧面有额外空间?

javascript - 使用 Angular-translate 进行参数格式化

javascript - Node .js : make http calls in for loop

javascript - 有人能解释一下这段 JavaScript 代码吗?

javascript - 单击提交按钮之前表单不断重定向

java - jaxb 不生成具有基本整数的枚举

java - 在同一个类中扩展并实现