HtmlPage.getElementById в HtmlUnit, кажется, повторно инициализирует JavaScript после многих вызовов - PullRequest
0 голосов
/ 16 июня 2011

У меня есть простая 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 для 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()
    }
}

Ответы [ 2 ]

2 голосов
/ 16 июня 2011

Полагаю, вам нужен обработчик щелчка якоря, чтобы "вернуть ложь".

Это должно предотвратить поведение браузера при перезагрузке страницы.

1 голос
/ 16 июня 2011

Превратите вашу ссылку <a href... в кнопку, и она должна работать. Используйте <button type="button", иначе это будет считаться кнопкой отправки.

Кнопка (при условии, что она не отправлена) не приведет к перезагрузке страницы. <a href='#' вызывает перезагрузку в HtmlUnit

...