Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / docshell / test / test_bug385434.html
blob108680a5b9b46829076782717b8ad41dc9ae6677
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=385434
5 -->
6 <head>
7 <title>Test for Bug 385434</title>
8 <script type="application/javascript" src="/MochiKit/packed.js"></script>
9 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10 <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
12 </head>
13 <body>
14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=385434">Mozilla Bug 385434</a>
15 <p id="display"></p>
16 <div id="content">
17 <iframe id="frame" style="height:100px; width:100px; border:0"></iframe>
18 <div id="status" style="display: none"></div>
19 </div>
20 <pre id="test">
21 <script type="application/javascript;version=1.7">
23 /** Test for Bug 385434 **/
24 SimpleTest.waitForExplicitFinish();
26 var gNumHashchanges = 0;
27 var gCallbackOnIframeLoad = false;
29 function statusMsg(msg) {
30 var msgElem = document.createElement("p");
31 msgElem.appendChild(document.createTextNode(msg));
33 document.getElementById("status").appendChild(msgElem);
36 function longWait() {
37 setTimeout(function() { gGen.next() }, 1000);
40 // onIframeHashchange, onIframeLoad, and onIframeScroll are all called by the
41 // content we load into our iframe in order to notify the parent frame of an
42 // event which was fired.
43 function onIframeHashchange() {
44 gNumHashchanges++;
45 gGen.next();
48 function onIframeLoad() {
49 if (gCallbackOnIframeLoad) {
50 gCallbackOnIframeLoad = false;
51 gGen.next();
55 function onIframeScroll() {
56 is(gNumHashchanges, 0, "onscroll should fire before onhashchange.");
59 function enableIframeLoadCallback() {
60 gCallbackOnIframeLoad = true;
63 function noEventExpected(msg) {
64 is(gNumHashchanges, 0, msg);
66 // Even if there's an error, set gNumHashchanges to 0 so other tests don't
67 // fail.
68 gNumHashchanges = 0;
71 function eventExpected(msg) {
72 is(gNumHashchanges, 1, msg);
74 // Eat up this event, whether the test above was true or not
75 gNumHashchanges = 0;
79 * The hashchange event is dispatched asynchronously, so if we want to observe
80 * it, we have to yield within run_test(), transferring control back to the
81 * event loop.
83 * When we're expecting our iframe to observe a hashchange event after we poke
84 * it, we just yield and wait for onIframeHashchange() to call gGen.next() and
85 * wake us up.
87 * When we're testing to ensure that the iframe doesn't dispatch a hashchange
88 * event, we try to hook onto the iframe's load event. We call
89 * enableIframeLoadCallback(), which causes onIframeLoad() to call gGen.next()
90 * upon the next observed load. After we get our callback, we check that a
91 * hashchange didn't occur.
93 * We can't always just wait for page load in order to observe that a
94 * hashchange didn't happen. In these cases, we call longWait() and yield
95 * until either a hashchange occurs or longWait's callback is scheduled. This
96 * is something of a hack; it's entirely possible that longWait won't wait long
97 * enough, and we won't observe what should have been a failure of the test.
98 * But it shouldn't happen that good code will randomly *fail* this test.
100 function run_test() {
102 * TEST 1 tests that:
103 * <body onhashchange = ... > works,
104 * the event is (not) fired at the correct times
106 var frame = document.getElementById("frame");
107 var frameCw = frame.contentWindow;
109 enableIframeLoadCallback();
110 frameCw.document.location = "file_bug385434_1.html";
111 // Wait for the iframe to load and for our callback to fire
112 yield;
114 noEventExpected("No hashchange expected initially.");
116 sendMouseEvent({type: "click"}, "link1", frameCw);
117 yield;
118 eventExpected("Clicking link1 should trigger a hashchange.");
120 sendMouseEvent({type: "click"}, "link1", frameCw);
121 longWait();
122 yield;
123 // succeed if a hashchange event wasn't triggered while we were waiting
124 noEventExpected("Clicking link1 again should not trigger a hashchange.");
126 sendMouseEvent({type: "click"}, "link2", frameCw);
127 yield;
128 eventExpected("Clicking link2 should trigger a hashchange.");
130 frameCw.history.go(-1);
131 yield;
132 eventExpected("Going back should trigger a hashchange.");
134 frameCw.history.go(1);
135 yield;
136 eventExpected("Going forward should trigger a hashchange.");
138 frameCw.window.location.hash = "";
139 yield;
140 eventExpected("Changing window.location.hash should trigger a hashchange.");
142 // window.location has a trailing '#' right now, so we append "link1", not
143 // "#link1".
144 frameCw.window.location = frameCw.window.location + "link1";
145 yield;
146 eventExpected("Assigning to window.location should trigger a hashchange.");
148 // Set up history in the iframe which looks like:
149 // file_bug385434_1.html#link1
150 // file_bug385434_2.html
151 // file_bug385434_1.html#foo <-- current page
152 enableIframeLoadCallback();
153 frameCw.window.location = "file_bug385434_2.html";
154 yield;
156 enableIframeLoadCallback();
157 frameCw.window.location = "file_bug385434_1.html#foo";
158 yield;
160 // Now when we do history.go(-2) on the frame, it *shouldn't* fire a
161 // hashchange. Although the URIs differ only by their hashes, they belong to
162 // two different Documents.
163 frameCw.history.go(-2);
164 longWait();
165 yield;
166 noEventExpected("Moving between different Documents shouldn't " +
167 "trigger a hashchange.");
170 * TEST 2 tests that:
171 * <frameset onhashchange = ... > works,
172 * the event is targeted at the window object
173 * the event's cancelable, bubbles settings are correct
175 enableIframeLoadCallback();
176 frameCw.document.location = "file_bug385434_2.html";
177 yield;
179 frameCw.document.location = "file_bug385434_2.html#foo";
180 yield;
182 eventExpected("frame onhashchange should fire events.");
183 // iframe should set gSampleEvent
184 is(gSampleEvent.target, frameCw,
185 "The hashchange event should be targeted to the window.");
186 is(gSampleEvent.type, "hashchange",
187 "Event type should be 'hashchange'.");
188 is(gSampleEvent.cancelable, false,
189 "The hashchange event shouldn't be cancelable.");
190 is(gSampleEvent.bubbles, false,
191 "The hashchange event shouldn't bubble.");
194 * TEST 3 tests that:
195 * hashchange is dispatched if the current document readyState is
196 * not "complete" (bug 504837).
198 frameCw.document.location = "file_bug385434_3.html";
199 yield;
200 eventExpected("Hashchange should fire even if the document " +
201 "hasn't finished loading.");
203 SimpleTest.finish();
204 yield;
207 var gGen = run_test();
208 gGen.next();
210 </script>
211 </pre>
212 </body>
213 </html>