views:

171

answers:

1

I am trying to test a web page that has ajax calls to update a price. An ajax call is fired on page load to update an initially empty div.

This is the extension method I'm using to wait for a change in the inner text of the div.

public static void WaitForTextChange(this IE ie, string id)
{
    string old = ie.Element(id).Text;
    ie.Element(id).WaitUntil(!Find.ByText(old));
}

However it's not pausing even though when I write out the old value and ie.Element(id).Text after the wait, they are both null. I can't debug as this acts as a pause.

Can the Find.ByText not handle nulls or have I got something wrong.

Has anyone got some code working similar to this?

+2  A: 

I found my own solution in the end after delving into WatiN's constraints.

Here's the solution:

public class TextConstraint : Constraint
{
 private readonly string _text;
 private readonly bool _negate;

 public TextConstraint(string text)
 {
  _text = text;
  _negate = false;
 }

 public TextConstraint(string text, bool negate)
 {
  _text = text;
  _negate = negate;
 }

 public override void WriteDescriptionTo(TextWriter writer)
 {
  writer.Write("Find text to{0} match {1}.", _negate ? " not" : "", _text);
 }

 protected override bool MatchesImpl(IAttributeBag attributeBag, ConstraintContext context)
 {
  return (attributeBag.GetAdapter<Element>().Text == _text) ^ _negate;
 }
}

And the updated extension method:

public static void WaitForTextChange(this IE ie, Element element)
{
    string old = element.Text;
    element.WaitUntil(new TextConstraint(old, true));
}

It assumes that the old value will be read before the change so there's a slight chance of a race condition if you use it too long after setting off the update but it works for me.

Chris Woodward
Actually. I've hit another problem. Sometimes the price I'm updating doesn't change, in which case I want to timeout and then carry on with the next user action but using .WaitUntil(new TextConstraint(old, true), 2000);Just gets stuck.
Chris Woodward