ScreenshotNeo

BlogHow-to

Why Does a Selenium Screenshot Show an Indian Portal’s Login OTP Page?

Selenium captures the browser’s current state. Learn why an OTP checkpoint appears, how to diagnose capture timing, and how to test login flows safely.

By the ScreenshotNeo team4 October 20267 min read

Short answer: Selenium takes a screenshot of what the browser is displaying at that moment. If login has reached an OTP checkpoint and the required factor has not been completed, the screenshot can show that page. Taking a screenshot does not authenticate the session, submit an OTP, or advance the browser.

The title does not identify the portal, account, automation script, or capture timing. So the exact reason that a particular run reached an OTP checkpoint cannot be established from the screenshot alone. The challenge may be part of that portal’s login policy, specific to the session, or simply still in progress when the script captured the page.

What the screenshot tells you

A WebDriver screenshot is a snapshot of the current browsing context. It records the page visible to that browser session; it does not report that login succeeded or explain why the page appeared. Selenium defines OTP as a second authentication factor that may come through an authenticator app, SMS, or email. Its guidance says that automating two-factor authentication consistently is difficult and recommends avoiding routine 2FA automation. Selenium’s two-factor authentication guidance and WebDriver screenshot documentation describe these limits.

For an unspecified Indian portal, do not infer a universal OTP validity period, retry limit, resend behavior, or portal-specific trigger. Those details differ by service. For example, the Income Tax Department documents a particular notice-authentication flow with a six-digit OTP, a 15-minute validity period, three attempts, and a resend option. Those rules apply to that named flow, not to Indian portals generally. Income Tax Department notice-authentication help.

Diagnose the capture in order

  1. Identify the exact step visible in the screenshot. Record the current URL, page heading, and whether the page is a login form, OTP prompt, error, or authenticated landing page. Do not share OTP values, cookies, or session tokens in logs.
  2. Trace the script sequence. Check that the preceding login form was submitted and that the script did not take the screenshot immediately after clicking Sign in. A click can begin a navigation or reveal a challenge without completing the login.
  3. Wait for the expected state. For a success screenshot, wait for an element that only appears after authorized authentication, rather than relying on a fixed delay or merely waiting for the document to load.
  4. Handle the OTP through an authorized path. If a human must provide a factor, pause for that person or use a sanctioned test account/token. Do not try to evade an OTP or CAPTCHA on a third-party service.
  5. Capture and label the result accurately. Save an OTP-page screenshot as an authentication checkpoint or failure state, not as evidence of a successful login.

Runnable Selenium example: wait for the expected page

This Python example opens a login page, submits credentials supplied through environment variables, then waits for either an OTP checkpoint or a known authenticated element before taking a screenshot. Replace the example URL and selectors with values for a system you are authorized to test. If the portal requires a person to enter an OTP, the script detects the checkpoint and captures it; it does not bypass it.

import os
from pathlib import Path

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

LOGIN_URL = "https://example.test/login"
OTP_SELECTOR = "[data-testid='otp-challenge']"  # Replace with an authorized test selector.
SIGNED_IN_SELECTOR = "[data-testid='account-home']"  # Replace with a post-login selector.

username = os.environ["PORTAL_TEST_USERNAME"]
password = os.environ["PORTAL_TEST_PASSWORD"]

options = webdriver.ChromeOptions()
# Keep the browser visible if a person must complete an authorized OTP step.
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 20)

try:
    driver.get(LOGIN_URL)
    wait.until(EC.visibility_of_element_located((By.NAME, "username"))).send_keys(username)
    driver.find_element(By.NAME, "password").send_keys(password)
    driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()

    # Wait until either the OTP checkpoint or the authenticated page is visible.
    try:
        wait.until(lambda d: d.find_elements(By.CSS_SELECTOR, OTP_SELECTOR)
                   or d.find_elements(By.CSS_SELECTOR, SIGNED_IN_SELECTOR))
    except TimeoutException:
        Path("diagnostics").mkdir(exist_ok=True)
        driver.save_screenshot("diagnostics/login-timeout.png")
        raise RuntimeError("Neither OTP checkpoint nor signed-in page appeared")

    if driver.find_elements(By.CSS_SELECTOR, OTP_SELECTOR):
        Path("diagnostics").mkdir(exist_ok=True)
        driver.save_screenshot("diagnostics/otp-checkpoint.png")
        print("OTP is required; screenshot shows the pending checkpoint.")
    else:
        Path("diagnostics").mkdir(exist_ok=True)
        driver.save_screenshot("diagnostics/signed-in.png")
        print("Expected authenticated element is visible.")
finally:
    driver.quit()

Install Selenium with python -m pip install selenium. Selenium Manager can manage a compatible browser driver in supported setups; browser and driver availability still depend on the machine and environment. Keep credentials in a secret store or environment variables, and use a test account rather than a personal account.

Why wait for an element instead of sleeping?

A fixed sleep guesses how long navigation or authentication will take. It may be too short on a slow run and unnecessarily long on a fast one. An explicit wait ties the capture to an observable page condition. The condition must be meaningful: a generic page load or disappearance of a spinner does not prove that login completed.

Choose a safe approach for two-factor authentication

If you control the application and its test environment, Selenium lists several approaches for making automated tests manageable:

  • Ask the team to provide a dedicated test token.
  • Use designated test users for which 2FA is disabled, when that is acceptable under the team’s security policy.
  • Disable 2FA in a test environment isolated from production.
  • Use an IP-based exception for known test infrastructure, if the application team supports it.

These are options for a system and environment under your team’s control. They are not authorization to bypass another organization’s authentication. Decide whether testing the OTP factor itself is in scope; if it is, test the supported factor flow with the application owner’s approved method. If it is not, use a documented test configuration and keep the exception limited to test accounts or infrastructure.

Common errors and fixes

Symptom Likely cause What to do
Screenshot consistently shows the OTP page The session reached a second-factor checkpoint, or the screenshot is taken before that factor is completed. Wait for and identify the OTP state. Complete it only through an authorized flow, or use a team-approved test configuration.
Screenshot is sometimes OTP and sometimes signed in Session state or timing differs between runs; the script may not wait for a decisive condition. Start from a known test state, wait for OTP or a post-login element, and save separate outcomes.
Timeout waiting for the signed-in selector The selector may be wrong, the page may still be at OTP, or login may have failed for another reason. On timeout, capture diagnostics and inspect the current URL and visible page. Confirm selectors against the authorized test page.
Element lookup fails after sign-in The page may have navigated, rendered asynchronously, or placed content in a frame. Wait for the target condition after navigation; switch to the correct frame if the application uses one.
Headless run behaves differently Browser configuration, session state, or the portal’s handling of the session may differ between environments. Reproduce with the same test account and approved environment settings. Do not assume headless mode can or should avoid authentication.
OTP is expired or rejected The factor may be stale, mistyped, or subject to service-specific rules. Follow that portal’s official instructions or request a fresh factor through its supported flow. Do not assume another portal has the same validity or attempt limits.

Performance, reliability, and cost

For Selenium, the main practical cost is maintaining a browser, driver, and test environment, plus handling authentication state. Explicit waits usually make captures more reliable than arbitrary delays because the script proceeds when a relevant condition occurs. Reusing a session can reduce repeated login steps, but session reuse should be limited to controlled test accounts and managed carefully; session cookies are credentials.

OTP introduces an external dependency when delivery or human approval is involved. A test that depends on SMS, email, or a person can be slower and less deterministic. If the factor is the subject of the test, keep that coverage intentional and use the application’s approved test mechanism. If it is outside the test’s scope, a dedicated test token or isolated test configuration can avoid making every screenshot depend on a live factor.

Or skip the browser setup

If the task is to capture a page rather than test an authenticated login flow, ScreenshotNeo can take a screenshot with one GET request. It is a website screenshot API and MCP server from ScreenshotNeo. This does not log into a portal or complete an OTP challenge; capture only pages you are authorized to access. See the ScreenshotNeo API documentation for options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Cookie and consent banners are accepted and removed before capture, along with supported newsletter popups and chat widgets; each of those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server offers take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.

FAQ

Does taking a Selenium screenshot submit the OTP?

No. It captures the current browser display; authentication requires the portal’s authorized login flow.

Can Selenium automate OTP for every Indian portal?

There is no universal method or rule established here. OTP implementations vary, and Selenium cautions that routine 2FA automation is difficult to make consistent.

Can I disable OTP to make my test pass?

Only for a system and test environment you control, and only through an approved configuration. Selenium suggests options such as dedicated test tokens or designated test users.

Does ScreenshotNeo get past an OTP page?

No. ScreenshotNeo captures webpages; it does not authenticate to a portal or bypass an OTP checkpoint.