Forum Discussion

thrilok_nath's avatar
thrilok_nath
Occasional Contributor
13 years ago

Any other way to recognise objects other than Name Mapping

Hi,



   I am doing R&D on Test Complete and recommend Client for their Automation, in simple POC(Proof of Concept). But i am just wondering if there is any other way to add objects other than Name Mapping.



I am trying to declare all the objects in one Script editor and try to retrieve those objects in another Script editor (I have associated those 2 Script editors by using Add Unit References).

But when i run the script i am getting run time error, since the objects are already read by the Test Complete and the screen is not available(application start up script is involved). Below is the script.



Can anyone tell me if there is any other way where in i store all my objects in one place and call them when required. As Descriptive programming!



When i declare my objects in the same function then it works

First Script Unit where all the objects are stored :


set wnd_Login=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in")

set txt_Login_UserName=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in").WPFObject("LoginWindow", "DMS Client uat1 - log in", 1).WPFObject("Grid", "", 1).WPFObject("_userName")

set txt_Login_Password=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in").WPFObject("LoginWindow", "DMS Client uat1 - log in", 1).WPFObject("Grid", "", 1).WPFObject("passwordBox")

set cmb_Login_Environment=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in").WPFObject("LoginWindow", "DMS Client uat1 - log in", 1).WPFObject("Grid", "", 1).WPFObject("combo")

set btn_Login_EditConnSettings=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in").WPFObject("LoginWindow", "DMS Client uat1 - log in", 1).WPFObject("Grid", "", 1).WPFObject("Button", "", 1)

set btn_Login_OK=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in").WPFObject("LoginWindow", "DMS Client uat1 - log in", 1).WPFObject("Grid", "", 1).WPFObject("Border", "", 1).WPFObject("UniformGrid", "", 1).WPFObject("Button", "_OK", 1)

set btn_Login_Cancel=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in").WPFObject("LoginWindow", "DMS Client uat1 - log in", 1).WPFObject("Grid", "", 1).WPFObject("Border", "", 1).WPFObject("UniformGrid", "", 1).WPFObject("Button", "_Cancel", 2)

 

'''''Login Failed 

set  dlg_AuthenticationError=Sys.Process("DMS.GUI.uat1").Window("#32770", "Authentication Error", 1)

set  static_AuthenticationError_ErrorText=Sys.Process("DMS.GUI.uat1").Window("#32770", "Authentication Error", 1).Window("Static", "Logon failed (username and/or password are invalid)", 2)

set  btn_AuthenticationError_OK=Sys.Process("DMS.GUI.uat1").Window("#32770", "Authentication Error", 1).Window("Button", "OK", 1)


 

Second Script Unit where i am calling my function which uses the above Objects:





Sub Test()

Call DMSLogin ("abcd","xyz", True)



End Sub


Function DMSLogin(strUserName,strPwd,blnNegetiveScenario)

                  

  ' Quit if Login window doesn't exists

  If wnd_Login.Exists <> True Then

     Log.Error "DMS Login Window doesn't exists. Quitting.."

     DMSLogin = False

     Exit Function

  End If

 

  wnd_Login.Activate()

  ' Login with user crendentials

  msgbox strUserName

  msgbox strPwd

  txt_Login_UserName.wText = strUserName

  txt_Login_Password.wText = strPwd   

  btn_Login_OK.Click()

  ' Some times Ok button is taking time to refresh, If not able to click Ok button again we are clicking

  Log.Enabled = False

  If wnd_Login.Exists = True Then

      btn_Login_OK.Click()

  End If

  Log.Enabled = True

  builtin.delay(5000)


                   

show_hid_icons_expander.click


button_Count=Notification_area.wButtonCount

for i=0 to button_Count-1

if  Notification_area.WButtonText(i,True)="DMS Client test (Default)" then

   DMS_Login_Status="True"             

end if

next


 if DMS_Login_Status="True" then

'   DMSLogin="PASS"

'   UPDATE_HTML_TEST_STEPLEVEL_DETAILED_RESULTS fnc_StepNo,"DMSLogin","Verify Login","User should be logged in","User logged into the application","PASS"

'   WriteResult  micPass, "Verify DMS Login window", "User logged in successfully",FALSE

    log.Message "Login Successful"

     else

'   DMSLogin="FAIL"

'   UPDATE_HTML_TEST_STEPLEVEL_DETAILED_RESULTS fnc_StepNo,"DMSLogin","Verify Login","User should be logged in","Failed to gain the access","FAIL" 

'   WriteResult micFail, "Verify DMS Login window", "Failed to login to the application",FALSE

   log.Message "Login unSuccessful"

    End If


End Function





Thanks in Advance

Thrilok

4 Replies

  • sastowe's avatar
    sastowe
    Super Contributor
    I don't know what this means "But when i run the script i am getting run time error, since the objects are already read by the Test Complete".



    You are probably getting a variable not defined error or some such. What is happening is that you are setting object reference variables. When you do this:



    set wnd_Login=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in")



    You are setting a variable named wnd_Login. It's scope is where ever you declare it. So



    Sub Test



        Dim wnd_Login



        set wnd_Login=Sys.Process("DMS.GUI.uat1").WPFObject("HwndSource: LoginWindow", "DMS Client uat1 - log in")





    End



    Or if Option Explicit not set, if no Dim statement, the scope of this variable is to the procedure Test.



    If you did



    Private wnd_Login

    Sub Test

        set wnd_Login...

    End Sub

    The scope is the entire unit. So if you declare them Private at the unit level, then do 'Useunit at the top of the second unit, you would have scoped them properly.

  • One thing to consider is that by trying to excise Name Mapping you are discarding a lot of TestComplete's functionality and usefulness at recognizing objects that would otherwise be inconsistent in characteristics.



    Consider if something like this would work for your needs:

    set wnd_Login= Aliases.DMS.LogInWnd

    set
    txt_Login_UserName=Aliases.DMS.LogInWnd.userName

    set
    txt_Login_Password=Aliases.DMS.LogInWnd.passwordBox

    set
    cmb_Login_Environment=Aliases.DMS.LogInWnd.EnvironmentCbo



    Then use Name Mapping and Aliases to define all the above Aliases. This way you have a point of abstraction if you need to account for dramatic change in the application under test in addition to the option of updating the Name Mapping itself in response to dramatic change.



    On your initial question, you might also look at using Find or FindChld, but these methods are slow in performance, and you need to have the object you want to identify on-screen at the time. You would have to call your custom solution to re-initialize all your objects when you went to a new screen or dialog to get the ones that are currently displayed, and I don't think you'd want to do that
  • thrilok_nath's avatar
    thrilok_nath
    Occasional Contributor
    Hi Stephanie,



                  Actually the object reference variables which are set, does recognise only for the application open(visible) and the objects under application which is not visible is the area where i am getting error. see the scr shot attached.



    1st scr shot attached you can see that the login window is visible on screen so objects set till login window doesn't have any problem, but beyond the login window which are set is the area i am getting this error.





    2nd Scr shot you can see the error displayed where set pane_searchpanel object is not visible on screen(This object(pane_searchpanel ) will come only after i login).So iam getting this error.



    I want to know why TC is trying to identify all the objects on screen before execution, which are set as object reference variables.



    Please give me some solution for this.



    Also i want to know is this the right approach using objects other than Name Mapping.



    If not tell me ways how to identify objects other than Name Mapping.





    Thanks in Advance

    Thrilok
  • What your code is trying to do is not just set X= H, where H is the cancel button or any other of the objects. It is trying to set X=A.B.C.E.F.G.H



    If A doesn't exist, it can't have child B. If B doesn't exist, it can't have child C, and so on.



    You can't expect the software to handle the instruction "These are all the objects I care about" up front because you don't have all those objects to give it.



    What you want to instruct is "Here is how you will get all the objects I care about," and then later during execution have it give you those objects based on the criteria you specify.



    You could store what you have as long strings, and when you need an object do an Execute commands to get it- though I wouldn't recommend it for stability.



    You could store an array of properties and values, and do a Find() with those when you need an object.



    Or you could re-implement your own version of name mapping, and every time you need an object call a function that takes a dot-separated string and returns an object, and put all your code into something that will iteratively parse that string if the object exists based upon your defined properties, and return a non-existent object if not.



    You could take the block of initialization code you have now and call it every time you need an object or change screens, instead of just once at the beginning.