Page 1 of 1

How to wait for Mouse.Cursor state by default

Posted: Wed May 25, 2016 12:37 pm
by Arnout
Hi,

The application i'm automating doesn't accept input when saving or searching. While it's busy, the mouse.cursor state is "[Cursor: WaitCursor]" visible as a spinning blue circle in Windows 7, so when manually using the application it's easy to wait for this busy-state to disappear before doing something else.

I've built a rudimentary while-loop in c# to wait for the cursor to change to a state other than WaitCursor, but I'll have to make a coded step every time I want to do this.

I'd prefer it if it were possible to do this by default: as long as mouse.cursor = WaitCursor, wait, without having to do this every time I save or search something. Is there common functionality for this, i.e. a setting somewhere?


EDIT

Code I've written:

Code: Select all

		public static void WaitForSaved(int maxLoopDuration)
        {
        	string currentState = Mouse.Cursor.ToString();			
        	System.Diagnostics.Stopwatch newWatch = System.Diagnostics.Stopwatch.StartNew();
        	
        	while (currentState == "[Cursor: WaitCursor]" && newWatch.Elapsed.Seconds <= maxLoopDuration)
        	{
        		Thread.Sleep(500);
        		currentState = Mouse.Cursor.ToString();
        	}
        	
        	//if you want the test to fail after maxLoopDuration:
        	if(newWatch.Elapsed.Seconds > maxLoopDuration)
        	{
        		Ranorex.Report.Error("Application still reports busy state after exceeding the allotted time (maxLoopDuration)");
        	}
        }

Re: How to wait for Mouse.Cursor state by default

Posted: Wed May 25, 2016 2:54 pm
by krstcs
Unfortunately, there is no way to do this without adding actions or user code in each module.

My suggestion would be to create a small module called "Wait_for_Mouse_Cursor" or something like that with your code in it. Then just drop it in your test case wherever you need to wait for the cursor.

This also means that you will likely need to break apart your test modules into much smaller modules, which you should be doing anyway. You should also name the modules according to what they do, and only have them do one thing.

Making modules as small as possible will be a huge benefit for reuse and maintenance in the long run. In addition, it makes creating test cases easy because you can just drop the modules in the test case in the order you need them without worrying about what the module does.

Re: How to wait for Mouse.Cursor state by default

Posted: Wed May 25, 2016 3:11 pm
by Arnout
Thanks for your answer, krstcs!
My suggestion would be to create a small module called "Wait_for_Mouse_Cursor" or something like that with your code in it. Then just drop it in your test case wherever you need to wait for the cursor.
Good idea, I usually make modules small enough that the 'wait' step is at the end anyway.
This also means that you will likely need to break apart your test modules into much smaller modules, which you should be doing anyway. You should also name the modules according to what they do, and only have them do one thing.

Making modules as small as possible will be a huge benefit for reuse and maintenance in the long run. In addition, it makes creating test cases easy because you can just drop the modules in the test case in the order you need them without worrying about what the module does.
I already keep 'em pretty small, with a maximum amount of 'steps' within each module never exceeding 10 (if they're always executed consecutively), but averaging around 3-4 :) Made most of them data-bound as well, so things should get exceedingly easier.

Re: How to wait for Mouse.Cursor state by default

Posted: Wed May 25, 2016 3:56 pm
by krstcs
Good, that is exactly what I do, it makes it soooo much easier.

I try not to put static delays in either. I use WaitFor.Exists()/NotExists() wherever possible. That also allows for not using while loops and will fail if the element doesn't exist or does exist (respectively) after the timeout period (which can be overridden if needed).

Good luck!

Re: How to wait for Mouse.Cursor state by default

Posted: Thu May 26, 2016 3:34 pm
by Arnout
The stopwatch makes the while loop a little less scary... wouldn't use it in any other situations either. The 'Wait For' functionality is most likely a while loop with a stopwatch at its most basic level anyway. :wink:

'Waiting for' stuff to exist is not always an option, if you want to do multiple actions on a screen and saving in between. During the 'saving' state the element used in the next step is already available, making Ranorex already execute it. In my application, another way to approach this problem is that saving usually assigns an ID to the saved item, or causes it to get a 'start date' or some other value. So I usually keep trying to validate that the string value of an element goes from "" to "something" using a stopwatched while loop.

Why Ranorex only has waiting for elements to (not) exist and not for elements to get a certain/any value is beyond me, that would be great standard functionality.

Re: How to wait for Mouse.Cursor state by default

Posted: Thu May 26, 2016 5:13 pm
by krstcs
One thing you could do is add the value to a COPY of the repo item as part of the XPath. Then wait for that repo item to exist.

So, if you had a button that changes it's name depending on the state of the page/app, it would look like this:

Code: Select all

Button_OKContinue_OK       -> button[@id='button_ok_continue' and @text='OK' and @enabled='true']
Button_OKContinue_Continue -> button[@id='button_ok_continue' and @text='Continue' and @enabled='true']
This is just one example. Remember, you can have as many repo items as you want that all point to the 'same' element, they just need different names.

Then, just waitfor.exist/notexist on the repo item you need...