1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/b2g/components/test/mochitest/systemapp_helper.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,141 @@ 1.4 +const Cu = Components.utils; 1.5 + 1.6 +const { Services } = Cu.import("resource://gre/modules/Services.jsm"); 1.7 + 1.8 +// Load a duplicated copy of the jsm to prevent messing with the currently running one 1.9 +let scope = {}; 1.10 +Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm", scope); 1.11 +const { SystemAppProxy } = scope; 1.12 + 1.13 +let frame; 1.14 + 1.15 +let index = -1; 1.16 +function next() { 1.17 + index++; 1.18 + if (index >= steps.length) { 1.19 + assert.ok(false, "Shouldn't get here!"); 1.20 + return; 1.21 + } 1.22 + try { 1.23 + steps[index](); 1.24 + } catch(ex) { 1.25 + assert.ok(false, "Caught exception: " + ex); 1.26 + } 1.27 +} 1.28 + 1.29 +// Listen for events received by the system app document 1.30 +// to ensure that we receive all of them, in an expected order and time 1.31 +let isLoaded = false; 1.32 +let n = 0; 1.33 +function listener(event) { 1.34 + if (!isLoaded) { 1.35 + assert.ok(false, "Received event before the iframe is ready"); 1.36 + return; 1.37 + } 1.38 + n++; 1.39 + if (n == 1) { 1.40 + assert.equal(event.type, "mozChromeEvent"); 1.41 + assert.equal(event.detail.name, "first"); 1.42 + } else if (n == 2) { 1.43 + assert.equal(event.type, "custom"); 1.44 + assert.equal(event.detail.name, "second"); 1.45 + 1.46 + next(); // call checkEventDispatching 1.47 + } else if (n == 3) { 1.48 + assert.equal(event.type, "custom"); 1.49 + assert.equal(event.detail.name, "third"); 1.50 + } else if (n == 4) { 1.51 + assert.equal(event.type, "mozChromeEvent"); 1.52 + assert.equal(event.detail.name, "fourth"); 1.53 + 1.54 + next(); // call checkEventListening(); 1.55 + } else { 1.56 + assert.ok(false, "Unexpected event of type " + event.type); 1.57 + } 1.58 +} 1.59 + 1.60 + 1.61 +let steps = [ 1.62 + function waitForWebapps() { 1.63 + // We are using webapps API later in this test and we need to ensure 1.64 + // it is fully initialized before trying to use it 1.65 + let { DOMApplicationRegistry } = Cu.import('resource://gre/modules/Webapps.jsm', {}); 1.66 + DOMApplicationRegistry.registryReady.then(function () { 1.67 + next(); 1.68 + }); 1.69 + }, 1.70 + 1.71 + function earlyEvents() { 1.72 + // Immediately try to send events 1.73 + SystemAppProxy.dispatchEvent({ name: "first" }); 1.74 + SystemAppProxy._sendCustomEvent("custom", { name: "second" }); 1.75 + next(); 1.76 + }, 1.77 + 1.78 + function createFrame() { 1.79 + // Create a fake system app frame 1.80 + let win = Services.wm.getMostRecentWindow("navigator:browser"); 1.81 + let doc = win.document; 1.82 + frame = doc.createElement("iframe"); 1.83 + doc.documentElement.appendChild(frame); 1.84 + 1.85 + // Ensure that events are correctly sent to the frame. 1.86 + // `listener` is going to call next() 1.87 + frame.contentWindow.addEventListener("mozChromeEvent", listener); 1.88 + frame.contentWindow.addEventListener("custom", listener); 1.89 + 1.90 + // Ensure that listener being registered before the system app is ready 1.91 + // are correctly removed from the pending list 1.92 + function removedListener() { 1.93 + assert(false, "Listener isn't correctly removed from the pending list"); 1.94 + } 1.95 + SystemAppProxy.addEventListener("mozChromeEvent", removedListener); 1.96 + SystemAppProxy.removeEventListener("mozChromeEvent", removedListener); 1.97 + 1.98 + // Register it to the JSM 1.99 + SystemAppProxy.registerFrame(frame); 1.100 + assert.ok(true, "Frame created and registered"); 1.101 + 1.102 + frame.contentWindow.addEventListener("load", function onload() { 1.103 + frame.contentWindow.removeEventListener("load", onload); 1.104 + assert.ok(true, "Frame document loaded"); 1.105 + 1.106 + // Declare that the iframe is now loaded. 1.107 + // That should dispatch early events 1.108 + isLoaded = true; 1.109 + SystemAppProxy.setIsReady(); 1.110 + assert.ok(true, "Frame declared as loaded"); 1.111 + 1.112 + // Once pending events are received, 1.113 + // we will run checkEventDispatching from `listener` function 1.114 + }); 1.115 + 1.116 + frame.setAttribute("src", "data:text/html,system app"); 1.117 + }, 1.118 + 1.119 + function checkEventDispatching() { 1.120 + // Send events after the iframe is ready, 1.121 + // they should be dispatched right away 1.122 + SystemAppProxy._sendCustomEvent("custom", { name: "third" }); 1.123 + SystemAppProxy.dispatchEvent({ name: "fourth" }); 1.124 + // Once this 4th event is received, we will run checkEventListening 1.125 + }, 1.126 + 1.127 + function checkEventListening() { 1.128 + SystemAppProxy.addEventListener("mozContentEvent", function onContentEvent(event) { 1.129 + assert.equal(event.detail.name, "first-content", "received a system app event"); 1.130 + SystemAppProxy.removeEventListener("mozContentEvent", onContentEvent); 1.131 + 1.132 + next(); 1.133 + }); 1.134 + let win = frame.contentWindow; 1.135 + win.dispatchEvent(new win.CustomEvent("mozContentEvent", { detail: {name: "first-content"} })); 1.136 + }, 1.137 + 1.138 + function endOfTest() { 1.139 + frame.remove(); 1.140 + sendAsyncMessage("finish"); 1.141 + } 1.142 +]; 1.143 + 1.144 +next();