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