Question

I'm using jRuby, watir-webdriver, and Page Object for testing a web application.

The application has a jquery autocomplete widget that provides responses from the backend database after some sort of delay, which I can't always predict.

I'm trying to poll and have my asserts in the tests happen only after all the data has shown up in the suggestion box under the autocomplete field.

How can I poll using Page Object or watir so that I know exactly when I've received all of the data from a successful AJAX call?

--

I have tried using

@page.wait_until do

end

The problem is, I can't find anything good to put in the block.

I'm guessing it will be something like

@browser.execute_script("some_sort_of_javascript_code_that_returns_a_boolean_when_the_ajax_call_is_done")

Obviously, I need help finding that special javascript I need or thinking of an alternative...

Was it helpful?

Solution

Solution - jQuery.active

You can check the jQuery.active property to see if there is a call running. A value of zero means that nothing is running.

running = @browser.execute_script('return jQuery.active == 0')

The page object gem has a built in method for waiting for jQuery ajax calls. It is configured by:

PageObject.javascript_framework = :jquery

and called using:

wait_for_ajax

While this works for many jQuery controls, the problem with the autocomplete is that it is often configured to have a delay between the user inputting the text field and then checking for autocomplete results. If configured, you would need to wait for the call to start as well as to end. If you do not check the start, it will seem like the call is done even though it has not yet started.

Here is an example using the jQuery UI remote database example. The script will input a value into the text field, wait for the list to appear and then select a value:

require 'watir-webdriver'
require 'page-object'

PageObject.javascript_framework = :jquery

class MyPage
  include PageObject

  text_field(:birds, :id => 'birds')
  def birds_select(value)
    # Wait for ajax call to start
    wait_until{ !execute_script('return jQuery.active == 0') }

    # Wait for ajax call to end
    wait_for_ajax

    # Select from autocomplete list
    list = unordered_list_element(:class => 'ui-menu')
    list.link_element(:text => 'Jack Snipe').click  
  end
end

@browser = Watir::Browser.new
@browser.goto 'http://jqueryui.com/resources/demos/autocomplete/remote.html'

page = MyPage.new(@browser)
page.birds = 'ja'
page.birds_select('Jack Snipe')

Solution - Wait for List

I think a better approach is to simply wait for the list element, which is the autocomplete list, to appear. This way you do not have to worry about the timing of checking the start/stop of ajax calls.

You can wait for the list using the when_present method. Here is a working example for the same page:

require 'watir-webdriver'
require 'page-object'

class MyPage
  include PageObject

  text_field(:birds, :id => 'birds')
  def birds_select(value)
    list = unordered_list_element(:class => 'ui-menu')
    list.when_present.link_element(:text => 'Jack Snipe').click  
  end
end

@browser = Watir::Browser.new
@browser.goto 'http://jqueryui.com/resources/demos/autocomplete/remote.html'

page = MyPage.new(@browser)
page.birds = 'ja'
page.birds_select('Jack Snipe')

OTHER TIPS

What are you going to to is to test jQuery plugin, which is already tested. You should assume it works and concentrate on testing your server functionality and create some unit tests instead of UI test.

I mean you should create test pairs with |request: expected respond| and test you server responses. In which case you don't need Watir at all.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top