Wikis - Page

Asynchronous JavaScript APIs in TruClient – Part II

0 Likes

Asynchronous JavaScript APIs In TruClient – Part I

Asynchronous JavaScript APIs In TruClient – Part III

A closer look at TruClient asynchronous APIs

Obviously, asynchronous APIs are different to synchronous APIs. Below I detail some of the main differences which will help you better understand how to use to use TruClient’s asynchronous APIs.

Use TCA.done or TCA.doneWithError to tell TruClient when current JavaScript execution is done

TruClient runs steps one at a time. It needs to know when a step finishes, so that the next step can be started. When executing synchronous JavaScript code, it’s clear when the code execution has finished. But TruClient can’t know when asynchronous JavaScript code execution has finished, because asynchronous means something was not executed in the main thread. So you need to call TCA.done or TCA.doneWithError to tell TruClient that the current JavaScript code execution has finished at every JavaScript code exit point. Otherwise, a timeout error is likely to occur.

TCA.done(result) API

Call TCA.done(result) to tell TruClient the current JavaScript code execution has finished successfully.

The result argument is optional. Usually, when called in the “Code” field in the “Arguments” section of an “Evaluate JavaScript” step, there is no need to provide a result. But the result is required when the JavaScript code is expected to return a result. For example, when called in the “Location” field in the “Arguments” section of a “Navigate” step, or in the “Value” field in the “Arguments” section of a “Type” step.

The code below is an example used in the “Location” field in the “Arguments” section of a “Navigate” step. Suppose the “URL” parameter provides the URL to navigate. The TCA.getParam API gets the URL and sets it to “content”, which is returned by the TCA.done(content) API. The URL is then used by the “Navigate” step.

TCA.getParam("URL").then( function(content) {

  TCA.done(content);

}).catch( function(error) {

  TCA.doneWithError(error);

});

TCA.doneWithError(error) API

Call TCA.doneWithError(error) to tell TruClient that the current JavaScript code execution has finished with an error, and that the current step failed.

The error argument is required. TruClient displays this error in the UI, and reports this error in the execution log.

About JavaScript code execution time limits

There are times that people forget to use the TCA.done or TCA.doneWithError call to tell TruClient that the current JavaScript code execution has finished. Since TruClient cannot wait indefinitely, it sets a time limit for JavaScript code execution (the default value is 20 seconds). This means, for example, that if an “Evaluate JavaScript” step doesn’t stop within 20 seconds, TruClient will stop it and report a timeout error.

A timeout error can be caused by a missing TCA.done or TCA.doneWithError call, or by a step taking longer to run than the 20 second time limit (what a long time!). If it’s the latter case, we suggest re-writing the JavaScript code to shorten execution time. For example, split the “Evaluate JavaScript” step into multiple steps so that each step doesn’t take too long to run. If a step must run more than 20 seconds, you can increase the timeout value by modifying the EvalJavaScriptTimeout item in the default.cfg file in the script folder. Avoid increasing the timeout value too much (try to keep it as small as possible).

Use TCA.useAsyncAPI to tell TruClient explicitly when asynchronous APIs are used

TruClient automatically detects when an asynchronous API is invoked in the main thread, and waits for TCA.done or TCA.doneWithError invocation to identify when the current JavaScript has finished, or for the step to time out. However, TruClient cannot detect invocation to asynchronous APIs in callback functions that are not executed in the main thread.

For example, if an “Evaluate JavaScript” step contains the below code (where the asynchronous APIs are invoked in the callback function outside the main thread), TruClient treats it as finished immediately after the setTimeout function returns. It then continues to execute the subsequent steps. Even if callbackFunc is executed a second later, this causes unpredictable results. Any subsequent steps that depend on the directory being created by this step may fail.

setTimeout(function callbackFunc() {

  IOA.createDir("C:\\Demo\\TestDir").then(function(result) {

    TCA.outputMessage("Create dir successfully");

    TCA.done(result);

  }).catch(function(error) {

    TCA.outputMessage(error);

    TCA.doneWithError(error);

  });

}, 1000);

 

To avoid this problem, use TCA.useAsyncAPI to notify TruClient that asynchronous APIs are being used, as shown below:

TCA.useAsyncAPI();

 

setTimeout(function callbackFunc() {

  IOA.createDir("C:\\Demo\\TestDir").then(function(result) {

    TCA.outputMessage("Create dir successfully");

    TCA.done(result);

  }).catch(function(error) {

    TCA.outputMessage(error);

    TCA.doneWithError(error);

  });

}, 1000);

Tips for using TCA.useAsyncAPI

  • TCA.useAsyncAPI must be invoked in the outermost scope. Do not invoke it inside any function. We recommend invoking it in the first line.
  • Only invoke TCA.useAsyncAPI when all other asynchronous APIs are invoked in callback functions.
  • If TCA.useAsyncAPI is invoked, make sure TCA.done or TCA.doneWithError is also invoked.

Exception handling

Exception handling of asynchronous JavaScript code is a little tricky. The difficulty is the try/catch method in the main thread cannot catch exceptions that occur in asynchronous code. Take a look at the example code below:

try {

  var fileToRead = "C:\\Demo\\1.txt";

  IOA.read(fileToRead).then(function(result) {

    TCA.outputMessage(result);

 

    TCA.done();

  });

} catch(error) {

  TC.outputMessage(error);

  TCA.doneWithError(error);

}

If an exception occurs when reading the file by asynchronous API IOA.read, the exception won’t be caught, and the sentences in the catch block won’t be executed. The final result is a timeout error because TCA.doneWithError won’t be executed. The reason is because the IO exception occurs in the asynchronous API, while the try/catch method is in the main thread.

Use a catch to handle exceptions from promises in asynchronous APIs

To avoid this problem in asynchronous APIs, use a catch to capture exceptions from promises, as shown below:

var fileToRead = "C:\\Demo\\1.txt";

IOA.read(fileToRead).then( function(content) {

  TC.outputMessage(content);

 

  TCA.done();

}).catch( function(error) {

  TCA.doneWithError(error);

});

Every TruClient asynchronous API returns a promise object, including IOA.read here. Use the catch method to capture possible exceptions that occur inside the API.

If you prefer the async/await pattern, use the wrapper template mentioned in my previous blog to capture exceptions in asynchronous APIs, as shown below. The wrapper async arrow function also returns a promise object. It can work with TruClient Chromium and TruClient Browser only.

((async () => {

  // your code here

})()).then(

  (result) => { TCA.done(result); }

).catch(

  (error) => { TCA.doneWithError(error); }

);

Use extended log to help check uncaught exceptions in asynchronous APIs

If exceptions in asynchronous APIs are not caught, either because there is no catch, or because the catch is not used correctly, the result is unpredictable-possibly a timeout or unexpected error. To check what exceptions actually occurred, set the Log Level in Runtime Settings to “Extended”. Then, most of time, the log will contain information of the exceptions that occurred in asynchronous APIs.

Extended log can only show exceptions inside asynchronous APIs.

Use DevTools to help check uncaught exceptions in TruClient Chromium

When working with TruClient Chromium, use Chrome DevTools to help capture and show exceptions inside or outside TruClient asynchronous APIs. To view logged messages, open DevTools of the AUT (application under test) tab, and switch to the Console tab.

Use the Browser Console to help check uncaught exceptions in TruClient Browser

When working with TruClient Browser, use the Mozilla Browser Console to help capture and show exceptions inside or outside TruClient asynchronous APIs. For details on how to view logged messages, see Open the Browser Console.

Conclusion

This blog took a closer look at how to use the TruClient asynchronous APIs, and how to handle exceptions.

In my next blog, I will provide examples of TruClient asynchronous functions.

For the latest information on using TruClient asynchronous APIs, see the TruClient Help Center.

Labels:

How To-Best Practice
Education-Training
Comment List
Related
Recommended