<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Test basic login autocomplete</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script src="/tests/SimpleTest/EventUtils.js"></script>
  <script type="text/javascript" src="../../../satchel/test/satchel_common.js"></script>
  <script type="text/javascript" src="pwmgr_common.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
Login Manager test: multiple login autocomplete
<p id="display"></p>

<!-- we presumably can't hide the content for this test. -->
<div id="content"></div>

<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Login Manager: multiple login autocomplete. **/

const INSECURE_WARNING_TEXT = "This connection is not secure. Logins entered here could be compromised. Learn More";

// Restore the form to the default state.
async function reinitializeForm(index) {
  // Using innerHTML is for creating the autocomplete popup again, so the
  // preference value will be applied to the constructor of
  // LoginAutoCompleteResult.
  let form = document.getElementById("form" + index);
  let temp = form.innerHTML;
  form.innerHTML = "";
  // eslint-disable-next-line no-unsanitized/property
  form.innerHTML = temp;

  await new Promise(resolve => {
    let observer = SpecialPowers.wrapCallback(() => {
      SpecialPowers.removeObserver(observer, "passwordmgr-processed-form");
      resolve();
    });
    SpecialPowers.addObserver(observer, "passwordmgr-processed-form");
  });

  await SimpleTest.promiseFocus(window);

  const uname = getFormElementByName(index, "uname");
  const pword = getFormElementByName(index, "pword");
  uname.value = "";
  pword.value = "";
  pword.focus();
}

function generateDateString(date) {
  let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
                                                              { dateStyle: "medium" });
  return dateAndTimeFormatter.format(date);
}

const DATE_NOW_STRING = generateDateString(new Date());

// Check for expected username/password in form.
function checkACFormPasswordField(expectedPassword) {
  const pword = getFormElementByName(1, "pword");
  is(pword.value, expectedPassword, "Checking form1 password is: " + JSON.stringify(expectedPassword));
}

async function userOpenAutocompleteOnForm1(autoFillInsecureForms) {
  await SpecialPowers.pushPrefEnv({"set": [
    ["signon.autofillForms.http", autoFillInsecureForms],
  ]});
  await reinitializeForm(1);
  const autocompleteItems = await popupBy();

  const popupState = await getPopupState();
  is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");

  const expectedMenuItems = [INSECURE_WARNING_TEXT,
                           "No username (" + DATE_NOW_STRING + ")",
                           "tempuser1",
                           "testuser2",
                           "testuser3",
                           "zzzuser4"];
  checkAutoCompleteResults(autocompleteItems, expectedMenuItems, "mochi.test", "Check all menuitems are displayed correctly.");
}

async function userPressedDown_passwordIs(value) {
  synthesizeKey("KEY_ArrowDown");
  await Promise.resolve(); // let focus happen
  checkACFormPasswordField(value);
}

async function userPressedEnter_passwordIs(value) {
  synthesizeKey("KEY_Enter");
  await Promise.resolve(); // let focus happen
  checkACFormPasswordField(value);
}

async function noPopupOnForm(formIndex, reason) {
  await SpecialPowers.pushPrefEnv({"set": [
    ["signon.autofillForms.http", true],
  ]});
  await reinitializeForm(formIndex);

  // Trigger autocomplete popup
  synthesizeKey("KEY_ArrowDown"); // open
  let popupState = await getPopupState();
  is(popupState.open, false, reason);
}

add_setup(async () => {
  await setStoredLoginsAsync(
    // login0 has no username, so should be filtered out from the autocomplete list.
    [location.origin, "http://autocomplete:8888", null, "", "user0pass", "", "pword"],
    [location.origin, "http://autocomplete:8888", null, "tempuser1", "temppass1", "uname", "pword"],
    [location.origin, "http://autocomplete:8888", null, "testuser2", "testpass2", "uname", "pword"],
    [location.origin, "http://autocomplete:8888", null, "testuser3", "testpass3", "uname", "pword"],
    [location.origin, "http://autocomplete:8888", null, "zzzuser4", "zzzpass4", "uname", "pword"]
  );
  createLoginForm({
    num: 1,
    action: "http://autocomplete:8888/formtest.js"
  });
  createLoginForm({
    num: 2,
    actio: "http://autocomplete:8888/formtest.js",
    password: {
      readonly: true
    }
  });
  createLoginForm({
    num: 3,
    action: "http://autocomplete:8888/formtest.js",
    password: {
      disabled: true
    }
  });
  listenForUnexpectedPopupShown();
});

add_task(async function form1_initial_empty() {
  await SimpleTest.promiseFocus(window);

  // Make sure initial form is empty.
  checkACFormPasswordField("");
  let popupState = await getPopupState();
  is(popupState.open, false, "Check popup is initially closed");
});

add_task(async function noAutocompleteForReadonlyField() {
  await noPopupOnForm(2, "Check popup is closed for a readonly field.");
});

add_task(async function noAutocompleteForDisabledField() {
  await noPopupOnForm(3, "Check popup is closed for a disabled field.");
});

add_task(async function insecureAutoFill_EnterOnWarning() {
  await userOpenAutocompleteOnForm1(true);
  await userPressedDown_passwordIs("");
  await userPressedEnter_passwordIs("");
});

add_task(async function insecureAutoFill_EnterOnLogin() {
  await userOpenAutocompleteOnForm1(true);
  await userPressedDown_passwordIs(""); // select insecure warning
  await userPressedDown_passwordIs(""); // select login
  await userPressedEnter_passwordIs("user0pass");
});

add_task(async function noInsecureAutoFill_EnterOnWarning() {
  await userOpenAutocompleteOnForm1(false);
  await userPressedDown_passwordIs(""); // select insecure warning
  await userPressedEnter_passwordIs("");
});

add_task(async function noInsecureAutoFill_EnterOnLogin() {
  await userOpenAutocompleteOnForm1(false);
  await userPressedDown_passwordIs(""); // select insecure warning
  await userPressedDown_passwordIs(""); // select login
  await userPressedEnter_passwordIs("user0pass");
});

</script>
</pre>
</body>
</html>
