John Lolis wrote:
> A second, slightly related question. Regardless of how you do it, i'm 
> wondering whats going on behind the scenes.
> If you do 
>   
>> headline = $ie.div(:text, 'Pragmatic Version Control')
>> link = $ie.link(:class => 'addtocart', :after? => headline) 
>>     
>
> Is headline now 'frozen'? For example, lets say there is a 'addtocart' after 
> headline. What happens if after you create your headline variable the page 
> changes (headline is now at the bottom of the page)? Will the after method re 
> evaluate headlines position in the page? Or is headline now static so after 
> would would be true even if it isn't?
>
> I'm not sure if that even made sense.
>   
Actually this is a good question.


Let's call each of these "Watir expressions". They can refer to 
different objects on different pages, or sometimes they refer to nothing.

> $ie.div(:text, 'Pragmatic Version Control')
> $ie.link(:class => 'addtocart', :after? => headline) 
>   

When they are used, they end up referring to specific control on a 
specific page at a specific point in time. Let's call this an "element 
reference" (internally it is called @o and getOLEobject and ole_object, 
variously depending on version). This reference is actually a COM object 
that will become stale as soon as a new page is loaded. However it will 
remain valid if javascript-based changes are made to the DOM.

So your question becomes: What is the relationship between Watir 
expressions and element references? And the answer depends on whether 
you are using Watir 1.4 or 1.5.

Both versions of Watir use "locate" methods to tie the Watir objects 
returned by Watir expressions to the element references, and we might 
call this process "binding". In Watir 1.4, this binding was made at call 
time. When the expression was executed, the Watir object would be bound. 
However, if there was a failure to bind (ObjectNotFound), an error would 
not be raised until you actually made a call to the object -- for 
example, calling its "click" method. The reason for this was to allow us 
to have an "exists?" method. This method would only return false if we 
had failed to bind -- not raise an error.

In Watir 1.5, i moved the timing of the locate method (in most cases) so 
that binding itself would not happen until this time -- when we 
previously were just checking to see if the binding had been made or 
not. In other words, we had "late binding" in 1.4 and "really-late 
binding" in 1.5.

In theory, really-late binding would allow you to create objects that 
would rebind themselves after a page load. However, i've never 
encouraged this, nor have i seen any evidence that people have actually 
been doing this. A big issue is that this automatic rebinding would 
happen in simple cases but not in complex cases and understanding the 
difference was really too much to expect from our users. I'm reluctant 
to even try and explain it, and frankly there are edge cases that i'm 
unsure of myself, and i also suspect there are bugs.

So we have consistently urged people to wrap their watir expressions in 
methods rather than assign them to global variables. This makes it easy 
to reuse them, and ensure that a correct rebinding occurs on each reuse. 
Also, as i have been using Watir more on large projects, i am finding 
that there are other reasons why this is a sound way to structure Watir 
libraries.

This made the automatic-rebinding we have in place simply a performance 
hog with no real benefit. I posted a patch the other day that removes it 
and will probably commit this to trunk soon. It has the potential to 
break tests, so first i want to post a release that rolls up the new 
features and bug fixes that will assuredly be popular.

So the short answer to your question, is "it depends".

    Is headline now 'frozen'? For example, lets say there is a 'addtocart' 
after headline. What happens if after you create your headline variable the 
page changes (headline is now at the bottom of the page)? Will the after method 
re evaluate headlines position in the page? Or is headline now static so after 
would would be true even if it isn't?
      

So when you say the page changes, we need to know whether a new page is 
loaded (or even reloading the same page) or whether the change is made 
dynamically. Right now, it will rebind if we get a page load (but, like 
i said, i'm considering removing this behavior). If it is an 
AJAX/Javascript change, then we would need more details. In particular, 
a lot of times when we see AJAX/Javascript page elements moving, they 
are actually being made visible or invisible, which is a whole other 
thing, since Watir can "see" invisible elements.

The important message is that you really should re-execute the headline 
Watir expression after a page change. That will ensure that your tests 
work correctly, not matter how your page works or what version of Watir 
you are using.

Bret
_______________________________________________
Wtr-general mailing list
Wtr-general@rubyforge.org
http://rubyforge.org/mailman/listinfo/wtr-general

Reply via email to