简体   繁体   中英

How Can I Handle Alerts In Selenium's Javascript Web Driver?

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 ).

PS 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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM