mozilla / geckodriver

WebDriver for Firefox
https://firefox-source-docs.mozilla.org/testing/geckodriver/
Mozilla Public License 2.0
7.18k stars 1.52k forks source link

Windows Authentication causes UnhandledAlertException #977

Open smit9234 opened 7 years ago

smit9234 commented 7 years ago

System

For this application you must login using Windows Authentication, a Windows Authentication dialog appears before you can enter the site, AutoIT script is used to enter the user name and password. The test works until you go to click on a button, then fails due to an UnhandledAlertException.

See below for detailed info.

Testcase

@Test
    public void testClick() throws InterruptedException, IOException {
        System.out.println("Starting test " + new Object(){}.getClass().getEnclosingMethod().getName());
        driver.get(baseURL);
       //Windows Authentication Dialog
        AutoITLoginJunit authLogin = new AutoITLoginJunit();
        authLogin.login();
        //Wait for Add button to load
        wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[contains(text(), 'ADD')]")));
        Thread.sleep(100);
        driver.findElement(By.cssSelector("button:nth-child(4)")).click();
  }

Driver Capabilities

System.setProperty("webdriver.gecko.driver", "./drivers/geckodriver.exe");//"<PATH TO LOCATION>\\chromedriver.exe");
FirefoxProfile ffprofile = new FirefoxProfile();
String sitelist = "sorry cannot say";
ffprofile.setPreference("browser.tabs.remote.force-enable",true);
ffprofile.setPreference("network.negotiate-auth.trusted-uris", sitelist);
ffprofile.setPreference("network.negotiate-auth.delegation-uris", sitelist);
ffprofile.setPreference("network.automatic-ntlm-auth.trusted-uris", sitelist);
ffprofile.setPreference("dom.disable_beforeunload", true);
FirefoxOptions options = new FirefoxOptions();
options.setProfile(ffprofile);
options.setLogLevel(Level.ALL);
DesiredCapabilities capability = DesiredCapabilities.firefox();
capability.setCapability("marionette", true);
capability.setCapability("acceptSslCerts ","true");
capability.setCapability("acceptInsecureCerts ","true");
 //capability.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE); --> doesn't work
capability.setCapability(FirefoxOptions.FIREFOX_OPTIONS,options);
return new FirefoxDriver(capability);

Stacktrace

org.openqa.selenium.UnhandledAlertException: : 
Build info: version: '3.5.3', revision: 'a88d25fe6b', time: '2017-08-29T12:42:44.417Z'
System info: host: 'localhost', ip: '', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_111'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{moz:profile=C:\Users\localhost\AppData\Local\Temp\rust_mozprofile.iAvlyj5amzOB, rotatable=false, timeouts={implicit=0, pageLoad=300000, script=30000}, pageLoadStrategy=normal, moz:headless=false, platform=XP, moz:accessibilityChecks=false, acceptInsecureCerts=true, browserVersion=57.0, platformVersion=6.1, moz:processID=7192, browserName=firefox, javascriptEnabled=true, platformName=XP, moz:webdriverClick=false}]

*** Element info: {Using=css selector, value=button:nth-child(4)}

    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:118)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:164)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:82)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:646)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:416)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementByCssSelector(RemoteWebDriver.java:510)
    at org.openqa.selenium.By$ByCssSelector.findElement(By.java:430)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:408)

Trace-level log

1506532875963   Marionette  DEBUG   Received DOM event "beforeunload" for "about:blank"
1506532876039   Marionette  DEBUG   Received observer notification "common-dialog-loaded"
1506532876042   Marionette  TRACE   0 <- [1,4,null,{}]
1506532876047   geckodriver::marionette TRACE   <- [1,4,null,{}]
1506532876047   webdriver::server   DEBUG   <- 200 OK {"value": {}}
1506532876057   webdriver::server   DEBUG   -> POST /session/ea8c69d8-f479-4a42-8f74-1b44843fe628/elements {"value":"//*[contains(text(), 'ADD')]","using":"xpath"}
1506532876058   geckodriver::marionette TRACE   -> 77:[0,5,"findElements",{"using":"xpath","value":"//*[contains(text(), 'ADD')]"}]
1506532876072   Marionette  TRACE   0 -> [0,5,"findElements",{"using":"xpath","value":"//*[contains(text(), 'ADD')]"}]
1506532879790   DeferredSave.webext.sc.lz4  DEBUG   Starting write
1506532879816   DeferredSave.webext.sc.lz4  DEBUG   Write succeeded
1506532886075   Marionette  TRACE   0 <- [1,5,null,[]]
1506532886074   geckodriver::marionette TRACE   <- [1,5,null,[]]
1506532886074   webdriver::server   DEBUG   <- 200 OK {"value":[]}
1506532886594   webdriver::server   DEBUG   -> POST /session/ea8c69d8-f479-4a42-8f74-1b44843fe628/elements {"value":"//*[contains(text(), 'ADD')]","using":"xpath"}
1506532886595   geckodriver::marionette TRACE   -> 77:[0,6,"findElements",{"using":"xpath","value":"//*[contains(text(), 'ADD')]"}]
1506532886597   Marionette  TRACE   0 -> [0,6,"findElements",{"using":"xpath","value":"//*[contains(text(), 'ADD')]"}]
1506532896180   Marionette  TRACE   0 <- [1,6,null,[{"element-6066-11e4-a52e-4f735466cecf":"00053f60-8aef-4894-adc7-49decf364f09","ELEMENT":"00053f60-8aef-4894-adc7-49decf364f09"}]]
1506532896186   geckodriver::marionette TRACE   <- [1,6,null,[{"element-6066-11e4-a52e-4f735466cecf":"00053f60-8aef-4894-adc7-49decf364f09","ELEMENT":"00053f60-8aef-4894-adc7-49decf364f09"}]]
1506532896186   webdriver::server   DEBUG   <- 200 OK {"value":[{"element-6066-11e4-a52e-4f735466cecf":"00053f60-8aef-4894-adc7-49decf364f09"}]}
1506532896294   webdriver::server   DEBUG   -> POST /session/ea8c69d8-f479-4a42-8f74-1b44843fe628/element {"value":"button:nth-child(4)","using":"css selector"}
1506532896295   geckodriver::marionette TRACE   -> 74:[0,7,"findElement",{"using":"css selector","value":"button:nth-child(4)"}]
1506532896292   Marionette  TRACE   0 -> [0,7,"findElement",{"using":"css selector","value":"button:nth-child(4)"}]
1506532896294   Marionette  TRACE   0 <- [1,7,{"error":"unexpected alert open","message":"","stacktrace":"WebDriverError@chrome://marionette/content/error.js:239:5\nUnexpectedAlertOpenError@chrome://marionette/content/error.js:523:5\nassert.that/<@chrome://marionette/content/assert.js:383:13\nassert.noUserPrompt@chrome://marionette/content/assert.js:157:3\nGeckoDriver.prototype.findElement@chrome://marionette/content/driver.js:2065:3\ndespatch@chrome://marionette/content/server.js:555:20\nexecute@chrome://marionette/content/server.js:529:11\nonPacket/<@chrome://marionette/content/server.js:504:15\nonPacket@chrome://marionette/content/server.js:503:8\n_onJSONObjectReady/<@chrome://marionette/content/transport.js:501:9\n"},null]
1506532896301   geckodriver::marionette TRACE   <- [1,7,{"error":"unexpected alert open","message":"","stacktrace":"WebDriverError@chrome://marionette/content/error.js:239:5\nUnexpectedAlertOpenError@chrome://marionette/content/error.js:523:5\nassert.that/<@chrome://marionette/content/assert.js:383:13\nassert.noUserPrompt@chrome://marionette/content/assert.js:157:3\nGeckoDriver.prototype.findElement@chrome://marionette/content/driver.js:2065:3\ndespatch@chrome://marionette/content/server.js:555:20\nexecute@chrome://marionette/content/server.js:529:11\nonPacket/<@chrome://marionette/content/server.js:504:15\nonPacket@chrome://marionette/content/server.js:503:8\n_onJSONObjectReady/<@chrome://marionette/content/transport.js:501:9\n"},null]
1506532896305   webdriver::server   DEBUG   <- 500 Internal Server Error {"value":{"error":"unexpected alert open","message":"","stacktrace":"stack backtrace:\n   0:           0x4821c4 - <no info>\n   1:           0x482933 - <no info>\n   2:           0x445159 - <no info>\n   3:           0x44eff6 - <no info>\n   4:           0x4322e1 - <no info>\n   5:           0x40ba4e - <no info>\n   6:           0x4119b9 - <no info>\n   7:           0x6d2c89 - <no info>\n   8:           0x426006 - <no info>\n   9:           0x6cd490 - <no info>\n  10:         0x777359cd - BaseThreadInitThunk"}}
1506532896320   webdriver::server   DEBUG   -> DELETE /session/ea8c69d8-f479-4a42-8f74-1b44843fe628 
1506532896321   geckodriver::marionette TRACE   -> 37:[0,8,"quit",{"flags":["eForceQuit"]}]
1506532896318   Marionette  TRACE   0 -> [0,8,"quit",{"flags":["eForceQuit"]}]
1506532896320   Marionette  INFO    New connections will no longer be accepted
1506532896339   addons.xpi  DEBUG   Calling bootstrap method shutdown on webcompat@mozilla.org version 1.1
1506532896339   addons.xpi  DEBUG   Calling bootstrap method shutdown on shield-recipe-client@mozilla.org version 73
1506532896340   addons.xpi  DEBUG   Calling bootstrap method shutdown on screenshots@mozilla.org version 19.0.0
1506532896345   addons.xpi  DEBUG   Calling bootstrap method shutdown on onboarding@mozilla.org version 0.1
1506532896345   addons.xpi  DEBUG   Calling bootstrap method shutdown on formautofill@mozilla.org version 1.0
1506532896346   addons.xpi  DEBUG   Calling bootstrap method shutdown on followonsearch@mozilla.com version 0.9.3
1506532896346   addons.xpi  DEBUG   Calling bootstrap method shutdown on firefox@getpocket.com version 1.0.5
1506532896347   addons.xpi  DEBUG   Calling bootstrap method shutdown on e10srollout@mozilla.org version 3.00
1506532896347   addons.xpi  DEBUG   Calling bootstrap method shutdown on aushelper@mozilla.org version 2.0
1506532896347   addons.xpi  DEBUG   Calling bootstrap method shutdown on activity-stream@mozilla.org version 2017.09.22.1389-2ee94db4
1506532896392   Marionette  TRACE   0 <- [1,8,null,{"cause":"shutdown"}]
1506532896416   geckodriver::marionette TRACE   <- [1,8,null,{"cause":"shutdown"}]
1506532896416   webdriver::server   DEBUG   Deleting session
1506532896416   geckodriver::marionette DEBUG   Stopping browser process
1506532896612   webdriver::server   DEBUG   <- 200 OK {"value": {}}
1506532896623   webdriver::server   DEBUG   -> GET /shutdown 
1506532896625   webdriver::server   DEBUG   <- 404 Not Found {"value":{"error":"unknown command","message":"GET /shutdown did not match a known command","stacktrace":"stack backtrace:\n   0:           0x4821c4 - <no info>\n   1:           0x482933 - <no info>\n   2:           0x445159 - <no info>\n   3:           0x43f00a - <no info>\n   4:           0x409e7b - <no info>\n   5:           0x41198a - <no info>\n   6:           0x6d2c89 - <no info>\n   7:           0x426245 - <no info>\n   8:           0x6cd490 - <no info>\n   9:         0x777359cd - BaseThreadInitThunk"}}
whimboo commented 7 years ago

It's expected that the next command will fail if a modal dialog is open and has not been closed by that time. You will have to make sure that you are waiting long enough, which means until your AutoIt script has been finished and closed the dialog. The 100ms sleep you added here seem to be too less.

whimboo commented 7 years ago

Hm, I actually had a look which command you execute and in this case it's findElement. Checking the WebDriver spec I don't see that alert checks should be done at all for any of the element retrieval methods.

@andreastt, you added those checks via bug 1359004 a while ago. As it looks like it was a mistake to add them to those retrieval methods. Can you please have a look?

andreastt commented 7 years ago

@whimboo That sounds like an omission from the specification. Filed https://github.com/w3c/webdriver/issues/1121.

whimboo commented 7 years ago

Lets leave it open until the specification question has been solved.

smit9234 commented 7 years ago

I was able to get this to work by replacing the AutoIT script with the following

Alert alert = driver.switchTo().alert();
alert.sendKeys(username + Keys.TAB.toString()+password);
alert.accept();
whimboo commented 7 years ago

Ah, nice workaround and good to know that we could even handle basic authentication that way. Thanks!

schmidtkp commented 7 years ago

I would question if this would truly work for Basic Authentication from all browsers, if at all.

whimboo commented 7 years ago

It works with Firefox because we can detect both types of dialogs at the moment.

antho03 commented 6 years ago

Someone have a solution with using autoIt ?

whimboo commented 6 years ago

@antho03 you should never use autoit if you really can avoid it. See above (https://github.com/mozilla/geckodriver/issues/977#issuecomment-336230380) for a possible solution.

antho03 commented 6 years ago

@whimboo Ok thx for your answer, but can i use that with robotframework ? With command "Execute Javascript" ?

whimboo commented 6 years ago

Sorry, but I don't know the robot framework, also is it off-topic here. Please get in contact with the support of that framework in how this can be done if unclear.

mgehmayr-micro-focus commented 6 years ago

Hi,

I encountered the same issue and I am not sure if the following aspect has already been considered:

I close the basic auth dialog via Auto It, then sleep for a couple of seconds to be sure it is closed already, and after that, subsequent WebDriver calls like "driver.findElement"or "driver.getTitle()" throw an UnhandledAlertException.

This seems inappropriate given that is no alert present anymore at this point in time.

andreastt commented 6 years ago

AutoIT and the Robot framework are completely off topic for this issue.

whimboo commented 6 years ago

@mgehmayr-micro-focus you are not saying which version of Firefox and geckodriver you are using. What you might want is https://bugzilla.mozilla.org/show_bug.cgi?id=1416284 but that is only available in Firefox 59. @andreastt, maybe we should consider an uplift of this patch to 58?

mgehmayr-micro-focus commented 6 years ago

@whimboo I initially used Firefox 57. Now I tried 59.0a1 (on Windows) and encountered a complete behavioral change in Firefox 59.0a1:

When I navigate to a web page that is secured by basic auth no "Authentication Required" dialog is displayed anymore. Instead I immeditaely see the "not authorized" web page (i.e. the weg page I see with Firefox 57 when I click Cancel on the "Authentication Required" dialog)

I also noticed exactly the same behaviour when I do start Firefox manually (like a normal Firefox user does that does not use Geckodriver or Selenium at all). I used the public site https://the-internet.herokuapp.com for testing.

Use case A (possible issue):

Expected: The "Authentication Required" asks me for my credentials Actual: I see the "not authorized" page immeditaely

Use case B (correct)

Is this behavioral change intended in Firefox 59.0a1?

mgehmayr-micro-focus commented 6 years ago

@whimboo I tried Firefox 59.0a1 on 2 different Windows 10 machines: Same result: No "Authentication Required" dialog is shown for https://the-internet.herokuapp.com/basic_auth

I tried Firefox 59.0a1 on macOs (High Sierra) and there the "Authentication Required" dialog is shown as expected. Here I also the plain Firefox app (no Geckodriver / Marionette involved)

I am well aware of the fact that my observerations are not related to Geckodriver but to Firefox itself and that they might be off-topic in this bug report. I am just posting this info here because I encountered this road block when trying to verify if https://bugzilla.mozilla.org/show_bug.cgi?id=1416284 solves my AutoIt use case.

mgehmayr-micro-focus commented 6 years ago

@whimboo I tried Firefox 59.0a1 with Geckodriver 19.1 on macOS.

This was my Selenium Test: I navigate to a basic auth web site and then manually log in (in my CI tests I use AutoIt for that). After that I get a NoAlertPresentException.

driver.navigate().to("https://the-internet.herokuapp.com/basic_auth");
Thread.sleep(20 * 1000); // sleep for 20 sec: in this time I manually enter the credentials (admin and admin)
driver.getTitle(); // fails with NoAlertPresentException

Geckodriver trace log is attached trace.log

Please note that the fix https://bugzilla.mozilla.org/show_bug.cgi?id=1416284 appears to work correctly: When I do not enter the credentials manually and just wait the 20 seconds I get an UnhandledAlertException and the basic auth dialog gets dismissed as expected with this fix.

whimboo commented 6 years ago

I cannot reproduce the problem with the Basic Auth on Windows 10. I always get the dialog displayed whether which version I'm using. So I assume something is broken on your local system. Maybe file a bug directly for Firefox on Bugzilla.

mgehmayr-micro-focus commented 6 years ago

I cannot reproduce the problem with Basic Auth on Windows 10 anymore with Firefox Nightly from 2018-01-07

CosminSontu commented 6 years ago

A similar issue happens with latest version of WebDriver (3.14) and Gekodriver from a nuget package (Selenium.WebDriver.GeckoDriver.Win64 v0.22.0) published on 17th of September.

It seems like Gekodriver keeps an internal state about a modal being open. I base that on the fact that i'm closing the modal with AutoIt and any action i perform in the homepage as authenticated user, yields NoAlertPresentException. This is my conclusion hearing cases that this goes away if you close the alert with Accept(). In my case checking if the alert is present prior to the action throwing the exception confirms the fact that the alert is not there. AutoIt is offtopic I agree, but having geckodriver unaware of an alert being close (no matter by what means (external to webdriver let's say)) (such as the one for AD login) that Firefox opens when opening such page (AD Login) i think represents an issue.

@whimboo: I think your comment on bug 1359004, regarding alert checks being performed during find elements is spot on and can be the trigger of the issue if geckodriver has some kind of internal state related to AD login alert which gets out of sync (stale) when you close it manually or with something like autoit.

I'm experiencing this exception after passing the AD authorization and after having home page being successfully loaded. The NoAlertPresentException is thrown when accessing TagName property on a page element.

_OpenQA.Selenium.NoAlertPresentException: No modal dialog is currently open at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse) at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary2 parameters) at OpenQA.Selenium.Remote.RemoteWebElement.Execute(String commandToExecute, Dictionary2 parameters) at OpenQA.Selenium.Remote.RemoteWebElement.getTagName()

It's likely that there are some alert checks for actions like retrieving TagName for an element and geckodriver wrongfully believing there is an alert open. It can get that wrong impression(repeating myself) if it would keep track of alerts open / closed only via its api method calls and not inspecting the actual browser session / dom etc.

whimboo commented 6 years ago

You cannot use any other tool beside geckodriver/Marionette at the moment to close those alerts. You would always face this above described problem. It will work once https://bugzilla.mozilla.org/show_bug.cgi?id=1477977 got fixed.

Please note that for authentication dialogs you can see a string like the following to the alert, which will enter both the user and password: "user" + Keys.TAB + "password". Then accept the alert.