Wikis - Page

Asynchronous JavaScript APIs in TruClient – Part I

1 Likes

Asynchronous JavaScript APIs In TruClient – Part II

Asynchronous JavaScript APIs In TruClient – Part III

Support for Asynchronous JavaScript APIs was added to TruClient 2020 service pack 1. TruClient asynchronous APIs provide the same functionality as synchronous ones, but in an asynchronous way.

Why asynchronous APIs

Most modern browsers have moved to, or are in the process of moving to, an asynchronous world. For example, all JavaScript APIs provided by Chrome/Chromium are asynchronous. There are very few ways to invoke these APIs in a synchronous way, and in some browsers, synchronous calls have been deprecated.

Asynchronous JavaScript provides improved performance and a better user experience, which are the main advantages that browsers are eager to have. Since TruClient is a browser-based scripting tool, we decided to embrace the asynchronous world, and recently introduced asynchronous JavaScript APIs. Even though asynchronous JavaScript is more complicated for writers to code (asynchronous programming is an advanced topic in programming languages, including JavaScript), now is the time to learn.

So let’s get familiar with promise, async/await, asynchronous patterns, and other asynchronous techniques, and start the journey into TruClient asynchronous APIs.

A first look at TruClient asynchronous APIs

Synchronous APIs and asynchronous APIs - Namespaces

Like synchronous APIs defined in synchronous namespaces (TC/IO/Utils), asynchronous APIs are defined in corresponding asynchronous namespaces (TCA/IOA/UtilsA). As the name implies, the “A” suffix means “asynchronous”. Every synchronous API has a corresponding asynchronous counterpart. The latter provides the same functionality as the former, but in an asynchronous way. Here are some examples:

Synchronous API

Asynchronous API

TC.evalC(funcname, functimeout)

TCA.evalC(funcname, functimeout)

TC.vtcConnectEx(serverName, port, userName, password, domain, vtsName)

TCA.vtcConnectEx(serverName, port, userName, password, domain, vtsName)

IO.read(filename, charset)

IOA.read(filename, charset)

Utils.clearCookie()

UtilsA.clearCookie()

Asynchronous API pattern - Promise vs. Callback

There are different patterns to define asynchronous APIs. Callback and promise are the two most commonly used. While callback is easier to use, promise is cleaner. It provides a catching mechanism that is better in exception handling, and it is compatible with async/await, which enables writing asynchronous code almost the same as synchronous code.

TruClient asynchronous APIs use promise pattern. Unlike a synchronous API, which returns a required result after it’s available, every TruClient asynchronous API returns a promise object immediately. Result accessing and error handling are done via the return promise.

For example, the synchronous IO.read(filename, charset) function is blocked when reading the file, and returns file content only after the file has been read. While the corresponding asynchronous IOA.read(filename, charset) function returns a promise object immediately, without being blocked when reading file content.

// synchronous API IO.read returns the file content after it’s read

var fileContent = IO.read("C:\\Demo\\1.txt");

 

// asynchronous API IOA.read returns a promise object immediately

var readPromise = IOA.read("C:\\Demo\\1.txt");

Invoke asynchronous API – Promise and await

When invoking an asynchronous API, you need to work with the returned promise object. There are two popular patterns to work with promises—using promise directly, or using await keywords. Let’s take the synchronous API code below as an example to show how to invoke an asynchronous API with promise and await.

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

var content = IO.read(fileToRead);

 

// content is content of fileToRead

// can be used here to do something

TC.outputMessage(content);

Invoke asynchronous API with Promise

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

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

  // content is content of fileToRead

  // can be used here to do something

  TC.outputMessage(content);

 

  // tell TruClient current JavaScript code is done

  TCA.done();

}).catch( function(error) {

  // tell TruClient current JavaScript code is done with error

  TCA.doneWithError(error);

});

Here, the asynchronous IOA.read function is used instead of the synchronous IO.read function. OA.read returns a promise object.

The function provided to the “then” method of the promise is used to work on normal logic (this means, no exception happens). TCA.done() is called here to tell TruClient that the current JavaScript code is finished.

The function provided to the “catch” method of the promise is used to handle possible exceptions. TCA.doneWithError(error) is called to tell TruClient that the current JavaScript code is finished, but an exception occurred.

Invoke asynchronous API with await

As you can see in the following example, using the await keyword to invoke an asynchronous API is almost the same as calling a synchronous API.

((async () => {

  // call any TruClient asynchronous JavaScript APIs with await,

  // it's almost same as calling synchronous JavaScript APIs

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

  let content = await IOA.read(fileToRead);

 

  // do something with the content got by IOA.read asynchronous API

  TC.outputMessage(content);

})()).then(

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

).catch(

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

);

You may notice here, there is additional code to define and call the outer async arrow function, and to call the “then” and “catch” method on the promise returned by this function. This wrapper code is required to support using async/await keywords inside it. It can be used as a template when using async/await keywords in TruClient. You can copy and paste it to where you want to write asynchronous JavaScript code with async/await keywords, then write you own code to replace the “// your code here” comment, as shown below.

((async () => {

  // your code here

})()).then(

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

).catch(

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

);

Internet Explorer (IE) doesn’t support ECMAScript 6

Although using the await keyword to invoke asynchronous API is more elegant, IE doesn’t supported it (actually, IE doesn’t support ECMAScript 6 ). This means that the “let” keyword, arrow function, async/await keywords, and several other features are not supported by IE. IE also doesn’t support promise; TruClient supports promise in the TruClient IE browser.

Note: You should avoid using async/await keywords, the “let” keyword, arrow function, or other ECMAScript 6 features in scripts which need to run with TruClient IE. They can work with TruClient Chromium and TruClient Browser only.

Where to use TruClient asynchronous APIs

TruClient asynchronous APIs can be used in the “Arguments” section of a step. For example, “Code” field in “Evaluate JavaScript” steps, “Location” in “Navigate” steps, and “Value” in “Type” steps. Of course, JavaScript should be selected as the value type.

TruClient asynchronous APIs are not supported in the following areas:

  • “Object” section of steps (not currently supported in object identification methods)
  • TruClient Coded
  • TruClient - Native Mobile protocol

TruClient asynchronous APIs vs. synchronous APIs vs. Generic APIs

Asynchronous APIs

TruClient asynchronous APIs are recommended for all the reasons we have already outlined in this blog.

Synchronous APIs

While synchronous APIs can still be used for a period of time, they will eventually be dropped. Although TruClient currently supports asynchronous and synchronous functions, support for synchronous APIs in JavaScript code will be deprecated in TruClient, and we recommend switching to asynchronous APIs.

Generic APIs

While TruClient Generic APIs were added in the past to simulate asynchronous requests, they are limited to only one TruClient synchronous API being executed in one step.

Although this can work in simple cases, it’s difficult to support in cases that cannot be implemented by invoking only one synchronous API. Where more than one synchronous API is required, you need to split it into multiple steps. If flow control is required (such as “if” or “for”), you need to add an “If Block” or “For Loop” step. Additional steps are required for more complex cases.

TruClient Generic APIs may also be deprecated in the future.

Conclusion

This blog provides an overview of the TruClient asynchronous APIs introduced in TruClient 2020 service pack 1, and the reasons for switching to TruClient asynchronous APIs.

In my next blog, I will take a more detailed look at the 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