author | Jim Mathies <jmathies@mozilla.com> |
Tue, 19 Feb 2013 19:51:02 -0600 | |
changeset 122443 | aae721e94e2c79143f68aac5b9b75ff03178824a |
parent 122442 | 17b80182ebd8b4502d1bef94b487018631794620 |
child 122444 | 4b6b0d48930130b9da23e9776495d4cd0423bb1b |
push id | 24342 |
push user | ryanvm@gmail.com |
push date | Thu, 21 Feb 2013 13:05:06 +0000 |
treeherder | mozilla-central@702d2814efbf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mbrubeck |
bugs | 782810 |
milestone | 22.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/metro/base/tests/Makefile.in +++ b/browser/metro/base/tests/Makefile.in @@ -20,16 +20,17 @@ BROWSER_TESTS = \ browser_onscreen_keyboard.html \ browser_remotetabs.js \ browser_downloads.js \ browser_plugin_input.html \ browser_plugin_input_mouse.js \ browser_plugin_input_keyboard.js \ browser_context_menu_tests.js \ browser_context_menu_tests_01.html \ + browser_context_menu_tests_02.html \ $(NULL) BROWSER_TEST_RESOURCES = \ res\image01.png \ $(NULL) libs:: $(BROWSER_TESTS) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/
--- a/browser/metro/base/tests/browser_context_menu_tests.js +++ b/browser/metro/base/tests/browser_context_menu_tests.js @@ -15,43 +15,272 @@ function debugClipFlavors(aClip) let count = array.Count(); info("flavors:" + count); for (let idx = 0; idx < count; idx++) { let string = array.GetElementAt(idx).QueryInterface(Ci.nsISupportsString); info("[" + idx + "] " + string); } } +// XXX won't work with out of process content +function emptyClipboard() { + Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard) + .emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); +} + +// Image context menu tests +gTests.push({ + desc: "text context menu", + run: function test() { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + + info(chromeRoot + "browser_context_menu_tests_02.html"); + yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); + + purgeEventQueue(); + + let win = Browser.selectedTab.browser.contentWindow; + + yield hideContextUI(); + + //////////////////////////////////////////////////////////// + // Context menu in content on selected text + + // select some text + let span = win.document.getElementById("text1"); + win.getSelection().selectAllChildren(span); + + // invoke selection context menu + let promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, span, 85, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + // selected text context: + checkContextUIMenuItemVisibility(["context-copy", + "context-search"]); + + promise = waitForEvent(document, "popuphidden"); + ContextMenuUI.hide(); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + win.getSelection().removeAllRanges(); + + //////////////////////////////////////////////////////////// + // Context menu in content on selected text that includes a link + + // invoke selection with link context menu + let link = win.document.getElementById("text2-link"); + win.getSelection().selectAllChildren(link); + promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, link, 40, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + // selected text context: + checkContextUIMenuItemVisibility(["context-copy", + "context-search", + "context-open-in-new-tab", + "context-copy-link"]); + + promise = waitForEvent(document, "popuphidden"); + ContextMenuUI.hide(); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + win.getSelection().removeAllRanges(); + + //////////////////////////////////////////////////////////// + // Context menu in content on a link + + link = win.document.getElementById("text2-link"); + promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, link, 40, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + // selected text context: + checkContextUIMenuItemVisibility(["context-open-in-new-tab", + "context-copy-link", + "context-bookmark-link"]); + + promise = waitForEvent(document, "popuphidden"); + ContextMenuUI.hide(); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + //////////////////////////////////////////////////////////// + // context in input with no selection, no data on clipboard + + emptyClipboard(); + + let input = win.document.getElementById("text3-input"); + promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, input, 20, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + checkContextUIMenuItemVisibility(["context-copy", + "context-select", + "context-select-all"]); + + // copy menu item should copy all text + let menuItem = document.getElementById("context-copy"); + ok(menuItem, "menu item exists"); + ok(!menuItem.hidden, "menu item visible"); + + let popupPromise = waitForEvent(document, "popuphidden"); + EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); + yield popupPromise; + ok(popupPromise && !(popupPromise instanceof Error), "promise error"); + let string = SpecialPowers.getClipboardData("text/unicode"); + ok(string, "hello, I'm sorry but I must be going.", "copy all"); + + emptyClipboard(); + + //////////////////////////////////////////////////////////// + // context in input with text selection, no data on clipboard + + input = win.document.getElementById("text3-input"); + input.select(); + promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, input, 20, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + // selected text context: + checkContextUIMenuItemVisibility(["context-copy", + "context-search"]); + + promise = waitForEvent(document, "popuphidden"); + ContextMenuUI.hide(); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + //////////////////////////////////////////////////////////// + // context in input with no selection, data on clipboard + + SpecialPowers.clipboardCopyString("foo"); + input = win.document.getElementById("text3-input"); + input.select(); + promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, input, 20, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + // selected text context: + checkContextUIMenuItemVisibility(["context-copy", + "context-search", + "context-paste"]); + + promise = waitForEvent(document, "popuphidden"); + ContextMenuUI.hide(); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + //////////////////////////////////////////////////////////// + // context in empty input, data on clipboard (paste operation) + + SpecialPowers.clipboardCopyString("foo"); + input = win.document.getElementById("text3-input"); + input.value = ""; + + promise = waitForEvent(document, "popupshown"); + sendContextMenuClickToElement(win, input, 20, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should be visible + ok(ContextMenuUI._menuPopup._visible, "is visible"); + + // selected text context: + checkContextUIMenuItemVisibility(["context-paste"]); + + promise = waitForEvent(document, "popuphidden"); + ContextMenuUI.hide(); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + //////////////////////////////////////////////////////////// + // context in empty input, no data on clipboard (??) + + emptyClipboard(); + + input = win.document.getElementById("text3-input"); + input.value = ""; + + promise = waitForEvent(Elements.tray, "transitionend"); + sendContextMenuClickToElement(win, input, 20, 10); + yield promise; + ok(promise && !(promise instanceof Error), "promise error"); + + // should *not* be visible + ok(!ContextMenuUI._menuPopup._visible, "is visible"); + + // the test above will invoke the app bar + yield hideContextUI(); + + Browser.closeTab(Browser.selectedTab); + purgeEventQueue(); + } +}); + // Image context menu tests gTests.push({ desc: "image context menu", run: function test() { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); info(chromeRoot + "browser_context_menu_tests_01.html"); yield addTab(chromeRoot + "browser_context_menu_tests_01.html"); let win = Browser.selectedTab.browser.contentWindow; + purgeEventQueue(); + yield hideContextUI(); + // If we don't do this, sometimes the first sendContextMenuClick + // will trigger the app bar. + yield waitForImageLoad(win, "image01"); + //////////////////////////////////////////////////////////// // Context menu options // image01 - 1x1x100x100 let promise = waitForEvent(document, "popupshown"); sendContextMenuClick(win, 10, 10); yield promise; ok(promise && !(promise instanceof Error), "promise error"); purgeEventQueue(); ok(ContextMenuUI._menuPopup._visible, "is visible"); - checkContextUIMenuItemCount(4); + checkContextUIMenuItemVisibility(["context-save-image-lib", + "context-copy-image", + "context-copy-image-loc", + "context-open-image-tab"]); //////////////////////////////////////////////////////////// // Save to image library let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties); let saveLocationPath = dirSvc.get("Pict", Components.interfaces.nsIFile); saveLocationPath.append("image01.png"); @@ -80,74 +309,74 @@ gTests.push({ purgeEventQueue(); ok(saveLocationPath.exists(), "image saved"); //////////////////////////////////////////////////////////// // Copy image let promise = waitForEvent(document, "popupshown"); - sendContextMenuClick(win, 30, 30); + sendContextMenuClick(win, 20, 20); yield promise; ok(promise && !(promise instanceof Error), "promise error"); ok(ContextMenuUI._menuPopup._visible, "is visible"); menuItem = document.getElementById("context-copy-image"); ok(menuItem, "menu item exists"); ok(!menuItem.hidden, "menu item visible"); popupPromise = waitForEvent(document, "popuphidden"); EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); yield popupPromise; ok(popupPromise && !(popupPromise instanceof Error), "promise error"); purgeEventQueue(); let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); let flavors = ["image/png"]; - ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my flavor"); + ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my png flavor"); //////////////////////////////////////////////////////////// // Copy image location promise = waitForEvent(document, "popupshown"); - sendContextMenuClick(win, 60, 60); + sendContextMenuClick(win, 30, 30); yield promise; ok(promise && !(promise instanceof Error), "promise error"); ok(ContextMenuUI._menuPopup._visible, "is visible"); menuItem = document.getElementById("context-copy-image-loc"); ok(menuItem, "menu item exists"); ok(!menuItem.hidden, "menu item visible"); popupPromise = waitForEvent(document, "popuphidden"); EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); yield popupPromise; ok(popupPromise && !(popupPromise instanceof Error), "promise error"); purgeEventQueue(); let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); let flavors = ["text/unicode"]; - ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my flavor"); + ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my text flavor"); let xfer = Cc["@mozilla.org/widget/transferable;1"]. createInstance(Ci.nsITransferable); xfer.init(null); xfer.addDataFlavor("text/unicode"); clip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard); let str = new Object(); let strLength = new Object(); xfer.getTransferData("text/unicode", str, strLength); str = str.value.QueryInterface(Components.interfaces.nsISupportsString); ok(str == "chrome://mochitests/content/metro/res/image01.png", "url copied"); //////////////////////////////////////////////////////////// // Open image in new tab promise = waitForEvent(document, "popupshown"); - sendContextMenuClick(win, 60, 60); + sendContextMenuClick(win, 40, 40); yield promise; ok(promise && !(promise instanceof Error), "promise error"); ok(ContextMenuUI._menuPopup._visible, "is visible"); menuItem = document.getElementById("context-open-image-tab"); ok(menuItem, "menu item exists"); ok(!menuItem.hidden, "menu item visible"); let tabPromise = waitForEvent(document, "TabOpen");
--- a/browser/metro/base/tests/browser_context_menu_tests_01.html +++ b/browser/metro/base/tests/browser_context_menu_tests_01.html @@ -2,13 +2,13 @@ <html> <head> <style> </style> </head> <body style="padding: 1px; margin: 1px;"> <div style="margin: 0; padding: 0;"> <span> - <img width="100" height="100" src="./res/image01.png" /> + <img id="image01" width="100" height="100" src="./res/image01.png" /> </span> </div> </body> </html> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/browser/metro/base/tests/browser_context_menu_tests_02.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <style> + </style> + </head> +<body style="padding: 10px; margin: 10px;"> + <div style="margin: 0; padding: 5px;"> + <span id="text1">hello, I'm sorry but I must be going.</span> + </div> + <div style="margin: 0; padding: 5px;"> + <span id="text2"><a id="text2-link" href="#test">hello, I'm sorry but</a> I must be going.</span> + </div> + <div style="margin: 0; padding: 5px;"> + <span id="text3"><input id="text3-input" value="hello, I'm sorry but I must be going." style="width:200px;"/></span> + </div> +</body> +</html> \ No newline at end of file
--- a/browser/metro/base/tests/head.js +++ b/browser/metro/base/tests/head.js @@ -27,23 +27,43 @@ function checkContextUIMenuItemCount(aCo let visibleCount = 0; for (let idx = 0; idx < ContextMenuUI._commands.childNodes.length; idx++) { if (!ContextMenuUI._commands.childNodes[idx].hidden) visibleCount++; } is(visibleCount, aCount, "command list count"); } +function checkContextUIMenuItemVisibility(aVisibleList) +{ + let errors = 0; + for (let idx = 0; idx < ContextMenuUI._commands.childNodes.length; idx++) { + let item = ContextMenuUI._commands.childNodes[idx]; + if (aVisibleList.indexOf(item.id) != -1 && item.hidden) { + // item should be visible + errors++; + info("should be visible:" + item.id); + } else if (aVisibleList.indexOf(item.id) == -1 && !item.hidden) { + // item should be hidden + errors++; + info("should be hidden:" + item.id); + } + } + is(errors, 0, "context menu item list visibility"); +} + /*============================================================================= Asynchronous Metro ui helpers =============================================================================*/ function hideContextUI() { + purgeEventQueue(); if (ContextUI.isVisible) { + info("is visible, waiting..."); let promise = waitForEvent(Elements.tray, "transitionend"); ContextUI.dismiss(); return promise; } } /*============================================================================= Asynchronous test helpers @@ -88,16 +108,17 @@ function addTab(aUrl) { * } * * @param aSubject the element that should receive the event * @param aEventName the event to wait for * @param aTimeoutMs the number of miliseconds to wait before giving up * @returns a Promise that resolves to the received event, or to an Error */ function waitForEvent(aSubject, aEventName, aTimeoutMs) { + info("waitForEvent: on " + aSubject + " event: " + aEventName); let eventDeferred = Promise.defer(); let timeoutMs = aTimeoutMs || kDefaultWait; let timerID = setTimeout(function wfe_canceller() { aSubject.removeEventListener(aEventName, onEvent); eventDeferred.reject( new Error(aEventName+" event timeout") ); }, timeoutMs); function onEvent(aEvent) { @@ -184,16 +205,33 @@ function waitForCondition(aCondition, aT setTimeout(testCondition, intervalMs); } } setTimeout(testCondition, 0); return deferred.promise; } +/* + * Waits for an image in a page to load. Wrapper around waitForCondition. + * + * @param aWindow the tab or window that contains the image. + * @param aImageId the id of the image in the page. + * @returns a Promise that resolves to true, or to an Error + */ +function waitForImageLoad(aWindow, aImageId) { + let elem = aWindow.document.getElementById(aImageId); + return waitForCondition(function () { + let request = elem.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST); + if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE)) + return true; + return false; + }, 5000, 100); +} + /** * Waits a specified number of miliseconds for an observer event. * * @param aObsEvent the observer event to wait for * @param aTimeoutMs the number of miliseconds to wait before giving up * @returns a Promise that resolves to true, or to an Error */ function waitForObserver(aObsEvent, aTimeoutMs) { @@ -334,16 +372,24 @@ function synthesizeNativeMouseMUp(aEleme function sendContextMenuClick(aWindow, aX, aY) { let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendMouseEventToWindow("contextmenu", aX, aY, 2, 1, 0, true, 1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH); } +function sendContextMenuClickToElement(aWindow, aElement, aX, aY) { + let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + let rect = aElement.getBoundingClientRect(); + utils.sendMouseEventToWindow("contextmenu", rect.left + aX, rect.top + aY, 2, 1, 0, true, + 1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH); +} + /*============================================================================= System utilities =============================================================================*/ /* * purgeEventQueue - purges the event queue on the calling thread. * Pumps latent in-process message manager events awaiting delivery. */