Global "Wait For"

Class library usage, coding and language questions.
peterbonney
Posts: 10
Joined: Tue Jun 25, 2013 2:13 pm

Global "Wait For"

Post by peterbonney » Thu Jul 24, 2014 1:51 pm

Hi,

We have a very dynamic web app, because of this we're seeing failures because ranorex is trying to execute before the page has finished loading or reading the DB.

What we'd like to do is either, set a global value that makes ranorex insert a "Wait For exists" in front of each step.
If that is not possible, we'd like to be able to read the browser status and make ranorex hold off until the browser has finished loading.

are either of these possible?
If so, how is it done?

Ideally we want to minimise user code or amending the RanoreXpath and maximise the record & Playback.

Thanks
Pete

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: Global "Wait For"

Post by krstcs » Thu Jul 24, 2014 3:14 pm

There is no way to have a global wait in Ranorex currently without changing the XPath, creating a custom module or both.

(Personal note: Record and play-back is great for quick and easy tests, but learning to create modules manually will benefit you greatly in the long-run, giving you greater flexibility and control in test creation.)

The two ways to do this are below:

1. Change your XPath for the /dom object to include " and @state='complete' " (sans quotes). This will force Ranorex to try to find a web document that is fully loaded. However, the default timeout is 30s, so if the page isn't loaded by then, Ranorex will report a failure still. You can change the search timeout for the dom object (ONLY - you don't need to change others) to something like 5 min, which will cause Ranorex to search for the complete dom for UP TO 5 min.
Pros: Easy to implement.
Cons: Doesn't always solve the whole problem especially with JavaScript loads and such. Setting a very high timeout for this causes ALL objects to have that same timeout PLUS their own (timeouts are cumulative from parents).

2. (What I do) In addition to changing the XPath like 1. above (I don't change the timeout), you can create a single recording module that does the WAIT actions and then you can drag and drop this into your test cases anywhere you need to wait for a page load to complete. I name my module "_WAIT_FOR_PAGE_LOAD" or something similar (underscore to start and all-caps makes it easier to find).
Pros: Only one module needs to be changed when changing timings.
Cons: You have to have created your test recordings to be modular and atomic (which you should be doing anyway, but not everyone does) and let the test case determine the business logic by dropping these atomic modules in the right order. And, you have to place this module in every spot that it will be needed by hand.
The module would look like:
1. Delay -> 1000ms (this waits for the system to start the new page load)
2. Wait for exist -> 30s -> DOM_COMPLETE (this will wait for UP TO 30s for the dom repo object from 1. to exist)
3. Delay -> 500 ms (this step and the next are optional but allow for pages that load several scripts and could get false "complete" readings)
4. Wait for exist -> 30s -> DOM_COMPLETE
5. Validate -> Exists -> DOM_COMPLETE (This makes the test fail of the page took too long to load. Long load times should be an issue for any normal website, but if this isn't a probem for yours you can remove this)


If you do this, you only have ONE place to make timing changes from now on.



********************************
As a note, when I say modular and atomic for recording modules, I mean that each module should do ONE atomic action.

If you are clicking a button, the module could be named "Click_OK" and it would contain one action:

1. Mouse -> Click -> Left -> OKButton


If you are entering text, the module could be named "Enter_UserName" and it would contain all actions needed for entering the username in a text field, such as:

1. Mouse -> Click -> Left -> UserNameField
2. Key -> Shortcut -> "Ctrl-A" -> UserNameField (select all current text, if you want to insert, you wouldn't do this or the next step)
3. Key -> Shortcut -> "Delete" -> UserNameField
4. Key -> Sequence -> $UserNameVar -> UserNameField (enters data passed in from the test case as a bound variable)
5. Validate -> AttributeEqual -> 'Text' -> $UserNameVar -> UserNameField (validates that the value was entered correctly)
Shortcuts usually aren't...