Waiting for knockout.js bindings to be complete before starting UI-test

As always when UI-testing javascript heavy code with ajax calls going around you might end up with some timing issues. The problem is that it’s not easy for the poor driver to know when the page is finished and the test can start. Recently I had the task of writing some UI-tests for a page that used knockout.js and this is how I solved the waiting part.

applyBindings

All the bindings are triggered through the page and it’s viewmodel with the standard applyBindings function. This will bind the viewmodel itself and all the other views the page contains.

ko.applyBindings(pageViewModel);

Since this call is blocking when it’s finished the bindings are applied. So I added a simple bool to the object that represented the page that tracks whether the page has finished it’s bindings.

SomeObject.BindingsAreApplied = false;
// Lots of setup
ko.applyBindings(pageViewModel);
SomeObject.BindingsAreApplied = true;

Selenium WebDriver side

When the driver browses to the page in question it issues a WebDriverWait with the condition that the bool we just added to the javasript is true.

new WebDriverWait(driver, TimeSpan.FromSeconds(secondsToWait))
  .Until(d =>
  {
    var result = (d as IJavaScriptExecutor).ExecuteScript("return window.SomeObject.BindingsAreApplied");

    if (result == null)
    {
      return false;
    }

    return (bool)result;
  });
  • http://swiety.tumblr.com/ Tomasz Święcicki

    It’s good idea. I think we should build something global. Something which will wait for all bindings.

  • Ben Power

    I agree with Tomasz, this is something that would be extremely useful. At the moment we are simply waiting for elements to exist on a page and timing out after a period of time. It’s not efficient and occasionally fails completely.