Skip to main content
SeleniumDecoded

Handle an Unexpected Alert Without Failing

Configure the session to dismiss surprise alerts automatically, and accept or dismiss expected ones explicitly with a wait.

Stable Verified against Selenium 4.48.0

Problem

An onbeforeunload confirm or a stray alert() appears mid-test, and the next command throws UnexpectedAlertPresentException. In other tests you expect a confirm and must accept it, but it appears a beat after the click.

Solution

Set the W3C unhandledPromptBehavior capability to define what happens to alerts you did not plan for, and use an explicit wait for the ones you did.

Session policy plus explicit handling
Selenium 4 Stable
// Policy for unexpected dialogs: dismiss them and raise so you know it happened
ChromeOptions options = new ChromeOptions();
options.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
// Alternatives: ACCEPT, DISMISS, ACCEPT_AND_NOTIFY, IGNORE
WebDriver driver = new ChromeDriver(options);
// Expected confirm after an action
driver.findElement(By.id("delete-account")).click();
Alert confirm = new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.alertIsPresent());
assertEquals("Delete your account?", confirm.getText());
confirm.accept();
// Prompt with input
Alert prompt = driver.switchTo().alert();
prompt.sendKeys("DELETE");
prompt.accept();
options = webdriver.ChromeOptions()
options.unhandled_prompt_behavior = "dismiss and notify"
# Alternatives: "accept", "dismiss", "accept and notify", "ignore"
driver = webdriver.Chrome(options=options)
driver.find_element(By.ID, "delete-account").click()
confirm = WebDriverWait(driver, 5).until(EC.alert_is_present())
assert confirm.text == "Delete your account?"
confirm.accept()
prompt = driver.switch_to.alert
prompt.send_keys("DELETE")
prompt.accept()
const options = new chrome.Options().setUserPreferences({});
// unhandledPromptBehavior is a top-level W3C capability
const driver = await new Builder().forBrowser('chrome')
.withCapabilities({ browserName: 'chrome', unhandledPromptBehavior: 'dismiss and notify' })
.setChromeOptions(options).build();
await driver.findElement(By.id('delete-account')).click();
await driver.wait(until.alertIsPresent(), 5000);
const confirm = await driver.switchTo().alert();
assert.strictEqual(await confirm.getText(), 'Delete your account?');
await confirm.accept();
var options = new ChromeOptions { UnhandledPromptBehavior = UnhandledPromptBehavior.DismissAndNotify };
var driver = new ChromeDriver(options);
driver.FindElement(By.Id("delete-account")).Click();
var confirm = new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(d =>
{
try { return d.SwitchTo().Alert(); } catch (NoAlertPresentException) { return null; }
});
Assert.That(confirm.Text, Is.EqualTo("Delete your account?"));
confirm.Accept();

Why It Works

unhandledPromptBehavior is part of the W3C session capabilities, so the driver handles surprise dialogs before your next command runs; the and notify variants still throw so the event is visible in logs. alertIsPresent polls for the dialog, covering the gap between a click and the dialog appearing.

Gotchas

  • onbeforeunload dialogs are suppressed by Chrome unless the user interacted with the page; tests that navigate away immediately after load may never see them.
  • Never leave an alert open across a screenshot call; screenshots fail while a dialog is showing.
  • Firefox and Safari implement the same capability; the option setter name differs per binding.

Learn the theory