test_ext_tabs_onUpdated.html (6302B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tabs onUpdated Test</title> 6 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 7 <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script> 8 <script type="text/javascript" src="head.js"></script> 9 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 10 </head> 11 <body> 12 13 <script type="text/javascript"> 14 "use strict"; 15 16 add_task(async function test_onUpdated() { 17 const extension = ExtensionTestUtils.loadExtension({ 18 manifest: { 19 "permissions": ["tabs"], 20 "content_scripts": [{ 21 "matches": ["http://mochi.test/*/context_tabs_onUpdated_page.html"], 22 "js": ["content-script.js"], 23 "run_at": "document_start", 24 }], 25 }, 26 27 background: function() { 28 const pageURL = "http://mochi.test:8888/tests/mobile/shared/components/extensions/test/mochitest/context_tabs_onUpdated_page.html"; 29 30 const expectedSequence = [ 31 {status: "loading"}, 32 {status: "loading", url: pageURL}, 33 {status: "complete"}, 34 ]; 35 36 const collectedSequence = []; 37 38 let tabId; 39 browser.tabs.onUpdated.addListener(function(tabId, updatedInfo) { 40 // onUpdated also fires with updatedInfo.faviconUrl, so explicitly 41 // check for updatedInfo.status before recording the event. 42 if ("status" in updatedInfo) { 43 collectedSequence.push(updatedInfo); 44 } 45 }); 46 47 browser.runtime.onMessage.addListener(async () => { 48 if (collectedSequence.length !== expectedSequence.length) { 49 browser.test.assertEq( 50 JSON.stringify(expectedSequence), 51 JSON.stringify(collectedSequence), 52 "got unexpected number of updateInfo data" 53 ); 54 } else { 55 for (let i = 0; i < expectedSequence.length; i++) { 56 browser.test.assertEq( 57 expectedSequence[i].status, 58 collectedSequence[i].status, 59 "check updatedInfo status" 60 ); 61 if (expectedSequence[i].url || collectedSequence[i].url) { 62 browser.test.assertEq( 63 expectedSequence[i].url, 64 collectedSequence[i].url, 65 "check updatedInfo url" 66 ); 67 } 68 } 69 } 70 71 await browser.tabs.remove(tabId); 72 browser.test.notifyPass("tabs.onUpdated"); 73 }); 74 75 browser.tabs.create({url: pageURL}).then(tab => { 76 tabId = tab.id; 77 }); 78 }, 79 files: { 80 "content-script.js": ` 81 window.addEventListener("message", function(evt) { 82 if (evt.data == "frame-updated") { 83 browser.runtime.sendMessage("load-completed"); 84 } 85 }, true); 86 `, 87 }, 88 }); 89 90 await Promise.all([ 91 extension.startup(), 92 extension.awaitFinish("tabs.onUpdated"), 93 ]); 94 95 await extension.unload(); 96 }); 97 98 async function do_test_update(background, withPermissions = true) { 99 const manifest = {}; 100 if (withPermissions) { 101 manifest.permissions = ["tabs", "http://mochi.test/"]; 102 } 103 const extension = ExtensionTestUtils.loadExtension({ 104 manifest, 105 background, 106 }); 107 108 await extension.startup(); 109 await extension.awaitFinish("finish"); 110 111 await extension.unload(); 112 } 113 114 add_task(async function test_url() { 115 await do_test_update(function background() { 116 // Create a new tab for testing update. 117 browser.tabs.create({}, function(tab) { 118 browser.tabs.onUpdated.addListener(async function onUpdated(tabId, changeInfo) { 119 // Check callback 120 browser.test.assertEq(tabId, tab.id, "Check tab id"); 121 browser.test.log("onUpdate: " + JSON.stringify(changeInfo)); 122 if ("url" in changeInfo) { 123 browser.test.assertEq("about:blank", changeInfo.url, 124 "Check changeInfo.url"); 125 browser.tabs.onUpdated.removeListener(onUpdated); 126 // Remove created tab. 127 await browser.tabs.remove(tabId); 128 browser.test.notifyPass("finish"); 129 } 130 }); 131 browser.tabs.update(tab.id, {url: "about:blank"}); 132 }); 133 }); 134 }); 135 136 add_task(async function test_title() { 137 await do_test_update(async function background() { 138 const url = "http://mochi.test:8888/tests/mobile/shared/components/extensions/test/mochitest/context_tabs_onUpdated_page.html"; 139 const tab = await browser.tabs.create({url}); 140 141 browser.tabs.onUpdated.addListener(async function onUpdated(tabId, changeInfo) { 142 browser.test.assertEq(tabId, tab.id, "Check tab id"); 143 browser.test.log(`onUpdated: ${JSON.stringify(changeInfo)}`); 144 if ("title" in changeInfo && changeInfo.title === "New Message (1)") { 145 browser.test.log("changeInfo.title is correct"); 146 browser.tabs.onUpdated.removeListener(onUpdated); 147 await browser.tabs.remove(tabId); 148 browser.test.notifyPass("finish"); 149 } 150 }); 151 152 browser.tabs.executeScript(tab.id, {code: "document.title = 'New Message (1)'"}); 153 }); 154 }); 155 156 add_task(async function test_without_tabs_permission() { 157 await do_test_update(async function background() { 158 const url = "http://mochi.test:8888/tests/mobile/shared/components/extensions/test/mochitest/context_tabs_onUpdated_page.html"; 159 const tab = await browser.tabs.create({url}); 160 let count = 0; 161 162 browser.tabs.onUpdated.addListener(async function onUpdated(tabId, changeInfo) { 163 browser.test.assertEq(tabId, tab.id, "Check tab id"); 164 browser.test.log(`onUpdated: ${JSON.stringify(changeInfo)}`); 165 166 browser.test.assertFalse("url" in changeInfo, "url should not be included without tabs permission"); 167 browser.test.assertFalse("favIconUrl" in changeInfo, "favIconUrl should not be included without tabs permission"); 168 browser.test.assertFalse("title" in changeInfo, "title should not be included without tabs permission"); 169 170 if (changeInfo.status == "complete") { 171 count++; 172 if (count === 2) { 173 browser.test.log("Reload complete"); 174 browser.tabs.onUpdated.removeListener(onUpdated); 175 await browser.tabs.remove(tabId); 176 browser.test.notifyPass("finish"); 177 } 178 } 179 }); 180 181 browser.tabs.reload(tab.id); 182 }, false /* withPermissions */); 183 }); 184 </script> 185 186 </body> 187 </html>