summaryrefslogtreecommitdiffstats
path: root/browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js')
-rw-r--r--browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js185
1 files changed, 185 insertions, 0 deletions
diff --git a/browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js b/browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js
new file mode 100644
index 0000000000..a10d92baac
--- /dev/null
+++ b/browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js
@@ -0,0 +1,185 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_setup(async function () {
+ TEST_LOGIN1 = await addLogin(TEST_LOGIN1);
+ await BrowserTestUtils.openNewForegroundTab({
+ gBrowser,
+ url: "about:logins",
+ });
+ registerCleanupFunction(() => {
+ BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ });
+});
+
+const gTests = [
+ {
+ name: "test contextmenu on password field in create login view",
+ async setup(browser) {
+ // load up the create login view
+ await SpecialPowers.spawn(browser, [], async () => {
+ let loginList = Cu.waiveXrays(
+ content.document.querySelector("login-list")
+ );
+ let createButton = loginList._createLoginButton;
+ createButton.click();
+ });
+ },
+ },
+];
+
+if (OSKeyStoreTestUtils.canTestOSKeyStoreLogin()) {
+ gTests[gTests.length] = {
+ name: "test contextmenu on password field in edit login view",
+ async setup(browser) {
+ let osAuthDialogShown = OSKeyStoreTestUtils.waitForOSKeyStoreLogin(true);
+
+ // load up the edit login view
+ await SpecialPowers.spawn(
+ browser,
+ [LoginHelper.loginToVanillaObject(TEST_LOGIN1)],
+ async login => {
+ let loginList = content.document.querySelector("login-list");
+ let loginListItem = loginList.shadowRoot.querySelector(
+ ".login-list-item[data-guid]:not([hidden])"
+ );
+ info("Clicking on the first login");
+
+ loginListItem.click();
+ let loginItem = Cu.waiveXrays(
+ content.document.querySelector("login-item")
+ );
+ await ContentTaskUtils.waitForCondition(() => {
+ return (
+ loginItem._login.guid == loginListItem.dataset.guid &&
+ loginItem._login.guid == login.guid
+ );
+ }, "Waiting for login item to get populated");
+ let editButton = loginItem.shadowRoot.querySelector(".edit-button");
+ editButton.click();
+ }
+ );
+ await osAuthDialogShown;
+ await SpecialPowers.spawn(browser, [], async () => {
+ let loginItem = Cu.waiveXrays(
+ content.document.querySelector("login-item")
+ );
+ await ContentTaskUtils.waitForCondition(
+ () => loginItem.dataset.editing,
+ "Waiting for login-item to be in editing state"
+ );
+ });
+ },
+ };
+}
+
+/**
+ * Synthesize mouse clicks to open the password manager context menu popup
+ * for a target input element.
+ *
+ */
+async function openContextMenuForPasswordInput(browser) {
+ const doc = browser.ownerDocument;
+ const CONTEXT_MENU = doc.getElementById("contentAreaContextMenu");
+
+ let contextMenuShownPromise = BrowserTestUtils.waitForEvent(
+ CONTEXT_MENU,
+ "popupshown"
+ );
+
+ let passwordInputCoords = await SpecialPowers.spawn(browser, [], async () => {
+ let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
+
+ // The password display field is in the DOM when password input is unfocused.
+ // To get the password input field, ensure it receives focus.
+ let passwordInput = loginItem.shadowRoot.querySelector(
+ "input[type='password']"
+ );
+ passwordInput.focus();
+ passwordInput = loginItem.shadowRoot.querySelector(
+ "input[name='password']"
+ );
+
+ passwordInput.focus();
+ let passwordRect = passwordInput.getBoundingClientRect();
+
+ // listen for the contextmenu event so we can assert on receiving it
+ // and examine the target
+ content.contextmenuPromise = new Promise(resolve => {
+ content.document.body.addEventListener(
+ "contextmenu",
+ event => {
+ info(
+ `Received event on target: ${event.target.nodeName}, type: ${event.target.type}`
+ );
+ content.console.log("got contextmenu event: ", event);
+ resolve(event);
+ },
+ { once: true }
+ );
+ });
+
+ let coords = {
+ x: passwordRect.x + passwordRect.width / 2,
+ y: passwordRect.y + passwordRect.height / 2,
+ };
+ return coords;
+ });
+
+ // add the offsets of the <browser> in the chrome window
+ let browserOffsets = browser.getBoundingClientRect();
+ let offsetX = browserOffsets.x + passwordInputCoords.x;
+ let offsetY = browserOffsets.y + passwordInputCoords.y;
+
+ // Synthesize a right mouse click over the password input element, we have to trigger
+ // both events because formfill code relies on this event happening before the contextmenu
+ // (which it does for real user input) in order to not show the password autocomplete.
+ let eventDetails = { type: "mousedown", button: 2 };
+ await EventUtils.synthesizeMouseAtPoint(offsetX, offsetY, eventDetails);
+
+ // Synthesize a contextmenu event to actually open the context menu.
+ eventDetails = { type: "contextmenu", button: 2 };
+ await EventUtils.synthesizeMouseAtPoint(offsetX, offsetY, eventDetails);
+
+ await SpecialPowers.spawn(browser, [], async () => {
+ let event = await content.contextmenuPromise;
+ // XXX the event target here is the login-item element,
+ // not the input[type='password'] in its shadowRoot
+ info("contextmenu event target: " + event.target.nodeName);
+ });
+
+ info("waiting for contextMenuShownPromise");
+ await contextMenuShownPromise;
+ return CONTEXT_MENU;
+}
+
+async function testContextMenuOnInputField(testData) {
+ let browser = gBrowser.selectedBrowser;
+
+ await SimpleTest.promiseFocus(browser.ownerGlobal);
+ await testData.setup(browser);
+
+ info("test setup completed");
+ let contextMenu = await openContextMenuForPasswordInput(browser);
+ let fillItem = contextMenu.querySelector("#fill-login");
+ Assert.ok(fillItem, "fill menu item exists");
+ Assert.ok(
+ fillItem && EventUtils.isHidden(fillItem),
+ "fill menu item is hidden"
+ );
+
+ let promiseHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
+ info("Calling hidePopup on contextMenu");
+ contextMenu.hidePopup();
+ info("waiting for promiseHidden");
+ await promiseHidden;
+}
+
+for (let testData of gTests) {
+ let tmp = {
+ async [testData.name]() {
+ await testContextMenuOnInputField(testData);
+ },
+ };
+ add_task(tmp[testData.name]);
+}