Jason Alexander wrote:
> Thanks for everyone’s help!
>
> Actually, I found a workaround of sorts -
>
> In my tests, I would grab a div and assign it to a variable and use
> that variable throughout. The problem was, during the operations after
> the var assignment, I would do some things that would cause postbacks.
> And, any references after those postbacks seemed to have lost all context.
>
> Removing the variable assignment and references and just calling
> straight to div() fixed all the issues.
>
> Very interesting, though. I’m not sure if this would be considered a
> bug, or a normal practice that I should watch out for going forward.
Jason. Thanks for letting us know what the problem was.
Recently the following recommendation to use variables was posted to
this list:
> When you're identifying an element that may may be many frames deep, or
> even deep within a single frame, save the element into a variable. This
> way Watir doesn't go through the entire search process every time you
> use the element:
>
> myframe = ie.frame(:name, "frame3").frame(:name, "frame4").frame(:name,
> "tframe1")
> puts myframe.html
> myframe.select_list(:name, "fromedate").flash
>
> Your Watir code also ends up a lot more readable without the very long
> lines :-)
I think this is a bad idea because of exactly the kinds of problems that
Jason encountered.
This is a good example of how you can optimize your script for
performance at the risk of reliability. Specifically, this approach only
works until your script initiates a new page load. After that point, any
variables you have that reference page elements will now be stale and
you will get OLE errors if you try to use them. The problem is that
Watir element references are not specific to a particular page,
considered as something corresponding to a URL or set of HTML, but
rather to a particular load of such a page. I have found that many
testers find it confusing to have to think about the relative timing of
Watir evaluation with respect to browser loading and therefore stopped
encouraging the use of variables in my Watir classes for testers. Indeed
we sometimes get questions on this list from testers who have done
exactly this and then ask why they are getting OLE errors. My
recollection is that i've been the only one to have responded to these
posts, so i suspect that this problem is not well understood in the
community.
I have found that web scrapers generally need performance and understand
the how Watir interacts with the page loading, so they are eager to use
techniques like this. But testers usually would rather pay a small
performance penalty for return for simplicity and reliability.
Testers who like the idea of making your code easier to read, can use
another technique that does not sacrifice reliability (nor improve
performance):
def myframe
$ie.frame(:name, "frame3").frame(:name, "frame4").frame(:name,
"tframe1")
end
puts myframe.html
myframe.select_list(:name, "fromedate").flash
This approach with work regardless of whether a page load happens, so
you don't need to think about that.
The trick to making this technique work is to make sure that you have a
valid reference to "ie" in the method. The easiest way to do this is to
make the variable global (as shown here). If you know how to use
instance variables, that can also work. Or you can pass it in as a
parameter.
Another technique that also simplifies code is this:
def with thing, &block
thing.instance_eval &block
end
with ie.frame(:name, "frame3").frame(:name, "frame4").frame(:name,
"tframe1") do
puts html
select_list(:name, "fromedate").flash
end
In this case, you do need to make sure that you don't do a page load in
the middle of the do/end block. This technique also gives you the
performance benefits of the variable.
Bret
_______________________________________________
Wtr-general mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/wtr-general