“I have a custom control in my application and I want to use web extensibility to identify the object. But I don’t know how to script in javascript, I am not able to implement the support for object properties and operations and So not able to use extensibility.” — I have been asked this and similar questions many times and I believe this could be one of the reason why extensibility is not so popular and being used widely. I remember, One of my colleague once mentioned that he does not even think of it, because it needs JavaScript language knowledge to implement the functionality.

Actually, the fact is that the role of javascript in extensibility is very less and simple. But still, I will agree that some knowledge is required to implement it and work with Add-in Extensibility. In this post I am going to provide a really simple workaround which helps to implement extensibility using VBScript i.e. without knowledge of JavaScript. I hope this will also interest you to try and use add-in extensibility wherever applicable. I have tried and implemented it for various web controls. Although I have not tested it for other add-ins, but I feel this workaround should work in the same way as Web.

Let us start with Extensibility Basics in brief first. Which will help you, If you are new to add-in extensibility or if you don’t know about it.

Add-in extensibility is a  great feature that was added to QuickTest Professional v9.5 with Web Add-in extensibility. Web extensibility allows you to customize, how QTP interacts with the objects in a web application including identification, recording, and playback. The whole process includes some XML configuration file and JavaScript code to create a toolkit package. We are planning to have a separate post on every detail of it, Stay tuned. You can refer the well explained in the post Web Extensibility at Advanced QTP.

For most of us, XML configuration is quite easy which is used to configure and declare object identification, object type classes, Properties and methods. To implement the methods and properties retrieval is been done using Java Script Code.

For your reference, below is an example of xml configuration for extensibility from Extensibility Documentation.

<?xml version="1.0" encoding="UTF-8"?> 
<Controls> 
	<Settings> 
	    <Variable name="default_imp_file" value="WebExtBook.js"/> 
	</Settings>
	<Control TestObjectClass="WebExtBook"> 
        <Identification> 
          <Browser name="*"> 
            <Conditions type="IdentifyIfPropMatch" logic="and"> 
                <Condition prop_name="tagName" expected_value="TABLE"/> 
                <Condition prop_name="className" expected_value="Book"/> 
            </Conditions> 
          </Browser> 
        </Identification> 
        </Control> 
</Controls>

In the above configuration file, if you notice in the Settings node, a javascript(js) file has been referred (WebExtBok.js). The Javascript file is used to develop support for running test object methods.

<Settings> 
	<Variable name="default_imp_file" value="WebExtBook.js"/> 
</Settings>

Once you enable QTP/UFT to recognize your custom controls, you must provide support for running test object methods. For each test object method that you defined in the test object configuration file, you must write a JavaScript function that QTP / UFT runs to perform the step on the control. The JavaScript file contains the implementation of test object method.

Below is sample of testobject Configuration file from the Extensibility documentation again.

<?xml version="1.0" encoding="UTF-8"?> 

<TypeInformation Load="true" AddinName="Web" PackageName="WebExtSample"> 

     <ClassInfo     BaseClassInfoName="WebElement" Name="WebExtBook"                             DefaultOperationName="Select" > 

         <IconInfo IconFile= 

                         "INSTALLDIR\dat\Extensibility\Web\Toolkits\WebExtSample\Res\WebBook.ico"/> 

         <TypeInfo> 

             <Operation ExposureLevel="CommonUsed" Name="Select" PropertyType="Method"> 

                 <Description>Selects the book.</Description> 

                 <Documentation><![CDATA[Select the %l book.]]></Documentation> 

             </Operation> 

             <Operation ExposureLevel="CommonUsed" Name="GoToAuthorPage"                        PropertyType="Method"> 

                 <Description>Opens the Web page for the specified author.</Description> 

                 <Documentation><![CDATA[Open the Web page for %a1.]]></Documentation> 

                 <Argument Name="AuthorName" IsMandatory="true" Direction="In"                            DynamicListOfValues="true"> 

                     <Type VariantType="String"/> 

                     <Description>The author.</Description> 

                 </Argument> 

             </Operation> 

             <Operation ExposureLevel="CommonUsed" Name="GoToUsedBooksPage" 

                             PropertyType="Method"> 

                 <Description>Opens the UsedBooks page.</Description> 

                 <Documentation><![CDATA[Open the %l UsedBooks page.]]></Documentation> 

             </Operation> 

         </TypeInfo> 

         <IdentificationProperties> 

             <IdentificationProperty ForDefaultVerification="true" ForVerification="true" 

                                                ForDescription="true" Name="title"/> 

             <IdentificationProperty ForDefaultVerification="true" ForVerification="true" 

                                                ForDescription="true" Name="authors"/> 

             <IdentificationProperty                         ForDefaultVerification="true" ForVerification="true" 

                                                ForDescription="false" Name="price"/> 

             <IdentificationProperty                         ForDefaultVerification="true" ForVerification="true" 

                                                ForDescription="false" Name="min_used_price"/> 

         </IdentificationProperties> 

     </ClassInfo> 

</TypeInformation>

The methods which has been defined are  – Select, GoToAuthorPage, GoToUsedBooksPage etc, which can be clearly seen here and defined into the Javascript file like below.

function Select() 

{    // Click the link in the second cell of the first row. 

     _elem.rows[0].cells[1].children[0].click(); 

} 

function GoToAuthorPage(AuthorName) 

{    // Look for the specified author name among the children 

     // of the first cell in the second row and click it. 

     var bWasFound = false; 

     for( var i = 0 ; i < _elem.rows[1].cells[0].children.length ; ++i ) 

    { 

         if( _elem.rows[1].cells[0].children[i].innerText == AuthorName ) 

        { 

             _elem.rows[1].cells[0].children[i].click(); 

             bWasFound = true; 

             break; 

        }     

         if( bWasFound == false ) 

         throw ("Author name not found !"); 

} 

function GoToUsedBooksPage() 

{    // Click the link in the first cell of the third row. 

     _elem.rows[3].cells[0].children[1].click(); 

}

Do you feel any difficulty to understand this scripting? Most of us gets confused to see the above code. This is a bit tricky part for me too, most of the times I get problem implementing _elem method. But, No worries we have the workaround 😎  .

By default, QTP / UFT uses this javascript file for all test objects methods defined within this element. QTP / UFT searches in the file specified for a function with the same name as the test object method. So there is no way we can skip this file. What we can do is, we will just create the java script file and write the function names into it without writing anything into it.

function Select() 

{    // Click the link in the second cell of the first row. 

} 

function GoToAuthorPage(AuthorName) 

{    // Look for the specified author name among the children 

     // of the first cell in the second row and click it. 

} 

function GoToUsedBooksPage() 

{    // Click the link in the first cell of the third row. 

}

And we will implement the Methods into a VBScript or function library.  All the methods should be defined into the vbs library and implemented as it is expected to perform. While implementing the same into library, you might need to use object repository or descriptive programming mostly. Below is the code to demonstrate the Select method implementation in VBS.

Function SelectX(obj, strItem)
	Dim nCnt  
	For nCnt = 1 to obj.RowCount
		If obj.GetCellData(nCnt,1) = strItem then
			Set oLink = obj.childItems(nCnt,2,"WebLink",0)
			oLink.Click
		End If
	Next
End Function

Once you are done with implementing all the methods in VBScripting, we need to override the functions defined into javascript file with the new defined function. The whole idea is based on this logic only, UFT calls the method but since we override the method using RegisterUserFunc, it now calls the new function defined into our vb script library.

RegisterUserFunc "WebExtBook", "Select", "SelectX"
RegisterUserFunc "WebExtBook", "GoToAuthorPage", "GoToAuthorPageX"

Now, question comes like – what is the use of blank functions defined in javascript file? Since UFT goes to search for the method into the javascript file, It will find the method there to run it and calls method from VBScript. You can try without writing anything into it, or without specifying the Javascript file as well. It works fine but sometimes it behaves unexpectedly. I am still working on it and will keep posted if I get any success.

The VB Script library file you create, should be associated with your test separately after deploying the extensibility.

You may choose this workaround to implement partially as well, if in case there is a difficulty to develop support for any specific functionality in Javascript file. This workaround can also be utilized when you have used extensibility accelerator.

Let us know if it helps you in Add-in Extensibility. Stay tuned and Subscribe to keep updated on such cool workarounds, tips and more.

 

2 COMMENTS

  1. Hi saket,

    looking for webextensibility help for desktop application developed in java and provide your contact details to discuss more

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.