Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 const Cu = Components.utils;
3 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
5 // Load a duplicated copy of the jsm to prevent messing with the currently running one
6 let scope = {};
7 Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm", scope);
8 const { SystemAppProxy } = scope;
10 let frame;
12 let index = -1;
13 function next() {
14 index++;
15 if (index >= steps.length) {
16 assert.ok(false, "Shouldn't get here!");
17 return;
18 }
19 try {
20 steps[index]();
21 } catch(ex) {
22 assert.ok(false, "Caught exception: " + ex);
23 }
24 }
26 // Listen for events received by the system app document
27 // to ensure that we receive all of them, in an expected order and time
28 let isLoaded = false;
29 let n = 0;
30 function listener(event) {
31 if (!isLoaded) {
32 assert.ok(false, "Received event before the iframe is ready");
33 return;
34 }
35 n++;
36 if (n == 1) {
37 assert.equal(event.type, "mozChromeEvent");
38 assert.equal(event.detail.name, "first");
39 } else if (n == 2) {
40 assert.equal(event.type, "custom");
41 assert.equal(event.detail.name, "second");
43 next(); // call checkEventDispatching
44 } else if (n == 3) {
45 assert.equal(event.type, "custom");
46 assert.equal(event.detail.name, "third");
47 } else if (n == 4) {
48 assert.equal(event.type, "mozChromeEvent");
49 assert.equal(event.detail.name, "fourth");
51 next(); // call checkEventListening();
52 } else {
53 assert.ok(false, "Unexpected event of type " + event.type);
54 }
55 }
58 let steps = [
59 function waitForWebapps() {
60 // We are using webapps API later in this test and we need to ensure
61 // it is fully initialized before trying to use it
62 let { DOMApplicationRegistry } = Cu.import('resource://gre/modules/Webapps.jsm', {});
63 DOMApplicationRegistry.registryReady.then(function () {
64 next();
65 });
66 },
68 function earlyEvents() {
69 // Immediately try to send events
70 SystemAppProxy.dispatchEvent({ name: "first" });
71 SystemAppProxy._sendCustomEvent("custom", { name: "second" });
72 next();
73 },
75 function createFrame() {
76 // Create a fake system app frame
77 let win = Services.wm.getMostRecentWindow("navigator:browser");
78 let doc = win.document;
79 frame = doc.createElement("iframe");
80 doc.documentElement.appendChild(frame);
82 // Ensure that events are correctly sent to the frame.
83 // `listener` is going to call next()
84 frame.contentWindow.addEventListener("mozChromeEvent", listener);
85 frame.contentWindow.addEventListener("custom", listener);
87 // Ensure that listener being registered before the system app is ready
88 // are correctly removed from the pending list
89 function removedListener() {
90 assert(false, "Listener isn't correctly removed from the pending list");
91 }
92 SystemAppProxy.addEventListener("mozChromeEvent", removedListener);
93 SystemAppProxy.removeEventListener("mozChromeEvent", removedListener);
95 // Register it to the JSM
96 SystemAppProxy.registerFrame(frame);
97 assert.ok(true, "Frame created and registered");
99 frame.contentWindow.addEventListener("load", function onload() {
100 frame.contentWindow.removeEventListener("load", onload);
101 assert.ok(true, "Frame document loaded");
103 // Declare that the iframe is now loaded.
104 // That should dispatch early events
105 isLoaded = true;
106 SystemAppProxy.setIsReady();
107 assert.ok(true, "Frame declared as loaded");
109 // Once pending events are received,
110 // we will run checkEventDispatching from `listener` function
111 });
113 frame.setAttribute("src", "data:text/html,system app");
114 },
116 function checkEventDispatching() {
117 // Send events after the iframe is ready,
118 // they should be dispatched right away
119 SystemAppProxy._sendCustomEvent("custom", { name: "third" });
120 SystemAppProxy.dispatchEvent({ name: "fourth" });
121 // Once this 4th event is received, we will run checkEventListening
122 },
124 function checkEventListening() {
125 SystemAppProxy.addEventListener("mozContentEvent", function onContentEvent(event) {
126 assert.equal(event.detail.name, "first-content", "received a system app event");
127 SystemAppProxy.removeEventListener("mozContentEvent", onContentEvent);
129 next();
130 });
131 let win = frame.contentWindow;
132 win.dispatchEvent(new win.CustomEvent("mozContentEvent", { detail: {name: "first-content"} }));
133 },
135 function endOfTest() {
136 frame.remove();
137 sendAsyncMessage("finish");
138 }
139 ];
141 next();