Step 1

In your test framework open Npm Console via main menu `Tools > Npm Console`. In the opened CMD window run the following commands:

npm install sharp
npm install jsqr
npm install otplib

After running the commands make sure that the framework root folder contains file `package.json`. It should have the following contents (package versions may be different):

{
  "dependencies": {
    "jsqr": "^1.4.0",
    "otplib": "^12.0.1",
    "sharp": "^0.33.4"
  }
}
      

Step 2

Place the following functions to `Common.js`.

// Install NPM modules if missing
function InstallModules()
{
	if(!File.FolderExists("node_modules"))
	{
		Log("otplib not installed, doing npm install");
		var cmd = "npm";
		var osType = Global.GetOsType();
		if (osType.toLowerCase().indexOf("windows") != -1)
		{
			Log("OS Type is Windows");
			cmd = '"' + g_helper.ResolvePath("InstrumentJS/npm.cmd") + '"';
		}
		var result = Global.DoCmd(`${cmd} ci`, g_workDir, true, false);
		Log(result);
	}
}

// Get current one-time password
function GetOTP()
{
    InstallModules()();
	const deasync = require("deasync");
	const { URL } = require('url');
	const sharp = require("sharp");
	const jsQR = require("jsqr");
	const { authenticator } = require("otplib");
	
	const imagePath = 'qr.png';
	
	var done = false;
	var data;
	var info;
	async function loadImageData(path)
	{
	    ({data, info} = await sharp(imagePath)
	        .ensureAlpha()
	        .raw()
	        .toBuffer({resolveWithObject: true}));
	    done = true;
	    return {data, info};
	}
	loadImageData(imagePath);
	
	deasync.loopWhile(function(){return !done;});
	
	const code = jsQR(new Uint8ClampedArray(data.buffer), info.width, info.height);
	console.log(code.data);
	const parsedUrl = new URL(code.data);
	const secret =  parsedUrl.searchParams.get("secret");
	const token = authenticator.generate(secret);
	return token;
}

GetOTP function assumes that the `qr.png` file with the OTP qr-code is in the root folder of the framework. If you know the secret you may simplify the function and load it from a text file.

If you have the secret in text form, you can use this simple function:

function GetOTP(secret)
{
	InstallModules();
	const { authenticator } = require("otplib");
	const token = authenticator.generate(secret);
	return token;
}

Update: otplib v13

otplib v13 introduced breaking changes, so a different code snippet is needed to generate the token.

function GetOTP(secret)
{
	InstallModules();
	
	const deasync = require("deasync");
	const { generate } = require("otplib");

	var done = false;
	var token;

	async function generateOtp()
	{
	    token = await generate({ secret });
	    done = true;
	}
	generateOtp();
	
	while(!done) 
	{
		deasync.runLoopOnce();
	}
	
	return token;
}

Step 3

Create RVL-based OTP module with GetCode action. It should use the functions from `Common.js` like shown below.

Step 4

Generate one-time password in your test case.