<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> <window title="Basic Plugin Tests" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <title>Plugin Hang UI Test</title> <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> <script type="application/javascript" src="plugin-utils.js" /> <script type="application/javascript" src="http://mochi.test:8888/chrome/dom/plugins/test/mochitest/hang_test.js" /> <script type="application/javascript" src="http://mochi.test:8888/chrome/dom/plugins/test/mochitest/hangui_common.js" /> <body xmlns="http://www.w3.org/1999/xhtml"> <iframe id="iframe1" src="hangui_subpage.html" width="400" height="400"></iframe> </body> <script class="testbody" type="application/javascript"> <![CDATA[ SimpleTest.waitForExplicitFinish(); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); Components.utils.import("resource://gre/modules/Services.jsm"); const hangUITimeoutPref = "dom.ipc.plugins.hangUITimeoutSecs"; const hangUIMinDisplayPref = "dom.ipc.plugins.hangUIMinDisplaySecs"; const timeoutPref = "dom.ipc.plugins.timeoutSecs"; var worker = new ChromeWorker("hangui_iface.js"); worker.onmessage = function(event) { var result = event.data; var params = result.params; var output = params.testName; if (result.msg) { output += ": " + result.msg; } ok(result.status, output); if (params.callback) { var cb = eval(params.callback); var timeout = setTimeout(function() { clearTimeout(timeout); cb(); }, 100); } }; worker.onerror = function(event) { var output = "Error: " + event.message + " at " + event.filename + ":" + event.lineno; ok(false, output); }; var iframe; var p; var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); function hanguiOperation(testName, timeoutSec, expectFind, expectClose, opCode, commandId, check, cb) { var timeoutMs = timeoutSec * 1000 + EPSILON_MS; worker.postMessage({ "timeoutMs": timeoutMs, "expectToFind": expectFind, "expectToClose": expectClose, "opCode": opCode, "commandId": commandId, "check": check, "testName": testName, "callback": cb }); } function hanguiExpect(testName, shouldBeShowing, shouldClose, cb) { var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref); if (!shouldBeShowing && !timeoutSec) { timeoutSec = Services.prefs.getIntPref(timeoutPref); } hanguiOperation(testName, timeoutSec, shouldBeShowing, shouldClose, HANGUIOP_NOTHING, 0, false, cb); } function hanguiContinue(testName, check, cb) { var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref); hanguiOperation(testName, timeoutSec, true, true, HANGUIOP_COMMAND, IDC_CONTINUE, check, cb); } function hanguiStop(testName, check, cb) { var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref); hanguiOperation(testName, timeoutSec, true, true, HANGUIOP_COMMAND, IDC_STOP, check, cb); } function hanguiCancel(testName, cb) { var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref); hanguiOperation(testName, timeoutSec, true, true, HANGUIOP_CANCEL, 0, false, cb); } function finishTest() { if (obsCount > 0) { os.removeObserver(testObserver, "plugin-crashed"); --obsCount; } SpecialPowers.clearUserPref(hangUITimeoutPref); SpecialPowers.clearUserPref(hangUIMinDisplayPref); SpecialPowers.clearUserPref(timeoutPref); SimpleTest.finish(); } function runTests() { resetVars(); hanguiOperation("Prime ChromeWorker", 0, false, false, HANGUIOP_NOTHING, 0, false, "test1"); } window.frameLoaded = runTests; var obsCount = 0; function onPluginCrashedHangUI(aEvent) { ok(true, "Plugin crashed notification received"); is(aEvent.type, "PluginCrashed", "event is correct type"); is(p, aEvent.target, "Plugin crashed event target is plugin element"); ok(aEvent instanceof PluginCrashedEvent, "plugin crashed event has the right interface"); is(typeof aEvent.pluginDumpID, "string", "pluginDumpID is correct type"); isnot(aEvent.pluginDumpID, "", "got a non-empty dump ID"); is(typeof aEvent.pluginName, "string", "pluginName is correct type"); is(aEvent.pluginName, "Test Plug-in", "got correct plugin name"); is(typeof aEvent.pluginFilename, "string", "pluginFilename is correct type"); isnot(aEvent.pluginFilename, "", "got a non-empty filename"); // The app itself may or may not have decided to submit the report, so // allow either true or false here. ok("submittedCrashReport" in aEvent, "submittedCrashReport is a property of event"); is(typeof aEvent.submittedCrashReport, "boolean", "submittedCrashReport is correct type"); os.removeObserver(testObserver, "plugin-crashed"); --obsCount; } function resetVars() { iframe = document.getElementById('iframe1'); p = iframe.contentDocument.getElementById("plugin1"); if (obsCount == 0) { os.addObserver(testObserver, "plugin-crashed", true); ++obsCount; } iframe.contentDocument.addEventListener("PluginCrashed", onPluginCrashedHangUI, false); } function test9b() { hanguiExpect("test9b: Plugin Hang UI is not showing (checkbox)", false); p.stall(STALL_DURATION); hanguiExpect("test9b: Plugin Hang UI is still not showing (checkbox)", false, false, "finishTest"); p.stall(STALL_DURATION); } function test9a() { resetVars(); SpecialPowers.setIntPref(hangUITimeoutPref, 1); SpecialPowers.setIntPref(hangUIMinDisplayPref, 1); SpecialPowers.setIntPref(timeoutPref, 45); hanguiContinue("test9a: Continue button works with checkbox", true, "test9b"); p.stall(STALL_DURATION); } function test9() { window.frameLoaded = test9a; iframe.contentWindow.location.reload(); } function test8a() { resetVars(); SpecialPowers.setIntPref(hangUITimeoutPref, 1); SpecialPowers.setIntPref(hangUIMinDisplayPref, 4); hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9"); var exceptionThrown = false; try { p.hang(); } catch(e) { exceptionThrown = true; } ok(exceptionThrown, "test8a: Exception thrown from hang() when plugin was terminated"); } function test8() { window.frameLoaded = test8a; iframe.contentWindow.location.reload(); } function test7a() { resetVars(); SpecialPowers.setIntPref(hangUITimeoutPref, 0); hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8"); var exceptionThrown = false; try { p.hang(); } catch(e) { exceptionThrown = true; } ok(exceptionThrown, "test7a: Exception thrown from hang() when plugin was terminated"); } function test7() { window.frameLoaded = test7a; iframe.contentWindow.location.reload(); } function test6() { SpecialPowers.setIntPref(hangUITimeoutPref, 1); SpecialPowers.setIntPref(hangUIMinDisplayPref, 1); SpecialPowers.setIntPref(timeoutPref, 3); hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7"); var exceptionThrown = false; try { p.hang(); } catch(e) { exceptionThrown = true; } ok(exceptionThrown, "test6: Exception thrown from hang() when plugin was terminated (child timeout)"); } function test5a() { resetVars(); hanguiCancel("test5a: Close button works", "test6"); p.stall(STALL_DURATION); } function test5() { window.frameLoaded = test5a; iframe.contentWindow.location.reload(); } function test4() { hanguiStop("test4: Stop button works", false, "test5"); // We'll get an exception here because the plugin was terminated var exceptionThrown = false; try { p.hang(); } catch(e) { exceptionThrown = true; } ok(exceptionThrown, "test4: Exception thrown from hang() when plugin was terminated"); } function test3() { hanguiContinue("test3: Continue button works", false, "test4"); p.stall(STALL_DURATION); } function test2() { // This test is identical to test1 because there were some bugs where the // Hang UI would show on the first hang but not on subsequent hangs hanguiExpect("test2: Plugin Hang UI is showing", true, true, "test3"); p.stall(STALL_DURATION); } function test1() { SpecialPowers.setIntPref(hangUITimeoutPref, 1); SpecialPowers.setIntPref(hangUIMinDisplayPref, 1); SpecialPowers.setIntPref(timeoutPref, 45); hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2"); p.stall(STALL_DURATION); } ]]> </script> </window>