Forum Discussion

NisHera's avatar
NisHera
Valued Contributor
11 years ago

A simple example of script extension to maintain common scripts


Hi 


I need to maintain common scripts in one place and call those scripts in various tests.


For eg Log on , Cheking basic data for tests, cleaning after test... ect 


In everywhere it says it could be done by implimenting script extension.


When I read through support litreture I'm overloaded with unwanted descrption of many things.


Any body could help me to find a simple example ?


 


  • Hi nishnatha, here is a simple example, please note, Test Complete does not handle Script Extension files that contain Unicode, for safety I always save files as ANSI


     


    Save the following as example.js


     


    var privateField = 123;


     


    //<Property Name="ReadonlyField" GetRoutine="get_readOnlyField">


    //  A Readonly field.


    //</Property>


    var readonlyField = "I am Readonly";


    function get_readOnlyField() {


      return readonlyField;


    }


     


    //<Property Name="PublicProperty" GetRoutine="get_PublicProperty" SetRoutine="set_PublicProperty">


    //  A Public Property.


    //</Property>


    var PublicProperty;


    function get_PublicProperty() {


      return PublicProperty;


    }


    function set_PublicProperty( value ) {


      PublicProperty = value;


    }


     


    //<Method Name="Func" Routine="func">


    //  Increments the private field and returns a message.


    //</Method>


    function func() {


      privateField++;


      return aqString.Format( "I incremented the Private field %i", privateField );


    }


     


    //<Method Name="FunctionWithParametes" Routine="functionWithParametes">


    //  Gets the result of adding a and b.


    //</Method>


    function functionWithParametes( a, b ) {


      return a + b;


    }


     


    Save the following as Description.xml


     


    <ScriptExtensionGroup>


      <Category Name="Runtime Objects">


        <!--


          The following elements define a simple example script extension.


        -->


        <ScriptExtension Name="Example Script Extension" Author="Phillip Baird (c) 2014 ARC Innovations" Version="1.0" HomePage="http://www.arcinnovations.com/">


          <Script Name="example.js">


            <RuntimeObject Name="SimpleExample" Namespace="Example">


              <Method Name="Func" Routine="func">


                Increments the private field and returns a message.


              </Method>


              <Method Name="FunctionWithParametes" Routine="functionWithParametes">


                Gets the result of adding a and b.


              </Method>


              <Property Name="ReadonlyField" GetRoutine="get_readOnlyField">


                A Readonly field.


              </Property>


              <Property Name="PublicProperty" GetRoutine="get_PublicProperty" SetRoutine="set_PublicProperty">


                A Public Property.


              </Property>


              <Description>


                Example script Extension members.


              </Description>


            </RuntimeObject>


          </Script>


          <Description>


            Example Script Extension.


          </Description>


        </ScriptExtension>


      </Category>


    </ScriptExtensionGroup>


     


    Compress example.js and Description.xml into a zip file example.zip


     


    Change the file extension of the zip file from example.zip to example.tcx


     


    Close Test Complete if it is open


     


    Copy the example.tcx to C:\Program Files (x86)\SmartBear\TestComplete 10\Bin\Extensions\ScriptExtensions (this path is dependant on your install)


     


    Start Test Complete


     


    In the intellisense, there will be a Namespace "Example" with a single Object "SimpleExample" that contains the members described in the Description.xml file


     


    The following function shows how the Script Extension may be used


     


    function useExampleScriptExtension() {


      Example.SimpleExample.PublicProperty = "abc"; 


      Log.Message( Example.SimpleExample.PublicProperty );


      Log.Message( Example.SimpleExample.ReadonlyField );


      Log.Message( Example.SimpleExample.Func() ); 


      Log.Message( Example.SimpleExample.Func() ); 


      Log.Message( Example.SimpleExample.FunctionWithParametes( 123, 456 ) );


    }


     


    Regards,


    Phil Baird

  • Philip_Baird's avatar
    Philip_Baird
    Community Expert

    Hi nishnatha, here is a simple example, please note, Test Complete does not handle Script Extension files that contain Unicode, for safety I always save files as ANSI


     


    Save the following as example.js


     


    var privateField = 123;


     


    //<Property Name="ReadonlyField" GetRoutine="get_readOnlyField">


    //  A Readonly field.


    //</Property>


    var readonlyField = "I am Readonly";


    function get_readOnlyField() {


      return readonlyField;


    }


     


    //<Property Name="PublicProperty" GetRoutine="get_PublicProperty" SetRoutine="set_PublicProperty">


    //  A Public Property.


    //</Property>


    var PublicProperty;


    function get_PublicProperty() {


      return PublicProperty;


    }


    function set_PublicProperty( value ) {


      PublicProperty = value;


    }


     


    //<Method Name="Func" Routine="func">


    //  Increments the private field and returns a message.


    //</Method>


    function func() {


      privateField++;


      return aqString.Format( "I incremented the Private field %i", privateField );


    }


     


    //<Method Name="FunctionWithParametes" Routine="functionWithParametes">


    //  Gets the result of adding a and b.


    //</Method>


    function functionWithParametes( a, b ) {


      return a + b;


    }


     


    Save the following as Description.xml


     


    <ScriptExtensionGroup>


      <Category Name="Runtime Objects">


        <!--


          The following elements define a simple example script extension.


        -->


        <ScriptExtension Name="Example Script Extension" Author="Phillip Baird (c) 2014 ARC Innovations" Version="1.0" HomePage="http://www.arcinnovations.com/">


          <Script Name="example.js">


            <RuntimeObject Name="SimpleExample" Namespace="Example">


              <Method Name="Func" Routine="func">


                Increments the private field and returns a message.


              </Method>


              <Method Name="FunctionWithParametes" Routine="functionWithParametes">


                Gets the result of adding a and b.


              </Method>


              <Property Name="ReadonlyField" GetRoutine="get_readOnlyField">


                A Readonly field.


              </Property>


              <Property Name="PublicProperty" GetRoutine="get_PublicProperty" SetRoutine="set_PublicProperty">


                A Public Property.


              </Property>


              <Description>


                Example script Extension members.


              </Description>


            </RuntimeObject>


          </Script>


          <Description>


            Example Script Extension.


          </Description>


        </ScriptExtension>


      </Category>


    </ScriptExtensionGroup>


     


    Compress example.js and Description.xml into a zip file example.zip


     


    Change the file extension of the zip file from example.zip to example.tcx


     


    Close Test Complete if it is open


     


    Copy the example.tcx to C:\Program Files (x86)\SmartBear\TestComplete 10\Bin\Extensions\ScriptExtensions (this path is dependant on your install)


     


    Start Test Complete


     


    In the intellisense, there will be a Namespace "Example" with a single Object "SimpleExample" that contains the members described in the Description.xml file


     


    The following function shows how the Script Extension may be used


     


    function useExampleScriptExtension() {


      Example.SimpleExample.PublicProperty = "abc"; 


      Log.Message( Example.SimpleExample.PublicProperty );


      Log.Message( Example.SimpleExample.ReadonlyField );


      Log.Message( Example.SimpleExample.Func() ); 


      Log.Message( Example.SimpleExample.Func() ); 


      Log.Message( Example.SimpleExample.FunctionWithParametes( 123, 456 ) );


    }


     


    Regards,


    Phil Baird

  • I haven't used script extensions but I achieve the same thing using a different method that seems to be simpler.



    I have a library of commonly used code that I add to all my projects and call repeatedly. Basically you just create a script unit that contains all the library functions you want available in different projects. I called my script unit Library, but that can be easily changed. Open a project that you want to add the script Library to, right-click on Advanced > Script, choose Add > Existing Item..., choose Library.sj (or whatever you called it). Done.



    You can now call the library functions using Library.<Some Function Name>(). You will also need to add a USEUNIT/Reference to Library in any script unit that calls Library.



    NOTE: Be aware that by adding an existing item, you are creating a link to that script file from your project. What that means is that you can double-click on the Library script unit in the project, edit, and save it back and it will be changed for all projects that use it. In my mind this is a good thing... but I just wanted you (and anyone else that reads this) to be aware that you aren't adding an instanced copy... all projects are linked to the same Library.sj file... so any change will affect all projects linked to Library.
  • Philip_Baird's avatar
    Philip_Baird
    Community Expert

    Hi Jeff, I also use the method you prscribe, however, in certain situations (such as static util libraries), I have found Script Extensions to be advantageous for the following reasons:


     


    1. Allows proper encapsulation, i.e. private, readonly and public members (Script Units make everything available as public)


    2. Embeds functionality into Test Complete which makes the functionality avaialable anywhere without the need for USEUNIT statements


    3. I have encountered situations where the functionality present in a Script Unit fails when executing as a shared reference


     


    Conversely, Script Extensions also have there disadvantages, such as:


     


    1. They cannot reference other Script Units and must be self contained which results in cut and paste code reuse (not cool)


    2. Debugging is difficult if an error occurs within a Script Extension


    4. They are not straight forward to create, there is a reasonable of manual work required to create and package the files in the .tcx file.


     


    I think the key with Script Extensions is to take the time to really learn and understand how they work and what their limitations are so as to use them to their best advantage.


     


    Regards,


    Phil Baird

    • finae's avatar
      finae
      Contributor

      One other limitation that i found when i started was that you cannot use code complete in the script file.

      I then change my way of handling it, the script file (vbs for me) contains a runner.callmethod which i call the test complete script that holds all the functions for the keyword test.

       

      This way i can use TC autocomplete codes as well as some functions to find out what they need. An example, 

      get the dropdown object on screen usig findchild.

      and then using the . to find all its function and their parameters, withing tc this reflects and i can then decide which i want to use.

       

       --Edit --

      this method also allows you to debug your scripts

       

      function Test(data)

      if Not runner.callmethod("tcScriptname.Scriptmethod",data) then

       log.error "failed"

      end if

      end function

       

      then all my coding can be done in TestComplete and i can run the script as well to see what was wrong with it, if it ever fails.