Executing JavaScript on Web Pages

Applies to TestComplete 14.20, last modified on September 11, 2019

TestComplete allows you to execute custom JavaScript code on web pages and get its results as part of your tests. For example, if your tested web application uses a custom JavaScript framework such as jQuery, you can use the framework’s utility functions to analyze and process web page elements.

You can execute JavaScript on web pages regardless of the scripting language of your test project - VBScript, JScript, Python, DelphiScript, C++Script or C#Script. However, there are some specifics of doing this in VBScript and DelphiScript projects that are explained in this topic.

How To Execute Scripts on Web Pages

TestComplete lets you access scripts on web pages using the contentDocument.Script property of the Page test object. It provides access to both functions defined directly on the web page as well as in external JavaScript scripts loaded by using <script src="filename.js"/>.

The following sections explain how you can:

  • execute application-defined JavaScript functions specified by their name,

  • execute arbitrary JavaScript expressions and statements.

Executing Application-Defined Script Functions

Application-defined script functions can be referenced directly by their name via the contentDocument.Script object and the dot notation (in VBScript, JScript, Python and DelphiScript) or bracket notation (in C++Script and C#Script):

JavaScript, JScript

// Calling a function with no return value
pageObj.contentDocument.Script.functionName();

// Calling a function with a return value
var res = pageObj.contentDocument.Script.functionName(param1, ..., paramN);

Python

# Calling a function with no return value
pageObj.contentDocument.Script.functionName();

# Calling a function with a return value
res = pageObj.contentDocument.Script.functionName(param1, ..., paramN);

VBScript

' Calling a function with no return value
pageObj.contentDocument.Script.functionName()

' Calling a function with a return value
res = pageObj.contentDocument.Script.functionName(param1, ..., paramN)

DelphiScript

// Calling a function with no return value
pageObj.contentDocument.Script.functionName();

// Calling a function with a return value
res := pageObj.contentDocument.Script.functionName(param1, ..., paramN);

C++Script, C#Script

// Calling a function with no return value
pageObj["contentDocument"]["Script"]["functionName"]();

// Calling a function with a return value
var res = pageObj["contentDocument"]["Script"]["functionName"](param1, ..., paramN);

For example, if a web page contains the following function:

HTML, JavaScript

<script>
function sum(a, b)
{
  return a + b;
}
</script>

you can call this function from your test as follows:

JavaScript, JScript

var sum = pageObj.contentDocument.Script.sum(3, 4);

Python

sum = pageObj.contentDocument.Script.sum(3, 4);

VBScript

sum = pageObj.contentDocument.Script.sum(3, 4)

DelphiScript

sum := pageObj.contentDocument.Script.sum(3, 4);

C++Script, C#Script

var sum = pageObj["contentDocument"]["Script"]["sum"](3, 4);

Note:

Due to limitations of Chrome’s native messaging protocol, the size of parameters passed to web page scripts cannot exceed 1 megabyte.

Executing Arbitrary JavaScript Code

To execute custom JavaScript code on a web page, you can use the following syntax:

JavaScript, JScript

pageObj.contentDocument.Script.eval("functionName()");

var res = pageObj.contentDocument.Script.eval("functionName(param1, ..., paramN)");

Python

pageObj.contentDocument.Script.eval("functionName()");

res = pageObj.contentDocument.Script.eval("functionName(param1, ..., paramN)");

VBScript

pageObj.contentDocument.Script.eval("functionName()")

res = pageObj.contentDocument.Script.eval("functionName(param1, ..., paramN)")

DelphiScript

pageObj.contentDocument.Script.eval('functionName()');

res := pageObj.contentDocument.Script.eval('functionName(param1, ..., paramN)');

C++Script, C#Script

pageObj["contentDocument"]["Script"]["eval"]("functionName()");

var res = pageObj["contentDocument"]["Script"]["eval"]("functionName(param1, ..., paramN)");

The eval approach is useful for calling:

  • DOM methods, such as history.back(), location.reload(), window.alert() and so on:

    JavaScript, JScript

    pageObj.contentDocument.Script.eval("history.back()");

    Python

    pageObj.contentDocument.Script.eval("history.back()");

    VBScript

    pageObj.contentDocument.Script.eval("history.back()")

    DelphiScript

    pageObj.contentDocument.Script.eval('history.back()');

    C++Script, C#Script

    pageObj["contentDocument"]["Script"]["eval"]("history.back()");

  • arbitrary JavaScript expressions:

    JavaScript, JScript

    pageObj.contentDocument.Script.eval("var i = 5; alert(i);");

    Python

    pageObj.contentDocument.Script.eval("var i = 5; alert(i);");

    VBScript

    pageObj.contentDocument.Script.eval("var i = 5; alert(i);")

    DelphiScript

    pageObj.contentDocument.Script.eval('var i = 5; alert(i);');

    C++Script, C#Script

    pageObj["contentDocument"]["Script"]["eval"]("var i = 5; alert(i);");

Example: Using jQuery to Find Web Page Elements

The following example uses the jQuery function $ and a CSS selector to find all links in the footer section of the main page of the SmartBear web site, http://smartbear.com.

To run this example from a keyword test, use the Run Script Routine operation.

JavaScript, JScript

function UsejQuery()
{
  var url = "http://smartbear.com/";
  Browsers.Item(btChrome).Run(url);
  var page = Sys.Browser().Page(url);

  var footerlinks = page.contentDocument.Script.$("a.footerlink");
  for (var i = 0; i < footerlinks.length; i++)
    Log.Message(footerlinks[i].firstChild.data, footerlinks[i].href);
}

Python

def UsejQuery():
  url = "http://smartbear.com/";
  Browsers.Item[btChrome].Run(url);
  page = Sys.Browser().Page(url);

  # Note we use the full function name - jQuery,
  # because the short name $ isn't a valid identifier in Python code
  footerlinks = page.contentDocument.Script.jQuery("a.footerlink");
  for i in range (0, footerlinks.length - 1):
    link = footerlinks.get(i);
    Log.Message(link.firstChild.data, link.href);

VBScript

Sub UsejQuery
  Dim url, page, footerlinks, i, link

  url = "http://smartbear.com/"
  Browsers.Item(btChrome).Run url
  Set page = Sys.Browser.Page(url)

  ' Note we use the full function name - jQuery,
  'because the short name $ isn't a valid identifier in VBScript code

  Set footerlinks = page.contentDocument.Script.jQuery("a.footerlink")
  For i = 0 To footerlinks.length - 1
    Set link = footerlinks.get(i)
    Call Log.Message(link.firstChild.data, link.href)
  Next
End Sub

DelphiScript

procedure UsejQuery;
var url, page, footerlinks, i, link;
begin
  url := 'http://smartbear.com/';
  Browsers.Item[btChrome].Run(url);
  page := Sys.Browser.Page(url);

  // Note we use the full function name - jQuery,
  // because the short name $ isn't a valid identifier in DelphiScript code

  footerlinks := page.contentDocument.Script.jQuery('a.footerlink');
  for i := 0 to footerlinks.length - 1 do
  begin
    link := footerlinks.get(i);
    Log.Message(link.firstChild.data, link.href);
  end;
end;

C++Script, C#Script

function UsejQuery()
{
  var url = "http://smartbear.com/";
  Browsers["Item"](btChrome)["Run"](url);
  var page = Sys["Browser"]()["Page"](url);

  var footerlinks = page["contentDocument"]["Script"]["$"]("a.footerlink");
  for (var i = 0; i < footerlinks["length"]; i++)
    Log["Message"](footerlinks[i]["firstChild"]["data"], footerlinks[i]["href"]);
}

Specifics of Calling Web Page Scripts

Executing JavaScript in Frames in Google Chrome

In Google Chrome, if you need to call a function defined on a web page frame, use the following syntax:

JavaScript, JScript

frameObj.contentDocument.Script.FunctionName();

Python

frameObj.contentDocument.Script.FunctionName();

VBScript

frameObj.contentDocument.Script.FunctionName()

DelphiScript

frameObj.contentDocument.Script.FunctionName();

C++Script, C#Script

frameObj["contentDocument"]["Script"]["FunctionName()"];

To execute arbitrary JavaScript code inside a frame using eval, use the following syntax with the frame ID and double eval:

JavaScript, JScript

frameObj.contentDocument.Script.eval("frameID.eval('var i = 5; alert(i);')");

Python

frameObj.contentDocument.Script.eval("frameID.eval('var i = 5; alert(i);')");

VBScript

frameObj.contentDocument.Script.eval("frameID.eval('var i = 5; alert(i);')")

DelphiScript

frameObj.contentDocument.Script.eval('frameID.eval("var i = 5; alert(i);")');

C++Script, C#Script

frameObj["contentDocument"]["Script"]["eval"]('frameID.eval("var i = 5; alert(i);")');

Using Parentheses in Function Calls in VBScript and DelphiScript

VBScript and DelphiScript let you omit parentheses when calling procedures and functions that do not take any parameters. However, when calling parameterless functions on web pages, do not omit parentheses:

VBScript

pageObj.contentDocument.Script.doSomething  ' Incorrect!
pageObj.contentDocument.Script.doSomething() ' Correct

DelphiScript

pageObj.contentDocument.Script.doSomething;  // Incorrect!
pageObj.contentDocument.Script.doSomething(); // Correct

This is because the syntax without parentheses does not execute the specified function. Instead, it returns the JavaScript Function object corresponding to this function.

Using Arrays in VBScript, Python and DelphiScript

The VBScript, Python and DelphiScript array format is incompatible with the JavaScript array format. As a result, you cannot directly pass arrays between your VBScript or DelphiScript tests and JavaScript scripts on web pages; you should use a specific approach for this.

To pass an array as a parameter to a web page’s JavaScript function, call this function using eval (see above). In this way, you can specify the array elements using JavaScript's array literal syntax [elem1, elem2, ..., elemN].

Python

pageObj.contentDocument.Script.eval("processArray([1, 2, 3])");

VBScript

pageObj.contentDocument.Script.eval("processArray([1, 2, 3])")

DelphiScript

pageObj.contentDocument.Script.eval('processArray([1, 2, 3])');

To use an array returned from the web page in your VBScript, Python or DelphiScript test, you need to convert it to the compatible array format. For this purpose, you can use the following JSArrayToVariantArray function:

Python

# Converts a JavaScript array to a DelphiScript-compatible array
def JSArrayToVariantArray(JSArray):
  arr = BuiltIn.CreateVariantArray(0, JSArray.length - 1);

  for i in range (0, JSArray.length - 1):
    arr[i] = aqObject.GetPropertyValue(JSArray, i);
  return arr;

VBScript

' Converts a JavaScript array to a VBScript-compatible array
Function JSArrayToVariantArray(JSArray)
  Dim arr(), i
  ReDim arr(JSArray.length - 1)

  For i = 0 To JSArray.length - 1
    arr(i) = aqObject.GetPropertyValue(JSArray, i)
  Next

  JSArrayToVariantArray = arr
End Function

DelphiScript

// Converts a JavaScript array to a DelphiScript-compatible array
function JSArrayToVariantArray(JSArray);
var arr, i;
begin
  arr := BuiltIn.CreateVariantArray(0, JSArray.length - 1);

  for i := 0 to JSArray.length - 1 do
    arr[i] := aqObject.GetPropertyValue(JSArray, i);

  Result := arr;
end;

You can use the JSArrayToVariantArray function as follows:

Python

arr = JSArrayToVariantArray(pageObj.contentDocument.Script.eval("getJSArray()");

VBScript

arr = JSArrayToVariantArray(pageObj.contentDocument.Script.eval("getJSArray()")

DelphiScript

arr := JSArrayToVariantArray(pageObj.contentDocument.Script.eval('getJSArray()');

The array obtained in this way is compatible with VBScript, Python and DelphiScript and can be processed using native array operations and functions of these scripting languages. For example, in VBScript you can use the LBound and UBound functions to determine the array’s lower and upper bounds and access array elements using the parenthesis syntax: arr(index).

Using Callback Functions

JavaScript supports using callback functions, that is, passing functions as arguments to other functions. For example:

HTML, JavaScript

<script>
// A sample function that takes a callback function as a parameter
function forEach(arr, callback)
{
  for (var i in arr)
    callback(arr[i]);
}


// Examples of using the forEach function with different callback functions
var numbers = [1, 2, 3, 4, 5];
forEach(numbers, printNumber); // specifying existing callback function
forEach(numbers, function (n) {alert(n);}); specifying callback function inline

function printNumber(n)
{
  document.write(n);
}
</script>

To call such functions from your test and specify a callback function, use eval (see above):

JavaScript, JScript

pageObj.contentDocument.Script.eval("forEach([1, 2, 3], printNumber)");

pageObj.contentDocument.Script.eval("forEach([1, 2, 3], function (n) {alert(n);})");

Python

pageObj.contentDocument.Script.eval("forEach([1, 2, 3], printNumber)");

pageObj.contentDocument.Script.eval("forEach([1, 2, 3], function (n) {alert(n);})");

VBScript

Call pageObj.contentDocument.Script.eval("forEach([1, 2, 3], printNumber)") ' Note: printNumber is a function defined on the web page

Call pageObj.contentDocument.Script.eval("forEach([1, 2, 3], function (n) {alert(n);})")

DelphiScript

pageObj.contentDocument.Script.eval('forEach([1, 2, 3], printNumber)');

pageObj.contentDocument.Script.eval('forEach([1, 2, 3], function (n) {alert(n);})');

C++Script, C#Script

pageObj["contentDocument"]["Script"]["eval"]("forEach([1, 2, 3], printNumber)");

pageObj["contentDocument"]["Script"]["eval"]("forEach([1, 2, 3], function (n) {alert(n);})");

Getting JScript Object's Properties in VBScript

When working with JScript objects and properties from a VBScript project, you may get the Object doesn’t support this property or method runtime error message. The problem occurs when you assign a value of an object’s property to the variable, and the variable name coincides with the property name but differs by case (for example, name and Name).

Suppose we have a JScript object, Obj, with a property, propertyName. Note that the property name is case-sensitive, that is:

VBScript

' The following syntax is correct
Obj.propertyName
' The following syntax is incorrect and the property value will not be returned
Obj.PropertyName

We want to get the property value to the PropertyName variable:

VBScript

' The property value will not be returned and an error will occur
Set PropertyName = Obj.propertyName

Due to VBScript specifics, if the property name coincides with the variable name, the scripting engine passes the variable name (instead of the property name) to the object. In other words, instead of getting the propertyName property, the code above will try to get the PropertyName property (which does not exist). That is why this code throws an error.

To avoid such issues, do not specify variable names that coincide with property names. The following code will work correctly:

VBScript

' The property value will not be returned and an error will occur
Set propertyNameValue = Obj.propertyName

See Also

Testing Web Applications
Common Tasks for Web Testing

Highlight search results