Home > Web Automation Specific > Web Advanced Synchronization

Web Advanced Synchronization

Article Web Synchronization introduced some basic web synchronization techniques. The topic discusses how to use the StartBrowser, UsePageClickHTMLElement and WriteHTML functions in addition to the #UsePageExact and #ActionTimeout system variables to synchronize web based automation scripts.

If you encounter difficulties using the above synchronization statements in your automation scripts, here are some additional synchronization techniques that can be used to provide reliable web page synchronization.

Three functions are provided below that can be cut-and-pasted into your automation script. Please review each one and use the functions that best suit your needs. Each function is heavily documented to give you a clear understanding of the function's calling parameters, what each statement in the function is doing and why it's being used in the function. There is also a section illustrating how to invoke each function. Do not be afraid to experiment and improvise if a function does not exactly match your requirements.

Wait until an HTML element can be clicked on the current page

Buttons on a web page cannot be clicked until the page has completely loaded. There may be situations where a sequence of similarly titled web pages allow the UsePage function to return before the intended page has finished loading. The result is that attempting to click a button before the page has loaded will cause the script to fail. The function below attempts to click the specified HTML element once per second until successful or the specified timeout has been reached.

'---------------------------------------------------------------
' Wait for the specified HTML element on the current page to
' become enabled and click it. The function will attempt to
' click the HTML element once a second until the elapsed time
' exceeds the specified timeout value.
'
' Parameters:
' html_element$ - HTML descriptor
' timeout - Maximum number of seconds to attempt clicking element
'
' Returns:
' 0 - HTML element has not been clicked
' 1 - HTML element has been clicked
'---------------------------------------------------------------
Function wait_html_element_clicked(html_element$, timeout)

local saveActionTimeout
    local saveIgnoreErrors
    local elapsedTime
    local elementClicked
    local ret

' Set the #ActionTimeout system variable to wait 1 second before a function times out.
    saveActionTimeout = #ActionTimeout
    #ActionTimeout = 1

' Set the #IgnoreErrors system variable to inhibit errors.
' We can now click an HTML element even if it does not exist without an error message popping up.
    saveIgnoreErrors = #IgnoreErrors
    #IgnoreErrors = 1

' Attempt to click the specified HTML element once a second
' until either the element has been loaded and clicked, or the specified timeout value has been exceeded.
    elapsedTime = 0
    elementClicked = 0
    Repeat
        ret = ClickHTMLElement(html_element$)
        If (ret = 0) Then
            ' Element has been clicked!
            elementClicked = 1
        Else
            ' Clicking the element has failed, one second has elapsed since calling ClickHTMLElement. Keep trying.
            ' NOTE: No error message has been displayed since #IgnoreErrors has been set to 1.
            elapsedTime = elapsedTime + 1
            ' Yield control to operating system.
            Pause 10 Ticks
        Endif
    Until (elementClicked = 1) Or (elapsedTime > timeout)

' Determine if element was clicked or timeout value has been exceeded.
    If (elementClicked = 0) Then
        ' Timeout value exceeded. Display an error and terminate all scripts
        ' if the original value of the #IgnoreErrors system variable was 0.
        ' NOTE: The function needs to perform these actions to exhibit the
        ' same behavior as the WinTask Functions since #IgnoreErrors is set to 1 for the duration of the function.
        If (saveIgnoreErrors = 0) Then
            MsgBox("Unable to click HTML Element: \n\"+html_element$, 16, "Runtime Error")
            Stop
        Endif
    Endif

' Set function return value based on whether element was clicked.
    wait_html_element_clicked = elementClicked

' Restore the original values of the system variables.
    #ActionTimeout = saveActionTimeout
    #IgnoreErrors = saveIgnoreErrors

EndFunction

'---------------------------------------------------------------
' Sample code using function wait_html_element_clicked()
'---------------------------------------------------------------

' Start Internet Explorer and load the Google web page.
    StartBrowser("IE", "www.google.com")

' Wait until web page loads and "Google" is displayed in the title.
    UsePage("Google")

' Attempt to click the "Google Search" button for up to 30 seconds.
    wait_html_element_clicked("INPUT SUBMIT[VALUE= 'Google Search']", 30)

 

Wait until an HTML element contains the specified text on the current page

There may be occasions where the automation script needs to read the contents of an HTML element that is populated after the page is loaded and the element is populated. The web server may wait to populate the element with a database query in response to a button click. The function below waits until the specified text is found within the specified HTML element on the current web page or the specified timeout has been reached.

'---------------------------------------------------------------
' Wait for the specified HTML element on the current page to
' contain the specified text. The function will attempt to
' read the text from the HTML element once a second until the
' elapsed time exceeds the specified timeout value.
'
' A sub-string of the expected text can be specified. The
' function matches the specified text if it is contained
' anywhere within the captured text.
'
' The function has two failure modes. Either the HTML element
' doesn't exist, or the expected text wasn't found in the HTML
' element before the time value was exceeded.
'
' Parameters:
' html_element$ - HTML descriptor
' text$ - Text to locate within HTML element
' timeout - Maximum number of seconds to search for text
'
' Returns:
' 0 - HTML element does not contain the specified text
' 1 - HTML element contains the specified text
'---------------------------------------------------------------
Function wait_html_element_text(html_element$, text$, timeout)

local saveIgnoreErrors
    local elapsedTime
    local textCaptured
    local elementText$
    local ret

' Set the #IgnoreErrors system variable to inhibit errors.
' We can now check an HTML element even if it does not exist
' or doesn't contain the specified text without an error message popping up.
    saveIgnoreErrors = #IgnoreErrors
    #IgnoreErrors = 1

' Attempt to read the specified text from the specified HTML
' element once a second until either the text has been read, or the specified timeout value has been exceeded.
    textCaptured = 0
    elapsedTime = 0
    Repeat
        ' NOTE: CaptureHTML returns immediately. We need to manually wait one second between calls.
        ret = CaptureHTML(html_element$, elementText$)
        If (ret <> 0) Then
            ' The text capture has failed, wait 1 second and keep trying.
            ' NOTE: No error message has been displayed since #IgnoreErrors has been set to 1.
            Pause 1 ' Yield control to operating system.
            elapsedTime = elapsedTime + 1
        Else
            ' Some text has been captured, verify it matches the specified text.
            If (Instr(elementText$, text$) > 0) Then
                ' Expected text has been captured from HTML element.
                textCaptured = 1
            Else
                ' Expected text has not been found, wait 1 second and keep trying.
                Pause 1 ' Yield control to operating system.
                elapsedTime = elapsedTime + 1
            Endif
        Endif
    Until (textCaptured = 1) Or (elapsedTime > timeout)

' Determine if element text was captured or timeout value has been exceeded.
    If (textCaptured = 0) Then
        ' Timeout value exceeded. Display an error and terminate all scripts
        ' if the original value of the #IgnoreErrors system variable was 0.
        ' NOTE: The function needs to perform these actions to exhibit the
        ' same behavior as the WinTask Functions since #IgnoreErrors is set to 1 for the duration of the function.
        If (saveIgnoreErrors = 0) Then
            MsgBox("Unable to read Text: "+text$+"\n\ from HTML Element: "+html_element$, 16, "Runtime Error")
            Stop
        Endif
    Endif

' Set function return value based on whether element text was captured.
    wait_html_element_text = textCaptured

' Restore the original value of the system variable.
    #IgnoreErrors = saveIgnoreErrors

 EndFunction

'---------------------------------------------------------------
' Sample code using function wait_html_element_text()
'---------------------------------------------------------------

' Start Internet Explorer and load the Google web page.
    StartBrowser("IE","www.wintask.com/demos",3)

' Wait up to 60 seconds for the "literature" word to appear on the page.
   wait_html_element_text("P[CONTENT= 'Click']", "literature", 60)

Wait until an HTML element exists on the current page

In a webpage with frames, if no element in this frame can be clicked, only the existence of an element can tell that the frame is loaded. The following function will wait until the specified HTML element exists on the page (just a plain text, not a clickable element).

'---------------------------------------------------------------
' Wait for the specified HTML element on the current page to exist
' The function will check the existence of the HTML element once a second until the elapsed time
' exceeds the specified timeout value.
'
' Parameters:
' html_element$ - HTML descriptor
' timeout - Maximum number of seconds to test existence
'
' Returns:
' 0 - HTML element does not exist
' 1 - HTML element does exist
'---------------------------------------------------------------
Function wait_html_element_exist(html_element$, timeout)

local saveActionTimeout
    local saveIgnoreErrors
    local elapsedTime
    local elementClicked
    local ret

' Set the #ActionTimeout system variable to wait 1 second before a function times out.
    saveActionTimeout = #ActionTimeout
    #ActionTimeout = 1

' Set the #IgnoreErrors system variable to inhibit errors.
    saveIgnoreErrors = #IgnoreErrors
    #IgnoreErrors = 1

' Check if the specified HTML element exists once a second
' until either the element has been loaded, or the specified timeout value has been exceeded.
    elapsedTime = 0
    elementexist = 0
    Repeat
        ret = ExistHTMLElement(html_element$)
        If (ret = 1) Then
            ' Element exists!
            elementexist = 1
        Else
            ' Element still does not exist, keep trying.
            ' NOTE: No error message has been displayed since #IgnoreErrors has been set to 1.
            elapsedTime = elapsedTime + 1
            ' Yield control to operating system.
            Pause 10 Ticks
        Endif
    Until (elementexist = 1) Or (elapsedTime > timeout)

' Determine if element exists or timeout value has been exceeded.
    If (elementexist = 0) Then
        ' Timeout value exceeded. Display an error and terminate all scripts
        ' if the original value of the #IgnoreErrors system variable was 0.
        ' NOTE: The function needs to perform these actions to exhibit the
        ' same behavior as the WinTask Functions since #IgnoreErrors is set to 1 for the duration of the function.
        If (saveIgnoreErrors = 0) Then
            MsgBox("Cannot detect HTML Element: \n\"+html_element$, 16, "Runtime Error")
            Stop
        Endif
    Endif

' Set function return value based on whether element exists or not.
    wait_html_element_exist = elementexist

' Restore the original values of the system variables.
    #ActionTimeout = saveActionTimeout
    #IgnoreErrors = saveIgnoreErrors

EndFunction

'---------------------------------------------------------------
' Sample code using function wait_html_element_exist()
'---------------------------------------------------------------

' Start Internet Explorer and load the WinTask demos web page.
    StartBrowser("IE", "
www.wintask.com/demos",3)
 

UsePage("WinTask Demonstration Pages")
 ClickHTMLElement("A[INNERTEXT= 'Form']")

' Check the existence of Name word for up to 30 seconds.
    wait_html_element_exist("TD[OUTERTEXT= 'Name:']", 30)

See also

Introduction
Web Synchronization
HTML Descriptor
HTML Descriptor Advanced
How To Measure Response Time
Data Driven Automation