Okey, I've finally found the culprit of my failing tests.

I don't know exactly, what has changed in Watir to make my tests to
fail, but I know that it is not Watir's fault per se.

I also changed subject of this topic, because original problem is not
related with this seem-to-be-greater problem.

Original problem was caused by the fact that when page loads then
select list doesn't have any values in it yet because all values are
fed to some kind of JavaScript function, which filters or sorts or
whatever does with those options and sometimes before JavaScript has
finished it's thing, then Watir can't find option to select from.

Solution for that was to use wait_until selectlist has values.

Anyway, now I have completely different problem. Problem is related
with fire_event. I have always assumed that Watir knows when
fire_event call has finished, but it seems that IE will respond
immediately to this call. I don't know if it is possible to make this
call blocking until event has really finished or not. I assume that
everything passed with Watir 1.5.6 because it was just slower than
1.6.2. Now, 1.6.2 fires event and my assertion will fail sometime.
This is due to the fact that fire_event call doesn't actually finish.
I've played around little bit with timings and it seems that if
onchange/onclick or whatever JavaScript event takes more than 220 -
230 ms of time to complete, then you might be in trouble, because
Watir finishes it's method invocation and passes to next command,
which might be assertion or whatever else, which fails due to the fact
that for user there isn't anything changed yet.

Consider I have this simple html opened in my IE:
<html>
    <body>
        <form>
            <input type="text" name="field1" onchange="setTimeout
(function() {document.getElementById('content').innerHTML='field1'},
500)">
            <input type="button" name="button1" onclick="setTimeout
(function() {document.getElementById('content').innerHTML='button1'},
500)" value="button">
        </form>
        <div id="content">empty</div>
    </body>
</html>

Notice the part where I have setTimeout to make the function to take
more time than it usually would.

Consider I have this Ruby code:
    b = Watir::IE.attach :url, //
    d = b.div(:id, "content")

    puts d.text
    t = b.text_field(:name, "field1")
    t.set "test"
    puts d.text

    b.button(:name, "button1").click
    puts d.text


What is the output? Of course:
empty
empty
empty

Since I'm not a specialist on JavaScript then I don't know if it is
possible to make fireEvent to block, but I tried something like this
instead for a solution:
    b = Watir::IE.attach :url, //
    d = b.div(:id, "content")

    puts d.text
    h = b.html
    t = b.text_field(:name, "field1")
    prev_html = t.html # this is needed because .set changes html,
e.g. value=new_value and next wait_until block might not wait enough
time before continuing
    t.set "test"
    Watir::Waiter.wait_until(5) {b.html.gsub(t.html, prev_html) != h}
# let's compare html-s, but ignore value= change part
    puts d.text

    h = b.html
    b.button(:name, "button1").click
    Watir::Waiter.wait_until(5) {b.html != h}
    puts d.text

Output now is as expected:
empty
field1
button1

Since usually onchange and onclick change html then something like
this could be used I thought.

Next I tried similar solution for our application instead, but it
still failed, because there is some timestamp, which gets updated in
the background, which in turn changed html, so bang.

Okay, next I tried something like this:
    b = Watir::IE.attach :url, //
    d = b.div(:id, "content")

    puts d.text
    t = b.text_field(:name, "field1")
    wait_for_html_change_on(d) {t.set "test"}
    puts d.text

    wait_for_html_change_on(d) {b.button(:name, "button1").click}
    puts d.text

where:
  def wait_for_html_change_on element, timeout=5
    old_element_html = element.html
    yield if block_given?
    Watir::Waiter.wait_until(timeout) {old_element_html !=
element.html}
  end

So, instead of monitoring whole page html, I narrowed it down to
monitor only specific ones. Seems like a regular wait_until already,
but it's fancier to see on test wait_for_html_change_on(d) {b.button
(:name, "button1").click} than h = d.html; button.click; wait_until
{d.html != h}

Anyway, I thought that this was everything what's needed. It worked
well with the short HTML written above. I turned again to see what's
happening with our application, where onclick is associated with
submit button, where form validation is executed.

It didn't work! So, I tried to play and ended up with solutions, which
work:
  def wait_for_html_change_on element, timeout=5
    old_element_html = element.html
    yield if block_given?
    sleep 3
    Watir::Waiter.wait_until(timeout) {old_element_html !=
element.html}
  end

For some reason there has to be sleep after click and before
wait_until block. I even tried regular Timeout.timeout block, but with
same result. I even tried like this: Watir::Waiter.wait_until(timeout)
{sleep 3; old_element_html != element.html} and it also worked. It
seems very strange for me and I don't like the fact that I still have
to sleep some additional seconds even if event is already finished.

And when I tried some other page on my application, then this didn't
work even. Even increasing the sleep time didn't help.

BUT as soon as I set breakpoint to my test and execute code lines one
by one, then onclick event triggers always and everything passes. As
soon as i try to run my test, it probably failes. So it seems that
there's some timing issues but i can't figure out anymore, what's
wrong.

Anyway, is there any better solutions for solving fireEvent
nonblocking problem and thus my problems? Even if i do fire_event
("onclick") after .click, then that doesn't change anything.

So, in the end i still have 5 questions:
1) why isn't fireEvent blocking? How to make it blocking?
2) why is sleep before wait_until helping sometimes and not another
times?
3) why isn't onclick triggering sometimes?
4) why is everything okay, when debugging and using "step over"
commands?
5) maybe some of the questions can be answered because Prototype is in
use regarding JavaScript on our application?

Any other/better ideas, comments or suggestions regarding this topic
are welcome!

Jarmo
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Watir General" group.
To post to this group, send email to watir-general@googlegroups.com
Before posting, please read the following guidelines: 
http://wiki.openqa.org/display/WTR/Support
To unsubscribe from this group, send email to 
watir-general-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/watir-general
-~----------~----~----~----~------~----~------~--~---

Reply via email to