From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../tests/browser/browser_contextmenuFillLogins.js | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js (limited to 'browser/components/aboutlogins/tests/browser/browser_contextmenuFillLogins.js') 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 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]); +} -- cgit v1.2.3