browser_icon_discovery.js (5453B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 /* eslint-disable mozilla/no-arbitrary-setTimeout */ 5 6 const ROOTURI = 7 "http://mochi.test:8888/browser/browser/base/content/test/favicons/"; 8 const ICON = "moz.png"; 9 const DATAURL = 10 "data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYABAQEAAgICAAMDAwAERERABYWFgAcHBwAIiIiACkpKQBVVVUATU1NAEJCQgA5OTkAgHz/AFBQ/wCTANYA/+zMAMbW7wDW5+cAkKmtAAAAMwAAAGYAAACZAAAAzAAAMwAAADMzAAAzZgAAM5kAADPMAAAz/wAAZgAAAGYzAABmZgAAZpkAAGbMAABm/wAAmQAAAJkzAACZZgAAmZkAAJnMAACZ/wAAzAAAAMwzAADMZgAAzJkAAMzMAADM/wAA/2YAAP+ZAAD/zAAzAAAAMwAzADMAZgAzAJkAMwDMADMA/wAzMwAAMzMzADMzZgAzM5kAMzPMADMz/wAzZgAAM2YzADNmZgAzZpkAM2bMADNm/wAzmQAAM5kzADOZZgAzmZkAM5nMADOZ/wAzzAAAM8wzADPMZgAzzJkAM8zMADPM/wAz/zMAM/9mADP/mQAz/8wAM///AGYAAABmADMAZgBmAGYAmQBmAMwAZgD/AGYzAABmMzMAZjNmAGYzmQBmM8wAZjP/AGZmAABmZjMAZmZmAGZmmQBmZswAZpkAAGaZMwBmmWYAZpmZAGaZzABmmf8AZswAAGbMMwBmzJkAZszMAGbM/wBm/wAAZv8zAGb/mQBm/8wAzAD/AP8AzACZmQAAmTOZAJkAmQCZAMwAmQAAAJkzMwCZAGYAmTPMAJkA/wCZZgAAmWYzAJkzZgCZZpkAmWbMAJkz/wCZmTMAmZlmAJmZmQCZmcwAmZn/AJnMAACZzDMAZsxmAJnMmQCZzMwAmcz/AJn/AACZ/zMAmcxmAJn/mQCZ/8wAmf//AMwAAACZADMAzABmAMwAmQDMAMwAmTMAAMwzMwDMM2YAzDOZAMwzzADMM/8AzGYAAMxmMwCZZmYAzGaZAMxmzACZZv8AzJkAAMyZMwDMmWYAzJmZAMyZzADMmf8AzMwAAMzMMwDMzGYAzMyZAMzMzADMzP8AzP8AAMz/MwCZ/2YAzP+ZAMz/zADM//8AzAAzAP8AZgD/AJkAzDMAAP8zMwD/M2YA/zOZAP8zzAD/M/8A/2YAAP9mMwDMZmYA/2aZAP9mzADMZv8A/5kAAP+ZMwD/mWYA/5mZAP+ZzAD/mf8A/8wAAP/MMwD/zGYA/8yZAP/MzAD/zP8A//8zAMz/ZgD//5kA///MAGZm/wBm/2YAZv//AP9mZgD/Zv8A//9mACEApQBfX18Ad3d3AIaGhgCWlpYAy8vLALKysgDX19cA3d3dAOPj4wDq6uoA8fHxAPj4+ADw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8ACgoKCgoKCgoKCgoKCgoKCgoKCgoHAQEMbQoKCgoKCgoAAAdDH/kgHRIAAAAAAAAAAADrHfn5ASQQAAAAAAAAAArsBx0B+fkgHesAAAAAAAD/Cgwf+fn5IA4dEus/IvcACgcMAfkg+QEB+SABHushbf8QHR/5HQH5+QEdHetEHx4K7B/5+QH5+fkdDBL5+SBE/wwdJfkf+fn5AR8g+fkfEArsCh/5+QEeJR/5+SAeBwAACgoe+SAlHwFAEhAfAAAAAPcKHh8eASYBHhAMAAAAAAAA9EMdIB8gHh0dBwAAAAAAAAAA7BAdQ+wHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AADwfwAAwH8AAMB/AAAAPwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAgAcAAIAPAADADwAA8D8AAP//AAA="; 11 12 let iconDiscoveryTests = [ 13 { 14 text: "rel icon discovered", 15 icons: [{}], 16 }, 17 { 18 text: "rel may contain additional rels separated by spaces", 19 icons: [{ rel: "abcdefg icon qwerty" }], 20 }, 21 { 22 text: "rel is case insensitive", 23 icons: [{ rel: "ICON" }], 24 }, 25 { 26 text: "rel shortcut-icon not discovered", 27 expectedIcon: ROOTURI + ICON, 28 icons: [ 29 // We will prefer the later icon if detected 30 {}, 31 { rel: "shortcut-icon", href: "nothere.png" }, 32 ], 33 }, 34 { 35 text: "relative href works", 36 icons: [{ href: "moz.png" }], 37 }, 38 { 39 text: "404'd icon is removed properly", 40 pass: false, 41 icons: [{ href: "notthere.png" }], 42 }, 43 { 44 text: "data: URIs work", 45 icons: [{ href: DATAURL, type: "image/x-icon" }], 46 }, 47 { 48 text: "type may have optional parameters (RFC2046)", 49 icons: [{ type: "image/png; charset=utf-8" }], 50 }, 51 { 52 text: "apple-touch-icon discovered", 53 richIcon: true, 54 icons: [{ rel: "apple-touch-icon" }], 55 }, 56 { 57 text: "apple-touch-icon-precomposed discovered", 58 richIcon: true, 59 icons: [{ rel: "apple-touch-icon-precomposed" }], 60 }, 61 { 62 text: "fluid-icon discovered", 63 richIcon: true, 64 icons: [{ rel: "fluid-icon" }], 65 }, 66 { 67 text: "unknown icon not discovered", 68 expectedIcon: ROOTURI + ICON, 69 richIcon: true, 70 icons: [ 71 // We will prefer the larger icon if detected 72 { rel: "apple-touch-icon", sizes: "32x32" }, 73 { rel: "unknown-icon", sizes: "128x128", href: "notthere.png" }, 74 ], 75 }, 76 ]; 77 78 add_task(async function () { 79 let url = ROOTURI + "discovery.html"; 80 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); 81 82 for (let testCase of iconDiscoveryTests) { 83 info(`Running test "${testCase.text}"`); 84 85 if (testCase.pass === undefined) { 86 testCase.pass = true; 87 } 88 89 if (testCase.icons.length > 1 && !testCase.expectedIcon) { 90 ok(false, "Invalid test data, missing expectedIcon"); 91 continue; 92 } 93 94 let expectedIcon = testCase.expectedIcon || testCase.icons[0].href || ICON; 95 expectedIcon = new URL(expectedIcon, ROOTURI).href; 96 97 let iconPromise = waitForFaviconMessage(!testCase.richIcon, expectedIcon); 98 99 await SpecialPowers.spawn( 100 gBrowser.selectedBrowser, 101 [[testCase.icons, ROOTURI + ICON]], 102 ([icons, defaultIcon]) => { 103 let doc = content.document; 104 let head = doc.head; 105 106 for (let icon of icons) { 107 let link = doc.createElement("link"); 108 link.rel = icon.rel || "icon"; 109 link.href = icon.href || defaultIcon; 110 link.type = icon.type || "image/png"; 111 if (icon.sizes) { 112 link.sizes = icon.sizes; 113 } 114 head.appendChild(link); 115 } 116 } 117 ); 118 119 try { 120 let { iconURL } = await iconPromise; 121 ok(testCase.pass, testCase.text); 122 is(iconURL, expectedIcon, "Should have seen the expected icon."); 123 } catch (e) { 124 ok(!testCase.pass, testCase.text); 125 } 126 127 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { 128 let links = content.document.querySelectorAll("link"); 129 for (let link of links) { 130 link.remove(); 131 } 132 }); 133 } 134 135 BrowserTestUtils.removeTab(tab); 136 });