How does QTP wait till the page loads dynamic data?

半世苍凉 提交于 2019-12-05 00:17:34


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.


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.


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
  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?


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


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
End Sub


Spy the loading Image and Add in Repository,

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

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


while Browser("user90site").Page("page1").WebButton("Button1").Exist(2)=false
wait 2

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