test_message_manager_ipc.html (8752B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Test for sending IndexedDB Blobs through MessageManager</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"> 6 </script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 8 </head> 9 <body> 10 <script type="application/javascript"> 11 "use strict"; 12 13 async function chromeScriptFunc() { 14 function childFrameScript() { 15 /* eslint-env mozilla/frame-script */ 16 "use strict"; 17 18 const mmName = "test:idb-and-mm"; 19 20 const dbName = "test_message_manager_ipc.html - CHILD"; 21 const dbVersion = 1; 22 const objStoreName = "bar"; 23 const key = 1; 24 25 const blobData = ["So", " ", "many", " ", "blobs!"]; 26 const blobText = blobData.join(""); 27 const blobType = "text/plain"; 28 29 function info(msg) { 30 sendAsyncMessage(mmName, { op: "info", msg }); 31 } 32 33 function ok(condition, name, diag) { 34 sendAsyncMessage(mmName, 35 { op: "ok", 36 condition, 37 name, 38 diag }); 39 } 40 41 function is(a, b, name) { 42 let pass = a == b; 43 let diag = pass ? "" : "got " + a + ", expected " + b; 44 ok(pass, name, diag); 45 } 46 47 function finish(result) { 48 sendAsyncMessage(mmName, { op: "done", result }); 49 } 50 51 function grabAndContinue(arg) { 52 testGenerator.next(arg); 53 } 54 55 function errorHandler(event) { 56 ok(false, 57 event.target + " received error event: '" + event.target.error.name + 58 "'"); 59 finish(); 60 } 61 62 function* testSteps() { 63 addMessageListener(mmName, grabAndContinue); 64 let message = yield undefined; 65 66 let blob = message.data; 67 68 ok(Blob.isInstance(blob), "Message manager sent a blob"); 69 is(blob.size, blobText.length, "Blob has correct length"); 70 is(blob.type, blobType, "Blob has correct type"); 71 72 info("Reading blob"); 73 74 let reader = new FileReader(); 75 reader.addEventListener("load", grabAndContinue); 76 reader.readAsText(blob); 77 78 yield undefined; 79 80 is(reader.result, blobText, "Blob has correct data"); 81 82 let slice = blob.slice(0, blobData[0].length, blobType); 83 84 ok(Blob.isInstance(slice), "Slice returned a blob"); 85 is(slice.size, blobData[0].length, "Slice has correct length"); 86 is(slice.type, blobType, "Slice has correct type"); 87 88 info("Reading slice"); 89 90 reader = new FileReader(); 91 reader.addEventListener("load", grabAndContinue); 92 reader.readAsText(slice); 93 94 yield undefined; 95 96 is(reader.result, blobData[0], "Slice has correct data"); 97 98 info("Deleting database"); 99 100 let req = indexedDB.deleteDatabase(dbName); 101 req.onerror = errorHandler; 102 req.onsuccess = grabAndContinue; 103 104 let event = yield undefined; 105 is(event.type, "success", "Got success event"); 106 107 info("Opening database"); 108 109 req = indexedDB.open(dbName, dbVersion); 110 req.onerror = errorHandler; 111 req.onupgradeneeded = grabAndContinue; 112 req.onsuccess = grabAndContinue; 113 114 event = yield undefined; 115 is(event.type, "upgradeneeded", "Got upgradeneeded event"); 116 117 event.target.result.createObjectStore(objStoreName); 118 119 event = yield undefined; 120 is(event.type, "success", "Got success event"); 121 122 let db = event.target.result; 123 124 info("Storing blob from message manager in database"); 125 126 let objectStore = 127 db.transaction(objStoreName, "readwrite").objectStore(objStoreName); 128 req = objectStore.add(blob, key); 129 req.onerror = errorHandler; 130 req.onsuccess = grabAndContinue; 131 132 event = yield undefined; 133 134 info("Getting blob from database"); 135 136 objectStore = db.transaction(objStoreName).objectStore(objStoreName); 137 req = objectStore.get(key); 138 req.onerror = errorHandler; 139 req.onsuccess = grabAndContinue; 140 141 event = yield undefined; 142 143 blob = event.target.result; 144 145 ok(Blob.isInstance(blob), "Database gave us a blob"); 146 is(blob.size, blobText.length, "Blob has correct length"); 147 is(blob.type, blobType, "Blob has correct type"); 148 149 info("Reading blob"); 150 151 reader = new FileReader(); 152 reader.addEventListener("load", grabAndContinue); 153 reader.readAsText(blob); 154 155 yield undefined; 156 157 is(reader.result, blobText, "Blob has correct data"); 158 159 info("Storing slice from message manager in database"); 160 161 objectStore = 162 db.transaction(objStoreName, "readwrite").objectStore(objStoreName); 163 req = objectStore.put(slice, key); 164 req.onerror = errorHandler; 165 req.onsuccess = grabAndContinue; 166 167 event = yield undefined; 168 169 info("Getting slice from database"); 170 171 objectStore = db.transaction(objStoreName).objectStore(objStoreName); 172 req = objectStore.get(key); 173 req.onerror = errorHandler; 174 req.onsuccess = grabAndContinue; 175 176 event = yield undefined; 177 178 slice = event.target.result; 179 180 ok(Blob.isInstance(slice), "Database gave us a blob"); 181 is(slice.size, blobData[0].length, "Slice has correct length"); 182 is(slice.type, blobType, "Slice has correct type"); 183 184 info("Reading Slice"); 185 186 reader = new FileReader(); 187 reader.addEventListener("load", grabAndContinue); 188 reader.readAsText(slice); 189 190 yield undefined; 191 192 is(reader.result, blobData[0], "Slice has correct data"); 193 194 info("Sending blob and slice from database to message manager"); 195 finish([blob, slice]); 196 } 197 198 let testGenerator = testSteps(); 199 testGenerator.next(); 200 } 201 202 /* globals Services, createWindowlessBrowser */ 203 let { windowlessBrowser, browser } = await createWindowlessBrowser(); 204 205 const system = Services.scriptSecurityManager.getSystemPrincipal(); 206 browser.loadURI( 207 Services.io.newURI("data:text/html,<!DOCTYPE HTML><html><body></body></html>"), 208 { triggeringPrincipal: system } 209 ); 210 211 function finish() { 212 sendAsyncMessage("done"); 213 windowlessBrowser.close(); 214 } 215 216 let mm = browser.messageManager; 217 218 const messageName = "test:idb-and-mm"; 219 const blobData = ["So", " ", "many", " ", "blobs!"]; 220 const blobText = blobData.join(""); 221 const blobType = "text/plain"; 222 const blob = new Blob(blobData, { type: blobType }); 223 224 function grabAndContinue(arg) { 225 testGenerator.next(arg); 226 } 227 228 function* testSteps() { 229 let result = yield undefined; 230 231 is(Cu.getClassName(result, true), "Array", "Child delivered an array of results"); 232 is(result.length, 2, "Child delivered two results"); 233 234 let blob = result[0]; 235 is(Blob.isInstance(blob), true, "Child delivered a blob"); 236 is(blob.size, blobText.length, "Blob has correct size"); 237 is(blob.type, blobType, "Blob has correct type"); 238 239 let slice = result[1]; 240 is(Blob.isInstance(slice), true, "Child delivered a slice"); 241 is(slice.size, blobData[0].length, "Slice has correct size"); 242 is(slice.type, blobType, "Slice has correct type"); 243 244 info("Reading blob"); 245 246 let reader = new FileReader(); 247 reader.onload = grabAndContinue; 248 reader.readAsText(blob); 249 yield undefined; 250 251 is(reader.result, blobText, "Blob has correct data"); 252 253 info("Reading slice"); 254 255 reader = new FileReader(); 256 reader.onload = grabAndContinue; 257 reader.readAsText(slice); 258 yield undefined; 259 260 is(reader.result, blobData[0], "Slice has correct data"); 261 262 slice = blob.slice(0, blobData[0].length, blobType); 263 264 is(Blob.isInstance(slice), true, "Child delivered a slice"); 265 is(slice.size, blobData[0].length, "Second slice has correct size"); 266 is(slice.type, blobType, "Second slice has correct type"); 267 268 info("Reading second slice"); 269 270 reader = new FileReader(); 271 reader.onload = grabAndContinue; 272 reader.readAsText(slice); 273 yield undefined; 274 275 is(reader.result, blobData[0], "Second slice has correct data"); 276 277 finish(); 278 } 279 280 let testGenerator = testSteps(); 281 testGenerator.next(); 282 283 mm.addMessageListener(messageName, function(message) { 284 let data = message.data; 285 switch (data.op) { 286 case "info": { 287 info(data.msg); 288 break; 289 } 290 291 case "ok": { 292 ok(data.condition, data.name + " - " + data.diag); 293 break; 294 } 295 296 case "done": { 297 testGenerator.next(data.result); 298 break; 299 } 300 301 default: { 302 ok(false, "Unknown op: " + data.op); 303 finish(); 304 } 305 } 306 }); 307 308 mm.loadFrameScript(`data:,(${childFrameScript})();`, 309 false); 310 311 mm.sendAsyncMessage(messageName, blob); 312 } 313 314 add_task(async function() { 315 let chromeScript = SpecialPowers.loadChromeScript(chromeScriptFunc); 316 await chromeScript.promiseOneMessage("done"); 317 await chromeScript.destroy(); 318 }); 319 </script> 320 </body> 321 </html>