1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/docshell/test/test_bug385434.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,208 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 1.8 +--> 1.9 +<head> 1.10 + <title>Test for Bug 385434</title> 1.11 + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.12 + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> 1.13 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 1.14 +</head> 1.15 +<body> 1.16 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=385434">Mozilla Bug 385434</a> 1.17 +<p id="display"></p> 1.18 +<div id="content"> 1.19 + <iframe id="frame" style="height:100px; width:100px; border:0"></iframe> 1.20 + <div id="status" style="display: none"></div> 1.21 +</div> 1.22 +<pre id="test"> 1.23 +<script type="application/javascript;version=1.7"> 1.24 + 1.25 +/** Test for Bug 385434 **/ 1.26 +SimpleTest.waitForExplicitFinish(); 1.27 + 1.28 +var gNumHashchanges = 0; 1.29 +var gCallbackOnIframeLoad = false; 1.30 + 1.31 +function statusMsg(msg) { 1.32 + var msgElem = document.createElement("p"); 1.33 + msgElem.appendChild(document.createTextNode(msg)); 1.34 + 1.35 + document.getElementById("status").appendChild(msgElem); 1.36 +} 1.37 + 1.38 +function longWait() { 1.39 + setTimeout(function() { gGen.next() }, 1000); 1.40 +} 1.41 + 1.42 +// onIframeHashchange, onIframeLoad, and onIframeScroll are all called by the 1.43 +// content we load into our iframe in order to notify the parent frame of an 1.44 +// event which was fired. 1.45 +function onIframeHashchange() { 1.46 + gNumHashchanges++; 1.47 + gGen.next(); 1.48 +} 1.49 + 1.50 +function onIframeLoad() { 1.51 + if (gCallbackOnIframeLoad) { 1.52 + gCallbackOnIframeLoad = false; 1.53 + gGen.next(); 1.54 + } 1.55 +} 1.56 + 1.57 +function onIframeScroll() { 1.58 + is(gNumHashchanges, 0, "onscroll should fire before onhashchange."); 1.59 +} 1.60 + 1.61 +function enableIframeLoadCallback() { 1.62 + gCallbackOnIframeLoad = true; 1.63 +} 1.64 + 1.65 +function noEventExpected(msg) { 1.66 + is(gNumHashchanges, 0, msg); 1.67 + 1.68 + // Even if there's an error, set gNumHashchanges to 0 so other tests don't 1.69 + // fail. 1.70 + gNumHashchanges = 0; 1.71 +} 1.72 + 1.73 +function eventExpected(msg) { 1.74 + is(gNumHashchanges, 1, msg); 1.75 + 1.76 + // Eat up this event, whether the test above was true or not 1.77 + gNumHashchanges = 0; 1.78 +} 1.79 + 1.80 +/* 1.81 + * The hashchange event is dispatched asynchronously, so if we want to observe 1.82 + * it, we have to yield within run_test(), transferring control back to the 1.83 + * event loop. 1.84 + * 1.85 + * When we're expecting our iframe to observe a hashchange event after we poke 1.86 + * it, we just yield and wait for onIframeHashchange() to call gGen.next() and 1.87 + * wake us up. 1.88 + * 1.89 + * When we're testing to ensure that the iframe doesn't dispatch a hashchange 1.90 + * event, we try to hook onto the iframe's load event. We call 1.91 + * enableIframeLoadCallback(), which causes onIframeLoad() to call gGen.next() 1.92 + * upon the next observed load. After we get our callback, we check that a 1.93 + * hashchange didn't occur. 1.94 + * 1.95 + * We can't always just wait for page load in order to observe that a 1.96 + * hashchange didn't happen. In these cases, we call longWait() and yield 1.97 + * until either a hashchange occurs or longWait's callback is scheduled. This 1.98 + * is something of a hack; it's entirely possible that longWait won't wait long 1.99 + * enough, and we won't observe what should have been a failure of the test. 1.100 + * But it shouldn't happen that good code will randomly *fail* this test. 1.101 + */ 1.102 +function run_test() { 1.103 + /* 1.104 + * TEST 1 tests that: 1.105 + * <body onhashchange = ... > works, 1.106 + * the event is (not) fired at the correct times 1.107 + */ 1.108 + var frame = document.getElementById("frame"); 1.109 + var frameCw = frame.contentWindow; 1.110 + 1.111 + enableIframeLoadCallback(); 1.112 + frameCw.document.location = "file_bug385434_1.html"; 1.113 + // Wait for the iframe to load and for our callback to fire 1.114 + yield undefined; 1.115 + 1.116 + noEventExpected("No hashchange expected initially."); 1.117 + 1.118 + sendMouseEvent({type: "click"}, "link1", frameCw); 1.119 + yield undefined; 1.120 + eventExpected("Clicking link1 should trigger a hashchange."); 1.121 + 1.122 + sendMouseEvent({type: "click"}, "link1", frameCw); 1.123 + longWait(); 1.124 + yield undefined; 1.125 + // succeed if a hashchange event wasn't triggered while we were waiting 1.126 + noEventExpected("Clicking link1 again should not trigger a hashchange."); 1.127 + 1.128 + sendMouseEvent({type: "click"}, "link2", frameCw); 1.129 + yield undefined; 1.130 + eventExpected("Clicking link2 should trigger a hashchange."); 1.131 + 1.132 + frameCw.history.go(-1); 1.133 + yield undefined; 1.134 + eventExpected("Going back should trigger a hashchange."); 1.135 + 1.136 + frameCw.history.go(1); 1.137 + yield undefined; 1.138 + eventExpected("Going forward should trigger a hashchange."); 1.139 + 1.140 + // window.location has a trailing '#' right now, so we append "link1", not 1.141 + // "#link1". 1.142 + frameCw.window.location = frameCw.window.location + "link1"; 1.143 + yield undefined; 1.144 + eventExpected("Assigning to window.location should trigger a hashchange."); 1.145 + 1.146 + // Set up history in the iframe which looks like: 1.147 + // file_bug385434_1.html#link1 1.148 + // file_bug385434_2.html 1.149 + // file_bug385434_1.html#foo <-- current page 1.150 + enableIframeLoadCallback(); 1.151 + frameCw.window.location = "file_bug385434_2.html"; 1.152 + yield undefined; 1.153 + 1.154 + enableIframeLoadCallback(); 1.155 + frameCw.window.location = "file_bug385434_1.html#foo"; 1.156 + yield undefined; 1.157 + 1.158 + // Now when we do history.go(-2) on the frame, it *shouldn't* fire a 1.159 + // hashchange. Although the URIs differ only by their hashes, they belong to 1.160 + // two different Documents. 1.161 + frameCw.history.go(-2); 1.162 + longWait(); 1.163 + yield undefined; 1.164 + noEventExpected("Moving between different Documents shouldn't " + 1.165 + "trigger a hashchange."); 1.166 + 1.167 + /* 1.168 + * TEST 2 tests that: 1.169 + * <frameset onhashchange = ... > works, 1.170 + * the event is targeted at the window object 1.171 + * the event's cancelable, bubbles settings are correct 1.172 + */ 1.173 + enableIframeLoadCallback(); 1.174 + frameCw.document.location = "file_bug385434_2.html"; 1.175 + yield undefined; 1.176 + 1.177 + frameCw.document.location = "file_bug385434_2.html#foo"; 1.178 + yield undefined; 1.179 + 1.180 + eventExpected("frame onhashchange should fire events."); 1.181 + // iframe should set gSampleEvent 1.182 + is(gSampleEvent.target, frameCw, 1.183 + "The hashchange event should be targeted to the window."); 1.184 + is(gSampleEvent.type, "hashchange", 1.185 + "Event type should be 'hashchange'."); 1.186 + is(gSampleEvent.cancelable, false, 1.187 + "The hashchange event shouldn't be cancelable."); 1.188 + is(gSampleEvent.bubbles, true, 1.189 + "The hashchange event should bubble."); 1.190 + 1.191 + /* 1.192 + * TEST 3 tests that: 1.193 + * hashchange is dispatched if the current document readyState is 1.194 + * not "complete" (bug 504837). 1.195 + */ 1.196 + frameCw.document.location = "file_bug385434_3.html"; 1.197 + yield undefined; 1.198 + eventExpected("Hashchange should fire even if the document " + 1.199 + "hasn't finished loading."); 1.200 + 1.201 + SimpleTest.finish(); 1.202 + yield undefined; 1.203 +} 1.204 + 1.205 +var gGen = run_test(); 1.206 +gGen.next(); 1.207 + 1.208 +</script> 1.209 +</pre> 1.210 +</body> 1.211 +</html>