diff --git a/browser/base/content/test/browser_bug556061.js b/browser/base/content/test/browser_bug556061.js index 0b8dd90af252..17e2c6d4f94f 100644 --- a/browser/base/content/test/browser_bug556061.js +++ b/browser/base/content/test/browser_bug556061.js @@ -35,53 +35,21 @@ * * ***** END LICENSE BLOCK ***** */ -let cbSvc = Cc["@mozilla.org/widget/clipboard;1"]. - getService(Ci.nsIClipboard); - let testURL = "http://example.org/browser/browser/base/content/test/dummy_page.html"; let testActionURL = "moz-action:switchtab," + testURL; let testTab; -let clipboardText = ""; -let currentClipboardText = null; -let clipboardPolls = 0; - -// The clipboard can have a string value without it being the one we expect, so -// we'll check the current value against the previous value to see if it changed. -// We can do this because our expected clipboard value should be different each -// time we wait. -function waitForClipboard() { - // Poll for a maximum of 5s (each run happens after 100ms). - if (++clipboardPolls > 50) { - // Log the failure. - ok(false, "Timed out while polling clipboard for pasted data"); - // Cleanup and interrupt the test. - cleanup(); - return; - } - - let xferable = Cc["@mozilla.org/widget/transferable;1"]. - createInstance(Ci.nsITransferable); - xferable.addDataFlavor("text/unicode"); - cbSvc.getData(xferable, cbSvc.kGlobalClipboard); - try { - let data = {}; - xferable.getTransferData("text/unicode", data, {}); - currentClipboardText = data.value.QueryInterface(Ci.nsISupportsString).data; - } catch (e) {} - - if (currentClipboardText == clipboardText) { - setTimeout(waitForClipboard, 100); - } else { - clipboardText = currentClipboardText; - runNextTest(); - } -} function runNextTest() { - // reset clipboard polling count - clipboardPolls = 0; - // run next test, just assume we won't call in here without more tests - tests.shift()(); + if (tests.length) { + let t = tests.shift(); + waitForClipboard(t.expected, t.setup, function() { + t.success(); + runNextTest(); + }, cleanup); + } + else { + cleanup(); + } } function cleanup() { @@ -89,65 +57,64 @@ function cleanup() { finish(); } -// Tests in order. Some tests setup for the next actual test... let tests = [ - function () { - // Set the urlbar to include the moz-action - gURLBar.value = testActionURL; - is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value"); + { + expected: testURL, + setup: function() { + gURLBar.value = testActionURL; + is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value"); - // Focus the urlbar so we can select it all & copy - gURLBar.focus(); - gURLBar.select(); - goDoCommand("cmd_copy"); - waitForClipboard(); + // Focus the urlbar so we can select it all & copy + gURLBar.focus(); + gURLBar.select(); + goDoCommand("cmd_copy"); + }, + success: function() { + is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying"); + } }, - function () { - is(clipboardText, testURL, "Clipboard has the correct value"); - // We shouldn't have changed the value of gURLBar - is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying"); - - // Set selectionStart/End manually and make sure it matches the substring - gURLBar.selectionStart = 0; - gURLBar.selectionEnd = 10; - goDoCommand("cmd_copy"); - waitForClipboard(); + { + expected: testURL.substring(0, 10), + setup: function() { + // Set selectionStart/End manually and make sure it matches the substring + gURLBar.selectionStart = 0; + gURLBar.selectionEnd = 10; + goDoCommand("cmd_copy"); + }, + success: function() { + is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying"); + } }, - function () { - is(clipboardText, testURL.substring(0, 10), "Clipboard has the correct value"); - is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying"); - - // Setup for cut test... - // Select all - gURLBar.select(); - goDoCommand("cmd_cut"); - waitForClipboard(); + { + expected: testURL, + setup: function() { + // Setup for cut test... + // Select all + gURLBar.select(); + goDoCommand("cmd_cut"); + }, + success: function() { + is(gURLBar.value, "", "gURLBar.value is now empty"); + } }, - function () { - is(clipboardText, testURL, "Clipboard has the correct value"); - is(gURLBar.value, "", "gURLBar.value is now empty"); + { + expected: testURL.substring(testURL.length - 10, testURL.length), + setup: function() { + // Reset urlbar value + gURLBar.value = testActionURL; + // Sanity check that we have the right value + is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value"); - // Reset urlbar value - gURLBar.value = testActionURL; - // Sanity check that we have the right value - is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value"); - - // Now just select part of the value & cut that. - gURLBar.selectionStart = testURL.length - 10; - gURLBar.selectionEnd = testURL.length; - - goDoCommand("cmd_cut"); - waitForClipboard(); - }, - function () { - is(clipboardText, testURL.substring(testURL.length - 10, testURL.length), - "Clipboard has the correct value"); - is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value"); - - // We're done, so just finish up - cleanup(); + // Now just select part of the value & cut that. + gURLBar.selectionStart = testURL.length - 10; + gURLBar.selectionEnd = testURL.length; + goDoCommand("cmd_cut"); + }, + success: function() { + is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value"); + } } -] +]; function test() { waitForExplicitFinish(); diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js index 3a37cc1a3355..f1b94cf8f3de 100644 --- a/testing/mochitest/browser-test.js +++ b/testing/mochitest/browser-test.js @@ -306,6 +306,10 @@ function testScope(aTester, aTest) { self.SimpleTest.waitForFocus(callback, targetWindow, expectBlankPage); }; + this.waitForClipboard = function test_waitForClipboard(expected, setup, success, failure) { + self.SimpleTest.waitForClipboard(expected, setup, success, failure); + }; + this.registerCleanupFunction = function test_registerCleanupFunction(aFunction) { self.__cleanupFunctions.push(aFunction); }; diff --git a/testing/mochitest/tests/SimpleTest/SimpleTest.js b/testing/mochitest/tests/SimpleTest/SimpleTest.js index deec90bb82e5..17dcf1fb3ca9 100644 --- a/testing/mochitest/tests/SimpleTest/SimpleTest.js +++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js @@ -350,6 +350,83 @@ SimpleTest.waitForFocus = function (callback, targetWindow, expectBlankPage) { } }; +SimpleTest.waitForClipboard_polls = 0; + +/* + * Polls the clipboard waiting for the expected value. A known value different than + * the expected value is put on the clipboard first (and also polled for) so we + * can be sure the value we get isn't just the expected value because it was already + * on the clipboard. This only uses the global clipboard and only for text/unicode + * values. + * + * @param aExpectedVal + * The string value that is expected to be on the clipboard + * @param aSetupFn + * A function responsible for setting the clipboard to the expected value, + * called after the known value setting succeeds. + * @param aSuccessFn + * A function called when the expected value is found on the clipboard. + * @param aFailureFn + * A function called if the expected value isn't found on the clipboard + * within 5s. It can also be called if the known value can't be found. + */ +SimpleTest.waitForClipboard = function(aExpectedVal, aSetupFn, aSuccessFn, aFailureFn) { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + + var cbSvc = Components.classes["@mozilla.org/widget/clipboard;1"]. + getService(Components.interfaces.nsIClipboard); + + // reset for the next use + function reset() { + SimpleTest.waitForClipboard_polls = 0; + } + + function wait(expectedVal, successFn, failureFn) { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + + if (++SimpleTest.waitForClipboard_polls > 50) { + // Log the failure. + SimpleTest.ok(false, "Timed out while polling clipboard for pasted data. " + + "Expected " + expectedVal); + reset(); + failureFn(); + return; + } + + var xferable = Components.classes["@mozilla.org/widget/transferable;1"]. + createInstance(Components.interfaces.nsITransferable); + xferable.addDataFlavor("text/unicode"); + cbSvc.getData(xferable, cbSvc.kGlobalClipboard); + var data = {}; + try { + xferable.getTransferData("text/unicode", data, {}); + data = data.value.QueryInterface(Components.interfaces.nsISupportsString).data; + } catch (e) {} + + if (data == expectedVal) { + // Don't show the success message when waiting for preExpectedVal + if (data != preExpectedVal) + SimpleTest.ok(true, + "Clipboard has the correct value (" + expectedVal + ")"); + reset(); + successFn(); + } else { + setTimeout(function() wait(expectedVal, successFn, failureFn), 100); + } + } + + // First we wait for a known value != aExpectedVal + var preExpectedVal = aExpectedVal + "-waitForClipboard-known-value"; + var cbHelperSvc = Components.classes["@mozilla.org/widget/clipboardhelper;1"]. + getService(Components.interfaces.nsIClipboardHelper); + cbHelperSvc.copyString(preExpectedVal); + wait(preExpectedVal, function() { + // Call the original setup fn + aSetupFn(); + wait(aExpectedVal, aSuccessFn, aFailureFn); + }, aFailureFn); +} + /** * Executes a function shortly after the call, but lets the caller continue * working (or finish).