TestComplete & MFA protected Apps Workaround
This question comes up often enough (or at least recently it did), and I figured it's worth it to post a workaround for the sake of documentation.
There are lots of applications that have multi factor authentication (MFA) enabled, requiring a user to enter a generated one time password (OTP) before accessing the application.
Can TestComplete work with MFA?
The defualt answer has usually been, "Not really, since MFA is doing its job! Protecting the application from unwanted attacks/automated software"
or "Set up a QA instance to test everything within the app, and just manually test the efficacy of MFA once"
However, if that is absolutely not an option to have a separate test instance where MFA is not required, we can use external libraries to tackle this problem.
This example will use Python, and a library called PyOTP.
This library can generate both time-based and counter-based OTP's. Essentially, the numbers that are automatically generated for you on apps like Google Authenticator, can be generated through script
so grab the shared secret key from your MFA (which should be the input parameter to the pyotp.TOPT() method in the below code snippet.
from os import sys sys.path.insert(0, 'C:\\Users\\justin.kim\\AppData\\Local\\Programs\\Python\\Python36\\Lib\\site-packages') #importing external python library import pyotp def create_opt(): totp = pyotp.TOTP("JBSWY3DPEHPK3PXP") #this JXXXXXXXXX is the shared secret from your MFA #create a project level variable first (i called mine my_otp) Project.Variables.my_otp = totp.now() Log.Message("The Generated OTP is : " + Project.Variables.my_otp) def test123(): create_opt() Browsers.Item[btFirefox].Run("www.google.com") Sys.Browser("firefox").Page("https://www.google.com/").FindElement("//input[@name='q']").SetText(Project.Variables.my_otp)
1) import external python package (this location is why my libraries get saved to when i use the command "pip install X"
2) generate the OTP using the instructions from the pyOTP github
3) save to variable and use it later as needed.