0

There are several other questions like this one (ie. questions about alert in Selenium) for non-Javascript versions of WebDriver. In the answers for those questions, the general pattern recommended is:

try {
    doSomethingWhichCausesAnAlert();
} catch(UnexpectedAlertOpenError e) {
    doSomethingAboutException(e);
}

However, I can't copy that pattern in the Javascript version, because everything is asynchronous:

try {
    doSomethingWhichCausesAnAlert();
} catch(e) {
    // this will never get reached
}
// 1ms or more later the alert appears, causing an exception

I thought perhaps I could use a .catch:

el.sendKeys('invalid keystrokes that cause an alert')
  .catch((e) => doSomethingWithException(e))

but that doesn't work either; it seems like the alert exception happens after that catch has resolved.

TLDR

How can I catch alert exceptions (and then do something about the alert) when they all seem to happen outside the context of my code?

By the way, here's an example stack trace of an alert exception:

UnexpectedAlertOpenError: unexpected alert open: {Alert text : Please enter a valid number ("not a number" is not a number).}
   (Session info: chrome=53.0.2785.116)
   (Driver info: chromedriver=2.23.409687 (c46e862757edc04c06b1bd88724d15a5807b84d1),platform=Linux 4.4.0-21-generic x86_64)
     at WebDriverError (/home/me/project/node_modules/selenium-webdriver/lib/error.js:27:5)
     at UnexpectedAlertOpenError (/home/me/project/node_modules/selenium-webdriver/lib/error.js:274:5)
     at Object.checkLegacyResponse (/home/me/project/node_modules/selenium-webdriver/lib/error.js:512:13)
     at parseHttpResponse (/home/me/project/node_modules/selenium-webdriver/lib/http.js:396:13)
     at doSend.then.response (/home/me/project/node_modules/selenium-webdriver/lib/http.js:328:11)
     at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: WebDriver.manage().deleteAllCookies()
     at Driver.schedule (/home/me/project/node_modules/selenium-webdriver/lib/webdriver.js:414:17)
     at Options.deleteAllCookies (/home/me/project/node_modules/selenium-webdriver/lib/webdriver.js:1178:25)
     at World.<anonymous> (/home/me/project/test/cucumber/features/support/Hooks.js:23:37)
     at _combinedTickCallback (internal/process/next_tick.js:67:7)

As you can see, the only part of my code that's even involved is my Hooks.js file, which causes the error when it tries to call:

this.driver.manage().deleteAllCookies();

to clean up the cookies in a this.After (obviously After the test completes it's too late for me to do anything about the alert).

P.S. I found a hacky way to at least confirm that an alert is present before After is triggered: if I call this.driver.manage().deleteAllCookies() in a step after the alert appears, it will cause the exception to occur. However, A) I don't want to delete cookies just to detect an alert, and B) I still have no way of actually closing the alert.

1 Answer 1

2

As the founders of Stack Overflow are fond of saying, I should have just "read the source Luke!" When I did I was able to work backwards and eventually figure out the JS pattern, which is:

// in a step or logic that goes off after the alert appears

this.driver.switchTo().alert().then((alert) => alert.dismiss());

Hope this helps other JS/Selenium users.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.