cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
159
Views
1
Helpful
0
Comments
oatroshc
Cisco Employee
Cisco Employee

Welcome to the second part of our series of articles about Transaction Tests in ThousandEyes!

ThousandEyes is a powerful SaaS platform that gives a digital picture of enterprise infrastructure, formed by test views, alerts, dashboards, and other components.

This article will show you how to set up Google 2-factor authentication (2FA) to log into an email account (in this case, a Gmail account) in a ThousandEyes Transaction Test. The previous article in the series covers the basics of setting up a Transaction Test to log into an email account. This is an article we will be referring to very often, I suggest you open it in a separate tab for quick reference.

What are the steps? A high-level overview:

  1. Setting up 2-factor authentication in the existing Gmail account we used in the previous part.
  2. Run the Integrated Development Environment (IDE) recorder to generate a script on how to log into the Gmail account using 2-factor authentication.
  3. Create a new Transaction Test and input the JS code from step 2.
  4. Add credentials into the Credential Repository and validate. (Please Note: In this walkthrough we will use the credentials generated in the previous article)
  5. Modify the Transaction Test to add the 6-digit code generation mechanism needed for 2-factor authentication.

 

Detailed overview

Step 1. Setting up 2-factor authentication in the existing Gmail account.

If you need help creating a Gmail account, you can get instructions here.

For the Transaction Test in this article, I am using the Gmail account thousandeyestest11@gmail.com with the password ******1, which was used in the previous article. In this case, as it's already created, we only need to enable 2-factor authentication.

Full details on Google 2-factor authentication can be found here, but we'll also go through the steps. Watch this short video to see how to enable 2-Step Verification.

Please take note of a few things:

When setting up Authenticator, instead of using a QR code you should use the option "Can't scan it". This will generate a setup key you use in the Authenticator (Enter a setup key option) and ThousandEyes too.

Here is a screen of which option to use on your phone for entering the setup key in the Google Authenticator:

Enter a setup key.png

Complete the steps in the Authentication and confirm the action in the Google account.

Please check this short video on how to verify 2-step verification is enabled on your Google account:

Step 2. Run the Integrated Development Environment (IDE) recorder to generate a script on how to log into the Gmail account using 2-factor authentication.

Watch this short video on how to use the IDE recorder to generate the 2FA account code:

Step 3: Create a new Transaction Test and input the JS code from Step 2.

You can follow the same process described in Step 3 of our previous article, or by watching this video:

Step 4. Add credentials into the Credential Repository and validate.

As mentioned earlier, we are using the existing credentials test11 to enter the password on authentication step 1. However, now that we are using 2-Step Verification, we need to create one more credential entry test11-2-auth for the ThousandEyes authenticator function. Steps for that follow:

  • Open the 'Credential Repository' [1] tab. In our example, credentials named test11 [2] already exist.
  • Click Add New Credential [3]:

Add credentials 1.png
  • Give the credential a nickname [4]
  • Add the setup key you entered in the Authenticator [5] (make sure you have removed spaces!).
  • Save it by clicking 'Add New Credential' [6]:
Add credentials 2.png

Once saved, the new test11 and test11-2-auth credentials should sit in the Credential Repository list:

Add credentials 3.png
 
Step 5. Modify the Transaction Test to add the 6-digit code generation mechanism needed for 2-factor authentication.

On step 3, we added the JS code taken from the IDE recorder. Now it's time to add entries related to 2-step verification.

First, we need to add the following code from the Authentication Module into the import section of our code:  import { authentication } from 'thousandeyes'.

Second, we need to replace and remove some entries in the code, since we are setting up the Test to use the password and 6-digit 2FA code credentials from the repository:

await typeText(credentials.get('pass_1711481371173'), By.name(`Passwd`));

await typeText(credentials.get('test11'), By.name(`Passwd`));

await typeText('001447', By.id(`totpPin`));

Now we will add the rest of the needed commands. We're using code from an example created by one of my colleagues (thank you Bostjan!):

Retrieve the tokens by using the call `credentials.get`:

const secretToken = credentials.get('test11-2-auth');

Call for the generation of a 6-digit authentication code with TOTP (time-based one-time password):

var totp = authentication.getTimeBasedOneTimePassword(secretToken);

This enters the generated authentication code:

await typeText(totp, By.id(`totpPin`));
 
Do not forget to enable the credentials for the test to be able to run them:
Select credentials.png

And that's it! Now when run, the Transaction Test will log into the Gmail account. You can check your results here (on a snapshot page):

Result screenshot 1.png
Result screenshot 2.pngResult screenshot 3.png

If you have any issues getting a Transaction Test set up - open a chat with ThousandEyes Customer Support, we'll be happy to help! Here is an article on getting in touch with us in only a few seconds.

Reference of useful ThousandEyes resources:

import { By, Key } from 'selenium-webdriver';
import { driver, test, credentials } from 'thousandeyes';
import { authentication } from 'thousandeyes';

runScript();

async function runScript() {

await configureDriver();

const settings = test.getSettings();

// Load page
await driver.get(settings.url);

await typeText('thousandeyestest11', By.id(`identifierId`));

await pressEnter(By.id(`identifierId`));

await typeText(credentials.get('test11'), By.name(`Passwd`));

await driver.takeScreenshot();
await pressEnter(By.name(`Passwd`));

await driver.sleep(5000);

const secretToken = credentials.get('test11-2-auth');

var totp = authentication.getTimeBasedOneTimePassword(secretToken);
await typeText(totp, By.id(`totpPin`));
await driver.takeScreenshot();
await pressEnter(By.id(`totpPin`));
//await typeText('653711', By.id(`totpPin`));

await driver.sleep(5000);
await driver.takeScreenshot();

}

async function configureDriver() {
await driver.manage().setTimeouts({
implicit: 7 * 1000 // If an element is not found, reattempt for this many milliseconds
});
}

async function typeText(value, selector) {
await simulateHumanDelay();
const element = await driver.findElement(selector);
await element.clear();
await element.sendKeys(value);
}

async function simulateHumanDelay() {
await driver.sleep(550);
}

async function pressEnter(selector) {
await driver.findElement(selector).
sendKeys(Key.RETURN);
}

async function click(selector) {
await simulateHumanDelay();

const configuredTimeouts = await driver.manage().getTimeouts();
const clickAttemptEndTime = Date.now() + configuredTimeouts.implicit;

await reattemptUntil(attemptToClick, clickAttemptEndTime);

async function attemptToClick() {
await driver.findElement(selector).
click();
}
}

async function reattemptUntil(attemptActionFn, attemptEndTime) {
const TIME_BETWEEN_ATTEMPTS = 100;
let numberOfAttempts = 0;
let attemptError;
while (Date.now() < attemptEndTime || numberOfAttempts === 0) {
try {
numberOfAttempts += 1;
await attemptActionFn();
}
catch (error) {
attemptError = error;
await driver.sleep(TIME_BETWEEN_ATTEMPTS);
continue; // Attempt failed, reattempt
}
attemptError = null;
break; // Attempt succeeded, stop attempting
}

const wasAttemptSuccessful = !attemptError;
if (!wasAttemptSuccessful) {
throw attemptError;
}
}
Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: