QA How-To
How to Fix Selenium UnexpectedAlertOpenException
Fix Selenium UnexpectedAlertOpenException by handling native alerts, timing delayed prompts, choosing confirm actions, and checking CI and Grid behavior.
22 min read | 3,195 words
TL;DR
Wait for a native alert right after its triggering action, assert its text, then accept or dismiss it before the next WebDriver command. For surprise dialogs, record their text and investigate the app state; use unhandledPromptBehavior only as a deliberate fallback.
Key Takeaways
- Handle an expected native alert immediately after the action that creates it.
- Use alert_is_present instead of sleeps for dialogs created after a delay.
- Assert the confirm or prompt result, not just that the dialog disappeared.
- Treat unexpected alert text as evidence of an application or test setup failure.
- Choose unhandledPromptBehavior intentionally; notify policies can still raise errors.
- Isolate browser sessions and verify effective capabilities on Selenium Grid.
If you need to fix Selenium UnexpectedAlertOpenException, the failure appears when WebDriver sends a command while a native JavaScript dialog is open. The click that opened the dialog may succeed; the next element lookup, navigation, or screenshot is often the line that fails.
selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: Session expired
Message: unexpected alert open
The alert text above is an illustrative application message. Python names the exception UnexpectedAlertPresentException; Java names it UnhandledAlertException. Both represent the protocol error unexpected alert open. The repair is to find the action that opened the prompt, decide whether it was expected, and handle it before the next ordinary WebDriver command. Selenium's browser alert documentation describes native alert, confirm, and prompt behavior.
TL;DR
Wait for the native dialog immediately after its trigger, check the message, and choose the response that matches the scenario:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
# driver and trigger are existing WebDriver and clickable WebElement objects.
trigger.click()
alert = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert alert.text == "Saved"
alert.accept()
A delayed dialog needs the same explicit wait, not a sleep. A confirm that tests Cancel needs dismiss(), not accept(). If the text says "Session expired" or reports an application error, record it and fix the underlying condition rather than letting a global prompt policy hide it. The Selenium alert guide covers the API details.
What the Error Actually Means
WebDriver treats window.alert, window.confirm, and window.prompt as modal user prompts. While one is open, a normal page command cannot proceed. The remote driver applies the session's unhandledPromptBehavior capability and may return unexpected alert open with the prompt text. The WebDriver specification defines the error, and Selenium's Python exception reference documents its binding-level name.
The default policy is dismiss and notify. The driver can dismiss an unhandled prompt and still raise an exception. That explains a confusing follow-up: catching UnexpectedAlertPresentException and then calling driver.switch_to.alert may raise NoAlertPresentException because the dialog is already gone. NoAlertPresentException also occurs when the test tries to switch before a delayed dialog appears. Locate the action and the current prompt state before choosing a fix.
A browser permission request, HTTP Basic Auth challenge, and in-page HTML modal are separate UI surfaces. A regular <div role="dialog"> is in the DOM and should be tested with locators. A native JavaScript prompt is accessed through Selenium's Alert API. For authentication challenges, use the authentication popup guide rather than applying switch_to.alert blindly.
Root-Cause Decision Table
| Symptom | Root cause | Fix |
|---|---|---|
A Save or Delete click is followed by unexpected alert open |
Expected native alert was skipped | Wait for it, assert text, then accept or dismiss |
| CI fails intermittently after a click | Timer or callback creates a delayed prompt | Use EC.alert_is_present() after the trigger |
| Cancel test deletes an item | Confirm or prompt handled with the wrong choice | Choose dismiss() for Cancel and assert the result |
| Dialog reports expired session or validation failure | Application produced an error alert | Capture text and investigate the app state |
| The exception occurs although the dialog disappeared | Default dismiss and notify policy acted |
Handle expected prompts explicitly; inspect the policy |
| A later test fails at its first command | Prior test leaked a prompt or reused a session | Isolate driver sessions and close each dialog |
| Only a remote Grid run fails | Node timing or capability differs | Run a focused alert test and inspect returned capabilities |
The exception line may be one command later than the actual cause. Read the preceding action, application event, and dialog text before changing a timeout. The Expected Conditions guide for Python helps when the dialog's appearance varies with timing.
1. Fix Selenium UnexpectedAlertOpenException After an Expected Alert
Set up a small reproduction that needs no application server. Install Selenium in a virtual environment, and ensure Chrome can launch. Modern Selenium uses Selenium Manager to find a matching driver in common local setups; restricted CI images may need browser and driver provisioning. Use your project's selected package version rather than copying an arbitrary pin.
python3 -m venv .venv
. .venv/bin/activate
python -m pip install selenium
python -m pip show selenium
Save this shared helper as alert_lab.py. Every later example imports page and make_driver with these exact signatures. The data: URL supplies deterministic HTML, and headless Chrome still exposes native dialogs to WebDriver.
# alert_lab.py
from urllib.parse import quote
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def page(markup: str) -> str:
return "data:text/html;charset=utf-8," + quote(markup)
def make_driver(prompt_behavior: str | None = None):
options = Options()
options.add_argument("--headless=new")
if prompt_behavior is not None:
options.unhandled_prompt_behavior = prompt_behavior
return webdriver.Chrome(options=options)
Save the next block as fix_expected_alert.py. The button creates a real native alert. Reading the paragraph only after accepting the prompt proves an ordinary command works again.
# fix_expected_alert.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from alert_lab import make_driver, page
driver = make_driver()
try:
driver.get(page('''<button id="save" onclick="alert('Saved')">Save</button>
<p id="status">Ready</p>'''))
driver.find_element(By.ID, "save").click()
alert = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert alert.text == "Saved"
alert.accept()
assert driver.find_element(By.ID, "status").text == "Ready"
print("Expected alert handled")
finally:
driver.quit()
Verify with python fix_expected_alert.py; expect Expected alert handled. The five-second wait is an illustrative local budget. The key is its placement directly after Save. If the alert's text signals a failure instead of success, leave the test failing with that message. Do not accept an error and report that the business flow passed. Java teams use ExpectedConditions.alertIsPresent() with WebDriverWait and the same order of operations; see Expected Conditions in Java.
2. Fix Selenium UnexpectedAlertOpenException Caused by a Delayed Dialog
A click can schedule an alert through a timer or a response callback. The click returns before the prompt exists, then the prompt opens while a later command is running. That is why a test may pass on one computer and fail on a busy CI worker. A fixed sleep(1) only moves the race and spends a full second even when the dialog appears immediately. Wait for the specific browser condition instead.
Save this as fix_delayed_alert.py. Its button schedules an alert after a short delay, while the test waits up to five seconds. The code imports the helper from section 1 unchanged.
# fix_delayed_alert.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from alert_lab import make_driver, page
driver = make_driver()
try:
driver.get(page('''<button id="sync" onclick="setTimeout(() => alert('Sync complete'), 300)">Sync</button>
<p id="status">Waiting</p>'''))
driver.find_element(By.ID, "sync").click()
alert = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert alert.text == "Sync complete"
alert.accept()
assert driver.find_element(By.ID, "status").text == "Waiting"
print("Delayed alert handled")
finally:
driver.quit()
Run python fix_delayed_alert.py; expect Delayed alert handled. If the wait times out, confirm the application actually created a native alert. An HTML toast, in-page dialog, or failed network request will not satisfy alert_is_present(). Increase the wait only when measured application timing justifies it. Avoid sprinkling alert waits into unrelated test setup because they mask which action should have opened the dialog and add unnecessary delay to tests with no prompt.
For an application whose alert follows an API response, record the request result and alert text together. A "Saved" dialog and a "Could not save" dialog are different outcomes even if both can be accepted. Keep the message assertion so the test tells them apart. The CI flaky test guide covers broader timing evidence, but this alert wait belongs next to the action that schedules the browser prompt.
3. Choose the Correct Confirm or Prompt Response
The three native dialog types share an Alert API but express different user decisions. window.alert() has a single acknowledgment. window.confirm() returns true for OK and false for Cancel. window.prompt() returns the entered text after OK, or null after Cancel. If a test always calls accept(), it may delete an item while claiming to test cancellation. If it fails to send prompt text, it may submit an empty name. Check the application result after closing the dialog.
Save this block as fix_confirm_prompt.py. It exercises two branches in one fresh browser session: Cancel on a delete confirmation, then text entry on a rename prompt.
# fix_confirm_prompt.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from alert_lab import make_driver, page
driver = make_driver()
try:
driver.get(page('''<button id="delete" onclick="document.querySelector('#result').textContent = confirm('Delete item?') ? 'deleted' : 'kept'">Delete</button>
<button id="rename" onclick="document.querySelector('#result').textContent = prompt('New name?')">Rename</button>
<p id="result">unchanged</p>'''))
driver.find_element(By.ID, "delete").click()
confirm = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert confirm.text == "Delete item?"
confirm.dismiss()
assert driver.find_element(By.ID, "result").text == "kept"
driver.find_element(By.ID, "rename").click()
prompt = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert prompt.text == "New name?"
prompt.send_keys("Updated item")
prompt.accept()
assert driver.find_element(By.ID, "result").text == "Updated item"
print("Confirm and prompt branches passed")
finally:
driver.quit()
Verify with python fix_confirm_prompt.py; expect Confirm and prompt branches passed. To test OK on the delete confirmation, accept it and assert deleted instead. Do not verify only that the prompt vanished; both OK and Cancel close it. In a real app, assert the persisted record, message, or navigation outcome that the choice controls. Use isolated test data for destructive confirmation paths.
send_keys() applies to a text prompt, not to a simple alert or confirm. Attempting to type into a dialog that has no input is a different error. Also distinguish a browser prompt from an HTML modal: buttons rendered by React or another framework belong to the page DOM and should be found by normal locators. Selenium's alert interaction reference shows the supported operations for each native type.
4. Investigate an Alert the Test Did Not Expect
An unexpected dialog may report a real application failure: expired authentication, rejected input, unavailable service, or a server error. If the test's next command raises an alert exception, read the dialog message before changing waits. Blindly accepting it can let a checkout, upload, or save test proceed after the operation actually failed. Capture the preceding action, message, and application state in the test report.
For a diagnostic reproduction, request the ignore prompt policy when the session starts. This leaves the dialog open when an ordinary command encounters it. The code below catches the resulting exception, reads optional protocol text, then reads the live prompt and closes it. Save it as diagnose_unexpected_alert.py.
# diagnose_unexpected_alert.py
from selenium.common.exceptions import UnexpectedAlertPresentException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from alert_lab import make_driver, page
driver = make_driver("ignore")
try:
driver.get(page('''<button id="submit" onclick="alert('Session expired')">Submit</button>
<p id="result">No submission</p>'''))
driver.find_element(By.ID, "submit").click()
try:
driver.find_element(By.ID, "result")
raise AssertionError("Expected an unexpected-alert error")
except UnexpectedAlertPresentException as error:
print("WebDriver reported:", error.alert_text)
alert = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert alert.text == "Session expired"
alert.dismiss()
assert driver.find_element(By.ID, "result").text == "No submission"
print("Unexpected alert diagnosed")
finally:
driver.quit()
Verify with python diagnose_unexpected_alert.py; expect the message and Unexpected alert diagnosed. The protocol's text field is optional, so error.alert_text may be None on another driver. This example can still read the dialog because it explicitly requested ignore. Under the default dismiss and notify policy, the alert may already be gone when the handler runs. The Python exception source documents alert_text.
In a real suite, use Selenium debugging in VS Code to stop before Submit and inspect why the application emits the dialog. If the session is expired, refresh the test's login setup. If the alert says validation failed, examine the submitted data and response. If the behavior is a product defect, fail with that message. Accepting an error prompt is only cleanup; it does not make the business action successful.
5. Set an Intentional Unhandled Prompt Policy
unhandledPromptBehavior is a WebDriver session capability. Supported values are dismiss, accept, dismiss and notify, accept and notify, and ignore. The and notify variants handle the prompt and still return an error. Plain accept or dismiss can let the command continue. ignore keeps the dialog open for explicit handling. These meanings come from the Selenium browser options guide and the WebDriver prompt handler definition.
Save verify_prompt_policy.py to inspect the effective capability and demonstrate a harmless automatic acknowledgment. Use this only if accepting every unhandled prompt in that session is the intended policy. An unexpected Delete confirmation or validation alert makes automatic accept a poor default.
# verify_prompt_policy.py
from selenium.webdriver.common.by import By
from alert_lab import make_driver, page
driver = make_driver("accept")
try:
assert driver.capabilities["unhandledPromptBehavior"] == "accept"
driver.get(page('''<button id="notice" onclick="alert('Informational notice')">Notice</button>
<p id="status">Page usable</p>'''))
driver.find_element(By.ID, "notice").click()
assert driver.find_element(By.ID, "status").text == "Page usable"
print("Prompt policy:", driver.capabilities["unhandledPromptBehavior"])
finally:
driver.quit()
Run python verify_prompt_policy.py; expect Prompt policy: accept. For a remote session, print the returned capabilities rather than assuming the requested policy was applied. Java callers can configure ChromeOptions#setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.ACCEPT) when the policy is deliberate; the Selenium driver session guide shows that API. The setting is selected at session creation, so changing a test variable after the driver starts does not reconfigure it.
beforeunload prompts deserve separate investigation. They appear around navigation away from unsaved work and have browser-specific handling. Current Selenium documentation notes special ChromeDriver conditions involving ignore and BiDi for keeping such a prompt open. Do not assume a global accept policy tests the Cancel branch. Save or discard through the application UI before navigating when that is the user workflow you intend to verify.
6. Isolate Sessions in CI and Selenium Grid
A reused WebDriver instance can carry a prompt from one test into another. The next test may fail on its first driver.get() even though it never clicked the button that opened the dialog. Parallel workers increase confusion if they share the same browser session or mutable account. Give each test an independent session where practical, and put the alert assertion inside the test that triggered it.
Save test_alert_isolation.py. It runs against local Chrome by default, or a remote Grid when SELENIUM_REMOTE_URL is set. Each unittest creates and quits its own session, so the clean branch cannot inherit the alert branch's state.
# test_alert_isolation.py
import os
import unittest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from alert_lab import page
class AlertIsolationTests(unittest.TestCase):
def setUp(self):
options = Options()
options.add_argument("--headless=new")
remote_url = os.environ.get("SELENIUM_REMOTE_URL")
self.driver = (webdriver.Remote(command_executor=remote_url, options=options)
if remote_url else webdriver.Chrome(options=options))
self.driver.get(page('''<button id="open" onclick="alert('One test only')">Open</button>
<p id="ready">Ready</p>'''))
def tearDown(self):
self.driver.quit()
def test_alert_branch(self):
self.driver.find_element(By.ID, "open").click()
alert = WebDriverWait(self.driver, 5).until(EC.alert_is_present())
self.assertEqual(alert.text, "One test only")
alert.accept()
self.assertEqual(self.driver.find_element(By.ID, "ready").text, "Ready")
def test_clean_branch(self):
self.assertEqual(self.driver.find_element(By.ID, "ready").text, "Ready")
if __name__ == "__main__":
unittest.main()
Verify locally with python -m unittest -v test_alert_isolation.py; expect two passing tests. In CI, run this small check before the broad suite. To test a running Grid from the host, use SELENIUM_REMOTE_URL=http://127.0.0.1:4444 python -m unittest -v test_alert_isolation.py. Probe the endpoint first with curl -fsS http://127.0.0.1:4444/status. The Selenium Grid quick start documents the URL and status endpoint.
For a Docker reproduction, choose a published Selenium standalone Chrome image tag that matches your selected Selenium release. Replace the placeholder after checking the project's version; do not copy a guessed number. Run this in one terminal and the status probe plus remote test in another:
docker run --rm -p 4444:4444 --shm-size=2g selenium/standalone-chrome:<your-selenium-image-tag>
The Docker for Selenium Grid guide covers a larger setup. If the Python test runs inside another Compose service, 127.0.0.1 points to that service, so use Grid's service hostname and internal port instead. Compare driver.capabilities on local and remote sessions if prompt behavior differs. A Grid endpoint does not change the rule: the test that creates a native dialog must assert and resolve it before its next page command.
When the failure appears only in a parallel run, identify the test and browser session ID in the report before changing code. Two workers using separate drivers can still share the same application account, so one worker may log out while another is submitting a form. The resulting "Session expired" alert is an application-state collision, not a WebDriver timing defect. Give workers separate accounts or records, then rerun the failing pair together. If the alert disappears under isolated data but not under a longer wait, the shared state was the cause. This distinction matters because a blanket accept would make the interference harder to detect.
If the remote browser is inside a container, also check whether your application URL is reachable from that container. An app outage can produce a native error dialog after a fetch fails, but the dialog itself is only the visible consequence. Probe the application endpoint from the browser network, inspect its response, and keep the alert assertion tied to the user action. Do not assume the Grid status endpoint proves the tested application is healthy.
How to Verify the Fix
Run the focused script for the root cause you identified, then repeat the exact application test that failed. The examples check the alert message and a normal page command after closing it; the confirm example also checks the selected business branch. Those assertions demonstrate more than merely suppressing an exception.
python fix_expected_alert.py
python fix_delayed_alert.py
python fix_confirm_prompt.py
python diagnose_unexpected_alert.py
python verify_prompt_policy.py
python -m unittest -v test_alert_isolation.py
Run from the directory containing alert_lab.py, with the virtual environment active and Chrome available. In the original suite, record the prompt text, the preceding action, the chosen response, and the resulting page or backend state. Repeat in the same browser and CI environment that exposed the error. If unexpected alert open changes into a failed business assertion, keep that assertion; you have uncovered a different defect. If it changes into NoAlertPresentException, check whether you switched too early or whether the default prompt policy already dismissed the dialog.
Avoid taking a screenshot while the prompt is still open. Screenshot capture is another ordinary WebDriver command and can fail for the same reason. Handle the dialog, then capture the page state. For a surprise prompt, log the exception's optional alert_text first and use ignore only when you deliberately need the live dialog for diagnosis. A retry should restart from known application state, not continue after half of a workflow was interrupted.
Prevent It From Coming Back
Place expected prompt handling inside the page-object method that performs the triggering action. A cancel_delete() helper should click Delete, assert the confirmation text, dismiss it, and verify the record remains. A confirm_delete() helper should accept and verify removal. These names make the intended branch visible to callers. Do not hide a global accept in test setup, where it can silently approve a destructive action or dismiss an application failure.
Give unrelated tests separate browser sessions and always call quit() during teardown. For a shared-session suite, document ownership of dialogs and assert that each workflow leaves the browser usable before handing it off. Keep unhandledPromptBehavior explicit if the suite depends on it, and inspect the returned capability on remote nodes. Review alert code when an application replaces a native browser prompt with an HTML dialog, since the correct API changes to DOM locators.
After a browser or driver upgrade, run a small native alert smoke test in each supported browser family. Prompt timing and navigation behavior, especially around beforeunload, can vary. Include the alert message, effective capabilities, last action, and Grid node in intermittent failure reports. Those details distinguish an application error from a race or leaked session. The Selenium flaky test debugging guide provides wider CI triage patterns.
Interview Questions and Answers
Q: Why can the exception point to a line after the click?
The click may open the dialog successfully. The next command that tries to interact with the page meets the modal prompt and fails. I inspect the action immediately before the failed line and handle the prompt there.
Q: What distinguishes a native alert from an HTML modal?
A JavaScript alert is a browser prompt accessed with Selenium's Alert API. An HTML modal is part of the DOM and needs element locators. I inspect the UI implementation before choosing the API.
Q: Why might an exception handler find no alert?
The default dismiss and notify policy may close the prompt before reporting the error. I capture the optional exception text and handle expected alerts before ordinary commands. I use ignore only when I intentionally need the prompt to remain open.
Q: How do you test a confirm's Cancel branch?
I wait for the confirm, assert its text, call dismiss(), and verify the application kept the item. The final assertion distinguishes Cancel from merely closing the dialog.
Q: When is ignore useful?
It preserves an unexpected prompt so I can inspect its live text. The test must then close it before further page commands. I avoid using it as a blanket production policy for every test.
Q: How do you diagnose a Grid-only failure?
I run a minimal alert test against the same remote endpoint, inspect returned capabilities, and compare the dialog sequence with local Chrome. I also check session isolation so another test cannot leave a prompt behind.
Common Mistakes
- Catching
UnexpectedAlertPresentExceptionand continuing without reading the application message. - Calling
switch_to.alertafter a default-policy exception when the driver has already dismissed the prompt. - Replacing an alert wait with a fixed sleep that remains timing-sensitive in CI.
- Accepting a confirm meant to test Cancel and failing to assert the resulting application state.
- Searching for a native alert with CSS selectors or using Alert APIs against an HTML modal.
- Reusing one driver across unrelated tests without clearing prompts and isolating test data.
- Changing page-load or implicit waits when the missing step is a prompt response.
- Setting plain
acceptglobally and hiding authentication, validation, or service errors. - Assuming a requested prompt capability applied to a remote session without checking returned capabilities.
Conclusion
To fix Selenium UnexpectedAlertOpenException, find the action that created the native dialog, wait for it, assert its message, and choose the response that matches the scenario. Treat a surprise alert as evidence of an application or setup problem. Run both a focused alert reproduction and the original failing workflow in the same browser environment to verify the exception and the underlying behavior are repaired.
Interview Questions and Answers
How would you triage UnexpectedAlertPresentException?
I inspect the action before the failed command, since it often opened the dialog. I capture the prompt text or optional exception alert_text, then decide whether the dialog was expected. I explicitly handle an expected prompt or investigate the application error that created an unexpected one.
What does the protocol error unexpected alert open mean?
A modal user prompt was present when an ordinary WebDriver command arrived. The driver applies its unhandled prompt policy and may return the error with optional prompt text. Python and Java expose different exception class names for it.
How do you avoid a race with an asynchronous alert?
I wait on EC.alert_is_present immediately after the triggering action, with a bounded timeout. I avoid fixed sleeps because callback timing varies across machines. After handling the prompt, I assert the resulting page state.
Why can an exception handler find no alert?
With dismiss and notify, the driver can close the prompt while returning the error. I use optional exception text for diagnostics and move expected prompt handling before page commands. I use ignore only when I deliberately need the prompt preserved.
How do you validate a cancellation confirmation?
I click the action, wait for the confirm, assert its message, call dismiss, and verify the item remains. That final assertion distinguishes the correct Cancel branch from merely closing a dialog.
What does unhandledPromptBehavior accept and notify do?
It accepts an unhandled prompt and still reports an unexpected alert error to the client. Plain accept handles the prompt without that notification. Neither policy replaces an assertion about an expected dialog's text and effect.
How would you diagnose a Grid-only alert failure?
I run a minimal alert test against the same remote endpoint and inspect returned capabilities. I compare the dialog text and action order with the local run. I also ensure every test owns its WebDriver session so another test cannot leave a prompt open.
Frequently Asked Questions
What does Selenium's unexpected alert open error mean?
A native browser prompt was present when WebDriver received a command that did not handle prompts. Python surfaces this as UnexpectedAlertPresentException, while Java uses UnhandledAlertException. Inspect the action before the failed command to find the trigger.
How do I wait for an alert in Selenium Python?
Use WebDriverWait(driver, timeout).until(EC.alert_is_present()) immediately after the action that opens it. The condition returns an Alert object. Check its text, then accept or dismiss it.
Why does Selenium say no alert is present after UnexpectedAlertPresentException?
The default dismiss and notify policy may dismiss the prompt before reporting the exception. By the time the handler switches to it, nothing remains. Handle expected prompts before the next page command.
What is the difference between accept and dismiss for a confirm?
Accept selects OK and dismiss selects Cancel. Verify the resulting application state, such as whether a record remains. For a text prompt, send the value before accepting.
Can unhandledPromptBehavior fix every unexpected alert?
No. It is a session fallback, not an assertion about the prompt's meaning. Plain accept can hide an application error, while accept and notify still returns an error. Expected dialogs deserve explicit handling.
Why does the alert error happen only in CI or Selenium Grid?
Different callback timing, a reused browser session, or a different remote capability can expose a missing alert step. Run a focused alert test in that environment and inspect returned capabilities and session ownership.
Does switch_to.alert handle an HTML modal?
No. It handles native JavaScript alerts, confirms, and prompts. An HTML modal lives in the page DOM and should be tested with element locators and clicks.
Related Guides
- How to Fix "Cypress failed to start" and cypress verify Errors
- How to Fix "Playwright Test did not expect test() to be called here"
- How to Fix Appium WebDriverAgent Failed to Start on iOS
- How to Fix Cypress "cy.visit() failed trying to load"
- How to Fix Playwright "Element is not attached to the DOM"
- How to Fix Playwright locator resolved to hidden element