Re: [Wtr-general] Wait for control to exist
My comments below.On 6/21/06, Jonathan Ni [EMAIL PROTECTED] wrote: I have tried to implement this wait_until function on my own. My code handles some situation, however the most case I got an error that I don't really understand. Error message: NoMethodError: undefined method `all' for nil:NilClass C:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.1.1029/./watir.rb:984:in `ole_inner_elements' C:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.1.1029/./watir.rb:1033:in `locate_input_element' C:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.1.1029/./watir.rb:3448:in `locate' C:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.1.1029/./watir.rb:2398:in `exists?'Without even looking at the code, let me explain what this message itself means. We have some code that looks like something.all and the something is actually nil. Now i know that ole_inner_elements is usually implemented as document.body.all -- so that would mean that the body is nil. This is happen randomly at all object when the page changes. After I try to understand the reason, I found the _javascript_ rendering data has following steps. 1. load object 2. load more attributes of this object 3. load more data that this object needs. (eg. select box options)I think that you need to first call ie.wait -- this will wait for the page load, which will ensure that you have a body. If you need additional waiting after that, then use your code for that. My code 1.upto timeout do result = object(:text_field,:name,/logonId/) if result result.respond_to?('exists?') result.exists? return result else sleep 1 end end The error is happens at result.exists? I think this is because object(:text_field,:name,/logonId/) is return the result at (1) stage, which is load object. What this mean is the text_field tag is already been loaded, but not completely. So when the result.exists, it goes to @o = @container.locate_input_element(@how , @what, self.class::INPUT_TYPES) From here, I am lost. Could someone help me with this? Maybe my finding about _javascript_ loading object is not right. Please help me! Thanks everyone. Regards, Jonathan Ni ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
Hi All: Sorry I forgot to metion, I am using Watir version 1.5.1.1029 Regards, Jonathan Ni___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
I'm not sure of the syntax, but I'd like to see it support multiple elements being verified. -andy Original Message Follows From: Bret Pettichord [EMAIL PROTECTED] Reply-To: wtr-general@rubyforge.org To: wtr-general@rubyforge.org Subject: [Wtr-general] Wait for control to exist Date: Tue, 13 Jun 2006 00:54:16 -0500 So, i think everyone can at least agree that it would be nice to have a method on Watir elements that would not return until the element appeared on a page. E.g.: ie.button(:value, OK).dont_return_until_this_element_exists This would be analogous to the existing ie.wait method, except that that waits for the page to load the browser to no longer be busy. The only thing is -- what should it be called? Some ideas... ie.button(:value, OK).wait_until_exists? ie.button(:value, OK).wait_til_exist? ie.button(:value, OK).wait ie.button(:value, OK).ever_exist? Bret ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
On 6/13/06, Andy Sipe [EMAIL PROTECTED] wrote: I'm not sure of the syntax, but I'd like to see it support multiple elementsbeing verified.-andyHow about this ?ie.button(:value, OK).wait_til_existsie.button(:value, Cancel).wait_til_exists Bret ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
On 6/13/06, David Schmidt [EMAIL PROTECTED] wrote: I called the function I wrote wait_for, though I like youruntil_with_timeout method that uses yield better.Then we could do something like:wait_for(10) { ie.button(:value, 'OK') }or just do it as a function like wait_for( ie.button(:value, 'OK'), 10 )How about this: wait_until(ie.button(:value, OK).exists?, 10)The advantage of this form is that we could use any boolean _expression_. So you could wait until a control was disabled or whatever. I'm not 100% sure that i can code this, however. I know i can implement using a block. Thus: wait_until(10) {ie.button(:value, OK).exists?}This, of course, is the existing until_with_timeout method. Or: ie.button(:value, OK).wait_until_exists?(10)Which follows the normal Watir practice if putting the methods on the elements. Note that in all these examples the timeout would be optional and would default to a user-configurable value. Probably @@default_timeout. Also, if the timeout were exceeded, it would raise a TimeOutException. BretWe could just use your until_with_timeout as is, too:until_with_timeout(10) { ie.button(:value, 'OK').exists? }I've been using that already to wait for AJAX events to complete bywatching for a spinner to appear and then disappear:# wait for Updating spinner to appear Watir::until_with_timeout(5) do@ie.div(:id, 'pnlLoading').document.style.invoke('display')!= 'none' @ie.div(:id,'pnlLoading').document.style.invoke('visibility') != 'hidden' end# wait for Updating spinner to hideWatir::until_with_timeout(30) do@ie.div(:id, 'pnlLoading').document.style.invoke('display')== 'none' ||@ ie.div(:id,'pnlLoading').document.style.invoke('visibility') == 'hidden'endWe may wish to make it a bit more visible though, so it can be usedwithout the Watir:: at the front. I agree and will make that change regardless. ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
Brett wrote The only thing is -- what should it be called? wait_for_object? Maybe with a default timeout in the initialize method when a parameter is not sent. wait_for_object #default wait_for_object(5000) #milliseconds Aidy --- This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not the intended recipient, please telephone or email the sender and delete this message and any attachment from your system. If you are not the intended recipient you must not copy this message or attachment or disclose the contents to any other person. --- ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
That woudl work. What would be nice would be something like this: @ie.wait(10) { button(:id, 'btnOne) span(:id, 'blah') } I'm not sure how that would translate into working code though. Also, is it enough to just check that the item exists? Often I have items that are being updated via AJAX style code and they exist, but they are changing, so I'm looking to see if the value is something specific or something different than last time. If I had the polling on exist it wouldn't be enough. -andy Original Message Follows From: Bret Pettichord [EMAIL PROTECTED] Reply-To: wtr-general@rubyforge.org To: wtr-general@rubyforge.org Subject: Re: [Wtr-general] Wait for control to exist Date: Tue, 13 Jun 2006 08:22:42 -0500 On 6/13/06, Andy Sipe [EMAIL PROTECTED] wrote: I'm not sure of the syntax, but I'd like to see it support multiple elements being verified. -andy How about this ? ie.button(:value, OK).wait_til_exists ie.button(:value, Cancel).wait_til_exists Bret ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
How about the easy way. Just alias your nice until_with_timeout to wait_until so both names work and just use that your first format with the block. That way the block can contain any code that returns a boolean, which will allow Andy's request for multiple element support to work like: wait_until(timeout) { ie.button(:id, 'btnOne').exists? and ie.span(:id, 'blah').exists? } with the timeout being optional and using a default_timeout like Bret suggests below. This can then support all *sorts* of things that folks wait for, including thing like the displayed spinners that I was waiting to appear and then disappear. David Bret Pettichord wrote: How about this: wait_until(ie.button(:value, OK).exists?, 10) The advantage of this form is that we could use any boolean expression. So you could wait until a control was disabled or whatever. I'm not 100% sure that i can code this, however. I know i can implement using a block. Thus: wait_until(10) {ie.button(:value, OK).exists?} This, of course, is the existing until_with_timeout method. Or: ie.button(:value, OK).wait_until_exists?(10) Which follows the normal Watir practice if putting the methods on the elements. Note that in all these examples the timeout would be optional and would default to a user-configurable value. Probably @@default_timeout. Also, if the timeout were exceeded, it would raise a TimeOutException. Bret ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
On 6/13/06, David Schmidt [EMAIL PROTECTED] wrote: How about the easy way.Just alias your nice until_with_timeout towait_until so both names work and just use that your first format withthe block.That way the block can contain any code that returns a boolean, which will allow Andy's request for multiple element support towork like:wait_until(timeout) { ie.button(:id, 'btnOne').exists? and ie.span(:id,'blah').exists? }with the timeout being optional and using a default_timeout like Bret suggests below.This can then support all *sorts* of things that folks wait for,including thing like the displayed spinners that I was waiting toappear and then disappear. +1Except that the old until_with_timeout method will be replaced by (rather than aliased to) wait_untilBTW, the existing until_with_timeout method had been intended for internal use only and that's why it is kinda ugly. Bret ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
Our solution is better than that. Bret already has a method that I've been using and it's generic enough that you can wait for just about anything. He's stated that he'll just be renaming it to wait_for. On a web scraper I have there is an AJAX request that fires when one of the fields is changed. When this happens, a graphical spinner image appears to let you know it's making a request. The spinner is always there, but the DIV containing it gets changed from hidden to visible and back again. I'm able to wait for the style to change to visible and then wait for the style to change to hidden (even though the DIV *always* exists) like this (using the new wait_for() method name): # wait for Updating spinner to appear wait_for(5) do @ie.div(:id, 'pnlLoading').document.style.invoke('display') != 'none' @ie.div(:id, 'pnlLoading').document.style.invoke('visibility') != 'hidden' end # wait for Updating spinner to hide wait_for(30) do @ie.div(:id, 'pnlLoading').document.style.invoke('display') == 'none' || @ie.div(:id, 'pnlLoading').document.style.invoke('visibility') == 'hidden' end The wait_for method will just keep trying the supplied block until the block returns true or the timeout has passed (where it will throw an exception). David Andy Sipe wrote: I'm not sure just exist is enough for what I'm talking about. If I have a span that already exists in the document and I do something that causes an async request/update to the server then the span always exists so saying: span(:id, ...).wait_for_exists? may blow right through without pausing because the span is there. Maybe something like span(:id, ...).wait_for_change('text', 'blah') where 'text' is the attribute i'm waiting to change and 'blah' is the value I'm waiting for it to change to. So you could also do span(:id, ...).wait_for_change('exists?', true) -andy ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
On 6/13/06, David Schmidt [EMAIL PROTECTED] wrote: The wait_for method will just keep trying the supplied block until the blockreturns true or the timeout has passed (where it will throw an exception).We want it to be called wait_until -- correct? ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
Yup, my bad. I just typed the wrong name out of habit. New name will be wait_until. *SLAP* Ouch! OK, I've been punished. David Bret Pettichord wrote: On 6/13/06, *David Schmidt* [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: The wait_for method will just keep trying the supplied block until the block returns true or the timeout has passed (where it will throw an exception). We want it to be called wait_until -- correct? ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
I've written this up as http://jira.openqa.org/browse/WTR-75 ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
Re: [Wtr-general] Wait for control to exist
That sounds great. I didn't realize that was what you were talking about. Thanks -andy Original Message Follows From: David Schmidt [EMAIL PROTECTED] Reply-To: wtr-general@rubyforge.org To: wtr-general@rubyforge.org Subject: Re: [Wtr-general] Wait for control to exist Date: Tue, 13 Jun 2006 14:28:41 -0700 Our solution is better than that. Bret already has a method that I've been using and it's generic enough that you can wait for just about anything. He's stated that he'll just be renaming it to wait_for. On a web scraper I have there is an AJAX request that fires when one of the fields is changed. When this happens, a graphical spinner image appears to let you know it's making a request. The spinner is always there, but the DIV containing it gets changed from hidden to visible and back again. I'm able to wait for the style to change to visible and then wait for the style to change to hidden (even though the DIV *always* exists) like this (using the new wait_for() method name): # wait for Updating spinner to appear wait_for(5) do @ie.div(:id, 'pnlLoading').document.style.invoke('display') != 'none' @ie.div(:id, 'pnlLoading').document.style.invoke('visibility') != 'hidden' end # wait for Updating spinner to hide wait_for(30) do @ie.div(:id, 'pnlLoading').document.style.invoke('display') == 'none' || @ie.div(:id, 'pnlLoading').document.style.invoke('visibility') == 'hidden' end The wait_for method will just keep trying the supplied block until the block returns true or the timeout has passed (where it will throw an exception). David Andy Sipe wrote: I'm not sure just exist is enough for what I'm talking about. If I have a span that already exists in the document and I do something that causes an async request/update to the server then the span always exists so saying: span(:id, ...).wait_for_exists? may blow right through without pausing because the span is there. Maybe something like span(:id, ...).wait_for_change('text', 'blah') where 'text' is the attribute i'm waiting to change and 'blah' is the value I'm waiting for it to change to. So you could also do span(:id, ...).wait_for_change('exists?', true) -andy ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general
[Wtr-general] Wait for control to exist
So, i think everyone can at least agree that it would be nice to have a method on Watir elements that would not return until the element appeared on a page. E.g.: ie.button(:value, OK).dont_return_until_this_element_exists This would be analogous to the existing ie.wait method, except that that waits for the page to load the browser to no longer be busy.The only thing is -- what should it be called?Some ideas... ie.button(:value, OK).wait_until_exists? ie.button(:value, OK).wait_til_exist? ie.button(:value, OK).wait ie.button(:value, OK).ever_exist?Bret ___ Wtr-general mailing list Wtr-general@rubyforge.org http://rubyforge.org/mailman/listinfo/wtr-general