1

Suppose, I have login to application function in setup module with the scope session.

Test file name: test_login_app.py

@pytest.fixture(scope="session")
def setup_module(request):
    login_to_app(username, password)

    #above function is responsible for login with multi-factor authentication using otp(google authenticator) into the application.
    
    def teardown_module():
       logger.info('Tearing Down Test Module.')
       driver.quit()
       driver.close()
    request.addfinalizer(teardown_module)

@pytest.mark.regression
def test_login_to_application(setup_module, service_data):

    #service_data is a parametrize fixture which is responsible to get the service data from test data file.it is data driven framework.
    
    // performing some actions
    // performing assertion.

Now the issue is, I need to execute this test file in parallel mode but when I'm running it in parallel mode with more than 1 node then it is launching the browser and loading the url also but to login to the application it requires otp, so on 1st node it is taking the otp 1st and then same otp is going into the other nodes for login so in that case, message we are getting after inputting the same otp is that its already used so we are regenrating the otp also and login to the 2nd node but when it comes to 3rd or 4th node then at that time, there would be an error to enter the otp like there are too many otp entered.

So how can I handle this otp issue in parallel mode with pytest framerwork? or any other approach if you can suggest. ??

Thanks in advance.

1 Answers1

0

You can use the SeleniumBase Python/pytest framework to handle OTP/MFA while running tests in multiple processes.

First, pip install -U seleniumbase, and then run this (with other tests) with pytest -n=4 (for 4 parallel threads for more tests):

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class TestMFALogin(BaseCase):
    def test_mfa_login(self):
        self.open("https://seleniumbase.io/realworld/login")
        self.type("#username", "demo_user")
        self.type("#password", "secret_pass")
        self.enter_mfa_code("#totpcode", "GAXG2MTEOR3DMMDG")  # 6-digit
        self.assert_text("Welcome!", "h1")
        self.highlight("img#image1")  # A fancier assert_element() call
        self.click('a:contains("This Page")')  # Use :contains() on any tag
        self.save_screenshot_to_logs()  # ("./latest_logs" folder for test)
        self.click_link("Sign out")  # Link must be "a" tag. Not "button".
        self.assert_element('a:contains("Sign in")')
        self.assert_exact_text("You have been signed out!", "#top_message")
Michael Mintz
  • 9,007
  • 6
  • 31
  • 48
  • Hi michael, can you please clarify with brief explanation that how BaseCase Class will help me to handle MAF(with OTP) in multiple browser instance while running in parallel. ??? Because I'm not getting how will it solve my issue. – Satyam Agrawal Jul 19 '23 at 05:48
  • The ``BaseCase`` class of ``seleniumbase`` gives you access to methods such as ``enter_mfa_code()``, which handle multiple factor authentication with a one-time-password generated via the string and the current timestamp. As a ``pytest`` plugin, ``seleniumbase`` tests can be run via ``pytest -n=4`` (for example) to easily run multiple tests in parallel. – Michael Mintz Jul 19 '23 at 08:06