browser_view_image.js (6478B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const chrome_base = getRootDirectory(gTestPath); 7 8 /* import-globals-from contextmenu_common.js */ 9 Services.scriptloader.loadSubScript( 10 chrome_base + "contextmenu_common.js", 11 this 12 ); 13 const http_base = chrome_base.replace( 14 "chrome://mochitests/content", 15 "https://example.com" 16 ); 17 18 async function test_view_image_works({ page, selector, urlChecker }) { 19 let mainURL = http_base + page; 20 let accel = AppConstants.platform == "macosx" ? "metaKey" : "ctrlKey"; 21 let tests = { 22 tab: { 23 modifiers: { [accel]: true }, 24 async loadedPromise() { 25 return BrowserTestUtils.waitForNewTab(gBrowser, urlChecker, true).then( 26 t => t.linkedBrowser 27 ); 28 }, 29 cleanup(browser) { 30 BrowserTestUtils.removeTab(gBrowser.getTabForBrowser(browser)); 31 }, 32 }, 33 window: { 34 modifiers: { shiftKey: true }, 35 async loadedPromise() { 36 // Unfortunately we can't predict the URL so can't just pass that to waitForNewWindow 37 let w = await BrowserTestUtils.waitForNewWindow(); 38 let browser = w.gBrowser.selectedBrowser; 39 let getCx = () => browser.browsingContext; 40 await TestUtils.waitForCondition( 41 () => 42 getCx() && urlChecker(getCx().currentWindowGlobal.documentURI.spec) 43 ); 44 await SpecialPowers.spawn(browser, [], () => { 45 return ContentTaskUtils.waitForCondition( 46 () => content.document.readyState == "complete" 47 ); 48 }); 49 return browser; 50 }, 51 async cleanup(browser) { 52 return BrowserTestUtils.closeWindow(browser.ownerGlobal); 53 }, 54 }, 55 tab_default: { 56 modifiers: {}, 57 async loadedPromise() { 58 return BrowserTestUtils.waitForNewTab(gBrowser, urlChecker, true).then( 59 t => { 60 is(t.selected, false, "Tab should not be selected."); 61 return t.linkedBrowser; 62 } 63 ); 64 }, 65 cleanup(browser) { 66 is(gBrowser.tabs.length, 3, "number of tabs"); 67 BrowserTestUtils.removeTab(gBrowser.getTabForBrowser(browser)); 68 }, 69 }, 70 tab_default_flip_bg_pref: { 71 prefs: [["browser.tabs.loadInBackground", false]], 72 modifiers: {}, 73 async loadedPromise() { 74 return BrowserTestUtils.waitForNewTab(gBrowser, urlChecker, true).then( 75 t => { 76 is(t.selected, true, "Tab should be selected with pref flipped."); 77 return t.linkedBrowser; 78 } 79 ); 80 }, 81 cleanup(browser) { 82 is(gBrowser.tabs.length, 3, "number of tabs"); 83 BrowserTestUtils.removeTab(gBrowser.getTabForBrowser(browser)); 84 }, 85 }, 86 }; 87 await BrowserTestUtils.withNewTab(mainURL, async browser => { 88 await SpecialPowers.spawn(browser, [], () => { 89 return ContentTaskUtils.waitForCondition( 90 () => !content.document.documentElement.classList.contains("wait") 91 ); 92 }); 93 for (let [testLabel, test] of Object.entries(tests)) { 94 if (test.prefs) { 95 await SpecialPowers.pushPrefEnv({ set: test.prefs }); 96 } 97 let contextMenu = document.getElementById("contentAreaContextMenu"); 98 is( 99 contextMenu.state, 100 "closed", 101 `${testLabel} - checking if popup is closed` 102 ); 103 let promisePopupShown = BrowserTestUtils.waitForEvent( 104 contextMenu, 105 "popupshown" 106 ); 107 await BrowserTestUtils.synthesizeMouse( 108 selector, 109 2, 110 2, 111 { type: "contextmenu", button: 2 }, 112 browser 113 ); 114 await promisePopupShown; 115 info(`${testLabel} - Popup Shown`); 116 let promisePopupHidden = BrowserTestUtils.waitForEvent( 117 contextMenu, 118 "popuphidden" 119 ); 120 let browserPromise = test.loadedPromise(); 121 contextMenu.activateItem( 122 document.getElementById("context-viewimage"), 123 test.modifiers 124 ); 125 await promisePopupHidden; 126 127 let newBrowser = await browserPromise; 128 let { documentURI } = newBrowser.browsingContext.currentWindowGlobal; 129 if (documentURI.spec.startsWith("data:image/svg")) { 130 await SpecialPowers.spawn(newBrowser, [testLabel], msgPrefix => { 131 let svgEl = content.document.querySelector("svg"); 132 ok(svgEl, `${msgPrefix} - should have loaded SVG.`); 133 is(svgEl.height.baseVal.value, 500, `${msgPrefix} - SVG has height`); 134 is(svgEl.width.baseVal.value, 500, `${msgPrefix} - SVG has height`); 135 }); 136 } else { 137 await SpecialPowers.spawn(newBrowser, [testLabel], msgPrefix => { 138 let img = content.document.querySelector("img"); 139 ok( 140 img instanceof Ci.nsIImageLoadingContent, 141 `${msgPrefix} - Image should have loaded content.` 142 ); 143 const request = img.getRequest( 144 Ci.nsIImageLoadingContent.CURRENT_REQUEST 145 ); 146 ok( 147 request.imageStatus & request.STATUS_LOAD_COMPLETE, 148 `${msgPrefix} - Should have loaded image.` 149 ); 150 }); 151 } 152 await test.cleanup(newBrowser); 153 if (test.prefs) { 154 await SpecialPowers.popPrefEnv(); 155 } 156 } 157 }); 158 } 159 160 /** 161 * Verify that the 'view image' context menu in a new tab for a canvas works, 162 * when opened in a new tab, a new window, or in the same tab. 163 */ 164 add_task(async function test_view_image_canvas_works() { 165 await test_view_image_works({ 166 page: "subtst_contextmenu.html", 167 selector: "#test-canvas", 168 urlChecker: url => url.startsWith("blob:"), 169 }); 170 }); 171 172 /** 173 * Test for https://bugzilla.mozilla.org/show_bug.cgi?id=1625786 174 */ 175 add_task(async function test_view_image_revoked_cached_blob() { 176 await test_view_image_works({ 177 page: "test_view_image_revoked_cached_blob.html", 178 selector: "#second", 179 urlChecker: url => url.startsWith("blob:"), 180 }); 181 }); 182 183 /** 184 * Test for https://bugzilla.mozilla.org/show_bug.cgi?id=1738190 185 * Inline SVG data URIs as a background image should also open. 186 */ 187 add_task(async function test_view_image_inline_svg_bgimage() { 188 await SpecialPowers.pushPrefEnv({ 189 // This is the default but we turn it off for unit tests. 190 set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], 191 }); 192 await test_view_image_works({ 193 page: "test_view_image_inline_svg.html", 194 selector: "body", 195 urlChecker: url => url.startsWith("data:"), 196 }); 197 });