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