How does QTP wait till the page loads dynamic data?
Asked Answered
R

6

5

I have a scenario where the browzer status =done but still the page is not loaded. Is there a common procedure where the qtp can wait till the page is fully loaded? I tried with objBrowzer.sync,objPage.Sync,objPage.waitproperty "readyState","completed",50. But it does not work always.

I cannot even but a wait statement so that it waits till that object appears.because in different cases different objects are present. Is there any common statement that would work in all scenarios?

Thanks in advance.

Rigel answered 28/8, 2014 at 4:53 Comment(1)
When you say dynamic data, are you just asking about syncing AJAX calls? If so, please mention what version of QTP/UFT are using and I can add a solution later.Snag
T
9

You just discovered that QTP does not offer any explicit support for synchronizing with asynchronous browser script execution like that of AJAX-driven websites. When QTP believes the page has been fully loaded, there actually are still JavaScript handlers running, possibly updating the HTML used for the page and QTP accesses the GUI to early.

readyState is a good idea, but usually, it is easy to find cases where that does not work good enough.

1. The best solution is to synchronize on a "busy" indicator of the application, like a progress bar, or activity indicator.

Unfortunately, waiting for a busy indicator implies the busy indicator does really appear, always, but many apps show one only if the process takes long enough (longer than 2 seconds, or the like). Then, this quickly becomes a bit messier than expected.

2. If the app does not have anything like this, often you might help yourself by synchronizing on some "ready" indicator, like "an expected field appeared", or "The OK button disappeared". This often requires a specific solution for every context if there is no real "ready" indicator (which usually does not exist).

3. In many projects, the automation folks can get a busy indicator built into the application just for them. While this does not create a lot of effort for the developers (because modern applications have a central message dispatcher so the transition for "busy" to "idle" state and vv can easily be tracked centrally), it greatly simplifies the amount of work required for synchronization.

So if possible, try to contact the developers and get them present a property (variable, memory-mapped file, semaphore, whatever they prefer) which the test robot "synch" routine can easily poll. (Hint: To be able to differentiate between two "ready" states even after "missing" the "busy" state between the two, it might be helpful to get a sequential "busy state count" in addition to a "busy status flag", so you might request that on the same occasion.) Then, all synch issues are a defect in the app since it obviously did not maintain the ready signal correctly.

Update For apps that are based on a de facto "standard" framework, one might find ways to implement synchronization in a generic way.

For example, for JavaScript applications, I managed to create an instrumentation that transparently reports the flow of events to QTP, which is used there to wait "just long enough", enabling one to set special checkpoint-like library calls that wait for certain events (especially "click", and for apps that do AJAX roundtripls a la Java Server Pages, "ajaxstop", events) to be completed before continueing.

This has proved to be extremely useful, because often, it is very complicated to get dev to implement any kind of support for test automation needs, and GUI-based synchronization (solely through test object state/existance) sometimes is not enough if the app performs asynchronuous requests in the background. It also eliminates the need to explore synchronization options for each and every GUI context, which can be extremely time-consuming and/or unreliable.

Trinitrocresol answered 28/8, 2014 at 9:42 Comment(0)
M
2

There is no simple answer for you I'm afraid, as usual 'it depends'

Here's a basic example, say you're waiting for a button or text to appear on screen:

If Browser("user90site").Page("page1").WebButton("Button1").Exist(30) Then
  Browser("user90site").Page("page1").WebButton("Button1").Click
Else
  Reporter.ReportEvent micFail,"button missing", "button missing"
End If

The above will wait up to 30seconds for the web element to appear, however if the button appears before 30seconds are up, it will continue and click the button, otherwise it will report a failure. Given you have multiple scenarios, you will need to do different variations to get your desired result.

Do you have failing tests because you're trying to act on elements that don't exist yet?

Mediative answered 29/8, 2014 at 11:14 Comment(3)
But i want to generalize the statement for which i cannot wait for a button for instance to exist.In all situation it does not appear in the page.Rigel
why not? Replace the bits in quotations with variables, have them change depending where you are in the application? WebElement may be lots easier to use than WebButton given the circumstanceMediative
no problem, good luck, I hope you get things working how you want themMediative
C
1

It's not easy, especially for sites with AJAX. The best way is to write simple function like

function WaitForObject(obj) WaitForObject = false Setting("DefaultTimeout") = 500 for i = 0 to 30 'or more If obj.Exist Then WaitForObject = true Exit For End If next Setting("DefaultTimeout") = 20000 ' or other value end function

And use this for objects which are loaded at the end

Crypto answered 3/9, 2014 at 13:5 Comment(1)
This is a good idea if the developers can tell you which object is created at the end, and if all background processing (especially server communication) has completed by that time. (Unfortunately, usually (or at least: often) there are still internal updates pending after GUI creation, i.e. after the last GUI object has been created -- which is the root cause of the problem OP is facing.Trinitrocresol
S
0

You can try for this. I know this is very late answer but it will help you in achieving the results more accurately. You can call this function many times if your browser is loading for more time as below:

Call AppBusyStatus(0)
if Browser("Browsername").Exist Then
   Call AppBusyStatus(0)
End If
Call AppBusyStatus(0)

Sub AppBusyStatus(intBrowserCreationTime)
    Do While Browser(CreationTime:intBrowserCreationTime).Object.Busy
       Wait 0,500
    Loop
End Sub
Shizukoshizuoka answered 31/5, 2016 at 8:15 Comment(0)
G
0

Spy the loading Image and Add in Repository,

Set obj = Browser().Page().Image()
wait()
While (obj.Exist)
'Do Nothing //commented
Wend

This may increase script execution time but will give solution to your problem.

Grandmotherly answered 20/9, 2016 at 13:43 Comment(0)
A
-1
while Browser("user90site").Page("page1").WebButton("Button1").Exist(2)=false
wait 2
wend
Browser("user90site").Page("page1").WebButton("Button1").Click

While statement will be in loop until the object is not identified. Using while instead of if is more accurate.

Abdomen answered 18/5, 2016 at 6:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.