browser_scroll-to-text-fragment-from-context-menu.js (3352B)
1 /* Any copyright is dedicated to the Public Domain. 2 https://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Opens a link (with a #:~:text= fragment) via the three context-menu 8 * commands (new tab, new window, private window) and checks that the 9 * destination page really scrolled to the fragment. 10 * 11 * See Bug 1955664. 12 */ 13 14 const TARGET_URL = 15 getRootDirectory(gTestPath).replace( 16 "chrome://mochitests/content", 17 "https://example.org" 18 ) + 19 "scroll-to-text-fragment-from-browser-chrome-target.html" + 20 "#:~:text=This%20is%20the%20text%20fragment%20to%20scroll%20to."; 21 22 // A minimal parent page served as a data: URL with one <a id="theLink">. 23 const PARENT_DATA_URL = 24 "data:text/html;base64," + 25 btoa(`data:text/html,<a id="theLink" href="${TARGET_URL}">Open link</a>`); 26 27 // Map variant -> context-menu command ID. 28 const VARIANTS = { 29 TAB: "context-openlinkintab", 30 WINDOW: "context-openlink", 31 PRIVATE: "context-openlinkprivate", 32 }; 33 34 async function openContextMenu(browser, selector) { 35 const menu = document.getElementById("contentAreaContextMenu"); 36 const shown = BrowserTestUtils.waitForEvent(menu, "popupshown"); 37 38 await BrowserTestUtils.synthesizeMouseAtCenter( 39 selector, 40 { type: "contextmenu", button: 2 }, 41 browser 42 ); 43 await shown; 44 return menu; 45 } 46 47 function waitForScroll(browser) { 48 return SpecialPowers.spawn(browser, [], () => { 49 return new Promise(resolve => { 50 if (content.scrollY > 0) { 51 resolve(true); 52 } else { 53 content.addEventListener("scroll", () => resolve(true), { 54 once: true, 55 capture: true, 56 }); 57 } 58 }); 59 }); 60 } 61 62 async function runVariant(menuItemId) { 63 await BrowserTestUtils.withNewTab( 64 { gBrowser, url: PARENT_DATA_URL }, 65 async browser => { 66 const menu = await openContextMenu(browser, "#theLink"); 67 68 let opened; 69 switch (menuItemId) { 70 case VARIANTS.TAB: 71 opened = BrowserTestUtils.waitForNewTab(gBrowser); 72 break; 73 case VARIANTS.WINDOW: 74 opened = BrowserTestUtils.waitForNewWindow(); 75 break; 76 case VARIANTS.PRIVATE: 77 opened = BrowserTestUtils.waitForNewWindow({ private: true }); 78 break; 79 default: 80 throw new Error(`Unexpected context-menu id: ${menuItemId}`); 81 } 82 const popupHidden = BrowserTestUtils.waitForEvent(menu, "popuphidden"); 83 84 const item = menu.ownerDocument.getElementById(menuItemId); 85 ok(!item.hidden, `${menuItemId} should be visible in this context`); 86 menu.activateItem(item); 87 88 await popupHidden; 89 const ctx = await opened; 90 91 const newBrowser = ctx.linkedBrowser || ctx.gBrowser.selectedBrowser; 92 93 await BrowserTestUtils.browserLoaded(newBrowser, false); 94 95 let scrolled = await waitForScroll(newBrowser); 96 ok(scrolled, `${menuItemId}: scrolled to text fragment`); 97 98 if (ctx.close) { 99 await BrowserTestUtils.closeWindow(ctx); // window 100 } else { 101 BrowserTestUtils.removeTab(ctx); // tab 102 } 103 } 104 ); 105 } 106 107 add_task(async function test_open_in_new_tab() { 108 await runVariant(VARIANTS.TAB); 109 }); 110 111 add_task(async function test_open_in_new_window() { 112 await runVariant(VARIANTS.WINDOW); 113 }); 114 115 add_task(async function test_open_in_private_window() { 116 await runVariant(VARIANTS.PRIVATE); 117 });