3

When trying to check if an alert is present, I call an extension method on IWebDriver called AlertIsDisplayed which is this:

try
{
    Driver.Instance.SwitchTo().Alert();

    return true;
}
catch (NoAlertPresentException)
{
    return false;
}
finally
{
    Driver.Instance.SwitchTo().DefaultContent();
}

However, due to the fact I am catching an exception, this is quite costly taking 2-3 seconds to return a result. With this being used in hundreds of tests it adds up to several minutes of extra execution time.

So in order to speed it up I tried changing the same method to this:

return ExpectedConditions.AlertIsPresent()(driver) != null;

Where driver is the IWebDriver the extension method was called on.

However, this takes the same amount of time. Looking at the source code of ExpectedConditions.AlertIsPresent reveals why - it is exactly what I was doing before, but just in a wrapper..

I have set my ImplicitWait to 0.

This is running on Selenium version 2.53.1. My driver is an EventFiringWebDriver with a WrappedDriver of FirefoxDriver. The Firefox version this is running on is 47.0.1.

Are there any alternatives to checking if an alert is present which take less time?

FLSH
  • 343
  • 1
  • 5
  • 15
  • Which driver and version are you using? Some of the drivers have an implicit wait time to switch to an alert. – Florent B. Nov 02 '16 at 10:42
  • Attributing this behavior merely to exception handling is misguided. It's possible that the delay is due to the driver for the browser you're using. For example, at one point, there was a hard-coded sleep switching to alerts in the open-source Firefox driver (the driver itself, not the language bindings) because there was no guarantee that the alert would be fully drawn by the window manager. Yes, a 2-3 second delay is bad, but let's not jump to conclusions about its cause, incorrectly blaming it on exception handling. – JimEvans Nov 02 '16 at 12:27
  • you can refer this like, in case helpful: http://stackoverflow.com/questions/14737095/webdriver-how-to-verify-if-an-alert-is-present – Priya P Nov 02 '16 at 13:30
  • @JimEvans I've updated the original question with version information, thanks. – FLSH Nov 02 '16 at 14:06
  • Can you try using javascript to detect if an alert is present with javascript executor? --- http://stackoverflow.com/questions/4866986/detect-if-an-alert-or-confirm-is-displayed-on-a-page – Grasshopper Nov 02 '16 at 14:21
  • @FLSH Using the legacy open-source Firefox driver, it's pretty easy [to see](https://github.com/SeleniumHQ/selenium/blob/master/javascript/firefox-driver/js/firefoxDriver.js#L51) that the 2 second delay is still there. It's likely that other browsers (Chrome, IE, etc.) will not suffer from the same delay. I've provided an answer to this question fleshing out the detail, and the theory behind the design of the API. – JimEvans Nov 02 '16 at 18:56

2 Answers2

1

The short answer is, "No, there is no way to avoid a 2-second delay in determining that an alert is not present, when using the legacy Firefox driver."

The longer answer is that the philosophy of the WebDriver API is that you should always know the state of the page you are automating. Once you ask the API to interact with the browser in a certain way, you should know what is the expected state of the page after that interaction. Thus, switching to an alert is something you would do only in the case where you expect an alert to be present. Attempting to switch to an alert with no alert present is an exceptional condition, and therefore an exception is correctly (according to the philosophy of the API) thrown.

In the specific case of the legacy Firefox driver, it is impossible to tell whether the window manager has fully drawn the alert, so it hard-codes a two-second sleep for locating that an alert is present. Note that the legacy Firefox driver has the requirement that it work cross-platform, so the fact that Windows may not require this delay is not a justification for removing it. Moreover, this legacy driver is deprecated, and will not work with any version of Firefox 48 and higher.

The good news is that other browser drivers should not have this limitation, so they should not suffer from this type of delay. It should also be pointed out that the next iteration of the Firefox driver (code-named Marionette, created and maintained by Mozilla, and the required mechanism for automating Firefox for versions 48 and above) is also likely not to suffer from this type of delay.

Community
  • 1
  • 1
JimEvans
  • 27,201
  • 7
  • 83
  • 108
  • Hi Jim, thanks very much for your answer. What I'm understanding from this is that there currently isn't a way to avoid the delay whilst using Firefox and I should wait for the Marionette driver. Is that correct? – FLSH Nov 03 '16 at 12:01
  • Either that, or restructure your code so you're not unnecessarily looking for an alert that isn't there. I apologize that my answer wasn't clear on that point. As a side note, you can use Marionette today, though there are a few pieces of functionality that Mozilla has yet to implement. – JimEvans Nov 03 '16 at 12:21
0

Expected Conditions (Explicit Waits): Write your own expected condition.

    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(1));
    IWebElement myDynamicElement = wait.Until(ExpectedConditions.AlertIsPresent());

Here, keep TimeSpan.FromSeconds(1) to wait only for one second (or 0.5 seconds as per you requirement). please change the code as per your requirement (I don't have knowledge in C#). The key point is how much time does webdriver waits to check for the expected condition to be true.

References:

  1. http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
Naveen Kumar R B
  • 6,248
  • 5
  • 32
  • 65
  • Where did you get that `driver.Manage().Timeouts().ImplicitlyWait` has an impact on switching to an alert? – Florent B. Nov 02 '16 at 12:09
  • Though I did not try practically, somewhere I read alerts are part of DOM level 0. so thought implicit_wait may have an effect on alerts. http://stackoverflow.com/questions/10166330/are-the-alert-and-confirm-functions-built-into-javascript-or-are-they-part-of-t. correct me if I am wrong. – Naveen Kumar R B Nov 02 '16 at 12:35
  • @FLSH, please try out and let us know whether implicit waits are working for you (in case of alerts). – Naveen Kumar R B Nov 02 '16 at 12:36
  • I'm inclined to say that it has no effect. The spec says that the implict wait applies to web elements only: https://www.w3.org/TR/webdriver/#dfn-session-implicit-wait-timeout – Florent B. Nov 02 '16 at 12:51
  • 1
    @FlorentB. I can confirm that implicit waits have no effect on the time taken to switch to an alert. – FLSH Nov 02 '16 at 14:08
  • 1
    @Naveen Afraid not - I have `PollingInterval` set to 50ms however when debugging I can see that it will poll once and then timeout after 1 second (and throw an exception) due to the timeout parameter. – FLSH Nov 02 '16 at 14:31
  • good to see it working... Yes, That's the behaviour expected, throw TimeOut exception after one second if the expected condition is not met. – Naveen Kumar R B Nov 02 '16 at 14:48
  • I don't think it is doing what you expected. It will be polled once, `ExpectedConditions.AlertIsPresent` will start up and, because of the long running execution of that method, the wait will time out. It does not time out because the condition is determined to be false, it times out because the condition does not return in time. – FLSH Nov 02 '16 at 14:52
  • how did you set PollingInterval? by default, it will be 500ms. – Naveen Kumar R B Nov 02 '16 at 14:56