Bug 1278158 - Allowing filling login forms with an inputElement but without loginFormForFill. r=MattN

MozReview-Commit-ID: 2aZCvMpH1eH

--HG--
extra : transplant_source : M3%B5i.FM%99%84%07%7E%E2%81%08y%AA%DC%BE%3C%ED
This commit is contained in:
Saad Quadri 2016-06-08 13:59:05 -07:00
Родитель dd4f3dccc6
Коммит 54056e201c
5 изменённых файлов: 153 добавлений и 61 удалений

Просмотреть файл

@ -470,7 +470,7 @@ var LoginManagerContent = {
*/
fillForm({ topDocument, loginFormOrigin, loginsFound, recipes, inputElement }) {
let topState = this.stateForDocument(topDocument);
if (!topState.loginFormForFill) {
if (!inputElement && !topState.loginFormForFill) {
log("fillForm: There is no login form anymore. The form may have been",
"removed or the document may have changed.");
return;

Просмотреть файл

@ -3,6 +3,7 @@ support-files =
../formsubmit.sjs
authenticate.sjs
form_basic.html
form_basic_iframe.html
formless_basic.html
form_same_origin_action.html
form_cross_origin_insecure_action.html
@ -46,7 +47,8 @@ support-files =
[browser_passwordmgr_editing.js]
skip-if = os == "linux"
[browser_context_menu.js]
subsuite = clipboard
skip-if = e10s
[browser_context_menu_iframe.js]
skip-if = e10s
[browser_passwordmgr_contextmenu.js]
subsuite = clipboard

Просмотреть файл

@ -229,65 +229,6 @@ add_task(function* test_context_menu_username_login_fill() {
});
});
/**
* Check if the password field is correctly filled when it's in an iframe.
*/
add_task(function* test_context_menu_iframe_fill() {
Services.prefs.setBoolPref("signon.schemeUpgrades", true);
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH,
}, function* (browser) {
let iframe = browser.contentWindow.document.getElementById("test-iframe");
let passwordInput = iframe.contentDocument.getElementById("form-basic-password");
let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown");
let eventDetails = {type: "contextmenu", button: 2};
// To click at the right point we have to take into account the iframe offset.
let iframeRect = iframe.getBoundingClientRect();
let inputRect = passwordInput.getBoundingClientRect();
let clickPos = {
offsetX: iframeRect.left + inputRect.width / 2,
offsetY: iframeRect.top + inputRect.height / 2,
};
// Synthesize a right mouse click over the password input element.
BrowserTestUtils.synthesizeMouse(passwordInput, clickPos.offsetX, clickPos.offsetY, eventDetails, browser);
yield contextMenuShownPromise;
// Synthesize a mouse click over the fill login menu header.
let popupHeader = document.getElementById("fill-login");
let popupShownPromise = BrowserTestUtils.waitForEvent(popupHeader, "popupshown");
EventUtils.synthesizeMouseAtCenter(popupHeader, {});
yield popupShownPromise;
let popupMenu = document.getElementById("fill-login-popup");
// Stores the original value of username
let usernameInput = iframe.contentDocument.getElementById("form-basic-username");
let usernameOriginalValue = usernameInput.value;
// Execute the command of the first login menuitem found at the context menu.
let firstLoginItem = popupMenu.getElementsByClassName("context-login-item")[0];
firstLoginItem.doCommand();
yield BrowserTestUtils.waitForEvent(passwordInput, "input", "Password input value changed");
// Find the used login by it's username.
let login = getLoginFromUsername(firstLoginItem.label);
Assert.equal(login.password, passwordInput.value, "Password filled and correct.");
Assert.equal(usernameOriginalValue,
usernameInput.value,
"Username value was not changed.");
let contextMenu = document.getElementById("contentAreaContextMenu");
contextMenu.hidePopup();
});
});
/**
* Synthesize mouse clicks to open the password manager context menu popup
* for a target password input element.

Просмотреть файл

@ -0,0 +1,136 @@
/*
* Test the password manager context menu.
*/
"use strict";
const TEST_HOSTNAME = "https://example.com";
// Test with a page that only has a form within an iframe, not in the top-level document
const IFRAME_PAGE_PATH = "/browser/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html";
/**
* Initialize logins needed for the tests and disable autofill
* for login forms for easier testing of manual fill.
*/
add_task(function* test_initialize() {
Services.prefs.setBoolPref("signon.autofillForms", false);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("signon.autofillForms");
Services.prefs.clearUserPref("signon.schemeUpgrades");
});
for (let login of loginList()) {
Services.logins.addLogin(login);
}
});
/**
* Check if the password field is correctly filled when it's in an iframe.
*/
add_task(function* test_context_menu_iframe_fill() {
Services.prefs.setBoolPref("signon.schemeUpgrades", true);
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_HOSTNAME + IFRAME_PAGE_PATH
}, function* (browser) {
let iframe = browser.contentWindow.document.getElementById("test-iframe");
let passwordInput = iframe.contentDocument.getElementById("form-basic-password");
let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown");
let eventDetails = {type: "contextmenu", button: 2};
// To click at the right point we have to take into account the iframe offset.
let iframeRect = iframe.getBoundingClientRect();
let inputRect = passwordInput.getBoundingClientRect();
let clickPos = {
offsetX: iframeRect.left + inputRect.width / 2,
offsetY: iframeRect.top + inputRect.height / 2,
};
// Synthesize a right mouse click over the password input element.
BrowserTestUtils.synthesizeMouse(passwordInput, clickPos.offsetX, clickPos.offsetY, eventDetails, browser);
yield contextMenuShownPromise;
// Synthesize a mouse click over the fill login menu header.
let popupHeader = document.getElementById("fill-login");
let popupShownPromise = BrowserTestUtils.waitForEvent(popupHeader, "popupshown");
EventUtils.synthesizeMouseAtCenter(popupHeader, {});
yield popupShownPromise;
let popupMenu = document.getElementById("fill-login-popup");
// Stores the original value of username
let usernameInput = iframe.contentDocument.getElementById("form-basic-username");
let usernameOriginalValue = usernameInput.value;
// Execute the command of the first login menuitem found at the context menu.
let firstLoginItem = popupMenu.getElementsByClassName("context-login-item")[0];
firstLoginItem.doCommand();
yield BrowserTestUtils.waitForEvent(passwordInput, "input", "Password input value changed");
// Find the used login by it's username.
let login = getLoginFromUsername(firstLoginItem.label);
Assert.equal(login.password, passwordInput.value, "Password filled and correct.");
Assert.equal(usernameOriginalValue,
usernameInput.value,
"Username value was not changed.");
let contextMenu = document.getElementById("contentAreaContextMenu");
contextMenu.hidePopup();
});
});
/**
* Search for a login by it's username.
*
* Only unique login/hostname combinations should be used at this test.
*/
function getLoginFromUsername(username) {
return loginList().find(login => login.username == username);
}
/**
* List of logins used for the test.
*
* We should only use unique usernames in this test,
* because we need to search logins by username. There is one duplicate u+p combo
* in order to test de-duping in the menu.
*/
function loginList() {
return [
LoginTestUtils.testData.formLogin({
hostname: "https://example.com",
formSubmitURL: "https://example.com",
username: "username",
password: "password",
}),
// Same as above but HTTP in order to test de-duping.
LoginTestUtils.testData.formLogin({
hostname: "http://example.com",
formSubmitURL: "http://example.com",
username: "username",
password: "password",
}),
LoginTestUtils.testData.formLogin({
hostname: "http://example.com",
formSubmitURL: "http://example.com",
username: "username1",
password: "password1",
}),
LoginTestUtils.testData.formLogin({
hostname: "https://example.com",
formSubmitURL: "https://example.com",
username: "username2",
password: "password2",
}),
LoginTestUtils.testData.formLogin({
hostname: "http://example.org",
formSubmitURL: "http://example.org",
username: "username-cross-origin",
password: "password-cross-origin",
}),
];
}

Просмотреть файл

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<!-- Form in an iframe -->
<iframe src="https://example.org/browser/toolkit/components/passwordmgr/test/browser/form_basic.html" id="test-iframe"></iframe>
</body>
</html>