Wednesday, February 17, 2010

How to handling timing in Selenium

I see a lot of people struggling with timing issues in Selenium. After you click an element you will need to wait for something. There are four possible outcomes of the click:

  1. It takes you to another page
  2. It creates a pop up
  3. It opens a frame
  4. It updates the DOM
The most basic of outcomes is #1. You have an anchor with an href attribute. You need to wait for the new page to load. For this you need to use:

selenium.waitForPageToLoad(timeout);

If clicking the element causes a pop up use:

selenium.waitForPopUp(windowID, timeout);

If clicking the element causes a new frame to appear use:

selenium.waitForFrameToLoad(frameAddress, timeout);

If clicking the element causes a change to the DOM it gets a little harder. The method to call is fairly straight forward:

selenium.waitForCondition(script, timeout);

The script is a piece of javascript typically. Finding the value for script is the hard part. If you need to look for something on the DOM of the application you need to get the 'document' for that window. So the script needs at least selenium.browserbot.getCurrentWindow(). For example, if I click a link and it updates the price of a shopping cart by modifying the DOM, at the start of the function it might set updating = 1; then at the end of the function, when it has finished updating, it will set updating = 0;. So the condition I am wait for is:

String script = "selenium.browserbot.getCurrentWindow().updating == 0";
The hardest part you will have is determining what condition to wait for. If possible, talk to the person developing the code and see what condition they recommend you wait for.

2 comments:

  1. FYI, there is no difference between WaitForPageToLoad() and WaitForFrameToLoad(). There really should be, but there isn't.

    ReplyDelete
  2. I haven't taken the time to step through the source code for SeleniumServer but even if waitForPageToLoad and waitForFrameToLoad are currently the same, you should use the appropriate call, in case their behaviour changes in the future. In other words, if you use waitForPageToLoad every where, it might work today but if you upgrade to a new version of SeleniumServer it could fail for instances of loading a frame.

    ReplyDelete

Note: Only a member of this blog may post a comment.