Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Start by identifying what “popup” means on the page. A JavaScript alert, confirm, or prompt is handled with Selenium’s alert API. An HTML modal is part of the page and uses normal element locators. A new tab or window needs a window-handle switch, while a popup inside an iframe needs a frame switch. Choosing the right context—and waiting for the matching state—is the key to reliable Selenium tests.

Classify the popup before interacting with it

Popups can look similar to a person while belonging to different parts of the browser or page. Selenium exposes different controls for each kind, so using the alert API on an HTML dialog, for example, will not work.

What appeared Where it lives How Selenium handles it
JavaScript alert, confirm, or prompt Browser dialog, outside the page DOM Wait for an alert and use its text, accept, dismiss, or input methods
HTML/CSS modal or overlay Page DOM Find and interact with its controls using ordinary locators
New tab or window Separate browsing context Wait for the new window handle and switch to it
Popup content in an iframe Nested browsing context within the page Switch into the frame, then locate its DOM elements

In Selenium’s terminology, the native JavaScript dialogs are alerts, confirms, and prompts. WebDriver can read their text and accept or dismiss them. The rest of this guide uses explicit waits so the test responds to the state it needs rather than relying on a guessed delay.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle a JavaScript alert, confirm, or prompt

Use EC.alert_is_present() to wait until a native dialog appears. The condition returns an alert object after switching WebDriver to it. You can then inspect the message and choose the appropriate action.

Accept an alert or confirm

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
alert = wait.until(EC.alert_is_present())
message = alert.text

assert "Continue?" in message
alert.accept()

accept() activates the dialog’s affirmative action, typically its OK button. For a plain alert, that closes the dialog. For a confirm, accepting may cause the application to continue down its positive branch. Read and assert the text when the message is part of what the test is verifying; otherwise, retaining it can still be useful for failure diagnostics.

Dismiss a confirm

alert = WebDriverWait(driver, 10).until(EC.alert_is_present())
alert.dismiss()

dismiss() chooses the cancel or negative action. A confirm usually produces different application behavior depending on whether it is accepted or dismissed, so test the branch your scenario intends rather than treating both actions as interchangeable.

Enter text in a prompt

alert = WebDriverWait(driver, 10).until(EC.alert_is_present())
alert.send_keys("sample response")
alert.accept()

A prompt has a text field. Send the value before accepting it. If your test also needs to validate what the page does with that value, assert the resulting page state after the dialog closes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A complete native-dialog example

This example assumes the page has already been opened and that clicking the relevant control triggers a JavaScript confirm. Replace the locator and expected message with those from your application.

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

wait = WebDriverWait(driver, 10)
original_url = driver.current_url

driver.find_element(By.ID, "delete-record").click()
alert = wait.until(EC.alert_is_present())
message = alert.text
assert "delete" in message.lower()
alert.accept()

wait.until(EC.url_changes(original_url))

The final wait is only an example of a post-action check: use the condition that reflects your application, such as a success message becoming visible, a row disappearing, or the URL changing. Closing the alert alone does not prove the intended application behavior occurred.

Handle an HTML or CSS modal

An HTML modal is ordinary page content, even if it visually blocks the rest of the page. Do not use driver.switch_to.alert for it. Locate its close button, confirmation button, or form fields with normal Selenium locators. If the modal is added asynchronously, wait for its controls to become visible or clickable before using them.

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

wait = WebDriverWait(driver, 10)

confirm = wait.until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, "[role='dialog'] button.confirm")
))
confirm.click()

wait.until(EC.invisibility_of_element_located(
    (By.CSS_SELECTOR, "[role='dialog']")
))

Use selectors that match the actual application; [role='dialog'] is not guaranteed to exist on every site. If the modal submits a form, fill its fields and wait for the expected result rather than assuming that clicking a button means the operation succeeded. Selenium’s expected conditions include visibility and clickability checks for synchronizing with page elements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle a popup that opens a new tab or window

A new tab is not a JavaScript alert. Record the current window handle before triggering it, wait for the window count to increase, switch to the new handle, and return to the original handle when finished.

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

wait = WebDriverWait(driver, 10)
original_handle = driver.current_window_handle
handles_before = set(driver.window_handles)

driver.find_element(By.LINK_TEXT, "Open details").click()
wait.until(EC.new_window_is_opened(handles_before))

new_handle = next(handle for handle in driver.window_handles
                  if handle not in handles_before)
driver.switch_to.window(new_handle)

# Work with the new tab or window here.
wait.until(EC.url_contains("details"))

# Return to the original browsing context.
driver.switch_to.window(original_handle)

If your scenario expects a known total number of windows, EC.number_of_windows_to_be(count) is another available condition. A set difference is useful when the test needs to identify which handle is new. Always switch explicitly before looking for elements in the new tab, and restore the original context before continuing on the parent page.

Handle popup content inside an iframe

When the popup’s controls are inside an iframe, Selenium must switch into that frame before locating them. After interaction, return to the top-level document with default_content().

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

wait = WebDriverWait(driver, 10)
frame = wait.until(EC.frame_to_be_available_and_switch_to_it(
    (By.CSS_SELECTOR, "iframe.payment-frame")
))

wait.until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, "button.confirm")
)).click()

driver.switch_to.default_content()

Use the frame locator that identifies the actual iframe in your page. If controls cannot be found despite appearing on screen, checking whether the content is framed is a useful diagnostic. Selenium searches the current browsing context, not every iframe automatically.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build reliable popup tests

  • Trigger the UI deliberately. Perform the click or other user action that causes the dialog, modal, tab, or frame to appear before waiting for it.
  • Wait for the state you need. Use alert presence for native dialogs, visibility or clickability for DOM controls, a window condition for a new context, and frame availability for an iframe.
  • Make the branch explicit. Choose accept, dismiss, or prompt input according to the behavior under test.
  • Restore context. Switch back to the original window or top-level document after working in another context.
  • Assert the result. Verify the application’s resulting state, not just that the popup disappeared.

A fixed sleep waits for a duration whether the popup appears quickly, slowly, or not at all. An explicit wait instead tests for the relevant condition and fails with a timeout if that state never occurs. Keep the timeout appropriate to your test environment, and make the condition as specific as the page allows.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common failures

“No alert present” or alert wait times out

The event may not be a native JavaScript dialog. Check whether it is an HTML modal, a new window, or a popup in a frame, and use the matching handling method. Also confirm that the action that triggers it actually ran before the wait begins.

Element cannot be found even though the modal is visible

The modal may be inside an iframe, or your test may still be switched to another window. Switch into the correct browsing context before finding the control. For an iframe, switch back to default_content() when the interaction is complete.

Click fails because the control is not ready

The modal may still be animating or the control may not yet be clickable. Wait for visibility or clickability rather than clicking immediately after navigation or opening the dialog. Check that the locator identifies the intended control in the current context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The popup closes, but the test still fails

Accepting or dismissing only handles the dialog action; it does not verify what the application did afterward. Add a wait for the expected page change, confirmation, or other result. For a confirm dialog, check that your choice matches the branch the test is meant to exercise.

Unexpected behavior from a before-unload prompt

Prompts shown while navigating away can behave differently from application-triggered alerts. Selenium documentation notes that recent drivers automatically dismiss beforeunload prompts by default; older behavior can be affected by the unhandledPromptBehavior capability. If a navigation test depends on that prompt, verify the behavior for the browser and driver versions used by your test setup rather than assuming every driver handles it identically.

Or skip the browser setup

If the job is to capture a page rather than test its interactive behavior, ScreenshotNeo provides a screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. Its capture options include accepting consent banners and removing more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. AI agents can use its MCP server tools, including take_screenshot, get_page_info, and capture_pdf.

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

See the ScreenshotNeo documentation for the API options and request details. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Sign up for ScreenshotNeo to try the free allowance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can Selenium click buttons in a native JavaScript alert?

No. Native dialogs expose alert operations such as accepting, dismissing, reading text, and entering prompt text; they are not page DOM buttons.

What should I use when a popup opens in a separate tab?

Wait for the new window handle, switch to it, and switch back to the original handle when finished.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.