toolkit/components/passwordmgr/test/test_prompt.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 <!DOCTYPE HTML>
     2 <html>
     3 <head>
     4   <title>Test for Login Manager</title>
     5   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>  
     6   <script type="text/javascript" src="pwmgr_common.js"></script>
     7   <script type="text/javascript" src="prompt_common.js"></script>
     8   <script type="text/javascript" src="notification_common.js"></script>
     9   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    10 </head>
    11 <body>
    12 Login Manager test: username/password prompts
    13 <p id="display"></p>
    15 <div id="content" style="display: none">
    16   <iframe id="iframe"></iframe>
    17 </div>
    19 <pre id="test">
    20 <script class="testbody" type="text/javascript">
    21 SimpleTest.waitForExplicitFinish();
    23 /** Test for Login Manager: username / password prompts. **/
    24 var pwmgr, ioService, observerService;
    25 var tmplogin, login1, login2A, login2B, login2C, login2D, login2E, login3A, login3B, login4, proxyLogin;
    26 var mozproxy, proxiedHost = "http://mochi.test:8888";
    27 var proxyChannel;
    28 var testNum = 1;
    30 function initLogins(pi) {
    31   observerService = Cc["@mozilla.org/observer-service;1"].
    32                       getService(Ci.nsIObserverService);
    33   observerService.addObserver(storageObserver, "passwordmgr-storage-changed", false);
    35   pwmgr = Cc["@mozilla.org/login-manager;1"].
    36           getService(Ci.nsILoginManager);
    37   ioService = Cc["@mozilla.org/network/io-service;1"].
    38               getService(Ci.nsIIOService);
    40   mozproxy = "moz-proxy://" + SpecialPowers.wrap(pi).host + ":" +
    41               SpecialPowers.wrap(pi).port;
    43   tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
    44              createInstance(Ci.nsILoginInfo);
    46   login1  = Cc["@mozilla.org/login-manager/loginInfo;1"].
    47             createInstance(Ci.nsILoginInfo);
    48   login2A = Cc["@mozilla.org/login-manager/loginInfo;1"].
    49             createInstance(Ci.nsILoginInfo);
    50   login2B = Cc["@mozilla.org/login-manager/loginInfo;1"].
    51             createInstance(Ci.nsILoginInfo);
    52   login2C = Cc["@mozilla.org/login-manager/loginInfo;1"].
    53             createInstance(Ci.nsILoginInfo);
    54   login2D = Cc["@mozilla.org/login-manager/loginInfo;1"].
    55             createInstance(Ci.nsILoginInfo);
    56   login2E = Cc["@mozilla.org/login-manager/loginInfo;1"].
    57             createInstance(Ci.nsILoginInfo);
    58   login3A = Cc["@mozilla.org/login-manager/loginInfo;1"].
    59             createInstance(Ci.nsILoginInfo);
    60   login3B = Cc["@mozilla.org/login-manager/loginInfo;1"].
    61             createInstance(Ci.nsILoginInfo);
    62   login4  = Cc["@mozilla.org/login-manager/loginInfo;1"].
    63             createInstance(Ci.nsILoginInfo);
    64   proxyLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
    65                createInstance(Ci.nsILoginInfo);
    67   login1.init("http://example.com", null, "http://example.com",
    68               "", "examplepass", "", "");
    69   login2A.init("http://example2.com", null, "http://example2.com",
    70                "user1name", "user1pass", "", "");
    71   login2B.init("http://example2.com", null, "http://example2.com",
    72                "user2name", "user2pass", "", "");
    73   login2C.init("http://example2.com", null, "http://example2.com",
    74                "user3.name@host", "user3pass", "", "");
    75   login2D.init("http://example2.com", null, "http://example2.com",
    76                "100@beef", "user3pass", "", "");
    77   login2E.init("http://example2.com", null, "http://example2.com",
    78                "100%beef", "user3pass", "", "");
    79   login3A.init("http://mochi.test:8888", null, "mochitest",
    80                "mochiuser1", "mochipass1", "", "");
    81   login3B.init("http://mochi.test:8888", null, "mochitest2",
    82                "mochiuser2", "mochipass2", "", "");
    83   login4.init("http://mochi.test:8888", null, "mochitest3",
    84                "mochiuser3", "mochipass3-old", "", "");
    85   proxyLogin.init(mozproxy, null, "Proxy Realm",
    86                   "proxuser", "proxpass", "", "");
    88   pwmgr.addLogin(login1);
    89   pwmgr.addLogin(login2A);
    90   pwmgr.addLogin(login2B);
    91   pwmgr.addLogin(login2C);
    92   pwmgr.addLogin(login2D);
    93   pwmgr.addLogin(login2E);
    94   pwmgr.addLogin(login3A);
    95   pwmgr.addLogin(login3B);
    96   pwmgr.addLogin(login4);
    97   pwmgr.addLogin(proxyLogin);
    98 }
   100 function finishTest() {
   101   try {
   102     ok(true, "finishTest removing testing logins...");
   103     observerService.removeObserver(storageObserver, "passwordmgr-storage-changed");
   105     dumpLogins(pwmgr);
   106     ok(true, "removing login 1...");
   107       pwmgr.removeLogin(login1);
   108     ok(true, "removing login 2A...");
   109       pwmgr.removeLogin(login2A);
   110     ok(true, "removing login 2B...");
   111       pwmgr.removeLogin(login2B);
   112     ok(true, "removing login 2C...");
   113       pwmgr.removeLogin(login2C);
   114     ok(true, "removing login 2D...");
   115       pwmgr.removeLogin(login2D);
   116     ok(true, "removing login 2E...");
   117       pwmgr.removeLogin(login2E);
   118     ok(true, "removing login 3A...");
   119       pwmgr.removeLogin(login3A);
   120     ok(true, "removing login 3B...");
   121       pwmgr.removeLogin(login3B);
   122     ok(true, "removing login 4...");
   123       pwmgr.removeLogin(login4);
   124     ok(true, "removing proxyLogin...");
   125       pwmgr.removeLogin(proxyLogin);
   126   } catch (e) {
   127     ok(false, "finishTest FAILED: " + e);
   128   }
   129   ok(true, "whee, done!");
   131   SimpleTest.finish();
   132 }
   134 function proxyChannelListener() { }
   135 proxyChannelListener.prototype = {
   136   onStartRequest: function(request, context) {
   137     doTests();
   138   },
   139   onStopRequest: function(request, context, status) { }
   140 };
   142 var resolveCallback = SpecialPowers.wrapCallbackObject({
   143   QueryInterface : function (iid) {
   144     const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
   146     if (!interfaces.some( function(v) { return iid.equals(v) } ))
   147       throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
   148     return this;
   149   },
   151   onProxyAvailable : function (req, uri, pi, status) {
   152     initLogins(pi);
   154     // I'm cheating a bit here... We should probably do some magic foo to get
   155     // something implementing nsIProxiedProtocolHandler and then call
   156     // NewProxiedChannel(), so we have something that's definately a proxied
   157     // channel. But Mochitests use a proxy for a number of hosts, so just
   158     // requesting a normal channel will give us a channel that's proxied.
   159     // The proxyChannel needs to move to at least on-modify-request to
   160     // have valid ProxyInfo, but we use OnStartRequest during startup()
   161     // for simplicity.
   162     proxyChannel = ioService.newChannel(proxiedHost, null, null);
   163     proxyChannel.asyncOpen(SpecialPowers.wrapCallbackObject(new proxyChannelListener()), null);
   164   }
   165 });
   167 function startup() {
   168   //need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy.
   169   var ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"].
   170     getService(SpecialPowers.Ci.nsIIOService);
   172   var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
   174   var uri = ios.newURI("http://example.com", null, null);
   175   pps.asyncResolve(uri, 0, resolveCallback);
   176 }
   178 function addNotificationCallback(cb) {
   179   storageObserver.notificationCallbacks.push(cb);
   180 }
   182 var storageObserver = SpecialPowers.wrapCallbackObject({
   183   notificationCallbacks: [],
   185   QueryInterface : function (iid) {
   186     const interfaces = [Ci.nsIObserver,
   187                         Ci.nsISupports, Ci.nsISupportsWeakReference];
   189     if (!interfaces.some( function(v) { return iid.equals(v) } ))
   190       throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
   191     return this;
   192   },
   194   observe : function (subject, topic, data) {
   195     ok(true, ".");
   196     ok(true, "observer for " + topic + " / " + data);
   197     ok(true, "Time is " + (new Date()).toUTCString());
   198     var wrapped = SpecialPowers.wrap(subject);
   199     try {
   200       switch (data) {
   201         case "addLogin":
   202           ok(wrapped.QueryInterface(Ci.nsILoginInfo), "subject QI 1");
   203           ok(wrapped.QueryInterface(Ci.nsILoginMetaInfo), "subject QI 2");
   204           dumpLogin("added: ", subject);
   205           break;
   206         case "modifyLogin":
   207           var arr = wrapped.QueryInterface(Ci.nsIArray);
   208           ok(arr, "subject QI");
   209           is(arr.length, 2, "should be 2 items");
   210           var oldLogin = arr.queryElementAt(0, Ci.nsILoginInfo);
   211           var newLogin = arr.queryElementAt(1, Ci.nsILoginInfo);
   212           dumpLogin("oldLogin: ", oldLogin);
   213           dumpLogin("newLogin: ", newLogin);
   214           break;
   215         case "removeLogin":
   216           ok(wrapped.QueryInterface(Ci.nsILoginInfo), "subject QI 1");
   217           ok(wrapped.QueryInterface(Ci.nsILoginMetaInfo), "subject QI 2");
   218           dumpLogin("removed: ", subject);
   219           break;
   220         case "removeAllLogins":
   221           is(subject, null, "no subject");
   222           break;
   223         case "hostSavingEnabled":
   224         case "hostSavingDisabled":
   225           ok(subject instanceof Ci.nsISupportsString, "subject QI");
   226           ok(true, "state is: " + subject.data);
   227           break;
   228         default:
   229           do_throw("Unhandled notification: " + data + " / " + topic);
   230       }
   232       if (this.notificationCallbacks.length)
   233         this.notificationCallbacks.splice(0, 1)[0]();
   234     } catch (e) {
   235       ok(false, "OBSERVER FAILED: " + e);
   236     }
   237   }
   238 });
   240 /*
   241  * handleDialog
   242  *
   243  * Invoked a short period of time after calling startCallbackTimer(), and
   244  * allows testing the actual auth dialog while it's being displayed. Tests
   245  * should call startCallbackTimer() each time the auth dialog is expected (the
   246  * timer is a one-shot).
   247  */
   248 function handleDialog(doc, testNum) {
   249   ok(true, "."); // make it easier to see next line in logs.
   250   ok(true, "handleDialog running for test " + testNum);
   251   ok(true, "Time is " + (new Date()).toUTCString());
   252   dumpNotifications();
   254   var clickOK = true;
   255   var body = doc.getElementById("info.body");
   256   var userfield = doc.getElementById("loginTextbox");
   257   var passfield = doc.getElementById("password1Textbox");
   258   var username = userfield.getAttribute("value");
   259   var password = passfield.getAttribute("value");
   260   var dialog    = doc.getElementById("commonDialog");
   262   switch(testNum) {
   263     case 1:
   264       is(username, "abc", "Checking provided username");
   265       userfield.setAttribute("value", "xyz");
   266       // Temporarily commented out because of Bug #718543
   267       // is(doc.activeElement, userfield.inputField, "focus correct for test" + testNum);
   268       // doc.commandDispatcher.rewindFocus();
   269       // is(doc.activeElement, body, "description focusable");
   270       break;
   271     case 2:
   272       clickOK = false;
   273       break;
   274     case 10:
   275       is(password, "inputpw", "Checking provided password");
   276       passfield.setAttribute("value", "secret");
   277       // Temporarily commented out because of Bug #718543
   278       // is(doc.activeElement, passfield.inputField, "focus correct for test" + testNum);
   279       break;
   280     case 11:
   281       is(password, "inputpw", "Checking provided password");
   282       clickOK = false;
   283       break;
   284     case 12:
   285       is(password, "", "Checking provided password");
   286       passfield.setAttribute("value", "secret");
   287       break;
   288     case 14:
   289       is(password, "", "Checking provided password");
   290       passfield.setAttribute("value", "secret");
   291       break;
   292     case 30:
   293     case 31:
   294       is(password, "", "Checking provided password");
   295       passfield.setAttribute("value", "fill2pass");
   296       break;
   297     case 100:
   298       is(username, "inuser", "Checking provided username");
   299       is(password, "inpass", "Checking provided password");
   300       userfield.setAttribute("value", "outuser");
   301       passfield.setAttribute("value", "outpass");
   302       break;
   303     case 101:
   304       clickOK = false;
   305       break;
   306     case 102:
   307       is(username, "", "Checking provided username");
   308       is(password, "examplepass", "Checking provided password");
   309       break;
   310     case 103:
   311       ok(username == "user1name" || username == "user2name", "Checking filled username");
   312       ok(password == "user1pass" || password == "user2pass", "Checking filled password");
   313       break;
   314     case 104:
   315       is(username, "user1name", "Checking filled username");
   316       is(password, "user1pass", "Checking filled password");
   317       break;
   318     case 105:
   319       is(username, "user2name", "Checking filled username");
   320       is(password, "user2pass", "Checking filled password");
   321       break;
   322     case 106:
   323       is(username, "user2name", "Checking filled username");
   324       is(password, "user2pass", "Checking filled password");
   325       passfield.setAttribute("value", "NEWuser2pass");
   326       break;
   327     case 107:
   328       is(username, "user2name", "Checking filled username");
   329       is(password, "NEWuser2pass", "Checking filled password");
   330       passfield.setAttribute("value", "user2pass");
   331       break;
   332     case 120:
   333     case 121:
   334       is(username, "", "Checking filled username");
   335       is(password, "", "Checking filled password");
   336       userfield.setAttribute("value", "fill2user");
   337       passfield.setAttribute("value", "fill2pass");
   338       break;
   339     case 500:
   340       is(username, "inuser", "Checking unfilled username");
   341       is(password, "inpass", "Checking unfilled password");
   342       userfield.setAttribute("value", "outuser");
   343       passfield.setAttribute("value", "outpass");
   344       break;
   345     case 501:
   346       clickOK = false;
   347       break;
   348     case 502:
   349       is(username, "", "Checking filled username");
   350       is(password, "examplepass", "Checking filled password");
   351       break;
   352     case 503:
   353       // either of the two logins might have been filled in
   354       ok(username == "user1name" || username == "user2name", "Checking filled username");
   355       ok(password == "user1pass" || password == "user2pass", "Checking filled password");
   356       break;
   357     case 504:
   358       // either of the two logins might have been filled in
   359       ok(username == "user1name" || username == "user2name", "Checking filled username");
   360       ok(password == "user1pass" || password == "user2pass", "Checking filled password");
   361       // enter one of the known logins, test 504+505 exercise the two possible states.
   362       userfield.setAttribute("value", "user1name");
   363       passfield.setAttribute("value", "user1pass");
   364       break;
   365     case 505:
   366       // either of the two logins might have been filled in
   367       ok(username == "user1name" || username == "user2name", "Checking filled username");
   368       ok(password == "user1pass" || password == "user2pass", "Checking filled password");
   369       // enter one of the known logins, test 504+505 exercise the two possible states.
   370       userfield.setAttribute("value", "user2name");
   371       passfield.setAttribute("value", "user2pass");
   372       break;
   373     case 506:
   374       // either of the two logins might have been filled in
   375       ok(username == "user1name" || username == "user2name", "Checking filled username");
   376       ok(password == "user1pass" || password == "user2pass", "Checking filled password");
   377       // force to user2, and change the password
   378       userfield.setAttribute("value", "user2name");
   379       passfield.setAttribute("value", "NEWuser2pass");
   380       break;
   381     case 507:
   382       // either of the two logins might have been filled in
   383       ok(username == "user1name" || username == "user2name", "Checking filled username");
   384       ok(password == "user1pass" || password == "user2pass", "Checking filled password");
   385       // force to user2, and change the password back
   386       userfield.setAttribute("value", "user2name");
   387       passfield.setAttribute("value", "user2pass");
   388       break;
   389     case 508:
   390       is(username, "proxuser", "Checking filled username");
   391       is(password, "proxpass", "Checking filled password");
   392       break;
   393     // No case 509, it's unprompted.
   394     case 510:
   395       is(username, "proxuser", "Checking filled username");
   396       is(password, "proxpass", "Checking filled password");
   397       break;
   398     case 511:
   399       is(username, "proxuser", "Checking filled username");
   400       is(password, "proxpass", "Checking filled password");
   401       break;
   402     case 1000:
   403       is(username, "mochiuser1", "Checking filled username");
   404       is(password, "mochipass1", "Checking filled password");
   405       break;
   406     case 1001:
   407       is(username, "mochiuser2", "Checking filled username");
   408       is(password, "mochipass2", "Checking filled password");
   409       break;
   410     // (1002 doesn't trigger a dialog)
   411     case 1003:
   412       is(username, "mochiuser1", "Checking filled username");
   413       is(password, "mochipass1", "Checking filled password");
   414       passfield.setAttribute("value", "mochipass1-new");
   415       break;
   416     case 1004:
   417       is(username, "mochiuser3", "Checking filled username");
   418       is(password, "mochipass3-old", "Checking filled password");
   419       passfield.setAttribute("value", "mochipass3-new");
   420       break;
   421     case 1005:
   422       is(username, "", "Checking filled username");
   423       is(password, "", "Checking filled password");
   424       userfield.setAttribute("value", "mochiuser3");
   425       passfield.setAttribute("value", "mochipass3-old");
   426       break;
   427     default:
   428       ok(false, "Uhh, unhandled switch for testNum #" + testNum);
   429       break;
   430   }
   432   if (clickOK)
   433     dialog.acceptDialog();
   434   else
   435     dialog.cancelDialog();
   437   ok(true, "handleDialog done");
   438   didDialog = true;
   439 }
   441 /*
   442  * handleLoad
   443  *
   444  * Called when a load event is fired at the subtest's iframe.
   445  */
   446 function handleLoad() {
   447   ok(true, "."); // make it easier to see next line in logs.
   448   ok(true, "handleLoad running for test " + testNum);
   449   ok(true, "Time is " + (new Date()).toUTCString());
   450   dumpNotifications();
   452   if (testNum != 1002)
   453     ok(didDialog, "handleDialog was invoked");
   455   // The server echos back the user/pass it received.
   456   var username = iframe.contentDocument.getElementById("user").textContent;
   457   var password = iframe.contentDocument.getElementById("pass").textContent;
   458   var authok = iframe.contentDocument.getElementById("ok").textContent;
   460   switch(testNum) {
   461     case 1000:
   462       testNum++;
   463       is(authok, "PASS", "Checking for successful authentication");
   464       is(username, "mochiuser1", "Checking for echoed username");
   465       is(password, "mochipass1", "Checking for echoed password");
   466       startCallbackTimer();
   467       // We've already authenticated to this host:port. For this next
   468       // request, the existing auth should be sent, we'll get a 401 reply,
   469       // and we should prompt for new auth.
   470       iframe.src = "authenticate.sjs?user=mochiuser2&pass=mochipass2&realm=mochitest2";
   471       break;
   472     case 1001:
   473       testNum++;
   474       is(authok, "PASS", "Checking for successful authentication");
   475       is(username, "mochiuser2", "Checking for echoed username");
   476       is(password, "mochipass2", "Checking for echoed password");
   477       // Now make a load that requests the realm from test 1000. It was
   478       // already provided there, so auth will *not* be prompted for -- the
   479       // networking layer already knows it!
   480       iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1";
   481       break;
   482     case 1002:
   483       testNum++;
   484       is(authok, "PASS", "Checking for successful authentication");
   485       is(username, "mochiuser1", "Checking for echoed username");
   486       is(password, "mochipass1", "Checking for echoed password");
   488       // Same realm we've already authenticated to, but with a different
   489       // expected password (to trigger an auth prompt, and change-password
   490       // popup notification).
   491       startCallbackTimer();
   492       iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1-new";
   493       break;
   494     case 1003:
   495       testNum++;
   496       is(authok, "PASS", "Checking for successful authentication");
   497       is(username, "mochiuser1", "Checking for echoed username");
   498       is(password, "mochipass1-new", "Checking for echoed password");
   500       // Housekeeping: change it back
   501       function resetIt() {
   502         tmpLogin.init("http://mochi.test:8888", null, "mochitest",
   503                       "mochiuser1", "mochipass1-new", "", "");
   504         pwmgr.modifyLogin(tmpLogin, login3A);
   505       }
   506       addNotificationCallback(resetIt);
   508       // Check for the popup notification, and change the password.
   509       popupNotifications = getPopupNotifications(window.top);
   510       popup = getPopup(popupNotifications, "password-change");
   511       ok(popup, "got popup notification");
   512       clickPopupButton(popup, kChangeButton);
   513       popup.remove();
   515       // Same as last test, but for a realm we haven't already authenticated
   516       // to (but have an existing saved login for, so that we'll trigger
   517       // a change-password popup notification.
   518       startCallbackTimer();
   519       iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-new&realm=mochitest3";
   520       break;
   521     case 1004:
   522       testNum++;
   523       is(authok, "PASS", "Checking for successful authentication");
   524       is(username, "mochiuser3", "Checking for echoed username");
   525       is(password, "mochipass3-new", "Checking for echoed password");
   527       // Housekeeping: change it back to the original login4. Actually,
   528       // just delete it and we'll re-add it as the next test.
   529       function clearIt() {
   530         ok(true, "1004's clearIt() called.");
   531        try {
   532         tmpLogin.init("http://mochi.test:8888", null, "mochitest3",
   533                       "mochiuser3", "mochipass3-new", "", "");
   534         pwmgr.removeLogin(tmpLogin);
   536         // Trigger a new prompt, so we can test adding a new login.
   537         startCallbackTimer();
   538         iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3";
   539        } catch (e) { ok(false, "clearIt GOT EXCEPTION: " + e); }
   540       }
   541       addNotificationCallback(clearIt);
   543       // Check for the popup notification, and change the password.
   544       popup = getPopup(popupNotifications, "password-change");
   545       ok(popup, "got popup notification");
   546       clickPopupButton(popup, kChangeButton);
   547       popup.remove();
   549       // Clear cached auth from this subtest, and avoid leaking due to bug 459620.
   550       var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
   551                     getService(Ci.nsIHttpAuthManager);
   552       authMgr.clearAll();
   553       ok(true, "authMgr cleared cached auth");
   554       break;
   555     case 1005:
   556       testNum++;
   557       is(authok, "PASS", "Checking for successful authentication");
   558       is(username, "mochiuser3", "Checking for echoed username");
   559       is(password, "mochipass3-old", "Checking for echoed password");
   561       function finishIt() {
   562         finishTest();
   563       }
   564       addNotificationCallback(finishIt);
   566       // Check for the popup notification, and change the password.
   567       popup = getPopup(popupNotifications, "password-save");
   568       ok(popup, "got popup notification");
   569       clickPopupButton(popup, kRememberButton);
   570       popup.remove();
   571       break;
   572     default:
   573       ok(false, "Uhh, unhandled switch for testNum #" + testNum);
   574       break;
   575   }
   576 }
   578 startup();
   580 function doTests() {
   581   var authinfo = {
   582     username : "",
   583     password : "",
   584     domain   : "",
   586     flags : Ci.nsIAuthInformation.AUTH_HOST,
   587     authenticationScheme : "basic",
   588     realm : ""
   589   };
   591   var proxyAuthinfo = {
   592     username : "",
   593     password : "",
   594     domain   : "",
   596     flags : Ci.nsIAuthInformation.AUTH_PROXY,
   597     authenticationScheme : "basic",
   598     realm : ""
   599   };
   601   var prefs = Cc["@mozilla.org/preferences-service;1"].
   602               getService(Ci.nsIPrefBranch);
   604   const Cc_promptFac= Cc["@mozilla.org/passwordmanager/authpromptfactory;1"];
   605   ok(Cc_promptFac != null, "Access Cc[@mozilla.org/passwordmanager/authpromptfactory;1]");
   607   const Ci_promptFac = Ci.nsIPromptFactory;
   608   ok(Ci_promptFac != null, "Access Ci.nsIPromptFactory");
   610   const promptFac = Cc_promptFac.getService(Ci_promptFac);
   611   ok(promptFac != null, "promptFac getService()");
   613   var prompter1 = promptFac.getPrompt(window, Ci.nsIAuthPrompt);
   614   var prompter2 = promptFac.getPrompt(window, Ci.nsIAuthPrompt2);
   616   function dialogTitle() { return "nsILoginManagerPrompter test #" + testNum; }
   617   var dialogText  = "This dialog should be modified and dismissed by the test.";
   618   var uname  = { value : null };
   619   var pword  = { value : null };
   620   var result = { value : null };
   621   var isOk;
   623   // popupNotifications (not *popup*) is a constant, per-tab container. So, we
   624   // only need to fetch it once.
   625   var popupNotifications = getPopupNotifications(window.top);
   626   ok(popupNotifications, "Got popupNotifications");
   628   // ===== test 1 =====
   629   testNum = 1;
   630   startCallbackTimer();
   631   isOk = prompter1.prompt(dialogTitle(), dialogText, "http://example.com",
   632                           Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result);
   634   ok(isOk, "Checking dialog return value (accept)");
   635   ok(didDialog, "handleDialog was invoked");
   636   is(result.value, "xyz", "Checking prompt() returned value");
   638   // ===== test 2 =====
   639   testNum++;
   640   startCallbackTimer();
   641   isOk = prompter1.prompt(dialogTitle(), dialogText, "http://example.com",
   642                           Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result);
   643   ok(didDialog, "handleDialog was invoked");
   644   ok(!isOk, "Checking dialog return value (cancel)");
   646   // ===== test 10 =====
   647   // Default password provided, existing logins are ignored.
   648   testNum = 10;
   649   pword.value = "inputpw";
   650   startCallbackTimer();
   651   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example.com",
   652                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   653   ok(isOk, "Checking dialog return value (accept)");
   654   ok(didDialog, "handleDialog was invoked");
   655   is(pword.value, "secret", "Checking returned password");
   657   // ===== test 11 =====
   658   // Default password provided, existing logins are ignored.
   659   testNum++;
   660   pword.value = "inputpw";
   661   startCallbackTimer();
   662   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example.com",
   663                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   664   ok(!isOk, "Checking dialog return value (cancel)");
   665   ok(didDialog, "handleDialog was invoked");
   667   // ===== test 12 =====
   668   // No default password provided, realm does not match existing login.
   669   testNum++;
   670   pword.value = null;
   671   startCallbackTimer();
   672   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://nonexample.com",
   673                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   674   ok(isOk, "Checking dialog return value (accept)");
   675   ok(didDialog, "handleDialog was invoked");
   676   is(pword.value, "secret", "Checking returned password");
   678   // ===== test 13 =====
   679   // No default password provided, matching login is returned w/o prompting.
   680   testNum++;
   681   pword.value = null;
   682   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example.com",
   683                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   684   ok(isOk, "Checking dialog return value (accept)");
   685   is(pword.value, "examplepass", "Checking returned password");
   687   // ===== test 14 =====
   688   // No default password provided, none of the logins from this host are
   689   // password-only so the user is prompted.
   690   testNum++;
   691   pword.value = null;
   692   startCallbackTimer();
   693   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example2.com",
   694                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   695   ok(isOk, "Checking dialog return value (accept)");
   696   ok(didDialog, "handleDialog was invoked");
   697   is(pword.value, "secret", "Checking returned password");
   699   // ===== test 15 =====
   700   // No default password provided, matching login is returned w/o prompting.
   701   testNum++;
   702   pword.value = null;
   703   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user1name@example2.com",
   704                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   705   ok(isOk, "Checking dialog return value (accept)");
   706   is(pword.value, "user1pass", "Checking returned password");
   708   // ===== test 16 =====
   709   // No default password provided, matching login is returned w/o prompting.
   710   testNum++;
   711   pword.value = null;
   712   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user2name@example2.com",
   713                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   714   ok(isOk, "Checking dialog return value (accept)");
   715   is(pword.value, "user2pass", "Checking returned password");
   717   // ===== test 17 =====
   718   // No default password provided, matching login is returned w/o prompting.
   719   testNum++;
   720   pword.value = null;
   721   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user3%2Ename%40host@example2.com",
   722                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   723   ok(isOk, "Checking dialog return value (accept)");
   724   is(pword.value, "user3pass", "Checking returned password");
   726   // ===== test 18 =====
   727   // No default password provided, matching login is returned w/o prompting.
   728   testNum++;
   729   pword.value = null;
   730   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://100@beef@example2.com",
   731                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   732   ok(isOk, "Checking dialog return value (accept)");
   733   is(pword.value, "user3pass", "Checking returned password");
   735   // ===== test 19 =====
   736   // No default password provided, matching login is returned w/o prompting.
   737   testNum++;
   738   pword.value = null;
   739   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://100%25beef@example2.com",
   740                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   741   ok(isOk, "Checking dialog return value (accept)");
   742   is(pword.value, "user3pass", "Checking returned password");
   744   // XXX test saving a password with  Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY
   746   // ===== test 30 =====
   747   // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt
   748   testNum = 30;
   749   pword.value = null;
   750   startCallbackTimer();
   751   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "example2.com:80 (somerealm)",
   752                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
   753   ok(isOk, "Checking dialog return value (accept)");
   754   ok(didDialog, "handleDialog was invoked");
   755   is(pword.value, "fill2pass", "Checking returned password");
   757   // ===== test 31 =====
   758   // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt
   759   testNum++;
   760   pword.value = null;
   761   startCallbackTimer();
   762   isOk = prompter1.promptPassword(dialogTitle(), dialogText, "example2.com:80 (somerealm)",
   763                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, pword);
   764   ok(isOk, "Checking dialog return value (accept)");
   765   ok(didDialog, "handleDialog was invoked");
   766   is(pword.value, "fill2pass", "Checking returned password");
   768   // ===== test 100 =====
   769   testNum = 100;
   770   uname.value = "inuser";
   771   pword.value = "inpass";
   772   startCallbackTimer();
   773   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://nonexample.com",
   774                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
   775   ok(isOk, "Checking dialog return value (accept)");
   776   ok(didDialog, "handleDialog was invoked");
   777   is(uname.value, "outuser", "Checking returned username");
   778   is(pword.value, "outpass", "Checking returned password");
   780   // ===== test 101 =====
   781   testNum++;
   782   uname.value = "inuser";
   783   pword.value = "inpass";
   784   startCallbackTimer();
   785   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://nonexample.com",
   786                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
   787   ok(!isOk, "Checking dialog return value (cancel)");
   788   ok(didDialog, "handleDialog was invoked");
   790   // ===== test 102 =====
   791   // test filling in existing password-only login
   792   testNum++;
   793   uname.value = null;
   794   pword.value = null;
   795   startCallbackTimer();
   796   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example.com",
   797                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   798   ok(isOk, "Checking dialog return value (accept)");
   799   ok(didDialog, "handleDialog was invoked");
   800   is(uname.value, "", "Checking returned username");
   801   is(pword.value, "examplepass", "Checking returned password");
   803   // ===== test 103 =====
   804   // test filling in existing login (undetermined from multiple selection)
   805   testNum++;
   806   uname.value = null;
   807   pword.value = null;
   808   startCallbackTimer();
   809   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
   810                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   811   ok(isOk, "Checking dialog return value (accept)");
   812   ok(didDialog, "handleDialog was invoked");
   813   ok(uname.value == "user1name" || uname.value == "user2name", "Checking returned username");
   814   ok(pword.value == "user1pass" || uname.value == "user2pass", "Checking returned password");
   816   // ===== test 104 =====
   817   // test filling in existing login (user1 from multiple selection)
   818   testNum++;
   819   uname.value = "user1name";
   820   pword.value = null;
   821   startCallbackTimer();
   822   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
   823                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   824   ok(isOk, "Checking dialog return value (accept)");
   825   ok(didDialog, "handleDialog was invoked");
   826   is(uname.value, "user1name", "Checking returned username");
   827   is(pword.value, "user1pass", "Checking returned password");
   829   // ===== test 105 =====
   830   // test filling in existing login (user2 from multiple selection)
   831   testNum++;
   832   uname.value = "user2name";
   833   pword.value = null;
   834   startCallbackTimer();
   835   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
   836                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   837   ok(isOk, "Checking dialog return value (accept)");
   838   ok(didDialog, "handleDialog was invoked");
   839   is(uname.value, "user2name", "Checking returned username");
   840   is(pword.value, "user2pass", "Checking returned password");
   842   // ===== test 106 =====
   843   // test changing password
   844   testNum++;
   845   uname.value = "user2name";
   846   pword.value = null;
   847   startCallbackTimer();
   848   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
   849                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   850   ok(isOk, "Checking dialog return value (accept)");
   851   ok(didDialog, "handleDialog was invoked");
   852   is(uname.value, "user2name", "Checking returned username");
   853   is(pword.value, "NEWuser2pass", "Checking returned password");
   855   // ===== test 107 =====
   856   // test changing password (back to original value)
   857   testNum++;
   858   uname.value = "user2name";
   859   pword.value = null;
   860   startCallbackTimer();
   861   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
   862                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   863   ok(isOk, "Checking dialog return value (accept)");
   864   ok(didDialog, "handleDialog was invoked");
   865   is(uname.value, "user2name", "Checking returned username");
   866   is(pword.value, "user2pass", "Checking returned password");
   868   // ===== test 120 =====
   869   // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt
   870   testNum = 120;
   871   uname.value = null;
   872   pword.value = null;
   873   startCallbackTimer();
   874   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "example2.com:80 (somerealm)",
   875                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
   876   ok(isOk, "Checking dialog return value (accept)");
   877   ok(didDialog, "handleDialog was invoked");
   878   is(uname.value, "fill2user", "Checking returned username");
   879   is(pword.value, "fill2pass", "Checking returned password");
   881   // ===== test 121 =====
   882   // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt
   883   testNum++;
   884   uname.value = null;
   885   pword.value = null;
   886   startCallbackTimer();
   887   isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "example2.com:80 (somerealm)",
   888                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
   889   ok(isOk, "Checking dialog return value (accept)");
   890   ok(didDialog, "handleDialog was invoked");
   891   is(uname.value, "fill2user", "Checking returned username");
   892   is(pword.value, "fill2pass", "Checking returned password");
   894   var channel1 = ioService.newChannel("http://example.com", null, null);
   895   var channel2 = ioService.newChannel("http://example2.com", null, null);
   897   var level = Ci.nsIAuthPrompt2.LEVEL_NONE;
   899   // ===== test 500 =====
   900   testNum = 500;
   901   authinfo.username = "inuser";
   902   authinfo.password = "inpass";
   903   authinfo.realm    = "some realm";
   905   startCallbackTimer();
   906   isOk = prompter2.promptAuth(channel1, level, authinfo);
   908   ok(isOk, "Checking dialog return value (accept)");
   909   ok(didDialog, "handleDialog was invoked");
   910   is(authinfo.username, "outuser", "Checking returned username");
   911   is(authinfo.password, "outpass", "Checking returned password");
   913   // ===== test 501 =====
   914   testNum++;
   915   startCallbackTimer();
   916   isOk = prompter2.promptAuth(channel1, level, authinfo);
   918   ok(!isOk, "Checking dialog return value (cancel)");
   919   ok(didDialog, "handleDialog was invoked");
   921   // ===== test 502 =====
   922   // test filling in password-only login
   923   testNum++;
   924   authinfo.username = "";
   925   authinfo.password = "";
   926   authinfo.realm    = "http://example.com";
   928   startCallbackTimer();
   929   isOk = prompter2.promptAuth(channel1, level, authinfo);
   931   ok(isOk, "Checking dialog return value (accept)");
   932   ok(didDialog, "handleDialog was invoked");
   933   is(authinfo.username, "", "Checking returned username");
   934   is(authinfo.password, "examplepass", "Checking returned password");
   936   // ===== test 503 =====
   937   // test filling in existing login (undetermined from multiple selection)
   938   testNum++;
   939   authinfo.username = "";
   940   authinfo.password = "";
   941   authinfo.realm    = "http://example2.com";
   943   startCallbackTimer();
   944   isOk = prompter2.promptAuth(channel2, level, authinfo);
   946   ok(isOk, "Checking dialog return value (accept)");
   947   ok(didDialog, "handleDialog was invoked");
   948   ok(authinfo.username == "user1name" || authinfo.username == "user2name", "Checking returned username");
   949   ok(authinfo.password == "user1pass" || authinfo.password == "user2pass", "Checking returned password");
   951   // ===== test 504 =====
   952   // test filling in existing login (undetermined --> user1)
   953   testNum++;
   954   authinfo.username = "";
   955   authinfo.password = "";
   956   authinfo.realm    = "http://example2.com";
   958   startCallbackTimer();
   959   isOk = prompter2.promptAuth(channel2, level, authinfo);
   961   ok(isOk, "Checking dialog return value (accept)");
   962   ok(didDialog, "handleDialog was invoked");
   963   is(authinfo.username, "user1name", "Checking returned username");
   964   is(authinfo.password, "user1pass", "Checking returned password");
   966   // ===== test 505 =====
   967   // test filling in existing login (undetermined --> user2)
   968   testNum++;
   969   authinfo.username = "";
   970   authinfo.password = "";
   971   authinfo.realm    = "http://example2.com";
   973   dumpNotifications();
   974   startCallbackTimer();
   975   isOk = prompter2.promptAuth(channel2, level, authinfo);
   977   ok(isOk, "Checking dialog return value (accept)");
   978   ok(didDialog, "handleDialog was invoked");
   979   is(authinfo.username, "user2name", "Checking returned username");
   980   is(authinfo.password, "user2pass", "Checking returned password");
   982   // ===== test 506 =====
   983   // test changing a password (undetermined --> user2 w/ newpass)
   984   testNum++;
   985   authinfo.username = "";
   986   authinfo.password = "";
   987   authinfo.realm    = "http://example2.com";
   989   dumpNotifications();
   990   startCallbackTimer();
   991   isOk = prompter2.promptAuth(channel2, level, authinfo);
   993   ok(isOk, "Checking dialog return value (accept)");
   994   ok(didDialog, "handleDialog was invoked");
   995   is(authinfo.username, "user2name", "Checking returned username");
   996   is(authinfo.password, "NEWuser2pass", "Checking returned password");
   998   // ===== test 507 =====
   999   // test changing a password (undetermined --> user2 w/ origpass)
  1000   testNum++;
  1001   authinfo.username = "";
  1002   authinfo.password = "";
  1003   authinfo.realm    = "http://example2.com";
  1005   dumpNotifications();
  1006   startCallbackTimer();
  1007   isOk = prompter2.promptAuth(channel2, level, authinfo);
  1009   ok(isOk, "Checking dialog return value (accept)");
  1010   ok(didDialog, "handleDialog was invoked");
  1011   is(authinfo.username, "user2name", "Checking returned username");
  1012   is(authinfo.password, "user2pass", "Checking returned password");
  1014   // ===== test 508 =====
  1015   // test proxy login (default = no autologin), make sure it prompts.
  1016   testNum++;
  1017   proxyAuthinfo.username = "";
  1018   proxyAuthinfo.password = "";
  1019   proxyAuthinfo.realm    = "Proxy Realm";
  1020   proxyAuthinfo.flags    = Ci.nsIAuthInformation.AUTH_PROXY;
  1022   dumpNotifications();
  1023   var time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
  1024   startCallbackTimer();
  1025   isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
  1026   var time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
  1028   ok(isOk, "Checking dialog return value (accept)");
  1029   ok(didDialog, "handleDialog was invoked");
  1030   isnot(time1, time2, "Checking that timeLastUsed was updated");
  1031   is(proxyAuthinfo.username, "proxuser", "Checking returned username");
  1032   is(proxyAuthinfo.password, "proxpass", "Checking returned password");
  1034   // ===== test 509 =====
  1035   // test proxy login (with autologin)
  1036   testNum++;
  1038   // Enable the autologin pref.
  1039   prefs.setBoolPref("signon.autologin.proxy", true);
  1041   proxyAuthinfo.username = "";
  1042   proxyAuthinfo.password = "";
  1043   proxyAuthinfo.realm    = "Proxy Realm";
  1044   proxyAuthinfo.flags    = Ci.nsIAuthInformation.AUTH_PROXY;
  1046   time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
  1047   isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
  1048   time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
  1050   ok(isOk, "Checking dialog return value (accept)");
  1051   isnot(time1, time2, "Checking that timeLastUsed was updated");
  1052   is(proxyAuthinfo.username, "proxuser", "Checking returned username");
  1053   is(proxyAuthinfo.password, "proxpass", "Checking returned password");
  1055   // ===== test 510 =====
  1056   // test proxy login (with autologin), ensure it prompts after a failed auth.
  1057   testNum++;
  1059   proxyAuthinfo.username = "";
  1060   proxyAuthinfo.password = "";
  1061   proxyAuthinfo.realm    = "Proxy Realm";
  1062   proxyAuthinfo.flags    = (Ci.nsIAuthInformation.AUTH_PROXY | Ci.nsIAuthInformation.PREVIOUS_FAILED);
  1064   time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
  1065   startCallbackTimer();
  1066   isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
  1067   time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
  1069   ok(isOk, "Checking dialog return value (accept)");
  1070   ok(didDialog, "handleDialog was invoked");
  1071   isnot(time1, time2, "Checking that timeLastUsed was updated");
  1072   is(proxyAuthinfo.username, "proxuser", "Checking returned username");
  1073   is(proxyAuthinfo.password, "proxpass", "Checking returned password");
  1075   // ===== test 511 =====
  1076   // test proxy login (with autologin), ensure it prompts in Private Browsing mode.
  1077   testNum++;
  1079   proxyAuthinfo.username = "";
  1080   proxyAuthinfo.password = "";
  1081   proxyAuthinfo.realm    = "Proxy Realm";
  1082   proxyAuthinfo.flags    = Ci.nsIAuthInformation.AUTH_PROXY;
  1084   prefs.clearUserPref("signon.autologin.proxy");
  1086   // XXX check for and kill popup notification??
  1087   // XXX check for checkbox / checkstate on old prompts?
  1088   // XXX check NTLM domain stuff
  1090   var iframe = document.getElementById("iframe");
  1091   iframe.onload = handleLoad;
  1093   // clear plain HTTP auth sessions before the test, to allow
  1094   // running them more than once.
  1095   var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
  1096                 getService(Ci.nsIHttpAuthManager);
  1097   authMgr.clearAll();
  1099   // ===== test 1000 =====
  1100   testNum = 1000;
  1101   startCallbackTimer();
  1102   iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1";
  1104   // ...remaining tests are driven by handleLoad()...
  1106 </script>
  1107 </pre>
  1108 </body>
  1109 </html>

mercurial