I am not able to wait in testcomplete for page element to load - vbscript

I am working on web application, using tool testcomplete with vbscript.
pageTab = Sys.Process("iexplore").IEFrame(0).CommandBar.TabBand.TabButton("Tieto Client Manager").Enabled
do while(pageTab <> True)
Sys.Process("Explorer").Refresh
pageTab = Sys.Process("iexplore").IEFrame(0).CommandBar.TabBand.TabButton("Tieto Client Manager").Enabled
Sys.Process("iexplore").IEFrame(0).CommandBar.TabBand.TabButton("Tieto Client Manager").Refresh
loop
pageBusyState = Sys.Process("iexplore" , 2).Page("*").Busy
do while(pageBusyState <> False)
pageBusyState = Sys.Process("iexplore" , 2).Page("*").Busy
loop
With this code i can wait for new page but not able to wait for control loading page.

The best approach to wait until a dynamic page is ready is to wait for a specific object on this page. For example, this can be the first object you need to work on the page. This approach is described along with a couple of other approaches in the Waiting For Web Pages help topic.

Timeout=False
'Check IEXPLORE Process running on window
If Sys.Process("IEXPLORE").Exists Then
Set obj = Sys.Process("IEXPLORE").Page("*")
Set PageObj = Eval(obj.FullName)
'Set Default Timeout
intDefaultTimeout=1000
'Do until Page Object readyState=4 or Timeout
Do
Set PageObj= Sys.Process("IEXPLORE").Page("*")
'Check for Timeout
If aqConvert.StrToInt(DateDiff("n",intTimerStart,Now))>= aqConvert.StrToInt(intDefaultTimeout) Then
Timeout=True
End If
Loop Until PageObj.ReadyState = 4 Or Timeout=True
Else
'Check iexplore 2 Process running on window
If Sys.Process("iexplore",2).Exists Then
Set obj = Sys.Process("iexplore",2).Page("*")
Set PageObj = Eval(obj.FullName)
'Set Default Timeout
intDefaultTimeout=Project.Variables.prjDefaultTimeout
'Do until Page Object readyState=4(page loaded fully or request finished and response is ready) or Timeout
Do
Set PageObj= Sys.Process("iexplore",2).Page("*")
If aqConvert.StrToInt(DateDiff("n",intTimerStart,Now))>= aqConvert.StrToInt(intDefaultTimeout) Then
Timeout=True
End If
'Check still the page is in busy mode or page loaded fully .
Loop Until PageObj.ReadyState = 4 Or Timeout=True
End If
End If
'Calling Activate method to apply a property collection corresponding to a run mode
PageObj.Activate

Related

why does LogonHostedExchangeMailbox get stuck with no error message?

We are using Redemption Library to access our e-mails. Scripts are automated on server and triggered by Task Scheduler at regular intervals. After server reboots we usually experience the problem with Session.Logon, since the user needs to log on again.
To avoid this problem, we are trying now to use LogonHostedExchangeMailbox Session method. Due to unknown reason the script gets stuck at this command. Could anyone advise what the reason might be? Here is the sample:
set Session = CreateObject("Redemption.RDOSession")
InboxName = "xxx#domain.com"
Session.LogonHostedExchangeMailbox InboxName,InboxName, "pwd" 'the script gets stuck here and does not throw any errors.
set oFolder = Session.GetFolderFromPath("\\"&InboxName&"\Inbox")
set items = oFolder.items
i = items.count
do until i = 0
if items.count > 0 then
set Mail = Items.Item(i)
wscript.echo Mail.Subject
'wscript.echo Mail.Body
end if
i = i - 1
loop
Session.Logoff
Thanks.

How to wait for object and page load

I wrote this function which is being called after clicking any links or buttons.
Function BrowerSync
If Browser("micclass:=Browser").Page("micclass:=Page").Exist(60) then
BrowerSync = 1
End if
End Function
It works fine most of the cases. However, I am experiencing two issues:
If the browser is already loaded before UFT calls the function, I have seen that UFT is still waiting for the page to be loaded. Instead, it should not wait and move on to the next step.
If UFT calls the function but the browser is not opened, UFT still waits for the browser to open and load. Instead it should not wait and move on to the next step.
How can I edit my function to fix the above two issues?
Your code is not dynamic at all. Also the ideal way to wait is to wait for an element to load in the page (in other word to be visible) that will make sure that the browser loaded successfully. In your case anytime you call the function BrowerSync it waits for to find that object for 60 seconds and then it will exit the function.
I will suggest you that you wait for an element in the page an make it dynamic by using the time as parameter for the method so you can wait sometimes 60 seconds and sometimes 10seconds , based on your browser. Below is my function that i use to wait for a webelement
PageLoad_Performance = 10 'this will be used in DWaitForWebElement Function , set the time in seconds, if time less than time added,element found and pages loaded
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'Function Name: WaitForWebElement
'Description: Its a dynamic Conditional Wait, It will wait for
' Webelement until It Exists
'Arguments: classVal - The class property Value of the Object
' innertextVal - The innertext Value of the object
'Created By:
'Date: 10/25/2016
'Usage: Call WaitForWebElement (classVal,innertextVal)
Function WaitForWebElement(classVal,innertextVal)
Dim Total_Time,oDesc
Total_Time=1
'create description of the object
Set oDesc = Description.Create
oDesc.Add "MicClass","WebElement"
oDesc.Add "class",classVal
oDesc.Add "innertext",innertextVal
With Browser("title:=yourtitleofthepage.*").Page("title:=yourtitleofthepage.*")
'this while loop , it will wait until the object exist , it will never exit the loop unless object is Found
While .WebElement(oDesc).Exist(1) = False
wait 1 ' we loop and check and then wait one second
'every time we loop we increment total time by 1 second , to check at the end to total time to load that page
Total_Time = Total_Time+1
Wend
If Total_Time < PageLoad_Performance Then 'if the page loads in less than 10 seconds Performance Report will Pass
'do your report
Else
'do your report
End If
End With
'clean up
Set oDesc = nothing
End Function

VBScript Code: Object required error

Guys
I just wrote a vbs code snippet to automatically post in a forum. That's just for convenience. I encountered a wired problem:
I have several accounts. When I login as some accounts and use the script to automatically post, everything is OK. However, when I login as the other accounts and run the script, I got the error:
Error : Object required "getElementById(...)"
Code : 800a01a8
Source : Microsoft VBScript runtime error
I'm sure the object exists because I get it in the source of the webpage. I feel the error occurred randomly and I cannot get the regularity.
The script is ran in a Windows 8 OS and the browser is IE9. I'm a new learner of vbs and I don't know how to debug it. So I hope someone can help me. You can give me some clue.
Here is my code snippet:
Option Explicit
Dim IEApp
Dim iURL1
Dim iURL2
Dim iURL3
Dim iURL4
Dim iURL5
Set IEApp = CreateObject("InternetExplorer.Application")
iURL1="http://bbs.dealmoon.com/thread-299027-1-1.html"
iURL2="http://bbs.dealmoon.com/thread-299195-1-1.html"
iURL3="http://bbs.dealmoon.com/thread-299018-1-1.html"
iURL4="http://bbs.dealmoon.com/thread-299015-1-1.html"
iURL5="http://bbs.dealmoon.com/thread-299014-1-1.html"
Open iURL1
Open iURL2
Open iURL3
Open iURL4
Open iURL5
WScript.Echo("Done!")
Sub Wait(IE)
Do
WScript.Sleep 500
Loop While IE.ReadyState < 4 And IE.Busy
Do
WScript.Sleep 500
Loop While IE.ReadyState < 4 And IE.Busy
End Sub
Sub Post(IE)
Dim count
For count=0 To 9
With IE.Document
.getElementById("fastpostmessage").innerHTML = "good"
.getElementById("fastpostsubmit").click
Wait IE
WScript.Sleep GetRandom(7,15)
End With
Next
End Sub
Sub Open(PageURL)
IEApp.Visible = False
IEApp.Navigate PageURL
Wait IEApp
Post IEApp
End Sub
Function GetRandom(floor,ceil)
Randomize
GetRandom=Int((ceil - floor + 1) * Rnd + floor)*1000
End Function
You should call your POST routine after all the HTML content is loaded, for example in DOMContentLoaded or window.onload (for IE<9).
You dimmed IEApp, created the object, but you are not using it when trying to get the element ID. Your With block should look like this:
With IEApp.Document
.getElementById("fastpostmessage").innerHTML = "good"
.getElementById("fastpostsubmit").click
Wait IEApp
WScript.Sleep GetRandom(7,15)
End With
There are a few other places you only have IE instead of IEApp. Clear those up and your code should run fine.

QTP Link object does not support the Exist property

I have a weird problem with QTP 11. The following piece of code worked so far, but suddenly stopped working and throws Object does not support this property or method.: 'objPage.Link' for the line with 'if link exist'
Set objBrowser = Browser("creationtime:=" & Desktop.ChildObjects(oDesc).Count - 1 & "")
Set objPage = objBrowser.Page("title:=.*")
If objPage.Link("class:=menu_link_tab_.*", "html id:=.*DesktopTab").Exist(3) Then
msgbox "ok"
End If
Can anyone tell me what is wrong and/or how to do it right?
EDIT: I solved this but still have no idea what happened. I just cut this part from QTP script and pasted it into Notepad and then copied it from Notepad to QTP. Everything works fine. I did not change anything... Any ideas what the hell happened are welcomed.
ANOTHER EDIT: The problem reappears randomly. With no changes to anything I can just run the test 10 times to have it fail randomly with the 'Object does not support this property or method' message
I have a startBrowser function where I set the objPage and objBrowser :
Function startBrowser(vURL)
Dim oDesc
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate vURL
Window("hwnd:=" & IE.HWND).Maximize
Set oDesc = Description.Create
oDesc( "micclass" ).Value = "Browser"
If Desktop.ChildObjects(oDesc).Count > 0 Then
Set objBrowser = Browser("creationtime:=" & Desktop.ChildObjects(oDesc).Count - 1 & "")
End If
Set objPage = objBrowser.Page("title:=.*")
End Function
I have added lots of msgboxes with GetROProperty to verify whether the objects are ok. They seem to be.
Now my function to click the link looks like this :
Function clickMainMenuLink(vIdentifier)
Set objLink = objPage.Link("class:=menu_link_tab_.*", "html id:=.*" & vIdentifier, "index:=0")
If objLink.Exist(timeOut) Then
objLink.Click
Else
reporter.ReportEvent micFail, "Click the " & vIdentifier & " menu link", "Cannot find the " & vIdentifier & " menu link"
ExitTestIteration
End If
End Function
So at the moment my test just opens the browser and clicks a link as I try to debug the thing, but it still fails or passes randomly. The run error indicates line with 'Set objLink'. Any ideas for further debugging? I'm on QTP11 and IE8 if it matters.
From your error does not support this property or method: objPage.Link it would appear that the problem isn't with the .Exist part of line but the .Link part (you can verify this by separating the line into two lines and see which fails
set objLink = objPage.Link("class:=menu_link_tab_.*", "html id:=.*DesktopTab")
If objLink.Exist(3) Then
From your comment it seems that you're creating objPage in a different location from where you're using it, I suggest making sure that the object arrives OK.
Thanks Motti, your reasoning was right. The problem was with the objPage part. Despite the fact that I could read every property of objPage in a function QTP sometimes just did not see this objPage as a Page object. I guess it has something to do with not declaring type explicitly, but that's just a guess. As a dirty workaround I set up the objBrowser and objPage in every function now and it works 100%.

Selenium-Webdriver Ruby --> How to wait for images to be fully loaded after click

I am very new to Ruby and Selenium-Webdriver, so please, help :)
I am trying to open email campaign , sent to my inbox, that has images and take a screenshot in the firefox. But i can not make it wait until images is fully loaded. Once i click on 'Show images' , screenshot is already taken , but image is not loaded at that time. How can i pause the script and take screenshot some time later, after all images is displayed?
Please, help :(
Bellow is my script:
enter code here
require 'selenium-webdriver'
browser = Selenium::WebDriver.for :firefox
#==========================================================================================
wait = browser.manage.timeouts.implicit_wait = 15
#==========================================================================================
url = 'https://login.yahoo.com/config/login_verify2?.intl=us&.src=ym'
# Open browser (firefox)
browser.navigate.to url
browser.find_element(:id, 'username').send_keys "some yahoo id"
browser.find_element(:id, 'passwd').send_key "some password"
browser.find_element(:id, ".save").click
browser.find_element(:id, "inbox-label").click
browser.find_element(:xpath, "//div[#class='subj']").click
browser.find_element(:xpath, "//a[#title='Display blocked images']").click
result_page_title = browser.find_element(:tag_name, 'title')
puts "Title of the page: \t\t: #{result_page_title.text}"
browser.save_screenshot "1.jpg"
You can use Implicit Wait and Explicit Wait to wait for a particular Web Element until it appears in the page. The wait period you can define and that is depends upon the application.
Explicit Wait:
An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code. If the condition achieved it will terminate the wait and proceed the further steps.
Code:
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(strEdit)));
Or
WebElement myDynamicElement = (new WebDriverWait(driver, 30))
.until(new ExpectedCondition<WebElement>(){
#Override
public WebElement apply(WebDriver d) {
return d.findElement(By.id("myDynamicElement"));
}});
This waits up to 30 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 30 seconds. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully. A successful return is for ExpectedCondition type is Boolean return true or not null return value for all other ExpectedCondition types.
You can use ExpectedConditions class as you need for the application.
Implicit Wait:
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available
Code:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
One thing to keep in mind is that once the implicit wait is set - it will remain for the life of the WebDriver object instance
For more info use this link http://seleniumhq.org/docs/04_webdriver_advanced.jsp
The above code is in Java. Change as your language need.
Ruby code from the docs (click on the 'ruby' button):
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
begin
element = wait.until { driver.find_element(:id => "some-dynamic-element") }
ensure
driver.quit
end
Which works for me
To add to the above answer, here is how I use implicit and explicit wait in Ruby.
Implicit Wait
I pass this option to Selenium::WebDriver after initializing with a couple of lines like this:
browser = Selenium::WebDriver.for :firefox
browser.manage.timeouts.implicit_wait = 10
Just replace "10" with the number of seconds you'd like the browser to wait for page refreshes and other such events.
Explicit Wait
There are two steps to declaring an explicit wait in Selenium. First you set the timeout period by declaring a wait object, and then you invoke the wait with Selenium::Webdriver's .until method. It would look something like this, in your example:
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { browser.find_element(:xpath, "//path/to/picture").displayed? }
This would tell the Webdriver to wait a maximum of 10 seconds for the picture element to be displayed. You can also use .enabled? if the element you're waiting for is an interactive element - this is especially useful when you're working with Ajax-based input forms.
You can also declare an explicit wait period at the start of your script, and then reference the object again whenever you need it. There's no need to redeclare it unless you want to set a new timeout. Personally, I like to keep the wait.until wrapped in a method, because I know I'm going to reference it repeatedly. Something like:
def wait_for_element_present( how_long=5, how, what )
wait_for_it = Selenium::WebDriver::Wait.new(:timeout => how_long )
wait_for_it.until { #browser.find_element(how, what) }
end
(I find it's easier to just declare browser as an instance variable so that you don't have to pass it to the method each time, but that part's up to you, I guess?)
ExpectedConditions isn't supported yet in the Ruby Selenium bindings. This snippet below does the same thing as ExpectedConditions.elementToBeClickable — clickable just means "visible" and "enabled".
element = wait_for_clickable_element(:xpath => xpath)
def wait_for_clickable_element(locator)
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
element = wait.until { #driver.find_element(locator) }
wait.until { element.displayed? }
wait.until { element.enabled? }
return element
end

Resources