• For the JavaScript unit tests that operate DOM, it's quite handy if the DOM fixtures could be shared between tests. This involves how to load another HTML file from one HTML file for most of the JavaScript testing frameworks (like Screw.Unit and JSUnit), the prior file is the DOM fixture and the later file hosts the test codes.

    This blog demonstrates a way to do it through jQuery synchronized Ajax call. Below is the code skeleton of a test file:

    <html>
      <head>
        <script type="text/javascript" src="lib/jquery-1.3.2.js"></script>
      </head>
    
      <body>
        <div id="fixture">
          <script type="text/javascript">
            $.ajaxSetup({ async: false }); // Ajax will run in sync
            $("#fixture").load("fixtures/DOMFixture.html"); // replace inner html with loaded content
          </script>
        </div>
    
        <script type="text/javascript">
          // tests go here
        </script>
      </body>
    </html>
    

    This works for all the mainstream browsers including Firefox and IE.

    Another possible approach that I haven't verified in detail is that 1) create XML document element dynamically, 2) load fixture file to the element synchronously, then 3) append the element to the place holder DIV in test file.

     

  • Mark Needham just posted a blog here described the 'waiting for jQuery ajax call' problem in selenium tests and the way we solved it.

    The basic idea is recording the count of active ajax requests in client side js code, and generically decorating the calls(click, type, select etc.) in selenium tests with the logic of waiting for the count to be zero.

    Ajax request may not be the only async point we want to wait for its completion in selenium tests, animation is another one we care about, but just turn off it in tests so that we don't need to worry about it any more. "jQuery.fx.off = true" will turn off jQuery animation.

    Is there any more async points? probably YES. Acturally, what we really want to wait is the completion of any action which is delayed to be executed by window.setTimeout() or window.setInterval(). Ajax and animation rely on window.setTimeout() or window.setInterval() to simulate the async behaviours eventually.

    Please check out the code at mark's post or here(with comments) for details. It works for the cases you fire multiple ajax requests at once or fire further ajax request in previous ajax request's callback.

    Given this, we removed almost all noisy thread.sleep() and waitForCondition() codes in selenium tests! The build is speeded up and the tests become more concise, readable and stable.

    This approach is simple, stable, side-effect free and able to be ported to other ajax framework easily.(jQuery Ajax provides proper events we can rely on, for other ajax framework without build-in events, we can try method delegation instead)

    Waiting for ajax call is a common issue in selenium tests, try this approach and make your selenium tests cleaner.