Forum Discussion

kimmatsumoto's avatar
kimmatsumoto
Contributor
9 years ago
Solved

Dialog windows in Delphi XE 10 (Rad Studio XE 10)

The application I'm testing is compiled with Rad Studio XE 10 and the dialog window is detected as:

Sys.Process('download').Window('#32770', 'download').Window('DirectUIHWND').Window('CtrlNotifySink', '', 7).Window('Button', 'OK').ClickButton;

 

In an earlier verison of the application, which was compiled with Delphi XE5, the window was detected as: 

Sys.Process('download').Window('TMessageForm', 'download').VCLObject('OK').ClickButton;.

Has anyone else encountered the same or similar issue?

If yes, what was your workaround?

 

Kind regards,

Kim

  • Our company uses the same framework for our applications. It is our policy to NOT compile the applications with debug information. So for the past 16 years I have been testing these applications with QARun, TestPartner, and now exclusively TestComplete.

    The issue of the popup window having two different class names was solved 16 years ago and I have converted the code to TestComplete. We use TestComplete version 11.20.1491.7.

    We do not use name mapping at all and rely on the various Find methods to access the objects.

    The function is called PopupsUniversal. You pass the process object, caption text, and the text of the button to the function. It returns True if the button was clicked.

    The example below should work for the information that you provided.

    Sorry about the indentions, when I copy and paste all tabs are lost.

     

    Sub One
        Dim p
        Set p = Sys.WaitProcess("download", 3000)
        If p.Exists = True Then
            If PopupsUniversal(p, "download", "OK") = True Then
                Log.Message "Clicked the popup."
            Else
                Log.Message "Did not click the popup."
            End If
       Else
            Log.Error "Process not found."
        End If
    End Sub

     

    Function PopupsUniversal(objProcess, svCaption, svButtonText)
        Dim f, objButton
        PopupsUniversal = False
        If Win32API.FindWindow("TMessageForm", svCaption) <> 0 Or Win32API.FindWindow("#32770", svCaption) <> 0 Then
            Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("TMessageForm", svCaption), 1, True, 500)
                If f.Exists = False Then
                    Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("#32770", svCaption), 1, True, 500)
                End If
                If f.Exists = True Then
                    f.Activate
                    Set objButton = f.Find(Array("WndClass", "WndCaption", "Visible"), Array("Button", svButtonText, True), 10, True)
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "ObjectIdentifier", "Visible"), Array("Button", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "Caption", "Visible"), Array("Button", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "WndCaption", "Visible"), Array("TButton", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "ObjectIdentifier", "Visible"), Array("TButton", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "Caption", "Visible"), Array("TButton", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = True Then
                        objButton.HoverMouse
                        objButton.Click
                        PopupsUniversal = True
                    End If
            End If
        End If
    End Function

9 Replies

  • TanyaYatskovska's avatar
    TanyaYatskovska
    SmartBear Alumni (Retired)

    Hi Kimmatsumoto,

     

    Make sure that your tested application was compiled according to the Compiling Delphi XE6, XE7, XE8 and 10 Applications With Debug Information ( http://smartbear.com/viewarticle/73596/ ) article. TestComplete doesn’t recognize the window correctly.

    If this doesn’t help, let us know what TestComplete version you are using.

    • kimmatsumoto's avatar
      kimmatsumoto
      Contributor

      Hi Tanya,

       

      Development gave me a new build that was compiled according to the Compiling Delphi XE6, XE7, XE8 and 10 Applications With Debug Information article, but there was change.

       

      I did notice one thing...when I used the object spy to capture the button in the dialog window and TestComplete didn't have a project opened, the object's name was:

      Sys.Process('tramswin').Window('#32770', 'Warning', 1).Pane('Warning').Window('CtrlNotifySink', '', 8).Window('Button', '&No', 1)

       

      But, when I opened a project and used the object spy to look at the button it looked like this:

      Sys.Process('tramswin').Window('#32770', 'Warning', 1).Pane('DirectUIHWND').Window('CtrlNotifySink', '', 8).Window('Button', '&No', 1).

       

      Do you know what could cause this difference?

       

      I'm using TestComplete version 11.20.1491.7.

       

      Kind Regards,

      Kim

      • TanyaYatskovska's avatar
        TanyaYatskovska
        SmartBear Alumni (Retired)

        kimmatsumoto wrote:

         

         

        I did notice one thing...when I used the object spy to capture the button in the dialog window and TestComplete didn't have a project opened, the object's name was:

        Sys.Process('tramswin').Window('#32770', 'Warning', 1).Pane('Warning').Window('CtrlNotifySink', '', 8).Window('Button', '&No', 1)

         

        But, when I opened a project and used the object spy to look at the button it looked like this:

        Sys.Process('tramswin').Window('#32770', 'Warning', 1).Pane('DirectUIHWND').Window('CtrlNotifySink', '', 8).Window('Button', '&No', 1).

         

        Do you know what could cause this difference?

         

         


        Hi Kim,

         

        The difference can be related to the fact that you've activated the UI Automation technology in your project. Please check the Tools | Current Project Properties | Open Applications | UI Automation project settings. If you have DirectUIHWND activated in the List of accepted windows box, deactivate it.

  • Our company uses the same framework for our applications. It is our policy to NOT compile the applications with debug information. So for the past 16 years I have been testing these applications with QARun, TestPartner, and now exclusively TestComplete.

    The issue of the popup window having two different class names was solved 16 years ago and I have converted the code to TestComplete. We use TestComplete version 11.20.1491.7.

    We do not use name mapping at all and rely on the various Find methods to access the objects.

    The function is called PopupsUniversal. You pass the process object, caption text, and the text of the button to the function. It returns True if the button was clicked.

    The example below should work for the information that you provided.

    Sorry about the indentions, when I copy and paste all tabs are lost.

     

    Sub One
        Dim p
        Set p = Sys.WaitProcess("download", 3000)
        If p.Exists = True Then
            If PopupsUniversal(p, "download", "OK") = True Then
                Log.Message "Clicked the popup."
            Else
                Log.Message "Did not click the popup."
            End If
       Else
            Log.Error "Process not found."
        End If
    End Sub

     

    Function PopupsUniversal(objProcess, svCaption, svButtonText)
        Dim f, objButton
        PopupsUniversal = False
        If Win32API.FindWindow("TMessageForm", svCaption) <> 0 Or Win32API.FindWindow("#32770", svCaption) <> 0 Then
            Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("TMessageForm", svCaption), 1, True, 500)
                If f.Exists = False Then
                    Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("#32770", svCaption), 1, True, 500)
                End If
                If f.Exists = True Then
                    f.Activate
                    Set objButton = f.Find(Array("WndClass", "WndCaption", "Visible"), Array("Button", svButtonText, True), 10, True)
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "ObjectIdentifier", "Visible"), Array("Button", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "Caption", "Visible"), Array("Button", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "WndCaption", "Visible"), Array("TButton", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "ObjectIdentifier", "Visible"), Array("TButton", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = False Then
                        Set objButton = f.Find(Array("WndClass", "Caption", "Visible"), Array("TButton", svButtonText, True), 10, True)
                    End If
                    If objButton.Exists = True Then
                        objButton.HoverMouse
                        objButton.Click
                        PopupsUniversal = True
                    End If
            End If
        End If
    End Function

    • AlexKaras's avatar
      AlexKaras
      Champion Level 3

      Hi,

       

      Just my $0.02 performance related...

      > Function PopupsUniversal [...]

      >  If Win32API.FindWindow("TMessageForm", svCaption) <> 0 Or Win32API.FindWindow("#32770", svCaption) <> 0 Then
      >      Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("TMessageForm", svCaption), 1, True, 500)
      >          If f.Exists = False Then
      >              Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("#32770", svCaption), 1, True, 500)
      >          End If

      > ...

       

      Considering that:

      a) VBScript does not support short-circuit logical expressions evaluation, the above code will result in window search done at least thrice: two WinAPI32.FindWindow() calls and one FindEx() one;

      b) I see no reason in using FindEx() call because if the call to WinAPI32.FindWindow() succeeds, this means that the window was found and thus a regular Find() can be used.

       

      My preference would be to omit the calls to WinAPI32.FindWindow() and

      a) either use just a pair of FindEx() calls, e.g.:

      Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("TMessageForm", svCaption), 1, True, 500)
      If (Not f.Exists) Then
        Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("#32770", svCaption), 1, True, 500)
      End If

       

      b) Or, utilizing the new functionality that was introduced in TC 11.x :

      Set f = objProcess.FindEx(Array("WndClass", "WndCaption"), Array("regexp: (TMessageForm)|(#32770)", svCaption), 1, True, 500)

      and expect that this type of search was implemented by SmartBear more effectively than two subsequent searches.

  • m_essaid's avatar
    m_essaid
    Valued Contributor

    hi,

    the #32770 windows is a Windows window, while your "TForm" is a VCL object.

    I bet that your dev colleagues changed the object. so you have to remap/change the script.

    in ANY case, two important things :

    1) never compile with debug info because you have to test the CUSTOMER version.

    2) you could though use a separate file containing debug info. Delphi will compile the exe without debug info while putting all debug info into the file. They just both have to be in the same directory.

     

    But... I just manage to test my exes without debut info and debug info file.