зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1595154, add a test for form fillin that uses a child iframe loaded in a separate process, r=MattN
Differential Revision: https://phabricator.services.mozilla.com/D52723 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c93677f198
Коммит
a3b79c2f38
|
@ -2,6 +2,7 @@
|
|||
head = head.js
|
||||
support-files =
|
||||
../fixtures/autocomplete_basic.html
|
||||
../fixtures/autocomplete_iframe.html
|
||||
../fixtures/autocomplete_simple_basic.html
|
||||
|
||||
[browser_autocomplete_footer.js]
|
||||
|
@ -15,6 +16,7 @@ skip-if = (verify && (os == 'win' || os == 'mac'))
|
|||
[browser_first_time_use_doorhanger.js]
|
||||
skip-if = verify
|
||||
[browser_manageAddressesDialog.js]
|
||||
[browser_remoteiframe.js]
|
||||
[browser_submission_in_private_mode.js]
|
||||
[browser_update_doorhanger.js]
|
||||
skip-if = true # bug 1426981 # Bug 1445538
|
||||
|
|
|
@ -3,20 +3,6 @@
|
|||
const URL = BASE_URL + "autocomplete_basic.html";
|
||||
const PRIVACY_PREF_URL = "about:preferences#privacy";
|
||||
|
||||
async function expectWarningText(browser, expectedText) {
|
||||
const {
|
||||
autoCompletePopup: { richlistbox: itemsBox },
|
||||
} = browser;
|
||||
const warningBox = itemsBox.querySelector(
|
||||
".autocomplete-richlistitem:last-child"
|
||||
)._warningTextBox;
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
return warningBox.textContent == expectedText;
|
||||
}, `Waiting for expected warning text: ${expectedText}, Got ${warningBox.textContent}`);
|
||||
ok(true, `Got expected warning text: ${expectedText}`);
|
||||
}
|
||||
|
||||
add_task(async function setup_storage() {
|
||||
await saveAddress(TEST_ADDRESS_2);
|
||||
await saveAddress(TEST_ADDRESS_3);
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
"use strict";
|
||||
|
||||
const IFRAME_URL_PATH = BASE_URL + "autocomplete_iframe.html";
|
||||
const PRIVACY_PREF_URL = "about:preferences#privacy";
|
||||
|
||||
// Start by adding a few addresses to storage.
|
||||
add_task(async function setup_storage() {
|
||||
await saveAddress(TEST_ADDRESS_2);
|
||||
await saveAddress(TEST_ADDRESS_4);
|
||||
await saveAddress(TEST_ADDRESS_5);
|
||||
});
|
||||
|
||||
// Verify that form fillin works in a remote iframe, and that changing
|
||||
// a field updates storage.
|
||||
add_task(async function test_iframe_autocomplete() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
|
||||
});
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
IFRAME_URL_PATH,
|
||||
true
|
||||
);
|
||||
let browser = tab.linkedBrowser;
|
||||
let iframeBC = browser.browsingContext.getChildren()[1];
|
||||
await openPopupForSubframe(browser, iframeBC, "#street-address");
|
||||
|
||||
// Highlight the first item in the list. We want to verify
|
||||
// that the warning text is correct to ensure that the preview is
|
||||
// performed properly.
|
||||
|
||||
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
|
||||
await expectWarningText(browser, "Autofills address");
|
||||
|
||||
// Highlight and select the second item in the list
|
||||
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
|
||||
await expectWarningText(browser, "Also autofills organization, email");
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
let promiseShown = BrowserTestUtils.waitForEvent(
|
||||
PopupNotifications.panel,
|
||||
"popupshown"
|
||||
);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
let loadPromise = BrowserTestUtils.browserLoaded(browser, true);
|
||||
await SpecialPowers.spawn(iframeBC, [], async function() {
|
||||
Assert.equal(
|
||||
content.document.getElementById("street-address").value,
|
||||
"32 Vassar Street MIT Room 32-G524"
|
||||
);
|
||||
Assert.equal(content.document.getElementById("country").value, "US");
|
||||
|
||||
let org = content.document.getElementById("organization");
|
||||
Assert.equal(org.value, "World Wide Web Consortium");
|
||||
|
||||
// Now, modify the organization.
|
||||
org.setUserInput("Example Inc.");
|
||||
|
||||
await new Promise(resolve => content.setTimeout(resolve, 1000));
|
||||
content.document.querySelector("input[type=submit]").click();
|
||||
});
|
||||
|
||||
await loadPromise;
|
||||
await promiseShown;
|
||||
|
||||
let onChanged = TestUtils.topicObserved("formautofill-storage-changed");
|
||||
await clickDoorhangerButton(MAIN_BUTTON);
|
||||
await onChanged;
|
||||
|
||||
// Check that the organization was updated properly.
|
||||
let addresses = await getAddresses();
|
||||
is(addresses.length, 3, "Still 1 address in storage");
|
||||
is(
|
||||
addresses[1].organization,
|
||||
"Example Inc.",
|
||||
"Verify the organization field"
|
||||
);
|
||||
|
||||
// Fill in the details again and then clear the form from the dropdown.
|
||||
await openPopupForSubframe(browser, iframeBC, "#street-address");
|
||||
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// Open the dropdown and select the Clear Form item.
|
||||
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
|
||||
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
await SpecialPowers.spawn(iframeBC, [], async function() {
|
||||
Assert.equal(content.document.getElementById("street-address").value, "");
|
||||
Assert.equal(content.document.getElementById("country").value, "");
|
||||
Assert.equal(content.document.getElementById("organization").value, "");
|
||||
});
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
// Choose preferences from the autocomplete dropdown within an iframe.
|
||||
add_task(async function test_iframe_autocomplete_preferences() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
|
||||
});
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
IFRAME_URL_PATH,
|
||||
true
|
||||
);
|
||||
let browser = tab.linkedBrowser;
|
||||
let iframeBC = browser.browsingContext.getChildren()[1];
|
||||
await openPopupForSubframe(browser, iframeBC, "#organization");
|
||||
|
||||
await expectWarningText(browser, "Also autofills address, email");
|
||||
|
||||
const prefTabPromise = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
PRIVACY_PREF_URL
|
||||
);
|
||||
|
||||
// Select the preferences item.
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
info(`expecting tab: about:preferences#privacy opened`);
|
||||
const prefTab = await prefTabPromise;
|
||||
info(`expecting tab: about:preferences#privacy removed`);
|
||||
BrowserTestUtils.removeTab(prefTab);
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
|
@ -6,6 +6,7 @@ support-files =
|
|||
../head.js
|
||||
!/browser/extensions/formautofill/test/fixtures/autocomplete_basic.html
|
||||
../../fixtures/autocomplete_creditcard_basic.html
|
||||
../../fixtures/autocomplete_creditcard_iframe.html
|
||||
head_cc.js
|
||||
|
||||
[browser_creditCard_doorhanger.js]
|
||||
|
|
|
@ -149,6 +149,61 @@ add_task(async function test_submit_untouched_creditCard_form() {
|
|||
await removeAllRecords();
|
||||
});
|
||||
|
||||
add_task(async function test_submit_untouched_creditCard_form_iframe() {
|
||||
if (!OSKeyStoreTestUtils.canTestOSKeyStoreLogin()) {
|
||||
todo(
|
||||
OSKeyStoreTestUtils.canTestOSKeyStoreLogin(),
|
||||
"Cannot test OS key store login on official builds."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
|
||||
});
|
||||
await saveCreditCard(TEST_CREDIT_CARD_1);
|
||||
let creditCards = await getCreditCards();
|
||||
is(creditCards.length, 1, "1 credit card in storage");
|
||||
|
||||
let osKeyStoreLoginShown = OSKeyStoreTestUtils.waitForOSKeyStoreLogin(true);
|
||||
let onUsed = TestUtils.topicObserved(
|
||||
"formautofill-storage-changed",
|
||||
(subject, data) => data == "notifyUsed"
|
||||
);
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: CREDITCARD_FORM_IFRAME_URL },
|
||||
async function(browser) {
|
||||
let iframeBC = browser.browsingContext.getChildren()[0];
|
||||
await openPopupForSubframe(browser, iframeBC, "form #cc-name");
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
await osKeyStoreLoginShown;
|
||||
await SpecialPowers.spawn(iframeBC, [], async function() {
|
||||
let form = content.document.getElementById("form");
|
||||
|
||||
// Wait 1000ms before submission to make sure the input value applied
|
||||
await new Promise(resolve => content.setTimeout(resolve, 1000));
|
||||
form.querySelector("input[type=submit]").click();
|
||||
});
|
||||
|
||||
await sleep(1000);
|
||||
is(PopupNotifications.panel.state, "closed", "Doorhanger is hidden");
|
||||
}
|
||||
);
|
||||
await onUsed;
|
||||
|
||||
creditCards = await getCreditCards();
|
||||
is(creditCards.length, 1, "Still 1 credit card");
|
||||
is(creditCards[0].timesUsed, 1, "timesUsed field set to 1");
|
||||
is(
|
||||
SpecialPowers.getIntPref(CREDITCARDS_USED_STATUS_PREF),
|
||||
3,
|
||||
"User has used autofill"
|
||||
);
|
||||
SpecialPowers.clearUserPref(CREDITCARDS_USED_STATUS_PREF);
|
||||
await removeAllRecords();
|
||||
});
|
||||
|
||||
add_task(async function test_submit_changed_subset_creditCard_form() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* exported MANAGE_ADDRESSES_DIALOG_URL, MANAGE_CREDIT_CARDS_DIALOG_URL, EDIT_ADDRESS_DIALOG_URL, EDIT_CREDIT_CARD_DIALOG_URL,
|
||||
BASE_URL, TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3, TEST_ADDRESS_4, TEST_ADDRESS_5, TEST_ADDRESS_CA_1, TEST_ADDRESS_DE_1,
|
||||
TEST_ADDRESS_IE_1,
|
||||
TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL, CREDITCARD_FORM_URL,
|
||||
TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL, CREDITCARD_FORM_URL, CREDITCARD_FORM_IFRAME_URL
|
||||
FTU_PREF, ENABLED_AUTOFILL_ADDRESSES_PREF, AUTOFILL_CREDITCARDS_AVAILABLE_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF,
|
||||
SUPPORTED_COUNTRIES_PREF,
|
||||
SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF, SYNC_CREDITCARDS_PREF, SYNC_CREDITCARDS_AVAILABLE_PREF, CREDITCARDS_USED_STATUS_PREF,
|
||||
DEFAULT_REGION_PREF,
|
||||
sleep, expectPopupOpen, openPopupOn, expectPopupClose, closePopup, clickDoorhangerButton,
|
||||
getAddresses, saveAddress, removeAddresses, saveCreditCard,
|
||||
sleep, expectPopupOpen, openPopupOn, openPopupForSubframe, expectPopupClose, closePopup, closePopupForSubframe,
|
||||
clickDoorhangerButton, getAddresses, saveAddress, removeAddresses, saveCreditCard,
|
||||
getDisplayedPopupItems, getDoorhangerCheckbox,
|
||||
getNotification, getDoorhangerButton, removeAllRecords, testDialog */
|
||||
getNotification, getDoorhangerButton, removeAllRecords, expectWarningText, testDialog */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -32,6 +32,10 @@ const CREDITCARD_FORM_URL =
|
|||
"https://example.org" +
|
||||
HTTP_TEST_PATH +
|
||||
"creditCard/autocomplete_creditcard_basic.html";
|
||||
const CREDITCARD_FORM_IFRAME_URL =
|
||||
"https://example.org" +
|
||||
HTTP_TEST_PATH +
|
||||
"creditCard/autocomplete_creditcard_iframe.html";
|
||||
|
||||
const FTU_PREF = "extensions.formautofill.firstTimeUse";
|
||||
const CREDITCARDS_USED_STATUS_PREF = "extensions.formautofill.creditCards.used";
|
||||
|
@ -175,7 +179,7 @@ async function sleep(ms = 500) {
|
|||
await new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function focusAndWaitForFieldsIdentified(browser, selector) {
|
||||
async function focusAndWaitForFieldsIdentified(browserOrContext, selector) {
|
||||
info("expecting the target input being focused and identified");
|
||||
/* eslint no-shadow: ["error", { "allow": ["selector", "previouslyFocused", "previouslyIdentified"] }] */
|
||||
|
||||
|
@ -197,10 +201,10 @@ async function focusAndWaitForFieldsIdentified(browser, selector) {
|
|||
FormAutofillParent.addMessageObserver(fieldsIdentifiedObserver);
|
||||
});
|
||||
|
||||
const { previouslyFocused, previouslyIdentified } = await ContentTask.spawn(
|
||||
browser,
|
||||
{ selector },
|
||||
async function({ selector }) {
|
||||
const { previouslyFocused, previouslyIdentified } = await SpecialPowers.spawn(
|
||||
browserOrContext,
|
||||
[selector],
|
||||
async function(selector) {
|
||||
const { FormLikeFactory } = ChromeUtils.import(
|
||||
"resource://gre/modules/FormLikeFactory.jsm"
|
||||
);
|
||||
|
@ -225,6 +229,20 @@ async function focusAndWaitForFieldsIdentified(browser, selector) {
|
|||
info("!previouslyFocused");
|
||||
}
|
||||
|
||||
// If a browsing context was supplied, focus its parent frame as well.
|
||||
if (
|
||||
browserOrContext instanceof BrowsingContext &&
|
||||
browserOrContext.parent != browserOrContext
|
||||
) {
|
||||
await SpecialPowers.spawn(
|
||||
browserOrContext.parent,
|
||||
[browserOrContext],
|
||||
async function(browsingContext) {
|
||||
browsingContext.embedderElement.focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (previouslyIdentified) {
|
||||
info("previouslyIdentified");
|
||||
return;
|
||||
|
@ -236,7 +254,7 @@ async function focusAndWaitForFieldsIdentified(browser, selector) {
|
|||
FormAutofillParent.removeMessageObserver(fieldsIdentifiedObserver);
|
||||
|
||||
await sleep();
|
||||
await ContentTask.spawn(browser, {}, async function() {
|
||||
await SpecialPowers.spawn(browserOrContext, [], async function() {
|
||||
const { FormLikeFactory } = ChromeUtils.import(
|
||||
"resource://gre/modules/FormLikeFactory.jsm"
|
||||
);
|
||||
|
@ -277,6 +295,14 @@ async function openPopupOn(browser, selector) {
|
|||
await expectPopupOpen(browser);
|
||||
}
|
||||
|
||||
async function openPopupForSubframe(browser, frameBrowsingContext, selector) {
|
||||
await SimpleTest.promiseFocus(browser);
|
||||
await focusAndWaitForFieldsIdentified(frameBrowsingContext, selector);
|
||||
info("openPopupOn: before VK_DOWN");
|
||||
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, frameBrowsingContext);
|
||||
await expectPopupOpen(browser);
|
||||
}
|
||||
|
||||
async function expectPopupClose(browser) {
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
() => !browser.autoCompletePopup.popupOpen,
|
||||
|
@ -285,7 +311,15 @@ async function expectPopupClose(browser) {
|
|||
}
|
||||
|
||||
async function closePopup(browser) {
|
||||
await ContentTask.spawn(browser, {}, async function() {
|
||||
await SpecialPowers.spawn(browser, [], async function() {
|
||||
content.document.activeElement.blur();
|
||||
});
|
||||
|
||||
await expectPopupClose(browser);
|
||||
}
|
||||
|
||||
async function closePopupForSubframe(browser, frameBrowsingContext) {
|
||||
await SpecialPowers.spawn(frameBrowsingContext, [], async function() {
|
||||
content.document.activeElement.blur();
|
||||
});
|
||||
|
||||
|
@ -415,6 +449,26 @@ async function waitForFocusAndFormReady(win) {
|
|||
]);
|
||||
}
|
||||
|
||||
// Verify that the warning in the autocomplete popup has the expected text.
|
||||
async function expectWarningText(browser, expectedText) {
|
||||
const {
|
||||
autoCompletePopup: { richlistbox: itemsBox },
|
||||
} = browser;
|
||||
let warningBox = itemsBox.querySelector(
|
||||
".autocomplete-richlistitem:last-child"
|
||||
);
|
||||
|
||||
while (warningBox.collapsed) {
|
||||
warningBox = warningBox.previousSibling;
|
||||
}
|
||||
warningBox = warningBox._warningTextBox;
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
return warningBox.textContent == expectedText;
|
||||
}, `Waiting for expected warning text: ${expectedText}, Got ${warningBox.textContent}`);
|
||||
ok(true, `Got expected warning text: ${expectedText}`);
|
||||
}
|
||||
|
||||
async function testDialog(url, testFn, arg = undefined) {
|
||||
// Skip this step for test cards that lack an encrypted
|
||||
// number since they will fail to decrypt.
|
||||
|
|
12
browser/extensions/formautofill/test/fixtures/autocomplete_creditcard_iframe.html
поставляемый
Normal file
12
browser/extensions/formautofill/test/fixtures/autocomplete_creditcard_iframe.html
поставляемый
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Form Autofill Credit Card With Remote IFrame Demo Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="https://test1.example.com:443/browser/browser/extensions/formautofill/test/browser/creditCard/autocomplete_creditcard_basic.html" width="400" height="400">
|
||||
</iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Form Autofill With Remote IFrame Demo Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="unused" src="data:text/html,<body>Just here to ensure code doesn't always pick the first child iframe.</body>"></iframe>
|
||||
<iframe src="https://test1.example.com:443/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html" width="400" height="400">
|
||||
</iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче