1
votes

I'm testing an internal website built on the Magento storefront. During the checkout process, certain parts of the form are hidden (style: none) until the previous section is filled out. These parts would normally break the script, but using when_present for the first element of the hidden form resolved this issue.

The Submit Order button, however, is not working well with these same methods. I worked with our lead developer today to verify that the only difference between this button and the previous form buttons is that a new page is loaded (new URL, new "done" status in the browser).

To be crystal clear:

  1. User enters name, address, email and clicks 'Continue' => JS "loading" animation spins while the General panel slides closed and the Shipping Method panel expands, all on the same page.
  2. User clicks 'Submit Order' => JS "loading" animation spins, when complete, the browser proceeds to /success/ (new page) with verifiable elements.
  3. If given enough time to complete (sleep statement), the test does pass.

Here is the somewhat-pseudo code for the form, and the Submit click:

def complete_form(data = {})
  data = DEFAULT_DATA.merge (data)
  select_guest
  continue_button.click  #proceed to billing panel
  enter_billing_and_shipping_info(data)
  enter_additional_information(data)

  place_order_button.when_present.click  #submit form
  #sleep 2  #this succeeds, but is undesirable
  thank_you_message.wait_until_present #I do not actually appear to wait until anything is present
end #

def enter_billing_and_shipping_info(data)
  billing_first_name.when_present.value = data['First Name'] #I work!
  billing_last_name.value = data['Last Name']
  #more fields
end #

From Steps:

thank_you_message.should include("Yippee")

The script fails in two different ways depending on how quickly the site is responding:

  1. fail with a message that the expected Thank You message was not found - a screenshot taken during the error shows the Checkout page, NOT the thank you page, with the "loading" animation displayed. (expected "Checkout" to include "Your order has been received")
  2. fail with the "Element not found in the cache" error - the screenshot in this case does display the Thank You page, containing the text we are looking for

Other methods such as Watir::Wait.until, or until {} do, resulted in the same behavior.

  • Windows 7 64-bit & Windows XP 32-bit
  • ruby 1.9.2p290 (2011-07-09) [i386-mingw32]
  • cucumber (1.0.2)
  • rspec (1.3.2)
  • watir-webdriver (0.3.0)

Update 8-15 Attempted solution #1:

  place_order_button.when_present.click  #complete form
  ajax_submit_image.wait_while_present

Same end result - script terminates with no success message found, screenshot shows the Ajax loading image mid-spin. Both this and the previous method SHOULD work, but seem to have no effect. I did verify that I can access the image using the locators in the script (img src match).

2
It would be useful to know the return type of thank_you_message in the code example (which seems to be some sort of Watir::Element since it responds to wait_until_present, though the "From Steps" code indicates that it's a string). Also, seeing the stacktraces from any errors would be helpful. Since you're waiting for the page to change, another nice trick is to wait for the page's title to change: old_title = browser.title; Wait.until { browser.title != old_title }jarib
Good catch, Jari. I was mixing two different attempts at the thank you page verification in an attempt to summarize the issue here. The "From Steps" code is for @browser.div(:class, /page-title/).text, and the wait_til_present version above was for @browser.button(:text, /Continue Shopping/) which only appears on the thank you page. The page title idea may solve the issue entirely, excited to check it out.adam reed
Jari, if you post your solution about the title as the answer, I will gladly accept it. Still not sure why the former methods don't work, but this one solved all my current problems: place_order_button.when_present.click #complete form Watir::Wait.until(15) { @browser.title == "Expected Title" }adam reed

2 Answers

2
votes

Have you considered using the presence of the 'loading animation' (which might just be an animated gif or similar) as a way to know you should keep waiting?

I've used that means in some of my scripts where the animation was just a simple graphic file that was being made visible or not by client side javascript. So my wait loop consisted of a brief sleep, and checking to see if the animation was still present, exiting once it had gone away.

1
votes

one option worth considering is requesting a testability feature of a flag in the application itself that lets you know if an asynchronous process is running. In one AJAX-heavy web app I tested, whenever an XRH or timer kicked off, we set an attribute on the body tag like AjaxStarted and the final thing any XHR or timer would do was set that attribute to AjaxStopped. That way, in any context (even where there might be multiple asynchronous processes underway, I had one easy method to call to see if I should move on or not.

You can read details of what we did and some other solutions we tried here: http://testingjeff.wordpress.com/2009/10/21/relief-for-the-pain-of-waiting-for-ajax-elements-on-the-page/